Overview
This article documents the complete process for deploying a persistent IPsec site-to-site VPN tunnel between an Ubuntu VPS running StrongSwan and a SonicWall TZ-series firewall. The end result is seamless, encrypted Layer 3 routing between two private networks across the internet with automatic reconnection on failure.
- Time to Complete: 45-90 minutes
- Cost: No licensing fees - all software is free and open source
- Platform: Ubuntu 22.04 + SonicOS 7.x
Prerequisites
- A VPS running plain Ubuntu 22.04
- Root or sudo SSH access to the VPS
- SonicWall TZ-series firewall running SonicOS 7.x with admin access
- Public IP of the SonicWall WAN interface
- The two private LAN subnets that need to communicate
- A strong pre-shared key (PSK) - generate one and record it securely in your password manager
Architecture Reference
| Setting | Value |
|---|---|
| VPS Public IP | Your VPS WAN IP (enp1s0) |
| VPS Private Subnet | Private network behind the VPS (enp8s0) |
| SonicWall Public IP | SonicWall WAN IP |
| SonicWall LAN Subnet | Private network behind the SonicWall |
| IKE Version | IKEv2 |
| Encryption | AES-256 / SHA-256 / DH Group 14 (modp2048) |
| Tunnel Mode | Persistent with DPD auto-restart |
| SA Lifetime | 28800 seconds (8 hours) - both phases |
Step 1 - Configure the Firewall
Before touching the VPS, create a firewall group and attach it to the VPS. This controls inbound traffic at the hypervisor level before packets even reach the OS.
Required Inbound Rules:
| Rule | Value |
|---|---|
| TCP 22 | SSH access from your management IP only |
| UDP 500 | IKE key exchange - allow from SonicWall WAN IP only |
| UDP 4500 | IPsec NAT traversal - allow from SonicWall WAN IP only |
| Protocol 50 (ESP) | Encrypted tunnel traffic - allow from SonicWall WAN IP only |
Verify the firewall group is created and attached to the VPS in the control panel. SSH into the VPS from your management IP and confirm access before continuing.
Step 2 - Install StrongSwan
SSH into the VPS and run the following commands to update the system and install StrongSwan with the required plugins:
sudo apt update && sudo apt upgrade -y
sudo apt install strongswan strongswan-pki libcharon-extra-plugins -y
Verify the installation completed successfully with no errors:
sudo ipsec version
Expected output: Linux strongSwan [version] / [kernel version]
Step 3 - Enable IP Forwarding
The VPS needs to forward packets between the tunnel interface and the private network. Enable this at the kernel level:
sudo nano /etc/sysctl.conf
Find the following line and remove the # to uncomment it:
net.ipv4.ip_forward=1
Save the file (CTRL+X, Y, Enter) and apply immediately:
sudo sysctl -p
Verify the output includes: net.ipv4.ip_forward = 1
Step 4 - Configure StrongSwan
4a. Edit ipsec.conf
Open the main StrongSwan configuration file:
sudo nano /etc/ipsec.conf
Replace all existing content with the following, substituting your actual IP addresses and subnets:
config setup
charondebug="ike 1, knl 1, cfg 0"
conn sonicwall-site
authby=secret
left=<VPS_PUBLIC_IP>
leftsubnet=<VPS_PRIVATE_SUBNET/MASK>
right=<SONICWALL_PUBLIC_IP>
rightsubnet=<SONICWALL_LAN_SUBNET/MASK>
ike=aes256-sha256-modp2048!
esp=aes256-sha256!
keyexchange=ikev2
ikelifetime=28800s
lifetime=28800s
auto=start
dpdaction=restart
dpddelay=30s
dpdtimeout=120s
! at the end of ike= and esp= forces StrongSwan to use only those exact proposals. This is required for reliable SonicWall interoperability.4b. Edit ipsec.secrets
Open the secrets file and add the pre-shared key:
sudo nano /etc/ipsec.secrets
Add the following line, substituting your actual IPs and PSK:
<VPS_PUBLIC_IP> <SONICWALL_PUBLIC_IP> : PSK "YourStrongPassphraseHere"
Verify the file is correct by running:
sudo cat /etc/ipsec.secrets
Confirm both IPs and PSK are present with correct formatting. The format must be: IP IP : PSK "passphrase" (note the space before the colon).
Step 5 - Start StrongSwan and Load Configuration
Enable StrongSwan to start on boot, then start the service and load the configuration:
sudo systemctl enable strongswan-starter
sudo systemctl start strongswan-starter
sudo ipsec reload
sudo ipsec rereadsecrets
Verify the connection definition is loaded:
sudo ipsec statusall
Under Connections you should see sonicwall-site listed with both IPs showing:
local uses pre-shared key authenticationremote uses pre-shared key authenticationchild: <VPS_SUBNET> === <SONICWALL_SUBNET> TUNNEL
Security Associations will show (0 up) until the SonicWall initiates - this is normal.
Step 6 - Configure UFW Forwarding Rules
Ubuntu's UFW firewall is active by default and will block forwarded traffic between subnets. Add persistent rules to allow traffic in both directions:
sudo ufw route allow from <VPS_PRIVATE_SUBNET> to <SONICWALL_LAN_SUBNET>
sudo ufw route allow from <SONICWALL_LAN_SUBNET> to <VPS_PRIVATE_SUBNET>
sudo ufw reload
Verify both route rules are listed:
sudo ufw status verbose
You should see both route allow rules listed under the active rules. Note that ufw route rules are persistent across reboots automatically - no additional steps are needed to save them.
Step 7 - Configure the SonicWall
Log into the SonicWall admin interface and navigate to Network > IPsec VPN > Site to Site. Create a new Site-to-Site VPN policy using the following settings:
Phase 1 (IKE) Settings:
| Setting | Value |
|---|---|
| IKE Version | IKEv2 |
| Authentication Method | Pre-Shared Key (PSK) |
| Pre-Shared Key | Must match exactly what is in /etc/ipsec.secrets |
| Encryption Algorithm | AES-256 |
| Authentication Algorithm | SHA-256 |
| Diffie-Hellman Group | Group 14 |
| Lifetime | 28800 seconds |
| Remote Gateway (Primary) | VPS Public IP |
Phase 2 (ESP / Tunnel) Settings:
| Setting | Value |
|---|---|
| Encryption Algorithm | AES-256 |
| Authentication Algorithm | SHA-256 |
| PFS (Perfect Forward Secrecy) | Group 14 |
| Lifetime | 28800 seconds |
| Local Network | SonicWall LAN subnet |
| Remote Network | VPS private subnet |
Step 8 - Bring Up the Tunnel and Verify
From the SonicWall admin interface, initiate the tunnel manually. Then verify from the VPS:
sudo ipsec statusall
Confirm the following in the output:
Security Associations (1 up, 0 connecting)sonicwall-site[X]: ESTABLISHED [time] agosonicwall-site{X}: INSTALLED, TUNNEL AES_CBC_256/HMAC_SHA2_256_128confirmed on both IKE and ESP linesbytes_iandbytes_oboth increasing with recent packet timestamps<VPS_SUBNET> === <SONICWALL_SUBNET>shown under the installed SA
To watch live tunnel negotiation in real time during initial bring-up:
sudo tail -f /var/log/syslog | grep charon
Step 9 - Configure Client Routing
Servers on the VPS private network need to know how to reach the SonicWall LAN subnet. Choose one of the following options:
Option A - Default Gateway Set to VPS Private IP (Simplest)
Set the default gateway on each private server to the VPS private IP (example: 192.168.213.6). All traffic including internet routes through the VPS.
Option B - Keep Existing Gateway, Add Specific Static Route (Recommended)
Keep the server's existing default gateway for internet traffic. Add a persistent static route only for the remote subnet via the VPS private IP.
Windows Server:
route add <SONICWALL_LAN_SUBNET> mask 255.255.255.0 <VPS_PRIVATE_IP> -p
Linux:
# Add to /etc/netplan or network config for persistence
ip route add <SONICWALL_LAN_SUBNET> via <VPS_PRIVATE_IP>
Verify by pinging a host on the remote subnet from a private server, confirming internet access still works, and re-running sudo ipsec statusall on the VPS to confirm bytes_i and bytes_o are increasing.
Quick Reference - Day-to-Day Commands
| Task | Command |
|---|---|
| Check tunnel status | sudo ipsec statusall |
| Watch live tunnel logs | sudo tail -f /var/log/syslog | grep charon |
| Reload config after changes | sudo ipsec reload |
| Reload PSK after changes | sudo ipsec rereadsecrets |
| Restart StrongSwan service | sudo systemctl restart strongswan-starter |
| Check UFW rules | sudo ufw status verbose |
| Check IP forwarding | sudo sysctl net.ipv4.ip_forward |
Deployment Checklist
- Firewall group created with correct inbound rules and attached to VPS
- StrongSwan and plugins installed successfully
- IP forwarding enabled and confirmed active (
net.ipv4.ip_forward = 1) /etc/ipsec.conf- correct IPs, subnets, proposals, and lifetimes/etc/ipsec.secrets- correct IPs and PSK with proper formatting- StrongSwan service enabled and started on boot
ipsec reloadandrereadsecretsrun - connection visible in statusall- UFW route rules added in both directions and reloaded
- SonicWall Phase 1 settings match StrongSwan exactly
- SonicWall Phase 2 settings match StrongSwan exactly
- Tunnel shows ESTABLISHED and INSTALLED in statusall
bytes_iandbytes_oboth showing traffic- End-to-end ping test successful between both private networks
- Internet access confirmed working on private servers
Notes
- All software used in this guide (StrongSwan, UFW, Ubuntu) is free and open source - no licensing is required
- Do not use the OpenVPN one-click image - it will conflict with StrongSwan
- The PSK must match exactly on both ends - copy and paste rather than typing it manually to avoid errors