Title Bar

OpenVPN

HOST YOUR OWN VPN

My son called me from school in full panic: “Dad… the unamed streaming app says I can’t watch anymore.” Geo-locking had struck—and most commercial VPN IPs are blocked. So I went full Dad Hacker Mode: I wiped a 10+ year-old laptop, installed Ubuntu Server 24.04 LTS, and built a private OpenVPN server that routes traffic through our home network. Now the kids can stream like they’re still on the couch.

SKILLS YOU'LL LEARN & PRACTICE:

Linux install & hardening · IP planning (192.168.0.0/24 → 10.20.0.0/24) · OpenVPN PKI · UFW + NAT · Router port-forwarding · DDNS · Log-driven troubleshooting

Prerequisites

  • Old x64 laptop/PC (2+ GB RAM) with Ethernet
  • Ubuntu Server 24.04 LTS ISO + 8GB USB
  • SOHO router with UDP port-forwarding
  • (Optional) Dynamic DNS (Cloudflare, DuckDNS)
  • Basic Linux/CLI familiarity
  • Plan LAN to avoid overlap: use 10.20.0.0/24
  • Static IP for VPN host (e.g., 10.20.0.201)
  • ~60–90 minutes

0) IP Plan — Fix the “LTE works, Wi‑Fi fails” trap

Many public/home routers use 192.168.0.0/24. If your home LAN matches that, clients on other Wi‑Fi networks will prefer the local route over the VPN, and traffic won’t reach home. The fix is simple: choose a unique range such as 10.20.0.0/24 for home.

1) Wipe Windows → Install Ubuntu Server 24.04

  1. Back up anything important (disk will be erased).
  2. Create a bootable USB on Windows with Rufus → write Ubuntu Server 24.04 LTS ISO.
  3. Boot from USB (F2/F12/DEL), run installer, enable OpenSSH, create a sudo user, hostname e.g. zack.

Post-install basics

sudo apt update && sudo apt upgrade -y
sudo apt install -y ufw fail2ban net-tools
sudo ufw allow ssh
sudo ufw enable

Static IP with Netplan (example)

sudo nano /etc/netplan/01-netcfg.yaml
network:
  version: 2
  ethernets:
    eno1:
      dhcp4: no
      addresses: [10.20.0.201/24]
      routes:
        - to: default
          via: 10.20.0.1
      nameservers:
        addresses: [1.1.1.1,8.8.8.8]
sudo netplan apply

2) Install OpenVPN + Easy‑RSA

sudo apt install -y openvpn easy-rsa
make-cadir ~/easy-rsa
cd ~/easy-rsa
./easyrsa init-pki
./easyrsa build-ca   # set a strong CA passphrase

Server certs/keys

./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-dh
openvpn --genkey --secret ta.key   # for tls-crypt
sudo install -d -m 755 /etc/openvpn/server
sudo cp pki/ca.crt pki/issued/server.crt pki/private/server.key pki/dh.pem ta.key /etc/openvpn/server/

3) OpenVPN server config (hardened)

Create /etc/openvpn/server/server.conf:

sudo install -d -m 755 /etc/openvpn/server && sudo nano /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun

ca ca.crt
cert server.crt
key server.key
dh dh.pem

tls-crypt ta.key
topology subnet
user nobody
group nogroup
persist-key
persist-tun

data-ciphers AES-256-GCM,AES-128-GCM
data-ciphers-fallback AES-256-CBC
auth SHA256

server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 8.8.8.8"

keepalive 10 120
explicit-exit-notify 3
verb 3

Enable forwarding + UFW NAT

echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Edit /etc/ufw/before.rules and add:

*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o eno1 -j MASQUERADE
COMMIT
sudo ufw allow 1194/udp
sudo sed -i 's/^DEFAULT_FORWARD_POLICY=.*/DEFAULT_FORWARD_POLICY="ACCEPT"/' /etc/default/ufw
sudo ufw reload
sudo systemctl enable --now openvpn-server@server
sudo systemctl status openvpn-server@server

4) Create per‑device client profiles

cd ~/easy-rsa
./easyrsa gen-req kidphone nopass
./easyrsa sign-req client kidphone

mkdir -p ~/client-build
cp pki/ca.crt pki/issued/kidphone.crt pki/private/kidphone.key ~/client-build/
cp ta.key ~/client-build/

Create kidphone.ovpn (replace vpn.example.com with your public IP/DDNS):

client
dev tun
proto udp
remote vpn.example.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
key-direction 1
auth SHA256
verb 3
data-ciphers AES-256-GCM,AES-128-GCM
data-ciphers-fallback AES-256-CBC

<ca>...</ca>
<cert>...</cert>
<key>...</key>
<tls-crypt>...</tls-crypt>

Optional QR for phones:

sudo apt install -y qrencode
qrencode -t ansiutf8 < kidphone.ovpn

5) Router port‑forwarding + DDNS

6) Smoke tests

sudo ss -lunp | grep 1194
sudo journalctl -u openvpn-server@server -b --no-pager

From outside your LAN, connect with the client and visit https://ifconfig.me — you should see your home IP.

Troubleshooting

A) LTE works, Wi‑Fi fails

Cause: overlapping subnets (e.g., both sides use 192.168.0.0/24). Fix: change home LAN to 10.20.0.0/24.

B) UDP/1194 already in use / stale daemon

sudo lsof -iUDP:1194
sudo kill <PID>
sudo systemctl restart openvpn-server@server

C) Service won’t start / tun missing

sudo systemctl status openvpn-server@server
sudo modprobe tun

D) Can’t reach from outside

E) DNS slow or leaking

F) Cert/auth errors

Security hardening

cd ~/easy-rsa
./easyrsa revoke kidphone
./easyrsa gen-crl
sudo cp pki/crl.pem /etc/openvpn/server/
# add to server.conf: crl-verify crl.pem
sudo systemctl restart openvpn-server@server

Conclusion

The kids can stream anywhere again—and I got a practical lab in Linux, networking, and security on hardware most people would recycle. This walkthrough is built to drop into your site structure; update links, images, and dates as you like.