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.
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
wirevnet {
devfs_ruleset = 13;
enforce_statfs = 2;
exec.clean;
exec.consolelog = /var/log/bastille/wirevnet_console.log;
exec.start = '/bin/sh /etc/rc';
exec.stop = '/bin/sh /etc/rc.shutdown';
host.hostname = wirevnet;
mount.devfs;
mount.fstab = /usr/local/bastille/jails/wirevnet/fstab;
path = /usr/local/bastille/jails/wirevnet/root;
securelevel = 2;
osrelease = 14.0-RELEASE;
# Allow loading kernel modules
allow.sysvipc;
vnet;
vnet.interface = e0b_bastille5;
exec.prestart += "jib addm bastille5 bge1";
exec.prestart += "ifconfig e0a_bastille5 description \"vnet host interface for Bastille jail wirevnet\"";
exec.poststop += "jib destroy bastille5";
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
mkdir -p /usr/local/etc/wireguard-ui/
wget -c https://github.com/ngoduykhanh/wireguard-ui/releases/download/v0.6.2/wireguard-ui-v0.6.2-freebsd-amd64.tar.gz -O - | tar -xz -C /usr/local/etc/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
Leave a comment