masipcat / wireguard-go-docker

Wireguard docker image
https://hub.docker.com/r/masipcat/wireguard-go
GNU General Public License v3.0
186 stars 42 forks source link

Docker #22

Closed nathandtrone closed 2 years ago

nathandtrone commented 3 years ago

I've spun up a docker container using sudo docker-compose up -d but the wireguard server isn't allowing clients to connect. I've got all of the related files here, and I've made sure that the clients are able to reach into the container(see the UDP NC listen below). I see it's reaching the server, but for whatever reason it refuses to respond to the handshake for the client. I'm not sure what I'm doing wrong here. I was hoping to use this container to build a web management interface as well. Any insight would be greatly appreciated.

bash$ cat docker-compose.yml
version: '3.3'
services:
  wireguard:
    image: masipcat/wireguard-go:latest
    hostname: wireguard
    cap_add:
     - NET_ADMIN
    sysctls:
     - net.ipv4.ip_forward=1
    volumes:
     - /dev/net/tun:/dev/net/tun
     # Folder with 'publickey', 'privatekey' and 'wg0.conf'
     - /containers/wireguard/etc:/etc/wireguard
    environment:
     - WG_COLOR_MODE=always
     - LOG_LEVEL=info
    ports:
     - 51820:51820/udp
     #added this just to test
     - 51820:51820/tcp
    # Uncomment the following line when 'AllowedIPs' is '0.0.0.0/0'
    privileged: true
    restart: always

bash$ wg show
interface: wg0
  public key: nBfPpavcYn1eP8iWnme7xzUE+hhgblHG93gBbbbycXU=
  private key: (hidden)
  listening port: 51820

bash$ ip -c a
2: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none
    inet 10.11.12.1/32 scope global wg0
       valid_lft forever preferred_lft forever

bash$ cat /etc/wireguard/wg0.conf
[Interface]
# Assign you an IP (that's not in use) and add it to server configmap
Address = 10.11.12.1/32
ListenPort = 51820
# generate private key using `wg genkey`
PrivateKey = mHYd133DU06uB2+UX+hpgqVrrDkQi8KReNfHIx9pynk=

[Peer]
# Wireguard server public key
PublicKey = nBfPpavcYn1eP8iWnme7xzUE+hhgblHG93gBbbbycXU=
# LoadBalancer IP (replace with your LoadBalancer ip)
Endpoint = vpn.MyServerHostname.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

bash$ sudo netstat -natp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 :::51820                :::*                    LISTEN      804614/docker-proxy

bash$ nc -v -lk -u -s 0.0.0.0 -p 51820
listening on 0.0.0.0:51820 ...
connect to 172.19.0.2:51820 from 192.168.1.1:51820 (192.168.1.1:51820)
Garbage-UDP-DATA_SHOWS_UP_HERE#WorkingConnection
masipcat commented 3 years ago

Hi,

I see a couple of things:

  1. Looking a this:
bash$ wg show
interface: wg0
  public key: nBfPpavcYn1eP8iWnme7xzUE+hhgblHG93gBbbbycXU=
  private key: (hidden)
  listening port: 51820

it seems that you haven't registered the peer in the server:

https://github.com/masipcat/wireguard-go-docker/blob/2517d7226c7be6ed5bdf6b092cdd3cac1c9a21d4/wireguard/wg0.conf#L7-L9

  1. Also, assuming the wg0.conf provided is the server configuration, it looks like you're using the same key for the client and the server. The server's private key mHYd133DU06uB2+UX+hpgqVrrDkQi8KReNfHIx9pynk= (pubkey: nBfPpavcYn1eP8iWnme7xzUE+hhgblHG93gBbbbycXU=) and at the same time you configure the peer (client) with same public key.

I hope this solves the problem!

PS: don't forget to change all the keys

nathandtrone commented 3 years ago

You nailed it. My Copy and paste didn't actually copy. Sorry for something so simple. I have a new problem though. My clients, testing using my phone right now and my personal machine.. I've discovered I cannot have wireguard for Android use the option AllowedIPs set to the wireguard network only(ex: 10.11.12.#/24). Anyway, on my desktop and phone, I don't seem to have internet access. I can ping the servers Local IP and everything networking wise functions as expected. I am concerned about my routing tables.

Do you think this is the appropriate approach for the post-up/down (In the event I set the AllowedIPs to something more restricting like 0.0.0.0/0.):

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

I am wondering how I should approach giving these clients access to a specific docker containers IP via the VPN. I was going to add another entry to the up/down to manually redirect an IP within the VPN range (ex .254), not sure how, but from my research I gather that should be possible. Just figure it's probably something you've seen attempted before?

I've since changed my keys haha. Thanks for the reminder.

masipcat commented 3 years ago

I understand that you want to use the wireguard server as a "privacy vpn" to route all your internet traffic. If that's the case, your server config should look like this:

[Interface]
Address = 10.11.12.1/24
ListenPort = 51820
PostUp = iptables -t nat -A POSTROUTING -s 10.11.12.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PrivateKey = ...

and the AllowedIPs in your client configuration should be 0.0.0.0/0 (route everything to the wg interface).

I am wondering how I should approach giving these clients access to a specific docker containers IP via the VPN. I was going to add another entry to the up/down to manually redirect an IP within the VPN range (ex .254), not sure how, but from my research I gather that should be possible. Just figure it's probably something you've seen attempted before?

This is the easiest way I know:

  1. Run wireguard on the host (not in a container), so we see the wg0 interface from the host
  2. Then, bind the port of the service we want to expose to the wg0 ip:

docker-compose.yaml

ports:
      - 10.11.12.2:80:80

If you want to run the wireguard in a container, I guess you could do the same as long as the docker containers you want to expose are in the same network as the wireguard container, but I haven't tried. If you find how to do it please share it ;)