- Details
- Hits: 516
INTRO

Set up a secure OpenVPN Remote Access server on pfSense, create a user, export a client profile for iPhone/desktop, and harden the service. This guide is written to be followed end-to-end on a working pfSense box.
Backup your existing pfSense config before starting.
Important Notes:
This guide uses example IPs and hostnames. Replace these with your own.
Never share your real certificates, private keys, or exported .ovpn files publicly.
Step 1 – Create the Certificate Authority (CA)
- Go to System → Cert. Manager → CAs, click + Add.
- Fill in:
- Descriptive name:
VPN_CA - Method: Create an internal Certificate Authority
- Key length: 4096 | Digest: SHA256 | Lifetime: 3650 days
- Common Name:
VPN_CA - Country/Org: optional
- Descriptive name:
- Click Save.
This CA will sign your server and user certificates.
Step 2 – Create the Server Certificate
- Go to System → Cert. Manager → Certificates, click + Add/Sign.
- Choose:
- Method: Create an internal certificate
- Certificate authority:
VPN_CA - Descriptive name:
OpenVPN_Server_Cert - Common Name:
vpn.yourdomain.com
- Under Alternative Names:
- Add SAN (Type IP Address):
[your router's public, fixed IP address here] - (Optional) Add SAN (Type FQDN):
vpn.yourdomain.com
- Add SAN (Type IP Address):
- Certificate Type: Server Certificate → Save.
Step 3 – Run the OpenVPN Wizard
- Go to VPN → OpenVPN → Wizards.
- Type: Local User Access → select
VPN_CAandOpenVPN_Server_Cert. - Core settings:
- Protocol: UDP on IPv4 only | Interface: WAN | Port: 1194 (or a custom high UDP port)
- Tunnel Network:
10.8.0.0/24 - Local Network:
192.168.1.0/24(your LAN) - Redirect Gateway: enabled (route all client traffic via VPN)
- Compression: None
- TLS: Enable TLS Authentication (adds a static key for DoS/hardening)
- Crypto: AES-256-GCM (data-cipher) and SHA256 (auth)
- Finish the wizard (pfSense will add a WAN rule and a basic OpenVPN rule).
Step 4 – Create a VPN User (+ user certificate)
- Go to System → User Manager → Add.
- Set:
- Username: [insert username here] | Strong password
- Check Click to create a user certificate → CA:
VPN_CA→ Type: User Certificate
- Save.
Step 5 – Verify/Add the WAN Firewall Rule
- Go to Firewall → Rules → WAN.
- Ensure there is a Pass rule:
- Protocol: UDP | Destination: WAN address | Port: 1194 (or your custom port)
- If it’s missing, click + Add (top) to create it, then Apply Changes.
Step 6 – (Optional) Assign the OpenVPN Interface
- Go to Interfaces → Assignments.
- Click + next to the OpenVPN instance (e.g.,
ovpns1) → name itVPN→ Save → Apply Changes.
This isn’t required but keeps rules/interfaces tidy and easier to manage later.
Step 7 – Export the Client Profile
- Install the package if needed: System → Package Manager → Available → openvpn-client-export → Install.
- Go to VPN → OpenVPN → Client Export.
- Under Remote Access Server, select your OpenVPN server.
- Host Name Resolution: choose your install hostname or Other and enter
vpn.yourdomain.com. - Under User-Specific Client Export, find your user and download the iOS inline (.ovpn) (and/or desktop installers as needed).
Step 8 – Test on iPhone / Desktop
- Transfer the
.ovpnto your iPhone (AirDrop/Files/email) and import into OpenVPN Connect or Passepartout. - Connect with your username and password.
- Verify:
- You receive a VPN IP in
10.8.0.x - Public IP becomes your home WAN (e.g., check whatismyipaddress.com)
- You receive a VPN IP in
Tip: Testing from inside your LAN against the WAN IP may require NAT reflection. Easiest is to test over mobile data (4G), i.e. disable Wifi on your mobile/cell phone.
Step 9 – (Optional) Email Alert on VPN Connect
If you want an email every time a user connects, use the small “client-connect” script below.
This script assumes pfSense’s email notification system is configured under System → Advanced → Notifications.
If you wish to implement this script, then once you have saved it to Pfsense, i.e. /usr/local/etc/openvpn-connect-notify.sh, then:
- Go to VPN → OpenVPN → Servers then EDIT and under ADVANCED CONFIGURATION add the following line to CUSTOM OPTIONS:
client-connect /usr/local/etc/openvpn-connect-notify.sh
Here's the script:
1#!/bin/sh2# OpenVPN connect email (safe; timestamp generated in PHP)3# By IanJ 15-10-254 5USER="${common_name:-unknown}"6VIP="${ifconfig_pool_remote_ip:-unknown}"7REMOTE="${untrusted_ip:-unknown}"8HOST="$(hostname -f 2>/dev/null || hostname)"9 10export OVPN_USER="$USER" OVPN_VIP="$VIP" OVPN_REMOTE="$REMOTE" OVPN_HOST="$HOST"11 12cat > /tmp/vpn_notify_min.php <<'PHP'13<?php 14require_once("notices.inc");15 16$user = getenv('OVPN_USER') ?: 'unknown';17$vip = getenv('OVPN_VIP') ?: 'unknown';18$remote = getenv('OVPN_REMOTE') ?: 'unknown';19$host = getenv('OVPN_HOST') ?: 'unknown';20$time = date('Y-m-d H:i:s T'); // safe: created here, no argv21 22$subject = "OpenVPN user connected: $user from $remote";23$message = "OpenVPN User Connected:\n\n"24 . "User: $user\n"25 . "VPN IP: $vip\n"26 . "Remote IP: $remote\n"27 . "Firewall: $host\n"28 . "Time: $time\n";29 30send_smtp_message($message, $subject);31PHP32 33/usr/local/bin/php -q /tmp/vpn_notify_min.php -->/dev/null 2>&1 || true34rm -f /tmp/vpn_notify_min.php35exit 0Codequote by Ian Johnston
This lightweight shell/PHP hybrid script runs each time a VPN user connects. It captures the OpenVPN-provided environment variables (username, assigned VPN IP, and the user’s public IP), then passes them to a short inline PHP routine. The PHP code uses pfSense’s built-in notification system to send an email showing who connected, from where, and when. No credentials or external SMTP settings are stored in the script, making it safe to use.
The output looks like this:
EMAIL SUBJECT:
OpenVPN user connected: someuser from 12.34.56.78
EMAIL BODY:
OpenVPN User Connected:
User: someuser
VPN IP: 10.8.0.2
Remote IP: 12.34.56.78
Firewall: firewall.local.lan
Time: 2025-10-03 13:00:42 BST
Step 10 – Security Hardening & Other
- Change default port: use a high UDP port (e.g.,
4433or55123) and update your WAN rule + client profiles. - TLS Authentication: keep enabled (already done by the wizard).
- Strong crypto: AES-256-GCM + SHA256 (done above); disable legacy compression.
- Geo-restrict with pfBlockerNG: allow inbound from your country only (advanced).
- Users: unique accounts, strong passwords; consider 2FA for the GUI and for VPN if your workflow allows.
- Keep certs fresh: rotate server/user certs periodically.
- If you wish to disable the VPN server quickly and easily then go to STATUS → SERVICES in Pfsense and STOP the openvpn service. You can easily restart it again.
The OpenVPN daemon stops immediately.
The WAN port you configured (e.g., UDP 1194 or your custom port) no longer listens.
Existing VPN sessions are terminated.
No clients can reconnect until you manually start the service again.
or,
Go to VPN → OpenVPN → Servers and open your VPN server config,
Check the Disable This Server checkbox.
Troubleshooting Quick Checks
- Client can’t connect? Confirm the WAN rule allows UDP to your chosen port, your DDNS/hostname resolves to the current WAN IP, and your ISP isn’t blocking your chosen port.
- Log view: Status → System Logs → OpenVPN and Status → System Logs → Firewall.
- Conflicting VPN apps on phone? Some “privacy VPNs” (e.g., AV/VPN apps) can block OpenVPN — disable them while testing.
Results
- Secure remote access to your network via pfSense OpenVPN.
- Simple user management (add/revoke per-user certs).
- Hardened service with TLS auth and modern ciphers.
This configuration is robust for home or small-office use.

