Skip to content

Commit

Permalink
Merge pull request #51 from iedon/nat
Browse files Browse the repository at this point in the history
Add nat mode
  • Loading branch information
cmj2002 authored Feb 4, 2025
2 parents b5dae4b + 604d5ad commit 0e8fe4f
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 0 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ ENV WARP_SLEEP=2
ENV REGISTER_WHEN_MDM_EXISTS=
ENV WARP_LICENSE_KEY=
ENV BETA_FIX_HOST_CONNECTIVITY=
ENV WARP_ENABLE_NAT=

HEALTHCHECK --interval=15s --timeout=5s --start-period=10s --retries=3 \
CMD /healthcheck/index.sh
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ services:
environment:
- WARP_SLEEP=2
# - WARP_LICENSE_KEY= # optional
# - WARP_ENABLE_NAT=1 # enable nat
cap_add:
# Docker already have them, these are for podman users
- MKNOD
Expand All @@ -40,6 +41,10 @@ services:
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv4.conf.all.src_valid_mark=1
# uncomment for nat
# - net.ipv4.ip_forward=1
# - net.ipv6.conf.all.forwarding=1
# - net.ipv6.conf.all.accept_ra=2
volumes:
- ./data:/var/lib/cloudflare-warp
```
Expand All @@ -61,6 +66,7 @@ You can configure the container through the following environment variables:
- `GOST_ARGS`: The arguments passed to GOST. The default is `-L :1080`, which means to listen on port 1080 in the container at the same time through HTTP and SOCKS5 protocols. If you want to have UDP support or use advanced features provided by other protocols, you can modify this parameter. For more information, refer to [GOST documentation](https://v2.gost.run/en/). If you modify the port number, you may also need to modify the port mapping in the `docker-compose.yml`.
- `REGISTER_WHEN_MDM_EXISTS`: If set, will register consumer account (WARP or WARP+, in contrast to Zero Trust) even when `mdm.xml` exists. You usually don't need this, as `mdm.xml` are usually used for Zero Trust. However, some users may want to adjust advanced settings in `mdm.xml` while still using consumer account.
- `BETA_FIX_HOST_CONNECTIVITY`: If set, will add checks for host connectivity into healthchecks and automatically fix it if necessary. See [host connectivity issue](docs/host-connectivity.md) for more information.
- `WARP_ENABLE_NAT`: If set, will work as warp mode and turn NAT on. You can route L3 traffic through `warp-docker` to Warp. See [nat gateway](docs/nat-gateway.md) for more information.

Data persistence: Use the host volume `./data` to persist the data of the WARP client. You can change the location of this directory or use other types of volumes. If you modify the `WARP_LICENSE_KEY`, please delete the `./data` directory so that the client can detect and register again.

Expand Down
5 changes: 5 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ services:
environment:
- WARP_SLEEP=2
# - WARP_LICENSE_KEY= # optional
# - WARP_ENABLE_NAT=1 # enable nat
cap_add:
# Docker already have them, these are for podman users
- MKNOD
Expand All @@ -22,5 +23,9 @@ services:
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv4.conf.all.src_valid_mark=1
# uncomment for nat
# - net.ipv4.ip_forward=1
# - net.ipv6.conf.all.forwarding=1
# - net.ipv6.conf.all.accept_ra=2
volumes:
- ./data:/var/lib/cloudflare-warp
Binary file added docs/images/nat-gateway-tldr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
105 changes: 105 additions & 0 deletions docs/nat-gateway.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Use warp-docker as a NAT gateway to route your traffic

Instead of using a SOCKS5 proxy, you can also route your traffic to `warp-docker`, with `WARP_ENABLE_NAT=1` and correct forwarding settings.

![Use warp-docker as a NAT gateway](images/nat-gateway-tldr.png)

## Steps
- Turn on nat by set `WARP_ENABLE_NAT=1`.

You will have to fix IPAM for `warp-docker`.

Don't forget to toggle IPv6 on if you are using an external network that not managed by Docker compose.
```yaml
# ...
networks:
dockernet: # The network warp-docker will use
ipv4_address: 192.168.255.1 # fixed IPv4
ipv6_address: fd42:4242:2189:ac:255::1 # fixed IPv6
# ...
networks:
dockernet: # Sample network using external bridged network
external: true
```
Don't forget to turn IP forwarding on, via sysctl:
```yaml
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.forwarding=1
- net.ipv6.conf.all.accept_ra=2
```
- Make `warp-docker` the default gateway of the container that you want to browse securely.

```bash
# Log in to your container from host
docker exec -it <Container Name> /bin/bash
# Inside your container, run:
ip route replace default via 192.168.255.1 # fixed IPv4 of warp-docker
ip -6 route replace default via fd42:4242:2189:ac:255::1 # fixed IPv4 of warp-docker
```


- With `ip rule` and/or `iptables | nftables`, you can do something magic like routing other subnets that even not on the same machine.

```bash
# Create a route table called warpdocker, if not exists
grep -q "^100 warpdocker$" /etc/iproute2/rt_tables || echo "100 warpdocker" | tee -a /etc/iproute2/rt_tables
# add default routes for warpdocker table
ip route add 0.0.0.0/0 via 192.168.255.1 table warpdocker
ip -6 route add ::/0 via fd42:4242:2189:ac:255::1 table warpdocker
# Create PBR rules
# This will route local lan traffic to `warp-docker`
ip rule add from 192.168.1.0/24 lookup warpdocker
ip -6 rule add from fd42:4242:2189:cafe::/64 lookup warpdocker
```
The above example will enable you to route local subnet `192.168.1.0/24` and `fd42:4242:2189:cafe::/64` using Linux PBR(Policy Based Routing) to `warp-docker` which will do NAT on your traffic.

For non-local subnets that are not directly connected, use `iptables | nftables` to do a secondary NAT on the host. Of course with firewall rules, you can control access in your flavor.

## Sample configuration

For example, the default `docker-compose.yml` file can be changed to:

```yaml
version: "3"
services:
warp:
image: caomingjun/warp
container_name: warp
restart: always
device_cgroup_rules:
- 'c 10:200 rwm'
ports:
- "1080:1080"
environment:
- WARP_SLEEP=2
- WARP_ENABLE_NAT=1 # enable nat
cap_add:
- MKNOD
- AUDIT_WRITE
- NET_ADMIN
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.forwarding=1
- net.ipv6.conf.all.accept_ra=2
volumes:
- ./data:/var/lib/cloudflare-warp
networks:
dockernet:
ipv4_address: 192.168.255.1
ipv6_address: fd42:4242:2189:ac:255::1
networks:
dockernet:
external: true
```

After updating the `docker-compose.yml` file, run `docker-compose down && docker-compose up -d` to restart the container.
27 changes: 27 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,32 @@ else
warp-cli --accept-tos debug qlog enable
fi

# if WARP_ENABLE_NAT is provided, enable NAT and forwarding
if [ -n "$WARP_ENABLE_NAT" ]; then
# switch to warp mode
echo "[NAT] Switching to warp mode..."
warp-cli --accept-tos mode warp
warp-cli --accept-tos connect

# wait another seconds for the daemon to reconfigure
sleep "$WARP_SLEEP"

# enable NAT
echo "[NAT] Enabling NAT..."
sudo nft add table ip nat
sudo nft add chain ip nat WARP_NAT { type nat hook postrouting priority 100 \; }
sudo nft add rule ip nat WARP_NAT oifname "CloudflareWARP" masquerade
sudo nft add table ip mangle
sudo nft add chain ip mangle forward { type filter hook forward priority mangle \; }
sudo nft add rule ip mangle forward tcp flags syn tcp option maxseg size set rt mtu

sudo nft add table ip6 nat
sudo nft add chain ip6 nat WARP_NAT { type nat hook postrouting priority 100 \; }
sudo nft add rule ip6 nat WARP_NAT oifname "CloudflareWARP" masquerade
sudo nft add table ip6 mangle
sudo nft add chain ip6 mangle forward { type filter hook forward priority mangle \; }
sudo nft add rule ip6 mangle forward tcp flags syn tcp option maxseg size set rt mtu
fi

# start the proxy
gost $GOST_ARGS

0 comments on commit 0e8fe4f

Please sign in to comment.