How to install a Wireguard VPN client in a FreeBSD jail

I installed/set up a Wireguard VPN server on Debian 10 Linux box. How do I install, configure and set up a Wireguard client in a FreeBSD jail?

WireGuard is an open-source software application and communication protocol that implements VPN to create secure point-to-point connections in routed or bridged mode. It was initially developed for Linux but now ported to FreeBSD and other operating systems. This page explains how to install and set up WireGuard clients on the FreeBSD system, including jail.

How to install a Wireguard VPN client in a FreeBSD

This guide assumes that the WireGuard server is up and running either Linux or FreeBSD server. See how to install WireGuard:

I tested this guide running on FreeBSD 11.x, but instructions remain same for FreeBSD 12.x.

A note about FreeBSD jail

Make sure you unhide tun* and bpf* devices for your jail. For example, here is my config file displayed using the cat command:
# cat /etc/devfs.rules

[devfsrules_jail_nixcraft-jail=5]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add path 'tun*' unhide
add path 'bpf*' unhide
add path zfs unhide

See my guide “How to configure a FreeBSD Jail with vnet and ZFS” for more information. If you are using FreeNAS based jail make sure you turn on VNET/BPF support as follows in UI:

Step 1 – Update FreeBSD

Run the following pkg command:
# pkg update
# pkg upgrade

Search for WireGuard package, run:
# pkg search wireguard

wireguard-1.0.20200827         Fast, modern and secure VPN Tunnel
wireguard-go-0.0.20200320      WireGuard implementation in Go

Step 2 – Installing a Wireguard VPN client in a FreeBSD jail

Execute the following command to install a Wireguard VPN client in a FreeBSD jail or FreeBSD host:
# pkg install wireguard

Step 3 – Generating private and public keys for WireGuard VPN client

We need to use the wg command command. It is the configuration utility for getting and setting the configuration of WireGuard tunnel interfaces:
# cd /usr/local/etc/wireguard/
# umask 077; wg genkey | tee privatekey-remote-ln-sg-vpn | wg pubkey > publickey-remote-ln-sg-vpn
# ls -l
# cat privatekey-remote-ln-sg-vpn publickey-remote-ln-sg-vpn

Step 4 – Creating wg0.conf file

Use a text editor such as vim to edit/update wg0.conf file:
# vim /usr/local/etc/wireguard/wg0.conf
Sample config file:

# WireGuard config client for Linode VPN server running on Debian 10 #
[Interface]
## FreeBSD client's private key here ##
PrivateKey = {FreeBSD_Jail_PRIVATE_KEY_HERE}
 
## Client ip address as per your set up ##
Address = 172.16.0.3/24
## Set DNS as per your VPN set up ##
DNS = 10.8.0.1
 
[Peer]
## Debian 10 WireGuard server's public key goes here ##
PublicKey = {SERVER_PUBLIC_KEY_HERE}
 
## set ACL ##
AllowedIPs = 0.0.0.0/0
 
## Your Debian 10 WireGuard server's public IPv4/IPv6 address and port goes here ##
Endpoint = {WG_PUBLIC_IP}:{WG_PORT}
 
## Keep connection alive ##
PersistentKeepalive = 15

Step 4 – Turn on WireGuard VPN client service

Type the following sysrc command:
# sysrc wireguard_interfaces="wg0"
# sysrc wireguard_enable="YES"

Step 5 – Running WireGuard VPN client on FreeBSD jail for the first time

The syntax is as follows for the service command:

Start the wireguard vpn client

# service wireguard start

[#] wireguard-go wg0
INFO: (wg0) 2020/08/08 12:24:37 Starting wireguard-go version 0.0.20200320
[#] wg setconf wg0 /tmp/tmp.DjieZIFu/sh-np.EtDMVd
[#] ifconfig wg0 inet 172.16.0.3/24 172.16.0.3 alias
[#] ifconfig wg0 mtu 1420
[#] ifconfig wg0 up
[#] resolvconf -a wg0 -x
[#] route -q -n add -inet 0.0.0.0/1 -interface wg0
[#] route -q -n add -inet 128.0.0.0/1 -interface wg0
[#] route -q -n add -inet 13.xxx.yyy.zzz -gateway 192.168.2.254
[+] Backgrounding route monitor

Stop the wireguard vpn client

# service wireguard stop

Restart the wireguard vpn client

# service wireguard restart

Get the status of wireguard vpn client

# wg
# ps aux | grep wireguard

Step 5 – Test WireGuard VPN connectivty

Let us verify VPN connectivty. Run the ping command to send ICMP ECHO_REQUEST packets to network to VPN server IP address 172.16.0.1:
# ping -c 4 ping 172.16.0.1

PING 172.16.0.1 (172.16.0.1): 56 data bytes
64 bytes from 172.16.0.1: icmp_seq=0 ttl=64 time=41.848 ms
64 bytes from 172.16.0.1: icmp_seq=1 ttl=64 time=41.683 ms
64 bytes from 172.16.0.1: icmp_seq=2 ttl=64 time=41.793 ms
64 bytes from 172.16.0.1: icmp_seq=3 ttl=64 time=42.089 ms

--- 172.16.0.1 ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 41.683/41.853/42.089/0.149 ms

Use the ifconfig command and netstat command to view routing information:
# ifconfig
# ifconfig wg0

wg0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1420
	options=80000<LINKSTATE>
	inet 172.16.0.3 --> 172.16.0.3 netmask 0xffffff00
	nd6 options=101<PERFORMNUD,NO_DAD>
	groups: tun
	Opened by PID 96281

See routing info on your FreeBSD:
# netstat -f inet -r -n
# netstat -f inet6 -r -n

Make sure you get public IPv4/IPv6 address of your VPN end point using the host command/dig command/drill command:
# drill TXT +short o-o.myaddr.l.google.com @ns1.google.com
# dig TXT +short o-o.myaddr.l.google.com @ns1.google.com

;; ->>HEADERo-o.myaddr.l.google.com.	60	IN	TXT	"13.xxx.yyy.zzz"

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 42 msec
;; SERVER: 216.239.32.10
;; WHEN: Sat Aug  8 12:23:05 2020
;; MSG SIZE  rcvd: 68

Helper script for connection

I have FTTH and backup 4G LTE internet at home. Once in a week/month, my FTTH will be down. Sometimes remote Debian 10 Wireguard VPN server at the office will be restarted or down for maintenance too. So I wrote a quick notification and wg service restart script in /bin/sh. It is also possible that there might be a bug in WireGuard FreeBSD package as it failed to restart when the remote server was down. Either way, this tiny script saved time for me.

#!/bin/sh
# Name: monitor-wg0.sh
# Purpose: Check for wg0 status and if it is down due to an Internet problem or remote VPN problem, try to restart it. 
# Tested on: FreeBSD 11.x and 12.x only
# Author: Vivek Gite {https://www.cyberciti.biz/} under GPL v2.x+
# ---------------------------------------------------------------------------------------------------------------------
# Replace domain name and wg0 gateway IP as per your set up
DOMAIN="www.google.com"
VPNGWIP="172.16.0.1"
if ! ping -q -c 4 "$DOMAIN" >/dev/null 2>&1 || ! ping -q -c 4 "$VPNGWIP" >/dev/null 2>&1
then
	/usr/bin/logger -p local0.crit "*** Cannot connect to the Internet via a VPN. Restarting wg0 ..."
	/usr/sbin/service wireguard restart
	if ! ping -q -c 4 "$DOMAIN" >/dev/null 2>&1 || ! ping -q -c 4 "$VPNGWIP" >/dev/null 2>&1
	then
		/usr/bin/logger -p local0.crit "*** VPN wg0 or the Internet still down. Manual intervention is needed ..."
	else
		/usr/bin/logger -p local0.crit "*** SUCCESS: VPN wg0 back online."
	fi
fi

I am going to run crontab (cron jobs) every 10 minutes to check wg0 VPN status as follows:

# monitor wg0 link and notify on my FreeBSD home server/laptop:
*/5 * * * *     /root/bin/monitor-wg0.sh

See how to set up and configure cron jobs/crontab for more info.

Conclusion

This quick guide covered the WireGuard VPN client installation and configuration for FreeBSD jail. See WireGuard project documentation or read man pages by typing the following man command:
$ man 8 wg-quick
$ man 8 wg

This entry is 5 of 7 in the WireGuard moden Linux/Unix/*BSD VPN Tutorial series. Keep reading the rest of the series:
  1. Ubuntu 20.04 set up WireGuard VPN server
  2. CentOS 8 set up WireGuard VPN server
  3. Debian 10 set up WireGuard VPN server
  4. WireGuard Firewall Rules in Linux
  5. Wireguard VPN client in a FreeBSD jail
  6. Alpine Linux set up WireGuard VPN server
  7. Import WireGuard profile using nmcli on Linux

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 4 comments so far... add one


CategoryList of Unix and Linux commands
Disk space analyzersdf ncdu pydf
File Managementcat cp mkdir tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
4 comments… add one
  • Mannekino Jan 12, 2021 @ 17:59

    Thank you for this guide. Worked like a charm for me to get WireGuard going inside a Jail on my TrueNAS server. I skipped the configuration file and private/public key sections because I got a configuration from my VPN provider.

  • Mike Feb 7, 2021 @ 3:41

    Thank you this worked perfectly. However, I’m unable to access my jail when the VPN connection is active. Do you know how I can have internet traffic still go through the VPN while keeping access from my local LAN?

  • Gleb May 27, 2021 @ 11:54

    Are you accept donations? This guide is rock 🤘!

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum