WireGuard VNET jail

Creating the Jail:

I created the jail using Bastille like this:

bastille create -V wirevnet 14.0-RELEASE 0.0.0.0 bge1

Initially, I assigned the IP address “0.0.0.0” to the jail. Then, using

bastille cmd wirevnet ifconfig,

I retrieved the Ethernet address and utilized it to create a static reservation on the router.

Configuring Hostname and SSH:

Next, I assign it a hostname and enable SSH. Then, I create my user account [eldapper] using ‘adduser’ and use ‘ssh-copy-id’ to add the public key. For security remove the password using ‘pw mod user [eldapper] -w no’. Finally I edit the sshd_config and harden it a bit.

# cat /etc/ssh/sshd_config

PasswordAuthentication no
KbdInteractiveAuthentication no
UsePAM yes

Configuration:

# cat /etc/rc.conf

ifconfig_e0b_bastille5_name="vnet0"
#ifconfig_vnet0="SYNCDHCP "
ifconfig_vnet0="inet 192.168.1.254/24 up"
defaultrouter="192.168.1.254"
hostname="wirevnet.eldapper.com"
gateway_enable="YES"
# SSH
sshd_enable="YES"

## wireguard server
wireguard_interfaces="wg0"
wireguard_enable="YES"

## wireguard-ui
wireguard_ui_enable="YES"
wgui_enable="YES"

## pf firewall
pf_enable="YES"
pf_rules="/etc/pf.conf"

Firewall

On the router create a redirect rule for the Wireguard Listen Port: 51820 to the jail’s IP: 192.168.1.254.

Kernel Module

Wireguard kernel module: On the host ensure that the if_wg kernel module is loaded automatically during system boot.

kld_list="if_wg"

Then allow the module on the jail: for the loaded module to pass through the jail you need to edit the jail.conf by adding allow.sysvipc;

# cat /usr/local/bastille/jails/wirevnet/jail.conf

Gateway & NAT

Packet forwarding and NAT must be enabled on the FreeBSD server if we wish to route and forward our VPN client packets. Modifying /etc/rc.conf enables packet forwarding

gateway_enable="YES

The gateway_enable="YES" setting in FreeBSD’s /etc/rc.conf file enables the system to act as a network gateway, allowing it to forward packets between interfaces. If your host system is configured as a gateway and you want your jail to also act as a gateway, you should enable gateway_enable="YES" in the jail’s /etc/rc.conf as well.

Enabling gateway_enable="YES" in the jail’s /etc/rc.conf is necessary if you want the jail to perform tasks like packet forwarding, NAT (Network Address Translation), or routing between different network interfaces within the jail.

wireguard, wireguard-ui, wgui daemons

Install wireguard tools

➡️ Wireguardtools-1.0.20210914_3 Fast, modern and secure VPN Tunnel

pkg install wireguard-tools

Enable wireguard
## wireguard server
wireguard_interfaces="wg0"
wireguard_enable="YES"

Download wireguard-ui

https://github.com/ngoduykhanh/wireguard-ui

Releases: https://github.com/ngoduykhanh/wireguard-ui/releases

➡️ Install wireguard-ui
# tree -a /usr/local/etc/wireguard-ui/

├── db
│ ├── clients
│ ├── server
│ │ ├── global_settings.json
│ │ ├── hashes.json
│ │ ├── interfaces.json
│ │ └── keypair.json
│ ├── users
│ │ └── admin.json
│ └── wake_on_lan_hosts
├── env
└── wireguard-ui
Create a wireguard-ui Startup Script

# cat /usr/local/etc/rc.d/wireguard-ui

#!/bin/sh
#
# PROVIDE: wireguard_ui
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf to enable wireguard_ui:
#
# wireguard_ui_enable="YES"
#
. /etc/rc.subr
name="wireguard_ui"
rcvar=wireguard_ui_enable
procname="/usr/local/etc/wireguard-ui/wireguard-ui"
pidfile="/var/run/wireguard_ui.pid"
wireguard_ui_chdir="/usr/local/etc/wireguard-ui"
wireguard_ui_env_file="/usr/local/etc/wireguard-ui/env"
command="/usr/sbin/daemon"
command_args=" -s notice -p ${pidfile} -f ${procname} ${wireguard_ui_env_file}"
stop_postcmd="wireguard_ui_poststop"
wireguard_ui_poststop()
{
    rm -f $pidfile
}
load_rc_config ${name}
: ${wireguard_ui_enable="NO"}
: ${wireguard_ui_pidfile="/var/run/${name}.pid"}
run_rc_command "$1" 

chmod +x /usr/local/etc/rc.d/wireguard-ui

add to /etc/rc.conf: wireguard_ui_enable="YES"

Create Environment Variables file and configure it
#!/usr/local/bin/bash
WGUI_USERNAME="admin"
WGUI_PASSWORD="1password"
SMTP_HOSTNAME="smtp.somemailserver.com"
SMTP_PORT="587"
SMTP_USERNAME="eldapper@somemailserver.com"
SMTP_PASSWORD="1234"
SMTP_NO_TLS_CHECK="true"
SMTP_AUTH_TYPE="LOGIN"
EMAIL_FROM_NAME="WireGuard-UI"
EMAIL_FROM_ADDRESS="eldapper@somemailserver.com"
WGUI_DNS="192.168.1.2,192.168.1.3"
WGUI_CONFIG_FILE_PATH="/usr/local/etc/wireguard/wg0.conf"
WGUI_SERVER_INTERFACE_ADDRESSES="10.10.100.0/24"

wireguard restart daemon

After installing and enabling the service you can reach the ui at port 5000

http://192.168.1.254:5000

In WireGuard, adding new clients requires restarting the server to apply the changes. However, WireGuard-UI in FreeBSD lacks this functionality. To address this, I’ve wrote a simple daemon to monitor changes in the ‘/usr/local/etc/wireguard/wg0.conf’ configuration file. For the script to work we need inotifywait first:

pkg install inotify-tools

# cat /usr/local/etc/rc.d/wgui

#!/bin/sh
#
# PROVIDE: wgui
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf to enable wgui:
#
# wgui_enable="YES"
#

. /etc/rc.subr

name="wgui"
rcvar=wgui_enable
procname="/usr/local/etc/wgui/wgui"
pidfile="/var/run/wgui.pid"
#wgui_chdir="/usr/local/opt/wgui/"
command="/usr/sbin/daemon"
command_args="-P ${pidfile} ${procname}"

stop_cmd="${name}_stop"
stop_postcmd="${name}_poststop"


wgui_stop()
{
        if [ -f $pidfile ]; then
                echo "Stopping wgui."
                kill $(cat $pidfile)
                echo "Stopped wgui."
        else
                echo "wgui is not running."
                exit 0
        fi
}


wgui_poststop()
{
        rm -f  $pidfile
}

load_rc_config ${name}

: ${wgui_enable="NO"}
: ${wgui_pidfile="/var/run/${name}.pid"}

run_rc_command "$1"

# cat /usr/local/etc/wgui/wgui

#!/bin/sh
PATH="$PATH:/usr/local/bin"
while inotifywait -e modify -e create  /usr/local/etc/wireguard/; do
  wg-quick down wg0
  wg-quick up wg0
done

After adding the script and making it executable chmod +x /usr/local/etc/wgui/wgui we enable it:

wgui_enable="YES"

pf firewall

On the jail I configured pf like this:

# cat /etc/pf.conf

wireguard_clients="10.10.100.0/24"
wanint="vnet0"
wg_ports="{51821}"
set skip on lo0
nat on $wanint inet from $wireguard_clients to any -> $wanint
pass in on $wanint proto udp from any to $wanint port $wg_ports
pass in on $wanint proto tcp from any to $wanint port 22 keep state
pass out quick
pass in on wg0 from any to any

2 responses to “WireGuard VNET jail”

Leave a comment

Design a site like this with WordPress.com
Get started