How to Connect Any Device to OPNsense OpenVPN: iOS, Android, macOS, Windows, and Linux

Running OPNsense on a Zimaboard gives you a fanless, low-power x86 firewall that is more than capable of terminating a handful of road-warrior VPN tunnels. In this post I walk through exactly how I set up OpenVPN on my own Zimaboard, and then — most importantly — how to bring any modern client device onto that tunnel: iPhone or iPad, Android, MacBook, Windows laptop, and Linux desktop or server.

The server side is the same regardless of which client you eventually use, so I cover it once at the top. After that comes a dedicated section for every common operating system with the exact app to install, the import flow, and the gotchas I have personally tripped over. By the end you will have one OpenVPN server on the firewall and a working .ovpn profile for every device in your household.

Why a Home VPN Is Still Worth Building in 2026

Commercial VPN providers solve a very different problem from a self-hosted one. A paid provider hides your traffic from the local coffee-shop network and lets you geo-hop streaming services. A home VPN does something a commercial product cannot: it puts your device on your own LAN, behind your own firewall, with full access to whatever you have on it. That means:

  • Reach your NAS, Plex, Home Assistant, Proxmox, or lab gear with the same hostnames you use at home.
  • Tunnel DNS through Pi-hole or Unbound and keep ad-blocking consistent on cellular and hotel Wi-Fi.
  • Open exactly one UDP port on the firewall instead of one port per exposed service.
  • Get out from under hostile or captive Wi-Fi without paying a third party to broker your traffic.

What You Need Before You Start

  • An OPNsense box reachable on its LAN. I am running 24.x on a Zimaboard 832, but anything from 22.x onward works identically.
  • Admin access to the OPNsense web UI.
  • A way for clients on the internet to find your WAN: a static public IP, or a Dynamic DNS hostname.
  • One UDP port reachable on your WAN. I use UDP/1194 in this guide.
  • The client app for whichever device(s) you want to connect. I cover the specifics per OS below.

If your ISP gives you CGNAT (a private 100.64.0.0/10 address on your WAN interface) OpenVPN over your own WAN will not work without help from a relay or an IPv6-only path. Check by comparing the WAN address on the OPNsense dashboard with what https://ifconfig.me reports from a device behind the firewall. If they differ and your WAN is in 100.64.x.x, call your ISP for a real public IP first — that is a separate topic.

Step 1: Set Up Dynamic DNS (Skip If You Have a Static IP)

Most residential connections have a public IP that changes every few weeks. The cleanest fix is OPNsense’s built-in Dynamic DNS client. Go to Services → Dynamic DNS → Settings and click +. Cloudflare, Duck DNS, and No-IP all work; I use Cloudflare because I already host the parent domain there.

  • Service: Cloudflare
  • Interface to monitor: WAN
  • Hostname: vpn.example.com (a subdomain of a domain you already control)
  • Username: your Cloudflare email
  • Password: a Cloudflare API token scoped to Zone.DNS.Edit for that one zone

Save and enable. Within a minute the status column should flip to green. From here on I will refer to your VPN hostname as vpn.example.com.

Step 2: Build a Certificate Authority

OpenVPN uses three building blocks: a Certificate Authority (CA), a server certificate signed by that CA, and one client certificate per device, also signed by that CA. Start with the CA.

Go to System → Trust → Authorities and click + Add.

  • Descriptive name: HomeVPN-CA
  • Method: Create an internal Certificate Authority
  • Key type: RSA
  • Key length: 2048 (4096 if you do not mind the extra handshake CPU)
  • Digest Algorithm: SHA256
  • Lifetime (days): 3650 — the CA should outlive every certificate it ever signs
  • Common Name: HomeVPN-CA

Save. The CA’s private key never leaves the firewall.

Step 3: Create the Server Certificate

Go to System → Trust → Certificates and click + Add.

  • Method: Create an internal certificate
  • Descriptive name: HomeVPN-Server
  • Certificate authority: HomeVPN-CA
  • Type: Server Certificate
  • Key length: 2048
  • Digest Algorithm: SHA256
  • Lifetime (days): 825 — anything longer is silently rejected by recent iOS/macOS
  • Common Name: vpn.example.com — must match the DDNS hostname clients dial in to
  • SAN (alternative names): add vpn.example.com as a DNS SAN as well

The 825-day lifetime is the single most common gotcha I see in homelab OpenVPN setups. Anything longer violates the CA/Browser Forum rules that Apple enforces in iOS and macOS, and the client will simply refuse to connect with a vague error.

Step 4: Create a User and a Client Certificate for Each Device

Each device gets its own certificate so you can revoke a single device without booting every other client. Create one OPNsense user per device.

Go to System → Access → Users and click + Add.

  • Username: iphone, android, macbook, laptop-win, desktop-linux — anything you can identify later
  • Password: set a real one — it becomes the second factor when you connect
  • Tick Click to create a user certificate and fill in:
    • Method: Create an internal certificate
    • Certificate authority: HomeVPN-CA
    • Type: Client Certificate
    • Lifetime: 825 days
    • Common Name: match the username

Save. Repeat the whole flow for every device you want to add. You can always come back later to add more.

Step 5: Configure the OpenVPN Server Instance

Go to VPN → OpenVPN → Servers and click + Add. The fields I do not call out can stay default.

General

  • Description: HomeVPN
  • Server Mode: Remote Access ( SSL/TLS + User Auth )
  • Backend for authentication: Local Database
  • Protocol: UDP
  • Device Mode: tun
  • Interface: WAN
  • Local port: 1194

Cryptographic Settings

  • TLS Authentication: enabled, Encryption and Authentication (this enables tls-crypt, which wraps the whole TLS handshake in a pre-shared symmetric key — internet scanners cannot even see a handshake)
  • Peer Certificate Authority: HomeVPN-CA
  • Server Certificate: HomeVPN-Server
  • DH Parameters Length: 2048
  • Data Encryption Algorithms: AES-256-GCM, AES-128-GCM, CHACHA20-POLY1305
  • Fallback Data Encryption Algorithm: AES-256-CBC
  • Auth Digest Algorithm: SHA256

Tunnel Settings

  • IPv4 Tunnel Network: 10.10.10.0/24 — pick something that does not collide with your LAN or with any network you might connect from. Avoid 192.168.1.0/24 and 192.168.0.0/24.
  • IPv4 Local Network(s): 192.168.1.0/24 — your real home LAN CIDR. This is what the client will route over the tunnel.
  • Redirect Gateway: leave unchecked for split-tunnel (recommended for mobile); check it if you want all client traffic to exit through home — useful on hostile Wi-Fi.
  • Concurrent connections: 10
  • Compression: Disabled — no adaptive compression. Compression in OpenVPN is broken (VORACLE).
  • Duplicate Connections: unchecked — one cert per connection.

Client Settings

  • Dynamic IP: checked
  • Topology: subnet
  • DNS Servers: 192.168.1.1 (your OPNsense LAN IP, or your Pi-hole). This is what makes the VPN feel like home — your device resolves nas.lan the same on cellular as on Wi-Fi.
  • Block Outside DNS: checked (Windows-only enforcement; harmless on other OSes).

In the Advanced configuration free-form box, add this so mobile clients on carrier NAT do not drop after a minute of idleness:

keepalive 10 60

Save. OPNsense starts the openvpn daemon. You should see the server with a green status indicator under VPN → OpenVPN → Connection Status.

Step 6: Open the Firewall

You need two firewall rules: one to let the internet reach UDP/1194 on WAN, and one to let traffic inside the tunnel reach your LAN.

WAN Rule (Inbound)

Go to Firewall → Rules → WAN and add:

  • Action: Pass
  • Interface: WAN
  • Protocol: UDP
  • Source: any
  • Destination: WAN address
  • Destination port: 1194
  • Description: Allow OpenVPN inbound

OpenVPN Interface Rule

Go to Firewall → Rules → OpenVPN (this tab appears automatically once the server is enabled) and add a permissive bootstrap rule. Tighten it later if you want to restrict what VPN clients can reach.

  • Action: Pass
  • Interface: OpenVPN
  • Protocol: any
  • Source: OpenVPN net
  • Destination: any
  • Description: Allow VPN clients to LAN and beyond

Apply changes. The firewall is now ready.

Step 7: Install the OpenVPN Client Export Plugin

You could build the client .ovpn file by hand, but OPNsense has a plugin that does it for you and bakes in the CA, the client certificate, and the TLS key. Go to System → Firmware → Plugins, search for os-openvpn-clientexport, and click + to install it. Once installed it appears under VPN → OpenVPN → Client Export.

Step 8: Export a Client Profile

Open VPN → OpenVPN → Client Export and configure:

  • Remote Access Server: HomeVPN
  • Export type: File Only — produces a single self-contained .ovpn
  • Hostname: vpn.example.com (your DDNS hostname, not the WAN IP)
  • Port: 1194
  • Validate server CN: checked
  • Validate server certificate: checked

Scroll to the bottom. Every user with a client certificate is listed. Click the inline-config download icon next to that user to get a self-contained .ovpn. Download one file per device.

Treat these files like passwords. Anyone with one and the user’s password can reach your LAN.

Step 9: Connect Your Devices

This is the part most guides skip past. The server is the same regardless of client OS — but each operating system has its own preferred app, transfer mechanism, and quirks. Pick the sections that match the devices you actually own.

iOS — iPhone and iPad

  • Install OpenVPN Connect from the App Store (the official one published by OpenVPN, Inc.).
  • Get the .ovpn file onto the device. Easiest options: AirDrop from a Mac, email it to yourself, or upload to iCloud Drive and open from the Files app.
  • Tap the file. iOS offers to hand it to OpenVPN Connect. Tap Add in the app.
  • Accept the iOS VPN configuration prompt (it installs a system VPN profile under Settings → General → VPN & Device Management).
  • Enter the username and password and tick Save.
  • Flip the toggle to Connect. A small “VPN” badge appears in the status bar.

iOS exposes a quick toggle in Settings → VPN, and you can also add a VPN button to Control Center for one-tap connect.

Android

Two good apps; pick one.

  • OpenVPN Connect (Play Store, by OpenVPN Inc.) — the official client, looks identical to the iOS version.
  • OpenVPN for Android by Arne Schwabe (Play Store / F-Droid) — open source, more diagnostic detail, my personal preference.

Transfer the .ovpn file via USB, email, or any cloud sync. In either app: tap + or Import → Import Profile from SD card, browse to the file, then enter username/password and connect. Android will show a key icon in the status bar when the tunnel is up.

macOS — MacBook and iMac

Two solid options.

Option A: OpenVPN Connect for macOS (easiest)

  • Download the installer from openvpn.net. It is signed and notarized.
  • Open the app, drag the .ovpn file onto the window, or click Import Profile → File.
  • Approve the system extension and VPN configuration prompts in System Settings → Privacy & Security.
  • Enter the username/password and connect.

Option B: Tunnelblick (open source)

  • Install Tunnelblick from tunnelblick.net.
  • Double-click the .ovpn file. Tunnelblick will ask “Only Me” vs. “All Users” — pick “Only Me”.
  • Click the Tunnelblick menu-bar icon → Connect <your-config>. Enter the username/password when prompted.

I run Tunnelblick on my own MacBook for the extra diagnostic detail; OpenVPN Connect is the friendlier choice for non-technical family members.

Windows 10 / 11

  • Download OpenVPN Connect for Windows from openvpn.net (MSI installer). The community OpenVPN GUI also works, but Connect is now the maintained client.
  • Run the installer. It will install a TAP/Wintun virtual adapter — this requires admin rights and a system reboot the first time.
  • Launch OpenVPN Connect. Click Import Profile → File and pick your .ovpn.
  • Enter the username and password. Click Connect. A green badge appears on the system tray icon and Windows shows a VPN entry in Settings → Network & Internet → VPN.

One Windows-specific gotcha: if a corporate AV or EDR strips VPN traffic, you may see “TLS handshake failed” only on that machine. Adding an exclusion for the OpenVPN service usually fixes it.

Linux — Desktop or Server

Linux has the strongest OpenVPN support of any platform because openvpn is just a package. Two patterns: CLI/systemd for headless servers, NetworkManager for desktops.

CLI / systemd (Debian, Ubuntu, RHEL, Fedora, Arch)

# Install the package
sudo apt install openvpn      # Debian/Ubuntu
sudo dnf install openvpn      # Fedora/RHEL
sudo pacman -S openvpn        # Arch

# Drop the exported profile in the systemd-managed directory
sudo cp ~/Downloads/desktop-linux.ovpn /etc/openvpn/client/home.conf

# Enable and start
sudo systemctl enable --now openvpn-client@home

# Watch it come up
sudo journalctl -u openvpn-client@home -f

If the profile expects an interactive username/password, create /etc/openvpn/client/home.auth with the username on line 1 and password on line 2, chmod 600 it, and reference it in the config with auth-user-pass /etc/openvpn/client/home.auth.

NetworkManager (GNOME / KDE)

  • Install the plugin: sudo apt install network-manager-openvpn-gnome (or the equivalent for your distro).
  • Open the network settings, click + next to VPN → Import from file…, and pick the .ovpn.
  • Enter the username and password, save, then toggle the VPN on from the system tray.

Travel Router (Bonus)

If you carry a GL.iNet, OpenWrt, or DD-WRT travel router, you can load the same .ovpn as an OpenVPN client on the router itself. Every device on its Wi-Fi automatically rides the tunnel — perfect for hotel rooms with cheap smart TVs that have no VPN app of their own. GL.iNet’s stock web UI has a one-click “Upload OpenVPN config” page that takes the same .ovpn file.

Verifying the Tunnel

Once the client says it is connected, sanity-check from a terminal (Linux/macOS shown — Windows equivalents are ipconfig, route print, ipconfig /all):

# You should have a tun/utun interface with a 10.10.10.x address:
ifconfig | grep -A2 -E 'utun|tun'

# Your gateway for the LAN should be the tunnel:
netstat -nr | grep 192.168.1

# DNS should be your OPNsense / Pi-hole:
scutil --dns | grep nameserver        # macOS
resolvectl status                     # Linux

# And you should be able to reach a LAN host by hostname:
ping nas.lan

On the OPNsense side, VPN → OpenVPN → Connection Status shows every active client with its real public IP, tunnel IP, and bytes in/out. That page is the first thing I check whenever someone reports a problem.

Troubleshooting Cheat Sheet

  • Connection times out before the TLS handshake — almost always a firewall problem. Watch Firewall → Log Files → Live View while you connect. If you see no hits at all on UDP/1194, your ISP or upstream router is dropping the packet before it reaches OPNsense.
  • “TLS handshake failed” — the tls-crypt key in the client file does not match the server. Re-export the profile.
  • “VERIFY ERROR: … certificate is not yet valid” — your firewall’s clock is wrong. Check System → Settings → General → Time servers.
  • Connected, but cannot reach the LAN — your OpenVPN-interface firewall rule (Step 6) is missing or too restrictive. Also confirm IPv4 Local Networks on the server matches your real LAN CIDR.
  • Connected, but DNS does not resolve nas.lan — the pushed DNS server is wrong, or your local resolver does not host that name. Try nslookup nas.lan 192.168.1.1 while connected.
  • Drops after a minute on cellular — confirm keepalive 10 60 is in the server’s Advanced configuration box. Carrier NAT drops idle UDP fast.
  • Windows shows “TAP-Win32 adapter not found” — reboot after install. The virtual adapter needs a fresh boot to register.
  • Android cannot import the file — make sure the file extension is exactly .ovpn; some mail clients silently rename it to .ovpn.txt.

Hardening You Should Do Next

  • Move OpenVPN off UDP/1194 to a less-scanned port. UDP/443 is convenient and tends to survive captive-portal Wi-Fi.
  • Tighten the OpenVPN interface firewall rule from “any” to only the destinations you actually want — for me, that is the LAN subnet plus the Pi-hole DNS port.
  • Enable two-factor auth via System → Access → Servers with the built-in TOTP provider, and switch the OpenVPN server’s authentication backend to that. Now even a stolen .ovpn file is useless without the user’s TOTP code.
  • Schedule a quarterly review of System → Trust → Certificates — revoke any cert you no longer need and the device is booted off immediately.
  • Back up your OPNsense config (System → Configuration → Backups) so you do not have to rebuild the CA if the SSD on the Zimaboard ever dies.

Wrapping Up

One OPNsense server, one CA, one certificate per device, and one client app per OS. That is the whole picture. Whether the device is an iPhone, an Android tablet, a MacBook, a Windows laptop, a Linux server, or a travel router, the workflow is identical: create a user, export their .ovpn, hand it to the right client app on the device. The Zimaboard quietly handles every tunnel without breaking a sweat.

If you want a follow-up walking through the WireGuard equivalent on the same Zimaboard — faster handshake, smaller footprint, but a different threat model — let me know in the comments and I will write it up next.

Leave a Reply