Skip to content

Instantly share code, notes, and snippets.

@qdm12
Last active April 8, 2024 08:45
Show Gist options
  • Star 30 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save qdm12/35ab96d6be470ce7a4314722a55a1859 to your computer and use it in GitHub Desktop.
Save qdm12/35ab96d6be470ce7a4314722a55a1859 to your computer and use it in GitHub Desktop.
Wireguard setup for Ubuntu server with LAN access

Wireguard setup for LAN access

Assumptions

  • The network 192.168.1.0/24 is your LAN
  • Your Ubuntu server is on your LAN at 192.168.1.10, through the network interface eth0
  • The network 192.168.5.0/24 is non existent
  • Your LAN DNS is at 192.168.1.1

Server installation

  1. Ensure IPv4 forwarding is enabled

    sysctl -w net.ipv4.ip_forward=1
  2. You might need to allow the VPN server port UDP 51820:

    sudo ufw allow 51820/udp
    sudo ufw enable
  3. Install Wireguard Kernel modules and CLI tools

    sudo add-apt-repository ppa:wireguard/wireguard
    sudo apt-get update
    sudo apt-get install -y wireguard
  4. Create the VPN interface configuration file

    sudo nano /etc/wireguard/wg0.conf

    with the following content

    [Interface]
    Address = 192.168.5.1
    ListenPort = 51820
    PrivateKey = <server private key>
    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
    
    [Peer]
    # Your first client
    PublicKey = <client 1 public key>
    AllowedIPs = 192.168.5.2/32
    
    # [Peer]
    # Your second client
    # PublicKey = <client 2 public key>
    # AllowedIPs = 192.168.5.3/32
  5. Generate a keypair on the server

    privateKey=`wg genkey`
    publicKey=`echo "$privateKey" | wg pubkey`
    echo "Private Key: $privateKey"
    echo "Public Key: $publicKey"
    unset -v privateKey
  6. Copy the private key into /etc/wireguard/wg0.conf in the [Interface] section, replacing <server privatekey>

  7. On your client, generate a key pair (see comment below to know how), and copy the client public key to the server's /etc/wireguard/wg0.conf in the [Peer] section and replace <client 1 public key>.

  8. Finally, launch the interface on the server

    wg-quick up wg0

    If it complains about Wireguard not being a type of interface, you can try modprobe wireguard or you will have to reboot your server to load the new Kernel module.

    You can remove the VPN interface with wg-quick down wg0.

  9. On your client, use this configuration

    [Interface]
    Address = 192.168.5.2
    PrivateKey = <client 1 auto generated private key>
    DNS = 192.168.1.1
    
    [Peer]
    PublicKey = <server public key>
    AllowedIPs = 0.0.0.0/0
    Endpoint = 192.168.1.10:51820
    PersistentKeepalive = 25

    And replace <server public key> with the public key you generated.

  10. You can try now to connect, it should take 3-5 seconds to connect.

  11. To access from outside, port forward for example port UDP 443 to 192.168.1.10:51820 and change the client endpoint to :443

@gurabli
Copy link

gurabli commented Jul 13, 2019

Amazing, many thanks.
Can you please expand section 5, how to create a key pair on client, and section 9, for port forwarding?

@qdm12
Copy link
Author

qdm12 commented Jul 13, 2019

  • On Windows clients, click on Create empty tunnel and it will have a generated keypair ready for you
  • On Android clients, a keypair will also be generated when you add a tunnel manually.
  • On other platforms, I'm not sure but you could always try the same command as on the server wg genkey | tee privatekey | wg pubkey > publickey

For port forwarding, you would first need a public IP address assigned by your ISP (usually the case). You can also use a domain name pointing to this IP address.

  1. Log in to your router, usually at http://192.168.1.1 with your credentials
  2. Find the port forwarding section (sometimes called NAT)
  3. Forward the port 443 UDP (from outside) to :51820 so that it works when a firewall might block ports other than HTTPS port 443

@gurabli
Copy link

gurabli commented Jul 16, 2019

Ok, I still need your help. I have some problem with the concept of IP.

I have a server at remote location. I run Wireguard serve there, together with a webui on port 9112. The local ip of the server os 192.168.1.11. UDP port 51820 opened in router amd forwarded to 192.168.1.11

I want to access from my client the webui at server, so basically 192.168.1.11:9112
I don't wan't all the traffic routed over the server, just for this single port. The local address of the client is 192.168.1.100

How should I do this?

@gurabli
Copy link

gurabli commented Jul 17, 2019

Update: I managed to configure everything. It is really great, Wireguard rules! Now I hope it will receive an audit soon! It is so much faster and more flexible than OpenVPN or other VPN implementations.

@qdm12
Copy link
Author

qdm12 commented Jul 17, 2019

Hi there,

Sorry I was cut off from internet. That great news you managed to set it up. It is indeed much simpler to setup than other VPN servers and have nice clients too. I'll probably add a link in the readme on how to configure Wireguard.

@gurabli
Copy link

gurabli commented Jul 18, 2019

Few days running Wireguard now and I must say I'm impressed! I run the server on a remote NanoPi NEO2 (H5) board, 1.2 Ghz, 512 RAM, gigabit Lan, and this small device is running it like it would a simple SSH session. Looking at htop, it is so low on resources, even if I stream high bitrate (12 Mbit/s) 1080i DVB-C stream from the remote Tvheadend server, ovet TCP, encapsulates over UDP of Wireguard. Perfecto!

An interesting way to use Wireguard and Docker together:

"Ready for Containers
WireGuard sends and receives encrypted packets using the network namespace in which the WireGuard interface was originally created. This means that you can create the WireGuard interface in your main network namespace, which has access to the Internet, and then move it into a network namespace belonging to a Docker container as that container's only interface. This ensures that the only possible way that container is able to access the network is through a secure encrypted WireGuard tunnel."

Based on this, Wireguard interface is created on system, but all the Docker containers can be routes over that connection. Actually no iptables needed, no routing, nothing (sure, iptables are there, but created by Docker automatically). This would be so easy. Docker containers can commumicate (hopefully) with each other using their name and ip comfigured by Docker.
I hope PIA will add Wireguard support soon. This can be run a medium category SoHo router. Sorry for being long, but I like this so much.

Btw, I had to use some other instructions to properly configure Wireguard, as ip4 forwarding has to be enabled, and iptables forwarding, masquarading is needed too (so simple).

@qdm12
Copy link
Author

qdm12 commented Jul 21, 2019

Thanks for the long review 😄

Indeed Wireguard is only about 2000 lines of code running in the Kernel space... so it's powerful !
I have not tried Wireguard with Docker containers yet as I have no use for it.
But PIA will eventually add it, they already mentioned it although they likely gave up, which is understandable given their already complex infrastructure.

Also would you mind giving more details about what were the instructions missing for the iptables forwarding and masquarading? I have added some new instructions already:

sysctl -w net.ipv4.ip_forward=1
sudo ufw allow 51820/udp
sudo ufw enable

but my system is Alpine for now so I'm a bit blind 🙈 and cannot be bothered launching an Ubuntu virtual machine 😆

@marcelloinfoweb
Copy link

how would I do to configure for local network (192.168.1.0) and the ip on the wireguard is 10.6.0.0?

@qdm12
Copy link
Author

qdm12 commented Mar 26, 2020

@AlwaysLivid I'll dig into that in the coming days

@marcelloinfoweb You should just have to change the 192.168.5.1 to 10.6.0.1 and 192.168.5.2/32 to 10.6.0.2/32.

@oezh
Copy link

oezh commented Aug 15, 2020

Hi, how would be the setup up if I only want to access the lan devices on the server side without pushing all the internet traffic? Case: I have a Proxmox host on a VPS and only want my laptop to connect with private IP to my VM's, but I don't want my laptop to push all traffic to the tunnel. Wireguard installed on the Proxmox host and my laptop. I guess "AllowedIPs = 0.0.0.0/0" needs to be changed to the private network of the host in the Peer side, but what about PostUP and PostDown iptables? do they stay the same?

@qdm12
Copy link
Author

qdm12 commented Aug 15, 2020

Lucky you I made a new Gist that should answer that!

@jonchancode
Copy link

jonchancode commented May 23, 2021

Hi,

I've been trying to setup my VPN as you instructed above so that my remote client (e.g. laptop at coffee shop) can access machines on my home LAN. The Wireguard server is also on the LAN. Currently I'm testing with my laptop at home first. Before connecting to the VPN server, the client is able to ssh into the LAN host using its LAN IP (192.168.0.158), After connecting the client to the VPN server, it's no longer able to ssh into the LAN host at the same IP. In general, it seems I've lost all ability to ping/route traffic to IPs on the original LAN network.

I noticed that if I connected both the host and the client to the VPN server, then the client can ssh the host using the host's VPN IP address, but still not using the LAN IP address.

Some minor differences - I am using a raspberry-pi for the VPN server, and my client and host machines are Windows.

Here's the setup:

LAN subnet is 192.168.0.0/24
LAN DNS is the router, 192.168.0.1

Server config:

[Interface]
PrivateKey = <server_priv_key>
Address = 192.168.5.1
MTU = 1420
ListenPort = 51820
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

# host
[Peer]
PublicKey = <host_public_key>
PresharedKey = <host_preshared_key>
AllowedIPs = 192.168.5.2/32

# client
[Peer]
PublicKey = <client_public_key>
PresharedKey = <client_preshared_key>
AllowedIPs = 192.168.5.3/32

Client config:

[Interface]
PrivateKey = <client_priv_key>
Address = 192.168.5.3/24
DNS = 192.168.0.1
MTU = 1420

[Peer]
PublicKey = <vpn_server_pub_key>
PresharedKey = <client_preshared_key>
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = <router_public_domain_name>:<public_port>

Host config:

[Interface]
PrivateKey = <host_priv_key>
Address = 192.168.5.2/24
DNS = 192.168.0.1
MTU = 1420

[Peer]
PublicKey = <vpn_server_pub_key>
PresharedKey = <host_preshared_key>
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = <router_public_domain_name>:<public_port>

Any debugging pointer or folks to talk to would help. Thanks for the resources!

@qdm12
Copy link
Author

qdm12 commented May 23, 2021

@jonchancode I also have the issue, on my home network and on another network too.

Activating Wireguard from within the same LAN network blocks access to the LAN. If you try from outside your LAN it does work though.

I didn't dig further as that fitted what I wanted and was fine with deactivating Wireguard when inside my LAN.

I'm not sure if this is a firewall iptables issue or a routing issue, or a Wireguard issue. But I would be curious how to solve it as well!

@qdm12
Copy link
Author

qdm12 commented May 23, 2021

Actually using my Android Wireguard app I don't have the problem, maybe that's a Windows Wireguard client issue (I was using Windows too).

@jonchancode
Copy link

Ah interesting, yeah, looks like it works the same for me too (can access externally, but not internally). I'll post back here if I find an answer. Thanks for the response!

Copy link

ghost commented Oct 1, 2021

If Wireguard is running on the server change your CLIENT CONFIG from AllowedIPs = 0.0.0.0/0 to AllowedIPs=192.168.0.0/24.
If Wireguard is running in Docker do the same but be aware that: If your Wireguard server is a container on your server, when your clients connect and try to traverse the LAN their traffic will be routed through the Docker network subnet where that container lives... Makes sense now but took digging through UFW logs to find out why I couldn't SSH to my server.

@Mladia
Copy link

Mladia commented Jan 11, 2023

That's right. UFW block network traffic from the docker container, since it comes from a different subnet.

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