Wireguard https://www.wireguard.com/made it into the kernel source it is enabled by setting CONFIG_WIREGUARD.
The package wireguard-tools needs to be installed to get the user-space tools as wg and wg-quick.
Wireguard uses a client server architecture, one server and multiple clients. The points to on the other end of the tunnel to be connected are peers having a private and a public key.
Private and public keys need to be created for the server and clients. Obviously not everybody should be able to read them so umask is used:
cd /etc/wireguard
add the two key files to this directory. Better know where the keys are used so:
$(umask 077; wg genkey | tee privatekey_<name>
| wg pubkey > publickey_<name>
)
It is a good habit to have separate key sets for each wireguard interface. This makes it more safe and makes maintenance easier. If just one wireguard tunnel is used then the command can be:
$(umask 077; wg genkey | tee privatekey | wg pubkey > publickey)
Wireguard uses its own network interface names having config files as /etc/wireguard/wg0.conf
or better /etc/wireguard/wg_
<name>
.conf
If this file gets edited from a remote connection then its syntax needs to be carefully checked other wise you saw off the branch you're sitting on. If copy and paste peers than make sure the public keys are unique.
As with any network interface, IP addresses needs to be assigned. Those IP addresses must be unique and not conflicting with the already used IP addresses. Those new IP addresses are assigned manually in the wg0.conf
files of the server and clients. A computer with one physical network interface will therefore get an additional wg0 interface having an new address. IP addresses for wireguard used in a small private network can therefore be in the 192.168.2.x range and the not wireguard addresses in the 192.168.1.x range.
A server has the following /etc/wireguard/wg0.conf
that is created manually.
A wireguard server in a private network will probably attached to the Internet via a router. This router must have an Internet address on the WAN side it is wise to setup dynDNS to also have a consistent name. It has probably 192.168.1.1 on the LAN side. To reach the wireguard server, Port forwarding 51820 needs to be set in the router to the IP address 192.168.1.1. So port 192.168.1.1 receives the encrypted wireguard packages.
The wg0 interface of the server needs also an address 192.168.2.1 is a choice for this interface.
Decrypted packages appear on wg0 or 192.168.2.1
A wg0.conf
file could look as the following and contains one or multiple [Peer] entries.
The peers also have IP addresses as set in their wg0.conf
files that are used just for wireguard.
If more than one wireguard connection is used, use instead wg0 a name as wg_<name where it goes>
[Interface] Address = 192.168.2.1/24 ListenPort = 51820 PrivateKey =<key>
[Peer] PublicKey =<key>
AllowedIPs = 192.168.2.2/32
wg-quick up wg0 create the network interface
ifconfig confirms it
wg-quick down wg0 removes it
For OpenRC ln -s /etc/init.d/wg-quick /etc/init.d/wg-quick.wg0
and rc-update add wg-quick.wg0 default
/etc/init.d/wg-quick.wg0 start
wg show
The following assumes that IP6 is disabled. If IP6 gets enabled a mixture between IP4 and IP6 addresses might occur and result in connection losses. It is therefore important to see what endpoint address wg show shows.
If a server gets accessed from a client in the Internet, it needs some traffic to keep the VPN tunnel alive. Wireguard might be too quiet for that. Adding
PersistentKeepalive = 25
to those peer sections will prevent that such tunnels get removed by the router.
And a client will have a /etc/wireguard/wg0.conf
as:
[Interface] PrivateKey =<key>
Address = 192.168.2.21/32 [Peer] PublicKey =<key>
AllowedIPs = 192.168.2.1/32 Endpoint =<servers internet ip or name>
:<servers port 51820>
Networkmanager can be used instead or additional to the above. Create a wireguard connection using the networkmanagers gui and add the above file content to the WireGuard tab and to the IPv4 Settings tab.
AllowedIP means that those IP addresses will be routed from an to the tunnel. More that one "range" can be set asAllowedIPs = 10.82.85.2/32, 192.168.200.0/24 AllowedIPs = 0.0.0.0/0 means all Internet
Some wireguard gui front end require a DNS ip address. DNS= 8.8.8.8 means google name server
There is no ListenPort definition for the client configuration. The port on the client will be assigned once the tunnel is created. The server has one ListenPort but many ports to the many clients. wg show will show the client port as 33658. If there is a need then a ListenPort definition could be added to a client.
Wireshark can be used to capture the packets. On the physical interface they are encrypted and marked as wireguard protocol, on the wg0 interface they appear as not encrypted.
Wireguard is supported by gui front ends as network manager, It has apps for android and windows.
For mobile phones there is a way to create a qr code and scan it in
install media-gfx/qrencode
qrencode -t ansiutf8 < wg0.conf
Comments in wireguard config files are not supported but still can be added using the # character. Comments are always nice to have but are necessary to name the peers in a wireguard config when having lots of them.
However wireguard contains a save and overwrite config files feature using wg-quick or even automatically. What it sees when it is running (and it does not see the comments) overwrites the config files, see man wg-quick. So a running configuration gets saved. To prevent loosing the important comments set
[Interface] SaveConfig = false
Having set SaveConfig = true would mean the file would be overwritten automatically on shutdown.
An other way is saving the config file on an other place and call wg-quick with the path to this file. wg-quick up </path/to/>
<ifname>
.conf
PostUp and PreDown can be put in the interface section to start commands as setting up and removing nftables or getting the private key in an encrypted form. See man wg-quick
To not create confusion each device involved and all networks involved have unique addresses.
The first network uses 192.168.1.<x>
and has a router 192.168.1.1 that can be pinged from the Internet using dyndns. The wireguard server is on this network
The second network is the wireguard network 192.168.10.<x>
that spawns over the internet.
The third network uses addresses 192.168.20.<x>
and might not be able to be pinged from the internet since it has no public Internet address on the WAN. It holds the wireguard client.
https://www.sigmdel.ca/michel/ha/wireguard/wireguard_02_en.html https://docs.sweeting.me/s/wireguard#
The wireguard server can also be pinged using the wireguard server address 192.168.10.1 from a 192.168.20.<x>
wireguard network client using its wireguard address from 192.168.10.0.
To allow also the 192.168.1.<x> addresses to be use on the wireguard network client on the 192.168.20.<x> network, the following needs to be added to the client
AllowedIPs= 192.168.10.1/32,192.168.1.0/24
This is enough for the wireguard client creating the tunnel, but other devices in the 192.168.20.<x> network will not know the path to the 192.168.1.0 network an send their messages to the router. A static route has to be added to the router to pass all 192.168.1.0 traffic to the wireguard client on the 192.168.20 .0 network
If the package is not for the server then it will be discharged except
cat /proc/sys/net/ipv4/ip_forward to see it
echo 1 > /proc/sys/net/ipv4/ip_forward to set it
to make it persistent add to the wireguard server
/etc/sysctl.conf
to
net.ipv4.ip_forward=1
sudo sysctl -p or reboot
Devices in network 192.168.1.<x> other than the wireguard server can not access devices in the 192.168.20.<x> network. They will send the 192.168.20.<x> messages to the router. To have the router sending those messages to the wireguard server in the 192.168.1.<x> network static routes must be configured in the router. To have the message find its way back to the 192.168.1.<x> device nat masquerading before transmitting is required at the postrouting hook. When the responding message comes back then again nat is required to find the originator in the 192.168.1.<x> network. This all is done by adding the following to the wireguard server /etc/nftables.conf
table ip wireguard-nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; } chain postrouting { type nat hook postrouting priority srcnat; policy accept; oifname "eth0" masquerade } }
sudo systemctl restart nftables and sudo nft list ruleset
Now the wireguard client can access the local network of the server
Clients often have an unknown IP address and/or can not be pinged from the internet.
To still access them from internet one client can act as server-like and can have a static local IP address in the 192.168.20.0 net and creates the wireguard tunnel to the server. The wireguard server then must contain for this peer also the local AllowedIPs 192.168.20.0/24. When the tunnel is there and created from the direction client to server then the server can also ping the client. The tunnel however collapses after a while when the routers see no traffic. The server can therefore have PersistentKeepalive=25 for this peer. The server can now ping the client using both addresses.
The server can not create the tunnel it can just keep it open. To create the tunnel the client must initiate something. One way of doing this is the client sends every 5min a ping to the server using a cron job.
However other clients on the servers local net not having wireguard installed will not know that those 192.168.20.0 addresses are for the wireguard tunnel and pass it to the default gateway. On the default gateway a static route can be configured so those addresses are passed to the wireguard server.
wg show will show the IP address of the endpoint. However the IP address might change due to DynDNS but wireguard will still use and show the outdated IP address and will therefore fail to have the VPN tunnel.
Just restart wireguard and the IP address gets updated. The question is how to know if the IP has changed.
Know and remember the working IP address, get it as from wg show
Know that the tunnel has failed. This must be handled on the remote node where access is lost. So a event or cron triggered script is required.
Verify if the reason, is really due to a IP address change or is it due to something else. Get the IP address using ping -c3 <domain>
or nslookup <domain>
restart wireguard for openRC /etc/init.d/wg-quick.wg0 start for systemd systemctl restart wg-quick@wg0
Adding PersistentKeepalive=25 might also help to recover from such IP changes.