BLOG POSTS
    MangoHost Blog / Setting Up an IKEv2 VPN Server with StrongSwan on Ubuntu 24
Setting Up an IKEv2 VPN Server with StrongSwan on Ubuntu 24

Setting Up an IKEv2 VPN Server with StrongSwan on Ubuntu 24

I need you to write an in-depth technical blog post for mangohost blog about setting up an IKEv2 VPN server with StrongSwan on Ubuntu 24. The post should be practical and actionable for system administrators and developers.

Setting up an IKEv2 VPN server with StrongSwan on Ubuntu 24 gives you a robust, enterprise-grade VPN solution that’s both secure and performant. IKEv2 (Internet Key Exchange version 2) paired with StrongSwan offers better connection stability, faster reconnection times, and superior mobile device support compared to older VPN protocols. In this guide, you’ll learn how to configure a complete IKEv2 VPN server from scratch, handle certificate management, troubleshoot common issues, and optimize performance for production environments.

How IKEv2 and StrongSwan Work Together

IKEv2 is a tunneling protocol that establishes secure connections between VPN clients and servers using IPSec. Unlike OpenVPN which runs in userspace, IKEv2 operates at the kernel level, resulting in better performance and lower CPU overhead. StrongSwan is an open-source IPSec-based VPN solution that implements IKEv2 with extensive configuration options and robust security features.

The protocol works through a two-phase process: IKE_SA_INIT for initial key exchange and authentication, followed by IKE_AUTH for user authentication and IPSec Security Association establishment. This design allows for seamless roaming between networks – particularly valuable for mobile devices switching between WiFi and cellular connections.

Feature IKEv2/StrongSwan OpenVPN WireGuard
Performance High (kernel-level) Medium (userspace) Very High
Mobile Support Excellent (MOBIKE) Good Fair
NAT Traversal Built-in Requires configuration Automatic
Enterprise Features Extensive Good Limited
Setup Complexity Medium Low Very Low

Prerequisites and Initial Server Setup

Before diving into StrongSwan configuration, ensure your server meets the basic requirements. You’ll need a VPS or dedicated server running Ubuntu 24.04 with root access, a public IP address, and proper DNS configuration.

# Update system packages
sudo apt update && sudo apt upgrade -y

# Install required packages
sudo apt install strongswan strongswan-pki libcharon-extra-plugins -y

# Enable IP forwarding
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding=1' | sudo tee -a /etc/sysctl.conf

# Apply sysctl changes
sudo sysctl -p

# Check if IP forwarding is enabled
cat /proc/sys/net/ipv4/ip_forward

Next, configure the firewall to allow VPN traffic. Ubuntu’s UFW works well for basic setups, but iptables gives more granular control:

# Allow SSH (adjust port if needed)
sudo ufw allow 22/tcp

# Allow IKEv2 VPN traffic
sudo ufw allow 500/udp
sudo ufw allow 4500/udp

# Enable UFW
sudo ufw --force enable

# Configure NAT for VPN clients
sudo iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -s 10.10.10.0/24 -j ACCEPT
sudo iptables -A FORWARD -d 10.10.10.0/24 -j ACCEPT

# Save iptables rules
sudo apt install iptables-persistent -y
sudo netfilter-persistent save

Certificate Authority and Certificate Generation

StrongSwan requires a proper PKI setup for secure authentication. We’ll create a Certificate Authority, server certificate, and client certificates using StrongSwan’s built-in PKI tools:

# Create directory structure for certificates
sudo mkdir -p /etc/ipsec.d/{cacerts,certs,private}

# Generate CA private key
sudo pki --gen --type rsa --size 4096 --outform pem > /etc/ipsec.d/private/ca-key.pem

# Create CA certificate
sudo pki --self --ca --lifetime 3650 --in /etc/ipsec.d/private/ca-key.pem \
    --type rsa --dn "CN=VPN Root CA" --outform pem > /etc/ipsec.d/cacerts/ca-cert.pem

# Generate server private key
sudo pki --gen --type rsa --size 4096 --outform pem > /etc/ipsec.d/private/server-key.pem

# Create server certificate (replace YOUR_SERVER_IP with actual IP)
sudo pki --pub --in /etc/ipsec.d/private/server-key.pem --type rsa \
    | sudo pki --issue --lifetime 1825 \
    --cacert /etc/ipsec.d/cacerts/ca-cert.pem \
    --cakey /etc/ipsec.d/private/ca-key.pem \
    --dn "CN=YOUR_SERVER_IP" --san YOUR_SERVER_IP \
    --flag serverAuth --flag ikeIntermediate --outform pem \
    > /etc/ipsec.d/certs/server-cert.pem

# Set proper permissions
sudo chmod 600 /etc/ipsec.d/private/*
sudo chmod 644 /etc/ipsec.d/cacerts/*
sudo chmod 644 /etc/ipsec.d/certs/*

For client certificate generation, create a script to streamline the process:

# Create client certificate generation script
sudo tee /usr/local/bin/generate-client-cert.sh > /dev/null << 'EOF'
#!/bin/bash
if [ $# -ne 1 ]; then
    echo "Usage: $0 "
    exit 1
fi

CLIENT_NAME=$1

# Generate client private key
pki --gen --type rsa --size 2048 --outform pem > /etc/ipsec.d/private/${CLIENT_NAME}-key.pem

# Generate client certificate
pki --pub --in /etc/ipsec.d/private/${CLIENT_NAME}-key.pem --type rsa \
    | pki --issue --lifetime 730 \
    --cacert /etc/ipsec.d/cacerts/ca-cert.pem \
    --cakey /etc/ipsec.d/private/ca-key.pem \
    --dn "CN=${CLIENT_NAME}" \
    --san ${CLIENT_NAME} \
    --outform pem > /etc/ipsec.d/certs/${CLIENT_NAME}-cert.pem

# Set permissions
chmod 600 /etc/ipsec.d/private/${CLIENT_NAME}-key.pem
chmod 644 /etc/ipsec.d/certs/${CLIENT_NAME}-cert.pem

echo "Client certificate for ${CLIENT_NAME} generated successfully"
EOF

sudo chmod +x /usr/local/bin/generate-client-cert.sh

StrongSwan Configuration

The main configuration happens in two files: ipsec.conf for connection definitions and ipsec.secrets for authentication credentials. Here’s a production-ready configuration:

# Backup original configuration
sudo cp /etc/ipsec.conf /etc/ipsec.conf.backup

# Create new ipsec.conf
sudo tee /etc/ipsec.conf > /dev/null << 'EOF'
config setup
    charondebug="ike 1, knl 1, cfg 0"
    uniqueids=no

conn ikev2-vpn
    auto=add
    compress=no
    type=tunnel
    keyexchange=ikev2
    fragmentation=yes
    forceencaps=yes
    
    # Server side
    left=%defaultroute
    leftid=@YOUR_SERVER_IP
    leftcert=server-cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    
    # Client side
    right=%any
    rightid=%any
    rightauth=eap-tls
    rightsourceip=10.10.10.0/24
    rightdns=8.8.8.8,8.8.4.4
    rightsendcert=never
    
    # Security parameters
    ike=chacha20poly1305-sha256-curve25519-prfsha256,aes256gcm16-sha384-prfsha384-ecp384,aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024!
    esp=chacha20poly1305-sha256,aes256gcm16-ecp384,aes256-sha256,aes256-sha1,3des-sha1!
    
    # Connection settings
    dpdaction=clear
    dpddelay=300s
    rekey=no
    left_id_type=fqdn
    eap_identity=%identity
EOF

Configure the secrets file for authentication:

# Create ipsec.secrets
sudo tee /etc/ipsec.secrets > /dev/null << 'EOF'
# Server authentication
: RSA "server-key.pem"

# Client authentication examples
# For certificate-based auth (recommended)
# client1 : EAP "client1-key.pem"

# For username/password auth (less secure)
# client1 : EAP "strongpassword123"
EOF

# Set proper permissions
sudo chmod 600 /etc/ipsec.secrets

Advanced Configuration Options

For high-traffic environments or specific security requirements, consider these advanced configurations. First, let's optimize for performance:

# Create performance-optimized configuration
sudo tee -a /etc/ipsec.conf > /dev/null << 'EOF'

# High-performance connection profile
conn ikev2-performance
    also=ikev2-vpn
    auto=add
    
    # Optimized encryption for performance
    ike=aes256gcm16-sha256-modp2048
    esp=aes256gcm16-modp2048
    
    # Reduced overhead
    fragmentation=no
    mobike=yes
    
    # Faster rekeying
    ikelifetime=24h
    lifetime=8h
    margintime=20m
EOF

For environments requiring split tunneling or specific routing:

# Split tunneling configuration
conn ikev2-split
    also=ikev2-vpn
    auto=add
    
    # Only route specific subnets through VPN
    leftsubnet=192.168.1.0/24,10.0.0.0/8
    
    # Custom DNS for internal resources
    rightdns=192.168.1.1,8.8.8.8
    
    # Disable default route
    rightsubnet=192.168.1.0/24,10.0.0.0/8
EOF

Client Configuration and Connection

Generate client certificates and create configuration files for different platforms. First, create a client certificate:

# Generate certificate for client 'john'
sudo /usr/local/bin/generate-client-cert.sh john

# Create PKCS#12 bundle for easy import
sudo openssl pkcs12 -export \
    -inkey /etc/ipsec.d/private/john-key.pem \
    -in /etc/ipsec.d/certs/john-cert.pem \
    -name "john" \
    -certfile /etc/ipsec.d/cacerts/ca-cert.pem \
    -caname "VPN Root CA" \
    -out /tmp/john.p12

For iOS and macOS clients, create a configuration profile:

# iOS/macOS configuration script
sudo tee /usr/local/bin/create-ios-config.sh > /dev/null << 'EOF'
#!/bin/bash
CLIENT_NAME=$1
SERVER_IP=$2

cat > /tmp/${CLIENT_NAME}-ios.mobileconfig << EOL




    PayloadContent
    
        
            IKEv2
            
                AuthenticationMethod
                Certificate
                RemoteAddress
                ${SERVER_IP}
                RemoteIdentifier
                ${SERVER_IP}
                UseConfigurationAttributeInternalIPSubnet
                
            
            PayloadDescription
            Configures VPN settings
            PayloadDisplayName
            VPN
            PayloadIdentifier
            com.strongswan.${CLIENT_NAME}
            PayloadType
            com.apple.vpn.managed
            PayloadUUID
            $(uuidgen)
            PayloadVersion
            1
            UserDefinedName
            IKEv2 VPN
            VPNType
            IKEv2
        
    
    PayloadDisplayName
    IKEv2 VPN Configuration
    PayloadIdentifier
    com.strongswan.${CLIENT_NAME}
    PayloadType
    Configuration
    PayloadUUID
    $(uuidgen)
    PayloadVersion
    1


EOL

echo "iOS configuration created: /tmp/${CLIENT_NAME}-ios.mobileconfig"
EOF

sudo chmod +x /usr/local/bin/create-ios-config.sh

For Android and Windows clients using the StrongSwan app or native clients, provide connection details:

  • Server: YOUR_SERVER_IP
  • VPN Type: IKEv2 EAP
  • Username: client certificate CN
  • Certificate: Import the .p12 file
  • CA Certificate: Import ca-cert.pem

Starting and Testing the VPN Service

Start StrongSwan and verify the configuration:

# Start and enable StrongSwan
sudo systemctl start strongswan-starter
sudo systemctl enable strongswan-starter

# Check service status
sudo systemctl status strongswan-starter

# Verify configuration syntax
sudo ipsec verify

# Check loaded connections
sudo ipsec statusall

# Monitor logs in real-time
sudo tail -f /var/log/syslog | grep charon

Test connectivity and troubleshoot common issues:

# Check listening ports
sudo netstat -tulpn | grep -E ':500|:4500'

# Test certificate validity
sudo ipsec pki --verify --in /etc/ipsec.d/certs/server-cert.pem \
    --cacert /etc/ipsec.d/cacerts/ca-cert.pem

# Debug connection attempts
sudo ipsec stroke loglevel ike 3
sudo ipsec stroke loglevel cfg 3

Performance Optimization and Monitoring

Monitor VPN performance and optimize based on usage patterns. Create a monitoring script:

# VPN monitoring script
sudo tee /usr/local/bin/vpn-monitor.sh > /dev/null << 'EOF'
#!/bin/bash

echo "=== StrongSwan Status ==="
ipsec status

echo -e "\n=== Active Connections ==="
ipsec statusall | grep "ESTABLISHED\|INSTALLED"

echo -e "\n=== Memory Usage ==="
ps aux | grep charon | grep -v grep

echo -e "\n=== Network Statistics ==="
cat /proc/net/xfrm_stat

echo -e "\n=== Recent Logs ==="
journalctl -u strongswan-starter --since "1 hour ago" --no-pager | tail -20
EOF

sudo chmod +x /usr/local/bin/vpn-monitor.sh

For high-traffic scenarios, tune kernel parameters:

# Optimize network performance
sudo tee -a /etc/sysctl.conf > /dev/null << 'EOF'
# Network performance tuning
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.netdev_max_backlog = 5000

# IPSec specific optimizations
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
EOF

sudo sysctl -p

Common Issues and Troubleshooting

Here are the most frequent problems you'll encounter and their solutions:

Issue Symptoms Solution
NAT Traversal Problems Connection timeout behind NAT Enable forceencaps=yes in config
Certificate Errors Authentication failures Check certificate validity and CN matching
Routing Issues No internet after connection Verify IP forwarding and iptables rules
DNS Resolution Can't resolve domains Check rightdns settings and client DNS config
Mobile Disconnections Frequent reconnections on mobile Enable MOBIKE and adjust DPD settings

Debug authentication issues:

# Enable detailed logging
sudo tee -a /etc/strongswan.d/charon-logging.conf > /dev/null << 'EOF'
charon {
    filelog {
        /var/log/charon.log {
            time_format = %b %e %T
            ike_name = yes
            append = no
            default = 2
            flush_line = yes
        }
    }
}
EOF

# Restart service and check logs
sudo systemctl restart strongswan-starter
sudo tail -f /var/log/charon.log

Fix common certificate issues:

# Regenerate server certificate with proper SAN
sudo pki --pub --in /etc/ipsec.d/private/server-key.pem --type rsa \
    | sudo pki --issue --lifetime 1825 \
    --cacert /etc/ipsec.d/cacerts/ca-cert.pem \
    --cakey /etc/ipsec.d/private/ca-key.pem \
    --dn "CN=vpn.yourdomain.com" \
    --san vpn.yourdomain.com \
    --san YOUR_SERVER_IP \
    --flag serverAuth --flag ikeIntermediate --outform pem \
    > /etc/ipsec.d/certs/server-cert.pem

# Update ipsec.conf with new identifier
sudo sed -i 's/leftid=@YOUR_SERVER_IP/leftid=@vpn.yourdomain.com/' /etc/ipsec.conf

Security Best Practices and Hardening

Implement additional security measures for production environments:

# Create security hardening script
sudo tee /usr/local/bin/harden-vpn.sh > /dev/null << 'EOF'
#!/bin/bash

# Disable weak ciphers
sed -i '/3des/d' /etc/ipsec.conf
sed -i '/modp1024/d' /etc/ipsec.conf

# Enable strict certificate validation
echo "conn %default" >> /etc/ipsec.conf
echo "    strictcrlpolicy=yes" >> /etc/ipsec.conf
echo "    uniqueids=never" >> /etc/ipsec.conf

# Configure certificate revocation
mkdir -p /etc/ipsec.d/crls
echo "ca strongswan" >> /etc/ipsec.conf
echo "    cacert=ca-cert.pem" >> /etc/ipsec.conf
echo "    crluri=file:///etc/ipsec.d/crls/ca-crl.pem" >> /etc/ipsec.conf
echo "    auto=add" >> /etc/ipsec.conf

# Set up log rotation
tee /etc/logrotate.d/strongswan > /dev/null << 'EOL'
/var/log/charon.log {
    daily
    missingok
    rotate 14
    compress
    notifempty
    create 640 root root
    postrotate
        systemctl reload strongswan-starter
    endscript
}
EOL

echo "VPN security hardening completed"
EOF

sudo chmod +x /usr/local/bin/harden-vpn.sh
sudo /usr/local/bin/harden-vpn.sh

Set up automated certificate renewal:

# Certificate renewal script
sudo tee /usr/local/bin/renew-certificates.sh > /dev/null << 'EOF'
#!/bin/bash

CERT_DIR="/etc/ipsec.d"
DAYS_THRESHOLD=30

check_cert_expiry() {
    local cert_file=$1
    local days_left=$(openssl x509 -in "$cert_file" -noout -checkend $((86400 * DAYS_THRESHOLD)) 2>/dev/null && echo "valid" || echo "expiring")
    
    if [ "$days_left" = "expiring" ]; then
        echo "Certificate $cert_file expires within $DAYS_THRESHOLD days"
        return 1
    fi
    return 0
}

# Check server certificate
if ! check_cert_expiry "$CERT_DIR/certs/server-cert.pem"; then
    echo "Renewing server certificate..."
    # Add renewal logic here
    systemctl restart strongswan-starter
fi

# Check client certificates
for cert in $CERT_DIR/certs/*-cert.pem; do
    if [[ $(basename "$cert") != "server-cert.pem" ]]; then
        check_cert_expiry "$cert" || echo "Client certificate $(basename "$cert") needs renewal"
    fi
done
EOF

sudo chmod +x /usr/local/bin/renew-certificates.sh

# Add to crontab for monthly checks
echo "0 0 1 * * /usr/local/bin/renew-certificates.sh" | sudo crontab -

Real-World Use Cases and Applications

IKEv2 VPN servers excel in several scenarios. Remote workforce scenarios benefit from the automatic reconnection features - employees switching between home WiFi, mobile hotspots, and office networks experience seamless connectivity. The certificate-based authentication provides enterprise-grade security without the hassle of managing shared keys.

For developers working with cloud infrastructure, an IKEv2 VPN provides secure access to private subnets across multiple cloud providers. The high performance and low latency make it suitable for real-time development work, database access, and API testing against internal services.

Multi-site business networks leverage IKEv2's site-to-site capabilities for connecting branch offices. The protocol's reliability and built-in redundancy features ensure consistent connectivity for business-critical applications.

Mobile app developers particularly appreciate IKEv2's MOBIKE (Mobility and Multihoming) support, which handles network changes gracefully without dropping connections. This is crucial when testing location-based features or maintaining persistent connections during device movement.

Organizations requiring compliance with security standards find IKEv2's strong encryption algorithms and certificate-based authentication meet most regulatory requirements. The detailed logging capabilities assist with audit trails and security monitoring.

For more advanced deployments, consider integrating with LDAP for user authentication, implementing load balancing across multiple VPN servers, or setting up geographical distribution of VPN endpoints for optimal performance. The official StrongSwan documentation provides comprehensive guidance for enterprise-scale implementations.

Performance benchmarks show IKEv2 typically achieves 80-95% of baseline network throughput, depending on encryption algorithms and server specifications. AES-GCM ciphers with hardware acceleration can maintain near line-speed performance on modern processors, making it viable for high-bandwidth applications like video streaming or large file transfers through the VPN tunnel.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked