Setup Server
Install WireGuard
Code: Select all
sudo apt update
sudo apt-get install wireguard -yNow we need to create the public and private key-pairs used for establishing a secure connection.
We can do this by running the following command:
Code: Select all
wg genkey | tee privatekey | wg pubkey > publickeyand publickey which contain the private and public keys accordingly.
Configure Tunnel Interface
Code: Select all
WIREGUARD_INTERFACE_NAME="wg0"
sudo touch /etc/wireguard/${WIREGUARD_INTERFACE_NAME}.confCode: Select all
wg0must be at that path and have the same name with the
Code: Select all
.confNow either fill it in manually by substituting the variables in the content below:
Code: Select all
[Interface]
PrivateKey=${PRIVATE_KEY}
# Specify the subnet that should be used for assigning IP addresses to the clients on this
# tunnel interface. This needs to not overlap with your server's private IP subnet!
Address=${WIREGUARD_SUBNET}
SaveConfig=false
# Add rules to iptables networking when the interface come up in order to have the server do the
# following:
# 1. Accept every forwarding packet on the tunnel interface (wg0)
# 2. have packets that we forward out on the eth0 interface be manipulated to look like they came
# from this server instead of having their original source IP.
PostUp=iptables -A FORWARD -i ${WIREGUARD_INTERFACE_NAME} -j ACCEPT; iptables -t nat -A POSTROUTING -o ${NORMAL_INTERFACE_NAME} -j MASQUERADE;
# Remove the rules we added, when the wireguard tunnel interface comes down
PostDown=iptables -D FORWARD -i ${WIREGUARD_INTERFACE_NAME} -j ACCEPT; iptables -t nat -D POSTROUTING -o ${NORMAL_INTERFACE_NAME} -j MASQUERADE;
# Specify which port you wish for the wireguard to listen on for this interface. This can be anything
# you want, but 51820 is the default for wireguard.
ListenPort=${PORT}Code: Select all
# Settings - fill these in as appropriate to you.
PRIVATE_KEY=""
WIREGUARD_INTERFACE_NAME="wg0"
WIREGUARD_SUBNET="10.172.0.1/24"
NORMAL_INTERFACE_NAME="eth0"
PORT=51820
sudo echo "
[Interface]
PrivateKey=${PRIVATE_KEY}
# Specify the subnet that should be used for assigning IP addresses to the clients on this
# tunnel interface. This needs to not overlap with your server's private IP subnet!
Address=${WIREGUARD_SUBNET}
# Specify if you want wireguard to overwrite the config on shutdown.
SaveConfig=false
# Add rules to iptables networking when the interface come up in order to have the server do the
# following:
# 1. Accept every forwarding packet on the tunnel interface (wg0)
# 2. have packets that we forward out on the eth0 interface be manipulated to look like they came from this
# server instead of having their original source IP.
PostUp=iptables -A FORWARD -i ${WIREGUARD_INTERFACE_NAME} -j ACCEPT; iptables -t nat -A POSTROUTING -o ${NORMAL_INTERFACE_NAME} -j MASQUERADE;
# Remove the rules we added, when the wireguard tunnel interface comes down
PostDown=iptables -D FORWARD -i ${WIREGUARD_INTERFACE_NAME} -j ACCEPT; iptables -t nat -D POSTROUTING -o ${NORMAL_INTERFACE_NAME} -j MASQUERADE;
# Specify which port you wish for the wireguard to listen on for this interface. This can be anything
# you want, but 51820 is the default for wireguard.
ListenPort=${PORT}
" | sudo tee /etc/wireguard/${WIREGUARD_INTERFACE_NAME}.confFinally, we need to ensure that the server will allow packet forwarding. This can be enabled by running:
Code: Select all
sudo echo 1 | sudo tee /proc/sys/net/ipv4/ip_forwardCode: Select all
SEARCH="#net.ipv4.ip_forward.*"
REPLACE="net.ipv4.ip_forward=1"
FILEPATH="/etc/sysctl.conf"
sudo sed -i "s;$SEARCH;$REPLACE;" $FILEPATH
# Have the change take immediate effect
sudo sysctl -pNow we need to setup and configure wireguard on the client, for it to connect to the server.
Install Wireguard
Install wireguard as you did before:
Code: Select all
sudo apt update
sudo apt-get install wireguard -yCode: Select all
wg genkey | tee privatekey | wg pubkey > publickeyNow create a wireguard configuration file by running:
Code: Select all
touch /etc/wireguard/wg0.confCode: Select all
wg0.confCode: Select all
.confCode: Select all
/etc/wireguardfile will reflect the name of the interface. The name of the interface doesn't need to match
the name of the interface on the server either.
Now either fill it with the following, taking care to manually swap out the values as appropriate
to your setup:
Code: Select all
[Interface]
PrivateKey=${PRIVATE_KEY}
# Specify the subnet that should be used for assigning IP addresses to the clients on this
# tunnel interface. This needs to not overlap with your private IP subnet, and needs to be
# unique on the subnet you created. E.g. we used 10.172.0.1 for the server, so we
# are using 10.172.0.2 here. If you were to create another client it would need to be
# 10.172.0.3 etc.
Address=10.172.0.2/24
# Specify if you wish for WireGuard to overwrite the config on shutdown.
SaveConfig=false
[Peer]
# Specify the public key of the server you wish to connect to.
PublicKey=${SERVER_PUBLIC_KEY}
# Specify the IP address of the server to connect to. If you are using something like DigitalOcean,
# then this would be that instance's public/internet IP address. If you are using a computer on
# your private network, then you could specify its private IP address.
Endpoint=${SERVER_PUBLIC_IP_ADDRESS}
# Specify which subnets that wireguard should send through the tunnel. We wish to send all traffic
# through the server, so we will use 0.0.0.0/0, but if you only wanted to forward traffic for
# another private subnet that your server is on, you could specify it's subnet instead.
AllowedIPs=0.0.0.0/0
# Optionally have the following to have wireguard send a keepalive packet every x seconds so
# that the connection remains open, otherwise routers/gateways between the server and the client
# may close the connection because wireguard uses UDP and is stateless.
PersistentKeepalive=30Code: Select all
CLIENT_PRIVATE_KEY=""
SERVER_PUBLIC_KEY=""
WIREGUARD_INTERFACE_NAME="wg0"
WIREGUARD_SUBNET_CLIENT_IP="10.172.0.2/24"
SERVER_PUBLIC_IP_ADDRESS=""
AllowedIPs="0.0.0.0/0"
PORT=51820
sudo echo "
[Interface]
PrivateKey=${CLIENT_PRIVATE_KEY}
# Specify the subnet that should be used for assigning IP addresses to the clients on this
# tunnel interface. This needs to not overlap with your private IP subnet, and needs to be
# unique on the subnet you created. E.g. we used 10.172.0.1 for the server, so we
# are using 10.172.0.2 here. If you were to create another client it would need to be
# 10.172.0.3 etc.
Address=${WIREGUARD_SUBNET_CLIENT_IP}
# Specify if you wish for WireGuard to overwrite the config on shutdown.
SaveConfig=false
[Peer]
# Specify the public key of the server you wish to connect to.
PublicKey=${SERVER_PUBLIC_KEY}
# Specify the IP address of the server to connect to. If you are using something like DigitalOcean,
# then this would be that instance's public/internet IP address. If you are using a computer on
# your private network, then you could specify its private IP address.
Endpoint=${SERVER_PUBLIC_IP_ADDRESS}:${PORT}
# Specify which subnets that wireguard should send through the tunnel. We wish to send all traffic
# through the server, so we will use 0.0.0.0/0, but if you only wanted to forward traffic for
# another private subnet that your server is on, you could specify it's subnet instead.
AllowedIPs=${AllowedIPs}
# Optionally have the following to have wireguard send a keepalive packet every x seconds so that
# the connection remains open, otherwise routers/gateways between the server and the client may
# close the connection because wireguard uses UDP and is stateless.
PersistentKeepalive=30" | sudo tee /etc/wireguard/${WIREGUARD_INTERFACE_NAME}.confWe now need to tell the server to allow the client to be able to connect. This is similar to how we
add a public SSH key to the $HOME/.ssh/authorized_keys file to tell the server we allow a
client to connect with their SSH Key.
Run the following BASH script to append the peer connection details to your WireGuard interface's configuration file:
Code: Select all
WIREGUARD_INTERFACE_NAME="wg0"
# Specify the *public* key of the client
CLIENT_PUBLIC_KEY="xxxxxxxxxxxxxxxxxxxx"
# Specify the IP address you gave the client in their `Address` setting but use /32 for the CIDR
# so that the client can only use that single IP.
CLIENT_TUNNEL_IP="10.172.0.2/32"
echo "
[Peer]
PublicKey = ${CLIENT_PUBLIC_KEY}
AllowedIPs = ${CLIENT_TUNNEL_IP}
" >> /etc/wireguard/${WIREGUARD_INTERFACE_NAME}.confCode: Select all
[Peer]
PublicKey = ${CLIENT_PUBLIC_KEY}
AllowedIPs = ${CLIENT_TUNNEL_IP}The alternative would be to just run the following command to add the client to wireguard interface:
Code: Select all
WIREGUARD_INTERFACE="wg0"
CLIENT_PUBLIC_KEY="xxxxxxxxxxxxxxxxxxxx"
# Specify the IP address you gave the client in their `Address` setting but use /32 for the CIDR
# so that the client can only use that single IP.
CLIENT_TUNNEL_IP="10.172.0.2/32"
sudo wg set $WIREGUARD_INTERFACE peer ${CLIENT_PUBLIC_KEY} allowed-ips ${CLIENT_TUNNEL_IP}Code: Select all
SaveConfigCode: Select all
trueconfig file for
the client to be kept, and you not having to keep entering the line. The
downside to this is that it will also write in the endpoint for
the client, which is not ideal in which your client's may likely change
IP such as a laptop you travel with. Thus I go with just adding
the peers manually to the config file, and having
Code: Select all
SaveConfigUsing The Wireguard Tunnel
Now in order to get the tunnel running and make use of it, you first need to run the connect/up command
shown below on the server first, before then running it on the client.
Connect
Finally, after all of that configuration, you should be able to use the following command on your client
in order to create the WireGuard tunnel connection to the server and start making use of it:
Code: Select all
WIREGUARD_INTERFACE_NAME="wg0"
sudo wg-quick up $WIREGUARD_INTERFACE_NAMEIf you don't like sticking the configuration files in the
Code: Select all
/etc/wireguardelse, then you can just specify the full path to the configuration file instead:
Code: Select all
CONFIG_FILEPATH="/path/to/my/wireguard/config.conf"
sudo wg-quick up $CONFIG_FILEPATHTo disconnect, you an then run the down command like so:
Code: Select all
WIREGUARD_INTERFACE_NAME="wg0"
sudo wg-quick down $WIREGUARD_INTERFACE_NAMEIf you wish to see your current wireguard connections and how much
traffic is being sent over them, you can run the following command:
Code: Select all
sudo wg showIf you wish for the wireguard connection to automatically start on boot, you cn enable this through
systemd like so:
Code: Select all
WG_INTERFACE="wg0"
sudo systemctl enable wg-quick@${WG_INTERFACE}.service
sudo systemctl daemon-reloadCode: Select all
WG_INTERFACE="wg0"
sudo systemctl start wg-quick@${WG_INTERFACE}