Simple site to site tunnel with Wireguard

Simple site to site tunnel with Wireguard

WireGuard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography.

preperation

The docker setup needs the wireguard kernel module , an open udp port in router, a free public subdomain , port forword the WG port to RPI lan IP in router settings

load kernel module

modprobe wireguard

load it on boot

create the config file:

sudo nano /etc/modules-load.d/wireguard.conf

add the module name

wireguard

check status of modules

lsmod |grep wireguard

Check if systemd service loaded the module:

systemctl status systemd-modules-load.service

grab the proccess id e.g.

Main PID: 210 (code=exited, status=0/SUCCESS) PID = 210

status=0/SUCCESS means systemd succesfully loaded the module

double verify

journalctl -b _PID=210

systemd-modules-load[210]: Inserted module ‘wireguard’

if lsmod is not confirming the journal look for

blacklist wireguard at configs

Forword ipv4

sudo nano /etc/sysctl.d/ipv4_forwarding.conf

add

net.ipv4.ip_forward=1

Verify

sysctl net.ipv4.ip_forward

setup

Docker & docker-compose

linuxserver Wireguard Docker image

Documentation is pretty straightforword there but lets clarify some things

Client config is under path/to/appdata/config as was set in the volume env var as PNG and text

Docker run

1
docker run -d   --name=wireguard   --cap-add=NET_ADMIN   --cap-add=SYS_MODULE   -e PUID=1000   -e PGID=1000   -e TZ=Europe/London   -e SERVERURL=your.ddns.domain.name.com `#optional`   -e SERVERPORT=51820 `#optional`   -e PEERS=1 `#optional`   -e PEERDNS=auto `#optional`   -e INTERNAL_SUBNET=10.13.13.0 `#optional`   -e SERVER_ALLOWEDIPS_PEER_phone="192.168.1.x/24, 10.13.13.1"   -e LOG_CONFS=true `#optional`   -p 51820:51820/udp   -v path/to/appdata/config:/config   -v /lib/modules:/lib/modules   --sysctl="net.ipv4.conf.all.src_valid_mark=1"   --restart unless-stopped   linuxserver/wireguard

docker-compose

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
version: '3'

services:
  wireguard:
    image: linuxserver/wireguard
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
      - SERVERURL=your.ddns.domain.name.com  # optional
      - SERVERPORT=51820  # optional
      - PEERS=1  # optional
      - PEERDNS=auto  # optional
      - INTERNAL_SUBNET=10.13.13.0  # optional
      - SERVER_ALLOWEDIPS_PEER_phone=192.168.1.x/24,10.13.13.1
      - LOG_CONFS=true  # optional
    ports:
      - "51820:51820/udp"
    volumes:
      - path/to/appdata/config:/config
      - /lib/modules:/lib/modules
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped

This will create path/to/appdata/config/wg0.conf which is your server config

And path/to/appdata/config/peer1/peer1.conf Which is your client config

You’ll add this to the android wiregurad app by either import the file or by scanning the path/to/appdata/config/peer1/peer1.png You can display the qr code in terminal with docker exec -it wireguard /app/show-peer 1

Consider the SERVER_ALLOWEDIPS_PEER_phone= And INTERNAL_SUBNET= enviromental variables If you only need access to your RPI for remote ssh all you need is to add your its local lan IP e.g. 192.168.1.24 together with the servers wireguard subnet address e.g. 10.13.13.1

Also consider the SERVERURL= Env var Which is your domain through which you access your raspbery on its running port e.g. If you own the ippo subdomain in duckdns SERVERURL=https://ippo.duckdns.org:51820

The wireguard config logic:

Wireguard needs a set of configs in the form of:

client:

1
2
3
4
5
6
7
8
9
10
11
[Interface]
Address = 10.13.13.2
PrivateKey = blahblahblah1=
ListenPort = 51000
DNS = 10.13.13.1

[Peer]
PublicKey = blahblahblah2=
PresharedKey = blahblahblah3=
Endpoint = my.ddns.domain.com:51000
AllowedIPs = 0.0.0.0/0, ::/0

server:

1
2
3
4
5
6
7
8
9
10
11
12
[Interface]
Address = 10.13.13.1
ListenPort = 51000
PrivateKey = blahblahblah4
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE

[Peer]
# peer1
PublicKey = blahblahblah5
PresharedKey = blahblahblah6
AllowedIPs = 10.13.13.2/32

In the public key field of the peer section of the server goes the public key of the client

In the public key field of the client’s peer section goes the server’s public key

In the PresharedKey field of both the server and the client goes the PresharedKey from the client’s folder. This key is optional and provides additional security

In the Endpoint field of the peer section of the client goes the public ip of the server and the port it is listening on e.g. if we have the dynamic dns domain wire-test.duckdns.org we will put this in this field wire-test.duckdns.org:5000

In the DNS field of the interface section of the client we put the wireguard subnet address of the server e.g. 10.13.13.1 as shown in the address field of the interface section of the server

The AllowedIPs fiend of the peer section of the client is the most interesting field because from this field we can configure whether the client can connect only to the specific device on which the server is running e.g. for remote ssh or to the whole subnet to all devices of the local LAN i.e. to be connected to the wifi of the house

Connecting to the whole subnet: AllowedIPs = 0.0.0.0/0, ::/0

Connection only to the server: Enter the local lan IP of the device running server e.g. 192.168.1.24 along with the wireguard subnet address of the server e.g. 10.13.13.1 as shown in the Address field of the interface section of the server AllowedIPs = 192.168.1.24/32 , 10.13.13.1/32

In the AllowedIPs fiend of the peer section of the server goes the wireguard subnet address of the client as shown in the Address field of the interface section of the client

The ListenPort field of the interface section of the server is the udp port on which the wireguard listens. We define it as env var to docker run. It has to be an open router port and port forworded to the device IP that is running the server

The address field of the interface section of both the server and the client are their ip address in the wireguard subnet (the wireguard internal addresses not the LAN’s)

In the PrivateKey fields on the interface section on both server and client are as shown in privatekey-peer1 and privatekey-server

The PostUp and PostDown fields of the server interface section are the iptables as created by the docker run.

comments powered by Disqus