Installing & Configuring Wireguard on Centos 7 Minimal - cfloquetprojects/homelab GitHub Wiki
- Centos 7 box is properly networked.
- Let's start by getting an update and installing the latest versions of what we need.
[cfloquet@wireguard ~]$ sudo yum -y install yum-utils epel-release
[cfloquet@wireguard ~]$ sudo yum -y update
- Luckily, a signed module is available as built-in to CentOS's kernel-plus, let's install that now:
[cfloquet@wireguard ~]$ sudo yum-config-manager --setopt=centosplus.includepkgs=kernel-plus --enablerepo=centosplus --save
[cfloquet@wireguard ~]$ sudo sed -e 's/^DEFAULTKERNEL=kernel$/DEFAULTKERNEL=kernel-plus/' -i /etc/sysconfig/kernel
[cfloquet@wireguard ~]$ sudo yum install kernel-plus wireguard-tools
[cfloquet@wireguard ~]$ reboot
- The default installation directory is located at
/etc/wireguard
, which we will navigate into to create the public/private key pair that is needed for this wireguard server.
cfloquet@wireguard:~# cd /etc/wireguard
# we can create our key pair for wireguard using this one liner
cfloquet@wireguard:/etc/wireguard# wg genkey | tee privatekey | wg pubkey > publickey
# this will set our private key to read only for everyone, eliminating tampering
cfloquet@wireguard:/etc/wireguard# chmod 400 privatekey
- Now that we have our key pair, we can create the config file for Wireguard:
cfloquet@wireguard:/etc/wireguard# vi wg0.conf
...
[Interface]
PrivateKey = private_key_of_wg_server
Address = internal_wg_server_ip (ex: 10.20.10.1/24)
ListenPort = 51263 (must be allowed through firewalls)
[Peer]
PublicKey = public_key_of_peer
PreSharedKey = preshared_key
AllowedIPs = ip_of_VPN_client/32
...
cfloquet@wireguard:/etc/wireguard# cat wg0.conf
- The only port you need to open on the firewall is the port you specified for listening.
- Now lets move over to our Wireguard client (Linux) to begin the client setup before returning to the server.
- Similarly to the server, lets start by updating our host packages before installing Wireguard:
client@wgclient:~$ sudo apt -y update
client@wgclient:~$ sudo apt -y upgrade
client@wgclient:~$ sudo apt-get -y install wireguard
# We are able to verify a successful installation by running the following:
client@wgclient:~$ sudo dpkg -l | grep wireguard
- Next let's navigate into Wireguards installation directory and generate a key pair for authentication:
client@wgclient:~# cd /etc/wireguard
# Generate public and private keys with one command using piping
client@wgclient:/etc/wireguard# wg genkey | tee privatekey | wg pubkey > publickey
client@wgclient:/etc/wireguard# nano wg0.conf
...
# client config
[Interface]
PrivateKey = client_private_key
Address = ip_of_client_within_target_subnet/24
DNS = primary_dns_server,secondary_dns_server
ListenPort = 4826
MTU = 1280
[Peer]
AllowedIPs = 0.0.0.0/0,::/0
Endpoint = public_ip_of_target_vpn_server:exposed_port
PersistentKeepalive = 25
PresharedKey = pre_shared_key
PublicKey = server_pubic_key
...
cfloquet@wgclient:/etc/wireguard# sudo wg-quick up wg0
- First we need to set the wireguard server to be able to route traffic.
cfloquet@wireguard:~# cat /proc/sys/net/ipv4/ip_forward
0
# If the returned result is 1, skip the next step, where we make it permanent
cfloquet@wireguard:~# echo "net.ipv4.ip_forward = 1" > /etc/sysctl.conf
cfloquet@wireguard:~# sysctl -w net.ipv4.ip_forward=1
cfloquet@wireguard:~# cat /proc/sys/net/ipv4/ip_forward
1
- Now it's time to complete the final stretch, rather than appending PostUp/PostDown rules to our wg0.conf file directly, we can define these externally in bash files within a
helper
directory.
cfloquet@wireguard:/etc/wireguard# mkdir helper/ && cd helper/
cfloquet@wireguard:/etc/wireguard/helper# touch addRules.bash && touch remRules.bash
cfloquet@wireguard:/etc/wireguard/helper# vi addRules.bash
<...>
#!/bin/bash
IPT="/sbin/iptables"
IPT6="/sbin/ip6tables"
IN_FACE="ens192" # NIC connected to the internet
WG_FACE="wg0" # WG NIC
SUB_NET="10.0.4.0/29" # WG IPv4 sub/net aka CIDR
WG_PORT="51263" # WG udp port
#SUB_NET_6="fd42:42:42:42::/112" # WG IPv6 sub/net
## IPv4 ##
$IPT -t nat -I POSTROUTING 1 -s $SUB_NET -o $IN_FACE -j MASQUERADE
$IPT -I INPUT 1 -i $WG_FACE -j ACCEPT
$IPT -I FORWARD 1 -i $IN_FACE -o $WG_FACE -j ACCEPT
$IPT -I FORWARD 2 -i $WG_FACE -o $IN_FACE -j ACCEPT
$IPT -I INPUT 1 -i $IN_FACE -p udp --dport $WG_PORT -j ACCEPT
## IPv6 (Uncomment) ##
## $IPT6 -t nat -I POSTROUTING 1 -s $SUB_NET_6 -o $IN_FACE -j MASQUERADE
## $IPT6 -I INPUT 1 -i $WG_FACE -j ACCEPT
## $IPT6 -I FORWARD 1 -i $IN_FACE -o $WG_FACE -j ACCEPT
## $IPT6 -I FORWARD 1 -i $WG_FACE -o $IN_FACE -j ACCEPT
<...>
- In order to turn off the rules when our VPN server isn't running, let's create a PostDown script shown below:
cfloquet@wireguard:/etc/wireguard/helper# vi delRules.bash
#!/bin/bash
IPT="/sbin/iptables"
IPT6="/sbin/ip6tables"
IN_FACE="ens192" # NIC connected to the internet
WG_FACE="wg0" # WG NIC
SUB_NET="10.0.4.0/29" # WG IPv4 sub/net aka CIDR
WG_PORT="51263" # WG udp port
#SUB_NET_6="fd42:42:42:42::/112" # WG IPv6 sub/net
# IPv4 rules #
$IPT -t nat -D POSTROUTING -s $SUB_NET -o $IN_FACE -j MASQUERADE
$IPT -D INPUT -i $WG_FACE -j ACCEPT
$IPT -D FORWARD 1 -i $IN_FACE -o $WG_FACE -j ACCEPT
$IPT -D FORWARD 2 -i $WG_FACE -o $IN_FACE -j ACCEPT
$IPT -D INPUT -i $IN_FACE -p udp --dport $WG_PORT -j ACCEPT
# IPv6 rules (uncomment) #
## $IPT6 -t nat -D POSTROUTING -s $SUB_NET_6 -o $IN_FACE -j MASQUERADE
## $IPT6 -D INPUT -i $WG_FACE -j ACCEPT
## $IPT6 -D FORWARD -i $IN_FACE -o $WG_FACE -j ACCEPT
## $IPT6 -D FORWARD -i $WG_FACE -o $IN_FACE -j ACCEPT
<...>
cfloquet@wireguard:/etc/wireguard/helper# chmod -v +x *.bash
cfloquet@wireguard:/etc/wireguard/helper# systemctl restart [email protected]
- Now we can add our externally defined tunneling/firewall instructions to the wg0.conf file:
root@wireguard:~# vi /etc/wireguard/wg0.conf
<...>
[Interface]
PrivateKey = private_key_of_wg_server
Address = internal_wg_server_ip (ex: 10.20.10.1/24)
ListenPort = 51263 (must be allowed through firewalls)
PostUp = /etc/wireguard/helper/addRules.bash
PostDown = /etc/wireguard/helper/remRules.bash
[Peer]
PublicKey = public_key_of_peer
PreSharedKey = preshared_key
AllowedIPs = ip_of_VPN_client/32
<...>
cfloquet@wireguard:~# systemctl restart [email protected]
- Now we are able to configure the client to forward all traffic, or just traffic destined for the remote LAN.
[Peer]
PublicKey = public_key_of_wireguard_server
PreSharedKey = preshared_key
AllowedIps = desired_network_ID/CIDR, 0.0.0.0/0 # use this if you want all VPN traffic (full-tunnel)
EndPoint = public_ip_of_vpn_server:port
💡 If you would like to add a
json
log forwarder for centralized management of Wireguard VPN logs, check out my other guide on Monitoring Wireguard VPN Connections with JSON Log Forwarding