Bureaucrats, Check users, Interface administrators, Push subscription managers, Suppressors, Administrators
511
edits
m (small note) |
No edit summary |
||
This guide will instruct you on how to set up a WireGuard tunnel between a server machine and one or more clients. This establishes a secure tunnel between the machines (connecting them as if they were on the same LAN), and can further be used to route traffic and forward ports.
These instructions are specifically tailored to Linux machines.
== Prerequisites ==
You'll need:
*A server machine that
*At least one client machine.
*Basic knowledge of how computers and Linux systems work.
==
For the purposes of this guide, we are calling our tunnel <code>wg0</code>. If you would like to use a different name, make sure to substitute <code>wg0</code> with the interface name of your choice in all commands and config files.
We will be using <code>10.0.32.0/24</code> as our WireGuard subnet for the purposes of this guide.
=== Install Dependencies ===
First
{{code|lang=bash|<nowiki>
$ sudo pacman --needed --noconfirm -Sy wireguard-tools nftables # Arch
$ sudo apt-get install -y wireguard-tools nftables # Debian
</nowiki>
}}
===
Now, we need to generate a public and private key for each system that will be in the tunnel. You can use these commands on each computer, as root:
{{code|lang=bash|<nowiki>
$ sudo -i
# mkdir -p /etc/wireguard/keys/wg0 # Create a directory for the keys
# cd /etc/wireguard/keys/wg
# umask 077 # Temporarily set the default permissions for all files to rwx------
# wg genkey</nowiki> > <nowiki>private.key # Generate the private key
# wg pubkey</nowiki> < <nowiki>private.key</nowiki> > <nowiki>public.key # Derive the public key from the private key
# cat private.key
/ExampleServerPrivateKey=
# cat public.key
/ExampleServerPublicKey=
</nowiki>}}
=== Configuring the tunnel (Server) ===
On your server machine, create <code>/etc/wireguard/wg0.conf</code> and put the following in it.
{{code|lang=ini|
[Interface]
<nowiki>PrivateKey = </nowiki> <
Address = 10.0.32.1/32
ListenPort = 51820
</nowiki>
}}
This will assign your WireGuard server with the IP <code>10.0.32.1</code> on the WireGuard tunnel, and listen on UDP port <code>51820</code>
Next, add the clients. In the server's wg0.conf, add the following for each client:
{{code|lang=ini|
[Peer]
<nowiki>PublicKey =</nowiki> <
<nowiki>AllowedIPs = 10.0.32.2/32</nowiki>
}}
This will give the specified client an IP address of <code>10.0.32.2</code> on the WireGuard tunnel. Make sure you increment this for each client and use the correct public keys.
Here is an example of a completed server wg0.conf:
{{code|lang=ini|<nowiki>
[Interface]
PrivateKey = /ExampleServerPrivateKey=
Address = 10.0.32.1/32
ListenPort = 51820
[Peer]
PublicKey = /ExampleClientPublicKey1=
AllowedIPs = 10.0.32.2/32
[Peer]
PublicKey = /ExampleClientPublicKey2=
AllowedIPs = 10.0.32.3/32
[Peer]
PublicKey = /ExampleClientPublicKey3=
AllowedIPs = 10.0.32.4/32
</nowiki>}}
=== Configuring the tunnel (Client) ===
Now, on your client(s), create <code>/etc/wireguard/wg0.conf</code> as well and put the following in
{{code|lang=ini|
[Interface]
<nowiki>PrivateKey =</nowiki>
<nowiki>Address = 10.0.32.2/24</nowiki>
<nowiki>[Peer]
PublicKey =</nowiki>
<nowiki>AllowedIPs = 10.0.32.0/24
Endpoint =</nowiki> <Your server's IP
}}
Make SURE to use the correct combination of IP address and private key defined in a <code>[Peer]</code> section in the server configuration.
=== Bringing Your WireGuard Tunnel Up ===
Now that we have configured our server and clients, we can start the tunnel. The following command will start the tunnel, and configure it to be started on every boot. Run it on your server and all your clients.
{{code|lang=bash|
}}
===
Assuming everything started correctly, each machine should now have a <code>wg0</code> interface with the correct IP assigned to it. Test the connection from one of the clients with ping:
{{code|lang=bash|<nowiki>
$ ping 10.0.32.1
PING 10.0.32.1 (10.0.32.1) 56(84) bytes of data.
64 bytes from 10.0.32.1: icmp_seq=1 ttl=64 time=1.99 ms
64 bytes from 10.0.32.1: icmp_seq=2 ttl=64 time=1.81 ms
64 bytes from 10.0.32.1: icmp_seq=3 ttl=64 time=1.76 ms
(...)
</nowiki>}}
If all went well, congratulations! You now have a secure tunnel between your server and all of your WireGuard clients. Continue reading for how to configure it to your liking
== Routing traffic ==
You may want to set up your WireGuard server as a router, so that all outbound traffic from one or more of your clients goes through the server (the common definition of a VPN). This is very easy to do.
=== Enable IP Forwarding ===
First, we enable IP forwarding on the server machine. This instructs the Linux kernel that when it receives a packet from one of your clients destined to the internet, it should route that packet to its destination.
Run the following command to enable IP forwarding in the sysctl configuration:
{{code|lang=bash|<nowiki>
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/router.conf
sudo sysctl --system
</nowiki>
}}
=== Configuring SNAT ===
With IP forwarding enabled, the next step is to set an SNAT rule. This instructs the server that when it routes a packet from your client to the internet, it should also replace the source IP address (the client's internal WireGuard IP) with its own public IP. This can be accomplished through the NFTables firewall.
First, get the name of the server's internet-facing network interface, and it's public IP address. For example, we will use <code>eth0</code> as the interface.
Now, open <code>/etc/nftables.conf</code> and configure as follows:
{{code|lang=ini|
table inet nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
meta iifname wg0 meta oifname eth0 snat ip to <Enter server's public IP
}
}
}}
Reload the NFTables configuration:
{{code|lang=bash|
sudo nft -f /etc/nftables.conf
}}
Depending on distro and prior configuration, you may already have a <code>table inet nat</code> block, and possibly a <code>chain postrouting</code> inside it. In this case, merge the above configuration with your own. Otherwise, paste the above snippet into the bottom of the file.
=== Configure the client route ===
Now, all you need to do is configure WireGuard on the client to route all traffic through the server. You do this by configuring the <code>[Peer]</code> section on the client to have an <code>AllowedIPs</code> value of <code>0.0.0.0/0</code>. For example:
{{code|lang=ini|<nowiki>
[Interface]
PrivateKey =
Address = 10.0.32.2/24
[Peer]
PublicKey =
AllowedIPs = 0.0.0.0/0
Endpoint = server ip:51820
</nowiki>}}
Restart the WireGuard tunnel on the client:
{{code|lang=bash|
sudo systemctl restart wg-quick@wg0
}}
If all went well, all traffic on the client should now be routed through the server:
{{code|<nowiki>
$ curl ipinfo.io/what-is-my-ip
{
"ip": "143.244.47.86",
"hostname": "unn-143-244-47-86.datapacket.com",
"city": "Weehawken",
"region": "New Jersey",
"country": "US",
"loc": "40.7696,-74.0204",
"org": "AS212238 Datacamp Limited",
"postal": "07086",
"timezone": "America/New_York",
"readme": "https://ipinfo.io/missingauth"
}
</nowiki>}}
== Port Forwarding ==
You may want to forward ports on your server's public IP to the guest. This is very easy to do. We will update the server's NFTables configuration to set a DNAT rule. The following example will forward TCP ports 80 and 443 to the client at <code>10.0.32.2</code>.
{{code|lang=ini|
table inet nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
meta iifname eth0 tcp dport
}
}
}}
Make sure to change <code>eth0</code> to your server's public interface if it differs. Note that this rule goes into the <code>prerouting</code> chain, NOT the previously used <code>postrouting</code> chain.
Reload the NFTables configuration:
{{code|lang=bash|
sudo nft -f /etc/nftables.conf
}}
If all went well, connections to ports 80 and 443 on the server's public IP should now be forwarded to the HTTP server running on the client at <code>10.0.32.2</code>.
|