Skip to content

Instantly share code, notes, and snippets.

@nitschis
Forked from tombowditch/tunneling.md
Last active November 13, 2023 11:47
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nitschis/8a839734b7f984bbee2b71d8235da65c to your computer and use it in GitHub Desktop.
Save nitschis/8a839734b7f984bbee2b71d8235da65c to your computer and use it in GitHub Desktop.
Tunneling a whole docker container through wireguard

Tunneling a whole docker container through wireguard

Certain company blocking a certain hosting provider? No problem, just tunnel the docker container through a small VPS with wireguard.

Consider server A your blocked server and server B your VPS.

Step 1: Generate a keypair on server A and server B

Server A:

wg genkey > endpoint-a.key
wg pubkey < endpoint-a.key > endpoint-a.pub

Server B:

wg genkey > endpoint-b.key
wg pubkey < endpoint-b.key > endpoint-b.pub

Step 2: Configure server B

Edit /etc/sysctl.conf and ensure the following line is uncommented:

net.ipv4.ip_forward=1

Create a wireguard config at /etc/wireguard/wg0.conf with the following content:

[Interface]
PrivateKey = <endpoint-b.key>
Address = 10.0.0.2/32
ListenPort = 51822

PreUp = iptables -t mangle -A PREROUTING -i wg0 -j MARK --set-mark 0x30
PreUp = iptables -t nat -A POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE
PostDown = iptables -t mangle -D PREROUTING -i wg0 -j MARK --set-mark 0x30
PostDown = iptables -t nat -D POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE

[Peer]
PublicKey = <endpoint-a.pub>
AllowedIPs = 10.0.0.1/32
Endpoint = <server A ip address>:51822

If you wish to forward ports, add the following 2 lines under [Interface] per port you wish to forward:

PreUp = iptables -t nat -A PREROUTING -p tcp --dport 12345 -j DNAT --to-destination 10.0.0.1
PostDown = iptables -t nat -D PREROUTING -p tcp --dport 12345 -j DNAT --to-destination 10.0.0.1

Enable & start wg0 using wg-quick:

systemctl enable --now wg-quick@wg0

Step 3: Configure server A

Create a wireguard config at .wireguard/wg0.conf with the following content:

[Interface]
PrivateKey = <endpoint-a.key>
ListenPort = 51821
Address = 10.0.0.1/32
DNS = 1.1.1.1, 8.8.8.8

[Peer]
PublicKey = <endpoint-b.pub>
Endpoint = <server B ip address>:51822
AllowedIPs = 0.0.0.0/0

Modify your existing docker-compose.yml file, integrating a new 'wireguard-client' container into its services hierarchy:

  wireguard-client:
    image: linuxserver/wireguard:latest
    container_name: wireguard-client
    cap_add:
      - NET_ADMIN  # Required for modifying network configurations
      - SYS_MODULE
    environment:
      - PUID=1000  # User ID for the process
      - PGID=1000  # Group ID for the process
      - TZ=Europe/Berlin  # Replace with your timezone
    volumes:
      - ./wireguard:/config  # Make sure your WireGuard config file is in the ./wireguard directory on your host
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped

To channel a service's (container) traffic through WireGuard, add the subsequent lines to the configuration of the specific container:

    network_mode: "service:wireguard-client"  # This container shares the network stack of the wireguard-client
    depends_on:
      - wireguard-client  # Ensures the WireGuard client is started before this container

Credit

This whole config was derived from https://www.procustodibus.com/blog/2023/04/wireguard-netns-for-specific-apps. All credit goes to them!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment