This page is part of the larger series of converting an old laptop into a bare metal home lab server. Click the link to be taken back to the original post.

Register for a Free Dynamic DNS Hostname
This step is necessary if you do not have a static IP address provided by your Internet service provider (ISP). I imagine most residential customers do not have static WAN IPs, but check with your ISP if you want to be sure.
The dynamic DNS hostname will be used to track your WAN IP anytime it changes. This will work, because a client will reach out to the dynamic DNS provider (No-IP in this case) and periodically inform the provider of the current WAN IP. If the WAN IP has changed since the last check-in, the DNS record will be updated.
Go to https://noip.com. Create an account if you do not already have one. Go to Dynamic DNS > No-IP Hostnames.

Click Create Hostname. Create the host using the following options. Change somename
with a hostname that you would like to resolve back to your house's public IP address.

Setup the Dynamic DNS Client in pfSense
pfSense is going to act as an updater client for us. It will periodically login to the https://noip.com service for us and tell them what our home’s new public IP address is when it changes.
Log into your pfSense web portal: https://pfsense-ip-address
. Go to Services > Dynamic DNS. Click Add.
- Service Type: No-IP (Free)
- Interface to monitor: WAN
- Hostname: Use the hostname from Step 5 above
- Username: https://noip.com username
- Password: https://noip.com password
- Description: Home public IP address
Create an OpenVPN Debian 11 Container
- Create the unprivileged container
- Set it to start at boot. Set the startup order if desired.
- Note the MAC address and create a static DHCP reservation for the server
- Port forward the OpenVPN listen port to the internal IP
Resources
- RAM: 512 MiB
- Swap: 512 MiB
- Cores: 1
- Disk: 10 GB
Network

Recommended Options
- Start at boot: Yes
- Start/Shutdown order: User preference
- Unprivileged Container: Yes
Create the Container
Open a shell on the Proxmox node and run this command:
# Update container template repository
pveam update
Now, create an unprivileged Debian 11 container using the GUI. Once you've created the container, we'll need to make a few small changes. Open a shell on the Proxmox node and run this command:
# Get the container configuration information
pct config [container-id]
# Edit the configuration information
nano /etc/pve/lxc/[id-number].conf
Add these lines:
lxc.cgroup.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net dev/net none bind,create=dir
Press CTRL + X
to exit. Save your changes.
pct start [id-number]
Open a Shell on Your OpenVPN Container
Run these commands
apt update
apt dist-upgrade
apt install openvpn git
git clone https://github.com/angristan/openvpn-install
cd openvpn-install
bash openvpn-install.sh
Answer the questions in the wizard. When the wizard asks you for IP address or hostname, provide the Dynamic DNS hostname you configured above.
This way it will always use your Dynamic DNS hostname to resolve your home’s public IP when connecting to the VPN server.
The client configuration will be in /root/client.ovpn
. Just move client.ovpn
to your phone or laptop. Install OpenVPN client app on your phone or laptop. Import the client.ovpn
configuration and connect.
If you have additional subnets you would like to be able to route to from your VPN client, you can edit the /etc/openvpn/server.conf
file and add multiple push "route"
commands. This will tell the VPN server to inform the VPN client of any routes that should be sent through the VPN tunnel.
push "route 10.0.0.0 255.255.255.0"
push "route 10.10.10.0 255.255.255.0"
If you do push additional routes to your VPN client(s), you'll need to make sure you update any firewall rules as necessary.
Create a Wireguard Debian 11 Container
- Create the unprivileged container
- Set it to start at boot. Set the startup order if desired.
- Note the MAC address and create a static DHCP reservation for the server
- Port forward the Wireguard listen port to the internal IP
Resources
- RAM: 512 MiB
- Swap: 512 MiB
- Cores: 1
- Disk: 10 GB
Network

Recommended Options
- Start at boot: Yes
- Start/Shutdown order: User preference
- Unprivileged Container: Yes
Open the Proxmox Shell
apt update
apt dist-upgrade
apt install pve-headers
echo deb http://deb.debian.org/debian bullseye-backports main >> /etc/apt/sources.list
apt clean && apt update
apt install -t bullseye-backports wireguard-dkms
modprobe wireguard # Load the kernel module
# Add kernel modules to autoload at boot
echo "wireguard" >> /etc/modules-load.d/modules.conf
Open the Wireguard Container Shell
apt clean && apt update
apt install -y --no-install-recommends wireguard-tools iptables
nano /etc/sysctl.conf
Uncomment the IPv4 forwarding configuration
- Before:
#net.ipv4.ip_forward=1
- After:
net.ipv4.ip_forward=1
Uncomment IPv6 forwarding configuration
- Before:
#net.ipv6.conf.all.forwarding=1
- After:
net.ipv6.conf.all.forwarding=1
Press CTRL+X
, then Y
, and Enter
to save your changes. Now, run these commands:
sysctl -p
cd /etc/wireguard
umask 077
Wireguard Server Setup
Wireguard uses public-key authentication to verify peers. Wireguard does not authenticate users, rather it authenticates devices to create a tunnel between the two.

Create a Server Public and Private Key Pair
wg genkey | tee server-private-key | wg pubkey > server-public-key
Edit the Server Interface Configuration File
nano /etc/wireguard/wg0.conf
The configuration data in the wg0.conf
file should look something like this.
Replace the <placeholder-values>
with their respective information.
NOTE: in the interface PostUp
command, I specified ip link set wg0 mtu 1500
, because this is the default MTU on my network. When the Wireguard default MTU of 1420
was being used, it was fragmenting the packets and causing EXTREME latency on my Windows client (for some reason, Android didn’t seem to mind the default of 1420).
That said, your MTU settings may be different, so you can try adjusting this if you have connectivity issues or poor performance.
[Interface]
PrivateKey = <server-PRIVATE-KEY file contents>
Address = 10.0.10.1/24
ListenPort = <port forward created above>
PostUp = ip link set wg0 mtu 1500 ; iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Smartphone
[Peer]
PublicKey = <smartphone-PUBLIC-KEY file contents>
AllowedIPs = 10.0.10.2/32
# Laptop
[Peer]
PublicKey = <laptop-PUBLIC-KEY file contents>
AllowedIPs = 10.0.10.3/32 # Same as internal LAN
Press CTRL+X
, then Y
, and Enter
to save your changes.
Edit the Client Interface Configuration File
This is just an example of client configuration. It’s the same for any device.
mkdir -p /etc/wireguard/clients/smartphone
cd /etc/wireguard/clients/smartphone
wg genkey | tee smartphone-private-key | wg pubkey > smartphone-public-key
nano smartphone.conf
The configuration file should look something like this.
Replace the <placeholder-values>
with their respective information.
[Interface]
PrivateKey = <smartphone-PRIVATE-KEY file contents>
Address = 10.0.10.2/32
DNS = # example: <home-router-ip>, 1.1.1.1, 1.0.0.1
[Peer]
PublicKey = <server-PUBLIC-KEY file contents>
Endpoint = dynamicdns.host.name:[port-forward]
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
For smartphones, you can import the config by scanning a QR code.
Install terminal QR code generator. This will be used to scan a QR code to generate a configuration file on the client.
You can enter the configuration details manually, this is just for convenience
apt install qrencode
qrencode -t ansiutf8 < smartphone.conf
Note: For laptops you’ll have to export the config file to the device and import it using the Wireguard client
Wrapping Up Wireguard Server Configurations
chown -R root:root /etc/wireguard
chmod -R og-rwx /etc/wireguard
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
Setup Port Forwarding in Home Router
Default Service Ports
Unless you configured them otherwise, these services are running on these ports:
- OpenVPN:
UDP 1994
- Wireguard:
UDP 51820
Configuring Port Forward in Home Router
This will vary from router to router. I am just demonstrating using my own router.
- Login to home router. For me, this is
https://172.16.1.1
- Go to Firewall > Port Forwarding
- Specify a target IP address from the list
- This is the internal host that will receive the external traffic
- Specify a port (eg. UDP 1194)
- Click Add
- Specify a target IP address from the list
- Now, when an application goes to:
your-dynamic-dns-name:port
,the application will be forewarded to the internal service
Example
- OpenVPN client tries to connect to
fakehost.ddns.net:UDP1194
- Your home router receives the connection
- It forwards the UDP traffic to the internal IP address of the OpenVPN container
Next Step: Proxmox Troubleshooting
