forked from cheng/wallet
733 lines
25 KiB
Markdown
733 lines
25 KiB
Markdown
|
---
|
|||
|
title: Wireguard
|
|||
|
...
|
|||
|
|
|||
|
Setting up your own vpn using wireguard and a Debian 11 server in the cloud
|
|||
|
|
|||
|
This tutorial largely stolen from [Linuxbabe](https://www.linuxbabe.com/debian/wireguard-vpn-server-debian){target="_blank"} It is slightly
|
|||
|
more up to date than her version at the time of writing.
|
|||
|
|
|||
|
# WireGuard VPN
|
|||
|
|
|||
|
Openvpn uses ssl, (not to be confused with ssh) Wireguard uses algorithms
|
|||
|
and code developed by privacy advocates. SSL has numerous well known
|
|||
|
vulnerabilities, notably that it is subject to active attack by any group
|
|||
|
that has a CA in its pocket. The NSA has a passive attack, which is not
|
|||
|
understood, but OpenSSL has an enormous codebase, that
|
|||
|
is impossible to audit with an architecture that seems designed for hiding
|
|||
|
obfuscated vulnerabilities, and NSA has contributed much to its codebase
|
|||
|
through innumerable proxies, who are evasive when I talk to them.
|
|||
|
|
|||
|
Wireguard uses cryptographic libraries developed by our allies, rather than our enemies.
|
|||
|
|
|||
|
Wireguard is lightweight and fast, blowing OpenVPN out of the water.
|
|||
|
|
|||
|
Openvpn is a gigantic pile of code, a maze of strange architectural
|
|||
|
decisions that slow things down, which vast complicated pile of
|
|||
|
incomprehensible things seem to be to provide no useful purpose other
|
|||
|
than places to hide backdoors in.
|
|||
|
|
|||
|
Wireguard is open source and and cross-platform. WireGuard can run on
|
|||
|
Linux, BSD, macOS, Windows, Android, iOS, and OpenWRT.
|
|||
|
|
|||
|
User authentication is done by exchanging public keys, similar to SSH keys.
|
|||
|
|
|||
|
Assigns static tunnel IP addresses to VPN clients.
|
|||
|
|
|||
|
Mobile devices can switch between Wi-Fi and mobile network seamlessly
|
|||
|
without dropping any connectivity.
|
|||
|
|
|||
|
Supercedes OpenVPN and IPSec, which are obsolete and insecure.
|
|||
|
|
|||
|
# Requirements
|
|||
|
|
|||
|
I assume you have a host in the cloud, with world accessible network address and ports, that can access blocked websites freely outside of your country or Internet filtering system.
|
|||
|
|
|||
|
The VPN server is running Debian 11 operating system. This tutorial is not
|
|||
|
going to work on Debian 10 or lower. Accessing your vpn from a windows
|
|||
|
client, however, easy since the windows wireguard windows client is very
|
|||
|
friendly. Setting up wireguard on windows is easy. Setting up a wireguard
|
|||
|
VPN server on windows is, on the other hand, very difficult. Don't even
|
|||
|
try. I am unaware of anyone succeeding.
|
|||
|
|
|||
|
# Install WireGuard on Debian Client and server
|
|||
|
|
|||
|
```bash
|
|||
|
apt update -qy
|
|||
|
apt full-upgrade -qy
|
|||
|
apt install -qy wireguard wireguard-tools linux-headers-$(uname -r)
|
|||
|
```
|
|||
|
|
|||
|
## Generate Public/Private Keypairs
|
|||
|
|
|||
|
On the server
|
|||
|
|
|||
|
```bash
|
|||
|
mkdir -p /etc/wireguard
|
|||
|
wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
|
|||
|
sudo chmod 600 /etc/wireguard/ -R
|
|||
|
```
|
|||
|
|
|||
|
On the client
|
|||
|
|
|||
|
```bash
|
|||
|
mkdir -p /etc/wireguard
|
|||
|
wg genkey | sudo tee /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key
|
|||
|
sudo chmod 600 /etc/wireguard/ -R
|
|||
|
```
|
|||
|
# Configure Wireguard on server
|
|||
|
|
|||
|
## Create WireGuard Server Configuration File
|
|||
|
|
|||
|
Use a command-line text editor like Nano to create a WireGuard configuration file on the Debian server. `wg0` will be the network interface name.
|
|||
|
|
|||
|
```bash
|
|||
|
sudo nano /etc/wireguard/wg0.conf
|
|||
|
```
|
|||
|
|
|||
|
Copy the following text and paste it to your configuration file. You need to use your own server private key and client public key.
|
|||
|
|
|||
|
The curly braces mean that you do not copy the text inside the curly braces, which is only there for example. You have to substitute your own private key (since everyone now knows this private key), and your own client public key., mutas mutandis.
|
|||
|
|
|||
|
```default
|
|||
|
[Interface]
|
|||
|
Address = 10.10.10.1/24
|
|||
|
ListenPort = «51820»
|
|||
|
PrivateKey = «cD+ZjXiVIX+0iSX1PNijl4a+88lCbDgw7kO78oXXLEc=»
|
|||
|
|
|||
|
[Peer]
|
|||
|
PublicKey = «AYQJf6HbkQ0X0Xyt+cTMTuJe3RFwbuCMF46LKgTwzz4=»
|
|||
|
AllowedIPs = 10.10.10.2/32
|
|||
|
```
|
|||
|
|
|||
|
As always «...» means that this is an example value, and you need to
|
|||
|
substitute your own actual value. "_Mutas mutandis_" means "changing that
|
|||
|
which ought to be changed". In other words, watch out for those «...» .
|
|||
|
|
|||
|
Or, as those that want to baffle you would say, metasyntactic variables are enclosed in «...» .
|
|||
|
|
|||
|
|
|||
|
Where:
|
|||
|
|
|||
|
- **Address**: Specify the private IP address of the VPN server. Here I’m using the 10.10.10.0/24 network range, so it won’t conflict with your home network range. (Most home routers use 192.168.0.0/24 or 192.168.1.0/24). 10.10.10.1 is the private IP address for the VPN server.
|
|||
|
- **PrivateKey**: The private key of VPN server, which can be found in the `/etc/wireguard/server_private.key` file on the server.
|
|||
|
- **ListenPort**: WireGuard VPN server will be listening on UDP port 51820, which is the default.
|
|||
|
- **PublicKey**: The public key of VPN client, which can be found in the `/etc/wireguard/public.key` file on the client computer.
|
|||
|
- **AllowedIPs**: IP addresses the VPN client is allowed to use. In this example, the client can only use the 10.10.10.2 IP address inside the VPN tunnel.
|
|||
|
|
|||
|
Change the file permission mode so that only root user can read the files. Private keys are supposed to be _private_,
|
|||
|
|
|||
|
```bash
|
|||
|
sudo chmod 600 /etc/wireguard/ -R
|
|||
|
```
|
|||
|
|
|||
|
## Configure IP Masquerading on the Server
|
|||
|
|
|||
|
We need to set up IP masquerading in the server firewall, so that the server becomes a virtual router for VPN clients. I will use UFW, which is a front end to the iptables firewall. Install UFW on Debian with:
|
|||
|
|
|||
|
``` bash
|
|||
|
apt -qy install ufw
|
|||
|
```
|
|||
|
|
|||
|
If ufw is already installed and running
|
|||
|
|
|||
|
``` bash
|
|||
|
ufw disable
|
|||
|
```
|
|||
|
|
|||
|
First, you need to allow SSH traffic.
|
|||
|
|
|||
|
```bash
|
|||
|
ufw allow 22/tcp
|
|||
|
```
|
|||
|
|
|||
|
Next, find the name of your server’s main network interface.
|
|||
|
|
|||
|
```bash
|
|||
|
ip addr | grep BROADCAST
|
|||
|
```
|
|||
|
|
|||
|
As you can see, it’s named `eth0` on my Debian server.
|
|||
|
|
|||
|
```terminal_image
|
|||
|
:~# ip addr | grep BROADCAST
|
|||
|
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
|
|||
|
```
|
|||
|
|
|||
|
To configure IP masquerading, we have to add iptables command in a UFW configuration file.
|
|||
|
|
|||
|
```bash
|
|||
|
nano /etc/ufw/before.rules
|
|||
|
```
|
|||
|
|
|||
|
By default, there are some rules for the `filter` table. Add the following
|
|||
|
lines at the end of these default rules. Replace `eth0` with your own
|
|||
|
network interface name.
|
|||
|
|
|||
|
# NAT table rules
|
|||
|
*nat
|
|||
|
:POSTROUTING ACCEPT [0:0]
|
|||
|
-F
|
|||
|
-A POSTROUTING -o «eth0» -j MASQUERADE
|
|||
|
|
|||
|
# End each table with the 'COMMIT' line or these rules
|
|||
|
# won't be processed
|
|||
|
COMMIT
|
|||
|
|
|||
|
"MASQUERADE" is NAT packet translation. This puts your IP4
|
|||
|
forwarded network addresses behind a NAT firewall, so that they appear
|
|||
|
on the internet with network address of the server.
|
|||
|
|
|||
|
If you want to NAT translate your IPv6 addresses, will have to do
|
|||
|
something similar in `/etc/ufw/before6.rules`. But you usually have lots
|
|||
|
of IPv6 addresses, so you seldom want to nat translate IPv6
|
|||
|
|
|||
|
In Nano text editor, you can go to the end of the file by pressing `Ctrl+W`, then pressing `Ctrl+V`.
|
|||
|
|
|||
|
```terminal_image
|
|||
|
-A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT
|
|||
|
|
|||
|
# don't delete the 'COMMIT' line or these rules won't be processed
|
|||
|
COMMIT
|
|||
|
|
|||
|
# NAT table rules
|
|||
|
*nat
|
|||
|
:POSTROUTING ACCEPT [0:0]
|
|||
|
-F
|
|||
|
-A POSTROUTING -o eth0 -j MASQUERADE
|
|||
|
COMMIT
|
|||
|
```
|
|||
|
|
|||
|
The above lines will append `-A` a rule to the end of the`POSTROUTING` chain of the `nat` table. It will link your virtual private network with the Internet. And also hide your network from the outside world. So the Internet can only see your VPN server’s IP, but can’t see your VPN client’s IP, just like your home router hides your private home network.
|
|||
|
|
|||
|
Like your home router, it means your client system behind the nat has no open ports.
|
|||
|
|
|||
|
If you want to open some ports, for example the bitcoin port 8333 so that you can run bitcoin core
|
|||
|
|
|||
|
```terminal_image
|
|||
|
NAT table rules
|
|||
|
*nat
|
|||
|
:PREROUTING ACCEPT [0:0]
|
|||
|
:POSTROUTING ACCEPT [0:0]
|
|||
|
-A POSTROUTING -o eth0 -j MASQUERADE
|
|||
|
-A PREROUTING -d «123.45.67.89»/32 -i eth0 -p tcp --dport 8333 -j DNAT --to-destination 10.10.10.2:8333
|
|||
|
-A PREROUTING -d «123.45.67.89»/32 -i eth0 -p udp --dport 8333 -j DNAT --to-destination 10.10.10.2:8333
|
|||
|
COMMIT
|
|||
|
```
|
|||
|
|
|||
|
Then open the corresponding ports in ufw
|
|||
|
|
|||
|
```bash
|
|||
|
ufw allow in 8333
|
|||
|
ufw enable
|
|||
|
```
|
|||
|
|
|||
|
If you have enabled UFW before, then you can use systemctl to restart UFW.
|
|||
|
|
|||
|
## Configure forwarding on the Server
|
|||
|
|
|||
|
By default, UFW forbids packet forwarding. We can allow forwarding for our private network, mutas mutandis.
|
|||
|
|
|||
|
```bash
|
|||
|
ufw route allow in on wg0
|
|||
|
ufw route allow out on wg0
|
|||
|
ufw allow in on wg0
|
|||
|
ufw allow «51820»/udp
|
|||
|
ufw allow to «2405:4200:f001:13f6:7ae3:6c54:61ab:1/112»
|
|||
|
```
|
|||
|
|
|||
|
As always «...» means that this is an example value, and you need to substitute your actual value. "_Mutas mutandis_" means "changing that which should be changed", in other words, watch out for those «...» .
|
|||
|
|
|||
|
Note that the last line is intended to leave your clients naked on the IPv6
|
|||
|
global internet with their own IPv6 addresses, as if they were in the cloud
|
|||
|
with no firewall. This is often desirable for linux systems, but dangerous
|
|||
|
for windows, android, and mac systems which always have loads of
|
|||
|
undocumented closed source mystery meat processes running that do who
|
|||
|
knows what.
|
|||
|
|
|||
|
You could open only part of the IPv6 subnet to incoming, and put
|
|||
|
windows, mac, and android clients in the part that is not open.
|
|||
|
|
|||
|
`wg0` is the virtual network card that `wg0.conf` specifies. If you called it `«your name».conf` then mutatis mutandis.
|
|||
|
|
|||
|
Now if you list the rules in the POSTROUTING chain of the NAT table by using the following command:
|
|||
|
|
|||
|
```bash
|
|||
|
iptables -t nat -L POSTROUTING
|
|||
|
```
|
|||
|
|
|||
|
You can see the Masquerade rule.
|
|||
|
|
|||
|
```terminal_image
|
|||
|
:~# iptables -t nat -L POSTROUTING
|
|||
|
Chain POSTROUTING (policy ACCEPT)
|
|||
|
target prot opt source destination
|
|||
|
MASQUERADE all -- anywhere anywhere
|
|||
|
```
|
|||
|
## Install a DNS Resolver on the Server
|
|||
|
|
|||
|
Since we will specify the VPN server as the DNS server for client, we need to run a DNS resolver on the VPN server. We can install the bind9 DNS server.
|
|||
|
|
|||
|
```bash
|
|||
|
apt install bind9
|
|||
|
```
|
|||
|
|
|||
|
Once it’s installed, BIND will automatically start. You can check its status with:
|
|||
|
|
|||
|
```bash
|
|||
|
systemctl status bind9
|
|||
|
```
|
|||
|
|
|||
|
Sample output:
|
|||
|
|
|||
|
```terminal_image
|
|||
|
:~$ systemctl status bind9
|
|||
|
● named.service - BIND Domain Name Server
|
|||
|
Loaded: loaded (/lib/systemd/system/named.service; enabled; vendor preset: enabled)
|
|||
|
Active: active (running) since Sun 2020-05-17 08:11:26 UTC; 37s ago
|
|||
|
Docs: man:named(8)
|
|||
|
Main PID: 13820 (named)
|
|||
|
Tasks: 5 (limit: 1074)
|
|||
|
Memory: 14.3M
|
|||
|
CPU: 8.709s
|
|||
|
CGroup: /system.slice/named.service
|
|||
|
└─13820 /usr/sbin/named -f -u bind
|
|||
|
```
|
|||
|
|
|||
|
If it’s not running, start it with:
|
|||
|
|
|||
|
```bash
|
|||
|
systemctl start bind9
|
|||
|
```
|
|||
|
|
|||
|
Edit the BIND DNS server’s configuration file.
|
|||
|
|
|||
|
```bash
|
|||
|
nano /etc/bind/named.conf.options
|
|||
|
```
|
|||
|
|
|||
|
Add the following line to allow VPN clients to send recursive DNS queries.
|
|||
|
|
|||
|
```default
|
|||
|
allow-recursion { 127.0.0.1; 10.10.10.0/24; ::1; 2405:4200:f001:13f6::1/64; };
|
|||
|
```
|
|||
|
|
|||
|
Save and close the file.
|
|||
|
|
|||
|
```terminal_image
|
|||
|
:~$ cat /etc/bind/named.conf.options | tail -n8
|
|||
|
// If BIND logs error messages about the root key being expired,
|
|||
|
// you will need to update your keys. See https://www.isc.org/bind-keys
|
|||
|
//========================================================================
|
|||
|
dnssec-validation auto;
|
|||
|
|
|||
|
listen-on-v6 { any; };
|
|||
|
allow-recursion { 127.0.0.1; 10.10.10.0/24; ::1; 2405:4200:f001:13f6::1/64; };
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
Then edit the `/etc/default/named` files.
|
|||
|
|
|||
|
```bash
|
|||
|
nano /etc/default/named
|
|||
|
```
|
|||
|
|
|||
|
Add `-4` to the `OPTIONS` to ensure BIND can query root DNS servers.
|
|||
|
|
|||
|
OPTIONS="-u bind -4"
|
|||
|
|
|||
|
Save and close the file.
|
|||
|
|
|||
|
By default, BIND enables DNSSEC, which ensures that DNS responses are correct and not tampered with. However, it might not work out of the box due to *trust anchor rollover* and other reasons. To make it work properly, we can rebuild the managed key database with the following commands.
|
|||
|
|
|||
|
```bash
|
|||
|
rndc managed-keys destroy
|
|||
|
rdnc reconfig
|
|||
|
```
|
|||
|
|
|||
|
Restart `bind9` for the changes to take effect.
|
|||
|
|
|||
|
```bash
|
|||
|
systemctl restart bind9
|
|||
|
```
|
|||
|
|
|||
|
Your ufw will allow vpn clients to access `bind9` because you earlier allowed in everything from `wg0`.
|
|||
|
|
|||
|
## Start WireGuard on the server.
|
|||
|
|
|||
|
Run the following command on the server to start WireGuard.
|
|||
|
|
|||
|
```bash
|
|||
|
wg-quick up /etc/wireguard/wg0.conf
|
|||
|
```
|
|||
|
|
|||
|
To stop it, run
|
|||
|
|
|||
|
```bash
|
|||
|
wg-quick down /etc/wireguard/wg0.conf
|
|||
|
```
|
|||
|
|
|||
|
You can also use systemd service to start WireGuard.
|
|||
|
|
|||
|
```bash
|
|||
|
systemctl start wg-quick@wg0.service
|
|||
|
```
|
|||
|
|
|||
|
Enable auto-start at system boot time.
|
|||
|
|
|||
|
```bash
|
|||
|
systemctl enable wg-quick@wg0.service
|
|||
|
```
|
|||
|
|
|||
|
Check its status with the following command. Its status should be `active (exited)`.
|
|||
|
|
|||
|
```bash
|
|||
|
systemctl status wg-quick@wg0.service
|
|||
|
```
|
|||
|
|
|||
|
Now WireGuard server is ready to accept client connections.
|
|||
|
|
|||
|
# Configure Wireguard on Debian 11 client.
|
|||
|
|
|||
|
```bash
|
|||
|
apt -qy install openresolv
|
|||
|
nano /etc/wireguard/wg-client0.conf
|
|||
|
```
|
|||
|
|
|||
|
You will edit the wireguard client config file so that the client will use
|
|||
|
`openresolv` to use your server's resolver to find the network addresses of
|
|||
|
domain names instead of leaking your activities all over the internet.
|
|||
|
|
|||
|
Copy the following text and paste it to your configuration file. You need to
|
|||
|
use your own client private key and server public key, _and your own endpoint and port_.
|
|||
|
Remember, curly braces mean that the material is only
|
|||
|
for example, and has to be customized. Mutas mutandis. Metasyntactic variables.
|
|||
|
|
|||
|
```default
|
|||
|
[Interface]
|
|||
|
Address = 10.10.10.2/24
|
|||
|
DNS = 10.10.10.1
|
|||
|
PrivateKey = «cOFA+x5UvHF+a3xJ6enLatG+DoE3I5PhMgKrMKkUyXI=»
|
|||
|
|
|||
|
[Peer]
|
|||
|
PublicKey = «kQvxOJI5Km4S1c7WXu2UZFpB8mHGuf3Gz8mmgTIF2U0=»
|
|||
|
AllowedIPs = 0.0.0.0/0
|
|||
|
Endpoint = «123.45.67.89:51820»
|
|||
|
PersistentKeepalive = 25
|
|||
|
```
|
|||
|
|
|||
|
Where:
|
|||
|
|
|||
|
- `Address`: Specify the private IP address of the VPN client.
|
|||
|
- `DNS`: specify 10.10.10.1 (the VPN server) as the DNS server. It will be configured via the `resolvconf` command. You can also specify multiple DNS servers for redundancy like this: `DNS = 10.10.10.1 8.8.8.8`
|
|||
|
- `PrivateKey`: The client’s private key, which can be found in the `/etc/wireguard/private.key` file on the client computer.
|
|||
|
- `PublicKey`: The server’s public key, which can be found in the `/etc/wireguard/server_public.key` file on the server.
|
|||
|
- `AllowedIPs`: 0.0.0.0/0 represents the whole Internet, which means all traffic to the Internet should be routed via the VPN.
|
|||
|
- `Endpoint`: The public IP address and port number of VPN server. Replace 123.45.67.89 with your server’s real public IP address and the port number with your server’s real port number.
|
|||
|
- `PersistentKeepalive`: Send an authenticated empty packet to the peer every 25 seconds to keep the connection alive. If PersistentKeepalive isn’t enabled, the VPN server might not be able to ping the VPN client.
|
|||
|
|
|||
|
Save and close the file.
|
|||
|
|
|||
|
Change the file mode so that only root user can read the files.
|
|||
|
|
|||
|
```bash
|
|||
|
chmod 600 /etc/wireguard/ -R
|
|||
|
```
|
|||
|
|
|||
|
Start WireGuard.
|
|||
|
|
|||
|
```bash
|
|||
|
systemctl start wg-quick@wg0-client0.service
|
|||
|
```
|
|||
|
|
|||
|
Enable auto-start at system boot time.
|
|||
|
|
|||
|
```bash
|
|||
|
systemctl enable wg-quick@wg0-client0.service
|
|||
|
```
|
|||
|
|
|||
|
Check its status:
|
|||
|
|
|||
|
```bash
|
|||
|
systemctl status wg-quick@wg0-client0.service
|
|||
|
```
|
|||
|
|
|||
|
Now go to this website: `http://icanhazip.com/` to check your public IP address. If everything went well, it should display your VPN server’s public IP address instead of your client computer’s public IP address.
|
|||
|
|
|||
|
You can also run the following command to get the current public IP address.
|
|||
|
|
|||
|
```bash
|
|||
|
curl https://icanhazip.com
|
|||
|
```
|
|||
|
|
|||
|
# Troubleshooting
|
|||
|
|
|||
|
## Check if UDP port «51820» is open
|
|||
|
|
|||
|
Install the `tshark` network traffic analyzer on the server. Tshark is the command-line version of Wireshark.
|
|||
|
|
|||
|
```bash
|
|||
|
apt install -qy tshark
|
|||
|
adduser «your-username» wireshark
|
|||
|
su -l «your-username»
|
|||
|
tshark -i «eth0» "udp port «51820»"
|
|||
|
```
|
|||
|
|
|||
|
If you are asked “_Should non-superusers be able to capture packets?_”,
|
|||
|
answer _Yes_. Once it’s installed, run the following command to add your
|
|||
|
user account to the `wireshark` group so that you can capture packets.
|
|||
|
|
|||
|
If the WireGuard client is able to connect to UDP port «51820» of the server, then you will see packets being captured by tshark like below. As you can see, the client started the handshake initiation, and the server sent back a handshake response. Once the connection is established, the client sends keepalive packets.
|
|||
|
|
|||
|
```terminal_image
|
|||
|
Capturing on 'eth0'
|
|||
|
1 105.092578905 11.22.33.44 → 12.34.56.78 WireGuard 190 Handshake Initiation, sender=0x3F1A04AB
|
|||
|
2 110.464628716 12.34.56.78 → 11.22.33.44 WireGuard 134 Handshake Response, sender=0x34ED7471, receiver=0xD4B23800
|
|||
|
3 110.509517074 11.22.33.44 → 12.34.56.78 WireGuard 74 Keepalive, receiver=0x34ED7471, counter=0
|
|||
|
```
|
|||
|
|
|||
|
If the WireGuard client can not connect to UDP port 51820 of the server, then you will only see handshake initiation packets. There’s no handshake respsonse.
|
|||
|
|
|||
|
```terminal_image
|
|||
|
Capturing on 'eth0'
|
|||
|
1 105.092578905 11.22.33.44 → 12.34.56.78 WireGuard 190 Handshake Initiation, sender=0x3F1A04AB
|
|||
|
2 149.670118573 11.22.33.44 → 12.34.56.78 WireGuard 190 Handshake Initiation, sender=0x7D584974
|
|||
|
3 152.575188680 11.22.33.44 → 12.34.56.78 WireGuard 190 Handshake Initiation, sender=0x8D2407B9
|
|||
|
4 153.706876729 12.34.56.78 → 11.22.33.44 WireGuard 190 Handshake Initiation, sender=0x47690027
|
|||
|
5 154.789959772 11.22.33.44 → 12.34.56.78 WireGuard 190 Handshake Initiation, sender=0x993232FC
|
|||
|
6 157.956576772 11.22.33.44 → 12.34.56.78 WireGuard 190 Handshake Initiation, sender=0x06AD433B
|
|||
|
7 159.082825929 12.34.56.78 → 11.22.33.44 WireGuard 190 Handshake Initiation, sender=0x8C089E1
|
|||
|
```
|
|||
|
|
|||
|
## Ping test
|
|||
|
|
|||
|
You can ping from the VPN server to VPN client (`ping 10.10.10.2`) to see if the tunnel works. If you see the following error message in the ping,
|
|||
|
|
|||
|
```terminal_image
|
|||
|
ping: sendmsg: Required key not available
|
|||
|
```
|
|||
|
|
|||
|
it might be that the `AllowedIPs` parameter is wrong, like a typo.
|
|||
|
|
|||
|
If the ping error message is
|
|||
|
|
|||
|
```terminal_image
|
|||
|
ping: sendmsg: Destination address required
|
|||
|
```
|
|||
|
|
|||
|
it could be that the private/public key is wrong in your config files.
|
|||
|
|
|||
|
## Not able to browse the Internet
|
|||
|
|
|||
|
If the VPN tunnel is successfully established, but the client public IP
|
|||
|
address doesn’t change, that’s because the masquerading or forwarding
|
|||
|
rule in your UFW config file is not working, typically typo in the
|
|||
|
`/etc/ufw/before.rules` file
|
|||
|
|
|||
|
## Enable Debug logging in Linux Kernel
|
|||
|
|
|||
|
If you use Linux kernel 5.6+, you can, as root, enable debug logging for
|
|||
|
WireGuard with the following command. As a non root wireguard user,
|
|||
|
cannot log kernel.
|
|||
|
|
|||
|
sudo su -
|
|||
|
echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control
|
|||
|
|
|||
|
Then you can view the debug logs with
|
|||
|
|
|||
|
sudo dmesg -wH
|
|||
|
|
|||
|
or
|
|||
|
|
|||
|
sudo journalctl -kf
|
|||
|
|
|||
|
## Restart
|
|||
|
|
|||
|
If your VPN still doesn’t work, try restarting the VPN server and client.
|
|||
|
|
|||
|
# Adding Additional VPN Clients
|
|||
|
|
|||
|
WireGuard is designed to associate one IP address with one VPN client. To add more VPN clients, you need to create a unique private/public key pair for each client, then add each VPN client’s public key in the server’s config file (`/etc/wireguard/wg0.conf`) like this:
|
|||
|
|
|||
|
```default
|
|||
|
[Interface]
|
|||
|
Address = 10.10.10.1/24
|
|||
|
PrivateKey = «UIFH+XXjJ0g0uAZJ6vPqsbb/o68SYVQdmYJpy/FlGFA=»
|
|||
|
ListenPort = «51820»
|
|||
|
|
|||
|
[Peer]
|
|||
|
PublicKey = «75VNV7HqFh+3QIT5OHZkcjWfbjx8tc6Ck62gZJT/KRA=»
|
|||
|
AllowedIPs = 10.10.10.2/32
|
|||
|
|
|||
|
[Peer]
|
|||
|
PublicKey = «YYh4/1Z/3rtl0i7cJorcinB7T4UOIzScifPNEIESFD8=»
|
|||
|
AllowedIPs = 10.10.10.3/32
|
|||
|
|
|||
|
[Peer]
|
|||
|
PublicKey = «EVstHZc6QamzPgefDGPLFEjGyedJk6SZbCJttpzcvC8=»
|
|||
|
AllowedIPs = 10.10.10.4/32
|
|||
|
```
|
|||
|
|
|||
|
Each VPN client will have a static private IP address (10.10.10.2,
|
|||
|
10.10.10.3, 10.10.10.4, etc). Restart the WireGuard server for the changes
|
|||
|
to take effect.
|
|||
|
|
|||
|
Then add WireGuard configuration on each VPN client as usual.
|
|||
|
|
|||
|
## Configure VPN Client on iOS/Andorid
|
|||
|
|
|||
|
Install the `WireGuard` app from the App store. Then open this app and click the `Add a tunnel` button.
|
|||
|
|
|||
|
You have 3 methods to create a new WireGuard tunnel.
|
|||
|
|
|||
|
- create from file or archive
|
|||
|
- create from QR code
|
|||
|
- Create from scratch
|
|||
|
|
|||
|
"Create from scratch" means that the Wireguard app gives you a private and public key pair, and an empty wg-client.conf file that you populate in
|
|||
|
the wireguard app ui. This is likely to result in a lot of typing where you
|
|||
|
are bound to do a typo, even though the correct and working information
|
|||
|
is already on your debian server and client and you would like to just copy
|
|||
|
and paste it.
|
|||
|
|
|||
|
Create from QR code means that you create `ios.conf` in your client, as before for debian, add the public key to your server `wg0.conf` as before for debian, restart the server as before, and then generate the QR code with
|
|||
|
|
|||
|
```bash
|
|||
|
apt install -qy qrencode
|
|||
|
cat /etc/wireguard/ios.conf | qrencode -t ansiutf8
|
|||
|
```
|
|||
|
This is apt to be easier, because it is likely to be hard to transfer information between android systems.
|
|||
|
|
|||
|
Grencode is very useful for transferring data to android systems, which tend to be locked down against ordinary users transferring computer data.
|
|||
|
|
|||
|
## Configure VPN Client on Windows
|
|||
|
|
|||
|
Download the [WireGuard installer for Windows](https://www.wireguard.com/install/).
|
|||
|
|
|||
|
Once it’s installed, start the WireGuard program. You need to right-click
|
|||
|
on the left sidebar to _create a new empty tunnel_. It will automatically
|
|||
|
create a public/private key for the Windows client.
|
|||
|
|
|||
|
And from there on, same as with the android client.
|
|||
|
|
|||
|
On Windows, you can [use the PowerShell program to SSH into your
|
|||
|
Linux server](https://www.linuxbabe.com/linux-server/ssh-windows), so you do not have the problem you had with android.
|
|||
|
|
|||
|
|
|||
|
# Policy Routing, Split Tunneling & VPN Kill Switch
|
|||
|
|
|||
|
It’s not recommended to use _policy routing_, _split tunneling_, or _VPN kill switch_ in conjunction with each other. If you use policy routing, then you should not enable split tunneling or VPN kill switch, and vice versa.
|
|||
|
|
|||
|
## Policy Routing
|
|||
|
|
|||
|
By default, all traffic on the VPN client will be routed through the VPN
|
|||
|
server. Sometimes you may want to route only a specific type of traffic,
|
|||
|
based on the transport layer protocol and the destination port. This is
|
|||
|
known as policy routing.
|
|||
|
|
|||
|
Policy routing is configured on the client computer, and we need to stop
|
|||
|
the WireGuard client process and edit the client configuration file.
|
|||
|
|
|||
|
```bash
|
|||
|
systemctl stop wg-quick@wg0.service
|
|||
|
nano /etc/wireguard/wg-client0.conf
|
|||
|
```
|
|||
|
|
|||
|
For example, if you add the following 3 lines in the `[interface]` section,
|
|||
|
then WireGuard will create a routing table named “1234” and add the ip rule
|
|||
|
into the routing table. In this example, traffic will be routed through VPN
|
|||
|
server only when TCP is used as the transport layer protocol and the
|
|||
|
destination port is 25, i.e, when the client computer sends emails.
|
|||
|
|
|||
|
```default
|
|||
|
Table = 1234
|
|||
|
PostUp = ip rule add ipproto tcp dport 25 table 1234
|
|||
|
PreDown = ip rule delete ipproto tcp dport 25 table 1234
|
|||
|
```
|
|||
|
|
|||
|
```terminal_image
|
|||
|
[Interface]
|
|||
|
Address = 10.10.10.2/24
|
|||
|
DNS = 10.10.10.1
|
|||
|
PrivateKey = «cOFA+x5UvHF+a3xJ6enLatG+DoE3I5PhMgKrMKkUyXI=»
|
|||
|
Table = 1234
|
|||
|
PostUp = ip rule add ipproto tcp dport 25 table 1234
|
|||
|
PreDown = ip rule delete ipproto tcp dport 25 table 1234
|
|||
|
|
|||
|
[Peer]
|
|||
|
PublicKey = «kQvxOJI5Km4S1c7WXu2UZFpB8mHGuf3Gz8mmgTIF2U0=»
|
|||
|
AllowedIPs = 0.0.0.0/0
|
|||
|
Endpoint = «123.45.67.89:51820»
|
|||
|
PersistentKeepalive = 25
|
|||
|
```
|
|||
|
|
|||
|
Save and close the file. Then start WireGuard client again.
|
|||
|
|
|||
|
## Split Tunneling
|
|||
|
|
|||
|
By default, all traffic on the VPN client will be routed through the VPN
|
|||
|
server. Here’s how to enable split tunneling, so only traffic to the
|
|||
|
`10.10.10.0/24` IP range will be tunneled through WireGuard VPN. This is useful when you want to build a private network for several cloud servers, because VPN clients will run on cloud servers and if you use a full VPN tunnel, then you will probably lose connection to the cloud servers.
|
|||
|
|
|||
|
Edit the client configuration file.
|
|||
|
|
|||
|
```default
|
|||
|
nano /etc/wireguard/wg-client0.conf
|
|||
|
```
|
|||
|
|
|||
|
Change
|
|||
|
|
|||
|
```default
|
|||
|
AllowedIPs = 0.0.0.0/0
|
|||
|
```
|
|||
|
|
|||
|
To
|
|||
|
|
|||
|
```default
|
|||
|
AllowedIPs = 10.10.10.0/24
|
|||
|
```
|
|||
|
|
|||
|
So traffic will be routed through VPN only when the destination address is
|
|||
|
in the 10.10.10.0/24 IP range. Save and close the file. Then restart WireGuard client.
|
|||
|
|
|||
|
sudo systemctl restart wg-quick@wg0.service
|
|||
|
|
|||
|
## VPN Kill Switch
|
|||
|
|
|||
|
By default, your computer can access the Internet via the normal gateway
|
|||
|
when the VPN connection is disrupted. You may want to enable the kill switch
|
|||
|
feature, which prevents the flow of unencrypted packets through
|
|||
|
non-WireGuard interfaces.
|
|||
|
|
|||
|
Stop the WireGuard client process and the client configuration file.
|
|||
|
|
|||
|
```default
|
|||
|
systemctl stop wg-quick@wg0.service
|
|||
|
nano /etc/wireguard/wg-client0.conf
|
|||
|
````
|
|||
|
|
|||
|
Add the following two lines in the `[interface]` section.
|
|||
|
|
|||
|
```default
|
|||
|
PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
|
|||
|
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
|
|||
|
```
|
|||
|
|
|||
|
Like this:
|
|||
|
```terminal_image
|
|||
|
[Interface]
|
|||
|
Address = 10.10.10.2/24
|
|||
|
DNS = 10.10.10.1
|
|||
|
PrivateKey = cOFA+x5UvHF+a3xJ6enLatG+DoE3I5PhMgKrMKkUyXI=
|
|||
|
PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
|
|||
|
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
|
|||
|
|
|||
|
[Peer]
|
|||
|
PublicKey = kQvxOJI5Km4S1c7WXu2UZFpB8mHGuf3Gz8mmgTIF2U0=
|
|||
|
AllowedIPs = 0.0.0.0/0
|
|||
|
Endpoint = 12.34.56.78:51820
|
|||
|
PersistentKeepalive = 25
|
|||
|
```
|
|||
|
|
|||
|
Save and close the file. Then start the WireGuard client.
|