How to Set Up a VPN Server with StrongSwan IPsec on RHEL 7

A Virtual Private Network (VPN) allows remote users and branch offices to securely connect to your corporate network over the public internet. StrongSwan is a robust, open-source IPsec-based VPN solution that supports IKEv2, the modern and recommended key-exchange protocol for road-warrior configurations. Unlike older PPTP or L2TP solutions, IKEv2 with StrongSwan provides strong encryption, certificate-based authentication, and native support on Android, iOS, macOS, and Windows 10/11 without any additional client software. This guide walks through a complete StrongSwan IKEv2 road-warrior server setup on Red Hat Enterprise Linux 7, including certificate generation, IP forwarding, masquerading, and testing from a mobile device.

Prerequisites

  • A RHEL 7 server with a static public IP address (or a hostname resolving to one)
  • Root or sudo access
  • EPEL repository enabled
  • A fully qualified domain name (FQDN) for the server, e.g., vpn.example.com
  • Ports UDP/500, UDP/4500, and ESP (protocol 50) open in your firewall
  • Basic familiarity with Linux networking and iptables

Step 1: Enable the EPEL Repository and Install StrongSwan

StrongSwan is not included in the base RHEL 7 repositories but is available in the Extra Packages for Enterprise Linux (EPEL) repository. Enable EPEL and install StrongSwan along with its utilities.

# Enable EPEL repository
sudo yum install -y epel-release

# Install StrongSwan and related tools
sudo yum install -y strongswan strongswan-charon-nm

# Verify the installation
strongswan version

After installation, the StrongSwan daemon (charon) is managed via systemd. The main configuration files reside in /etc/strongswan/.

Step 2: Generate a PKI Certificate Infrastructure

IKEv2 road-warrior setups work best with certificate-based authentication. StrongSwan ships with the strongswan pki tool for generating a private CA, a server certificate, and optionally client certificates.

# Create directories for your PKI
sudo mkdir -p /etc/strongswan/pki/{ca,certs,private}

# Generate the CA private key
sudo strongswan pki --gen --type rsa --size 4096 
  --outform pem | sudo tee /etc/strongswan/pki/private/ca-key.pem

# Self-sign the CA certificate (10-year validity)
sudo strongswan pki --self --ca --lifetime 3650 
  --in /etc/strongswan/pki/private/ca-key.pem 
  --type rsa --dn "CN=VPN Root CA" 
  --outform pem | sudo tee /etc/strongswan/pki/ca/ca-cert.pem

# Generate the server private key
sudo strongswan pki --gen --type rsa --size 2048 
  --outform pem | sudo tee /etc/strongswan/pki/private/server-key.pem

# Issue the server certificate signed by your CA
# Replace vpn.example.com with your actual FQDN or IP SAN
sudo strongswan pki --pub 
  --in /etc/strongswan/pki/private/server-key.pem 
  --type rsa | sudo strongswan pki --issue --lifetime 1825 
  --cacert /etc/strongswan/pki/ca/ca-cert.pem 
  --cakey /etc/strongswan/pki/private/ca-key.pem 
  --dn "CN=vpn.example.com" 
  --san "vpn.example.com" 
  --san "203.0.113.10" 
  --flag serverAuth --flag ikeIntermediate 
  --outform pem | sudo tee /etc/strongswan/pki/certs/server-cert.pem

# Copy certificates to StrongSwan's expected locations
sudo cp /etc/strongswan/pki/ca/ca-cert.pem 
  /etc/strongswan/ipsec.d/cacerts/

sudo cp /etc/strongswan/pki/certs/server-cert.pem 
  /etc/strongswan/ipsec.d/certs/

sudo cp /etc/strongswan/pki/private/server-key.pem 
  /etc/strongswan/ipsec.d/private/

sudo chmod 600 /etc/strongswan/ipsec.d/private/server-key.pem

Step 3: Configure ipsec.conf for IKEv2 Road-Warrior

The main IPsec configuration file defines connection profiles. Create a clean /etc/strongswan/ipsec.conf for an IKEv2 road-warrior setup that assigns virtual IP addresses to clients.

sudo tee /etc/strongswan/ipsec.conf <<'EOF'
# /etc/strongswan/ipsec.conf - StrongSwan IPsec configuration file

config setup
    charondebug="ike 2, knl 2, cfg 2, net 2, esp 2, dmn 2, mgr 2"
    uniqueids=never

conn %default
    ikelifetime=60m
    keylife=20m
    rekeymargin=3m
    keyingtries=1
    keyexchange=ikev2
    authby=rsasig

conn ikev2-vpn
    left=%any
    [email protected]
    leftcert=server-cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    right=%any
    rightid=%any
    rightauth=eap-mschapv2
    rightsourceip=10.10.10.0/24
    rightdns=8.8.8.8,8.8.4.4
    rightsendcert=never
    eap_identity=%identity
    dpdaction=clear
    dpddelay=300s
    rekey=no
    auto=add
EOF

Step 4: Configure ipsec.secrets for User Credentials

When using EAP-MSCHAPv2, user credentials are stored in ipsec.secrets. This file also references the server’s private key.

sudo tee /etc/strongswan/ipsec.secrets <<'EOF'
# /etc/strongswan/ipsec.secrets

# Server RSA private key
: RSA "server-key.pem"

# EAP users: "username" EAP "password"
alice : EAP "SecurePassword1!"
bob   : EAP "AnotherPassw0rd!"
EOF

sudo chmod 600 /etc/strongswan/ipsec.secrets

Step 5: Configure strongswan.conf Plugins

The /etc/strongswan/strongswan.conf file controls the charon daemon and its plugins. Ensure the EAP plugins are loaded.

sudo tee /etc/strongswan/strongswan.conf <<'EOF'
# /etc/strongswan/strongswan.conf

charon {
    load_modular = yes
    dns1 = 8.8.8.8
    dns2 = 8.8.4.4
    nbns1 = 8.8.8.8

    plugins {
        include strongswan.d/charon/*.conf
        eap-mschapv2 {
            load = yes
        }
        eap-identity {
            load = yes
        }
    }
    i_dont_care_about_security_and_use_aggressive_mode_psk = yes
}

include strongswan.d/*.conf
EOF

Step 6: Enable IP Forwarding

For VPN clients to reach the internet or other network resources through the server, kernel IP forwarding must be enabled permanently.

# Add forwarding to sysctl configuration
sudo bash -c 'cat >> /etc/sysctl.d/99-vpn.conf <<EOF
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
EOF'

# Apply immediately
sudo sysctl -p /etc/sysctl.d/99-vpn.conf

# Verify
sysctl net.ipv4.ip_forward

Step 7: Configure iptables Masquerade and Firewall Rules

VPN clients receive addresses in the 10.10.10.0/24 range. You need masquerade (NAT) rules so their traffic is forwarded to the internet through your server’s public interface. Replace ens33 with your actual outbound interface name.

# Allow IKE, ESP, and NAT-T traffic
sudo iptables -A INPUT -p udp --dport 500 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 4500 -j ACCEPT
sudo iptables -A INPUT -p esp -j ACCEPT

# Allow forwarded traffic from VPN subnet
sudo iptables -A FORWARD -s 10.10.10.0/24 -j ACCEPT
sudo iptables -A FORWARD -d 10.10.10.0/24 -j ACCEPT

# Masquerade VPN client traffic on the outbound interface
sudo iptables -t nat -A POSTROUTING 
  -s 10.10.10.0/24 -o ens33 -j MASQUERADE

# Save rules so they persist across reboots
sudo service iptables save

If you are using firewalld, you may need to either disable it or configure it to allow these rules alongside iptables. For simplicity on a dedicated VPN server, using iptables directly (with service iptables save) is the most straightforward approach on RHEL 7.

Step 8: Start and Enable the StrongSwan Service

# Start StrongSwan
sudo systemctl start strongswan

# Enable at boot
sudo systemctl enable strongswan

# Check status
sudo systemctl status strongswan

# View active connections
sudo strongswan statusall

If StrongSwan fails to start, inspect the journal with sudo journalctl -u strongswan -n 50 for detailed error messages.

Step 9: Install the CA Certificate on Android or iOS Clients

For clients to trust the server certificate, they must trust your custom CA. Export and transfer the CA certificate to the client device.

# Copy the CA cert to a web-accessible location temporarily,
# or transfer via SCP to the client machine

# On the client machine (for testing with strongswan CLI):
scp [email protected]:/etc/strongswan/pki/ca/ca-cert.pem ~/

# On Android: install via Settings > Security > Install from storage
# On iOS: email the .pem file to yourself, open it to install profile
# On macOS: import into Keychain Access and set "Always Trust"
# On Windows: import via certmgr.msc > Trusted Root Certification Authorities

For Android and iOS, navigate to Settings > VPN, add a new IKEv2 VPN connection, enter your server’s FQDN as the server address, set the identity to the username (e.g., alice), and provide the EAP password. Both platforms support IKEv2 natively with no additional app required (Android 11+, iOS 9+).

Step 10: Testing and Troubleshooting

# Monitor live StrongSwan logs
sudo journalctl -u strongswan -f

# List active IPsec security associations
sudo ip xfrm state list

# List active security policies
sudo ip xfrm policy list

# Show established connections
sudo strongswan statusall

# Reload configuration without restart
sudo strongswan reload

# Test from another Linux machine with strongswan client
# Configure /etc/strongswan/ipsec.conf on the client:
# conn vpn-client
#     left=%any
#     leftauth=eap-mschapv2
#     eap_identity=alice
#     right=vpn.example.com
#     [email protected]
#     rightsubnet=0.0.0.0/0
#     rightauth=pubkey
#     auto=start

Setting up a StrongSwan IKEv2 VPN server on RHEL 7 provides a production-grade, cross-platform remote access solution. By using certificate-based server authentication combined with EAP-MSCHAPv2 user credentials, you get a balance of security and convenience that works natively on all major client platforms. Remember to rotate certificates before they expire, back up your CA private key offline, and regularly audit the user list in ipsec.secrets. With IP forwarding and masquerade configured, your VPN clients can securely route all traffic through your RHEL 7 gateway, protecting them on untrusted networks.