Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ibndias
Last active June 3, 2022 09:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ibndias/9997f971fe540199bc9b5f37423cccbe to your computer and use it in GitHub Desktop.
Save ibndias/9997f971fe540199bc9b5f37423cccbe to your computer and use it in GitHub Desktop.
strongswan-roadwarrior-ipsec-vpn-guide

Strongswan Roadwarrior IPSec VPN Guide

Creates an easy Roadwarrior IPSec VPN by using StrongSwan on Ubuntu 22.04 with x509 authentication.

10.1.0.0/16 -- | 192.168.0.1 | === | x.x.x.x | -- 10.30.0.1
  moon-net          moon              carol       virtual IP
                  (Gateway)        (Roadwarrior)

Prerequisites:

  • Three Ubuntu 22.04 Virtual Machines connected as follows:
    • moon as gateway for moon-net (10.1.0.1) and accessible as 192.168.0.1.
    • carol as roadwarrior x.x.x.x have access to moon
    • alice as someone in moon-net (10.1.0.2)

1 Install Strongswan on both Gateway and Roadwarrior machines

apt-get install strongswan libcharon-extra-plugins strongswan-pki strongswan-swanctl -y

2 Generate CA Certificates

Edwards-curve key with 128bit strength

pki --gen --type ed25519 --outform pem > strongswanKey.pem

Self-signed Public key

pki --self --ca --lifetime 3652 --in strongswanKey.pem \
           --dn "C=CH, O=strongSwan, CN=strongSwan Root CA" \
           --outform pem > strongswanCert.pem

Print it

pki --print --in strongswanCert.pem

subject:  "C=CH, O=strongSwan, CN=strongSwan Root CA"
issuer:   "C=CH, O=strongSwan, CN=strongSwan Root CA"
validity:  not before May 18 08:32:06 2017, ok
           not after  May 18 08:32:06 2027, ok (expires in 3651 days)
serial:    57:e0:6b:3a:9a:eb:c6:e0
flags:     CA CRLSign self-signed
subjkeyId: 2b:95:14:5b:c3:22:87:de:d1:42:91:88:63:b3:d5:c1:92:7a:0f:5d
pubkey:    ED25519 256 bits
keyid:     a7:e1:6a:3f:e7:6f:08:9d:89:ec:23:92:a9:a1:14:3c:78:a8:7a:f7
subjkey:   2b:95:14:5b:c3:22:87:de:d1:42:91:88:63:b3:d5:c1:92:7a:0f:5d

Then copy the CA certificate to both Gateway and Roadwarrior client(s), you can use scp.

3 Setting up the moon Gateway

3.1 Generate Gateway Certificate

pki --gen --type ed25519 --outform pem > moonKey.pem

Create PKCS#10 Request to be signed by CA

pki --req --type priv --in moonKey.pem \
          --dn "C=CH, O=strongswan, CN=moon.strongswan.org" \
          --san moon.strongswan.org --outform pem > moonReq.pem

Multiple use of the --san parameter any number of desired subjectAlternativeNames can be added to the request, such as:

--san sun.strongswan.org     # fully qualified host name
--san carol@strongswan.org   # RFC822 user email address
--san 192.168.0.1            # IPv4 address
--san fec0::1                # IPv6 address

As a CA, issues the signed certificate using

pki --issue --cacert strongswanCert.pem --cakey strongswanKey.pem \
            --type pkcs10 --in moonReq.pem --serial 01 --lifetime 1826 \
            --outform pem > moonCert.pem

Print the issued certificate

pki --print --in moonCert.pem

Moves the certificate

sudo cp strongswanCert.pem /etc/swanctl/x509ca/ && sudo cp moonCert.pem /etc/swanctl/x509/ && sudo cp moonKey.pem /etc/swanctl/private/

3.2 Configure the Strongswan on moon

Make sure all the certs are in correct directory

/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem

Modify the Strongswan config

sudo vi /etc/swanctl/swanctl.conf

3.2.1 Contents of /etc/swanctl/swanctl.conf for moon as Gateway

    connections {
        rw {
            pools = rw_pool

            local {
                auth = pubkey
                certs = moonCert.pem
                id = moon.strongswan.org
            }
            remote {
                auth = pubkey
            }
            children {
                net-net {
                    local_ts  = 10.1.0.0/16
                }
            }
        }
    }

    pools {
        rw_pool {
            addrs = 10.30.0.0/16
        }
    }

Pools is a virtual IP pools for clients. This will be needed for easy routing.

3.3 Routing

Add routing so carol can ping to moon-net

sudo iptables -t nat -A POSTROUTING -s 10.30.0.0/24  -d 10.1.0.0/24 -j MASQUERADE
sudo iptables -A FORWARD  -s 10.30.0.0/24  -d 10.1.0.0/24 -j ACCEPT

3.4 Configure Packet Forwarding

In ubuntu 20.04, packet forwarding between internal and external interfaces is disabled by default.

sudo vi /etc/systemctl.conf

and uncomment these lines

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

Save and do

sudo sysctl -p

3.5 Start the service and show the status

sudo systemctl start strongswan-starter.service
sudo systemctl status strongswan-starter.service

Now load all the configurations with sudo swanctl -q

We can trace the log on moon gateway using sudo swanctl -T

Or check the whole logs with

cat /var/log/auth.log | grep charon

We are now done with the gateway setup, now let's move to the client setup.

4 Setting up the carol Roadwarrior

4.1 Generate Roadwarrior Certificate

pki --gen --type ed25519 --outform pem > carolKey.pem

Create PKCS#10 Request to be signed by CA

pki --req --type priv --in carolKey.pem \
          --dn "C=CH, O=strongswan, CN=moon.strongswan.org" \
          --san carol@strongswan.org --outform pem > carolReq.pem

As a CA, issues the signed certificate using

pki --issue --cacert strongswanCert.pem --cakey strongswanKey.pem \
            --type pkcs10 --in carolReq.pem --serial 01 --lifetime 1826 \
            --outform pem > carolCert.pem

Print the issued certificate

pki --print --in carolCert.pem

Moves the cetificate

sudo cp strongswanCert.pem /etc/swanctl/x509ca/ && sudo cp carolCert.pem /etc/swanctl/x509/ && sudo cp carpolKey.pem /etc/swanctl/private/

4.2 Configure the Strongswan on carol

Make sure all the certs are placed in correct directory

/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/carolCert.pem
/etc/swanctl/private/carolKey.pem

Modify the Strongswan config

sudo vi /etc/swanctl/swanctl.conf

4.2.1 Contents of /etc/swanctl/swanctl.conf for carol as Roadwarrior

    connections {
        home {
            remote_addrs = moon.strongswan.org
            vips = 0.0.0.0

            local {
                auth = pubkey
                certs = carolCert.pem
                id = carol@strongswan.org
            }
            remote {
                auth = pubkey
                id = moon.strongswan.org
            }
            children {
                home {
                    remote_ts  = 10.1.0.0/16
                    start_action = start
                }
            }
        }
    }

Note that this remote_addrs = moon.strongswan.org field can be replaced with an ip address for example in this case moon's ip is 192.168.0.1.

4.3 Start the service and show the status

sudo systemctl start strongswan-starter.service
sudo systemctl status strongswan-starter.service

Now load all the configurations with sudo swanctl -q

4.4 Initiate Connection from carol

sudo swanctl --initiate --child home
[IKE] initiating IKE_SA home[7] to 192.168.0.1
[ENC] generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) ]
[NET] sending packet: from 192.168.0.2[500] to 192.168.0.1[500] (904 bytes)
[NET] received packet: from 192.168.0.1[500] to 192.168.0.2[500] (293 bytes)
[ENC] parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) CERTREQ N(FRAG_SUP) N(HASH_ALG) N(CHDLESS_SUP) N(MULT_AUTH) ]
[CFG] selected proposal: IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_AES128_XCBC/CURVE_25519
[IKE] received cert request for "C=CH, O=strongSwan, CN=strongSwan Root CA"
[IKE] received 1 cert requests for an unknown ca
[IKE] sending cert request for "C=CH, O=strongSwan, CN=strongSwan Root CA"
[IKE] authentication of 'carol@strongswan.org' (myself) with ED25519 successful
[IKE] sending end entity cert "C=CH, O=strongswan, CN=moon.strongswan.org"
[IKE] establishing CHILD_SA home{31}
[ENC] generating IKE_AUTH request 1 [ IDi CERT N(INIT_CONTACT) CERTREQ IDr AUTH CPRQ(ADDR DNS) SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(MULT_AUTH) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
[NET] sending packet: from 192.168.0.2[4500] to 192.168.0.1[4500] (864 bytes)
[NET] received packet: from 192.168.0.1[4500] to 192.168.0.2[4500] (688 bytes)
[ENC] parsed IKE_AUTH response 1 [ IDr CERT AUTH CPRP(ADDR) SA TSi TSr N(MOBIKE_SUP) N(ADD_4_ADDR) N(ADD_4_ADDR) ]
[IKE] received end entity cert "C=CH, O=strongswan, CN=moon.strongswan.org"
[CFG]   using certificate "C=CH, O=strongswan, CN=moon.strongswan.org"
[CFG]   using trusted ca certificate "C=CH, O=strongSwan, CN=strongSwan Root CA"
[CFG] checking certificate status of "C=CH, O=strongswan, CN=moon.strongswan.org"
[CFG] certificate status is not available
[CFG]   reached self-signed root ca with a path length of 0
[IKE] authentication of 'moon.strongswan.org' with ED25519 successful
[IKE] IKE_SA home[7] established between 192.168.0.2[carol@strongswan.org]...192.168.0.1[moon.strongswan.org]
[IKE] scheduling rekeying in 13904s
[IKE] maximum IKE_SA lifetime 15344s
[IKE] installing new virtual IP 10.30.0.1
[CFG] selected proposal: ESP:AES_GCM_16_128
[IKE] CHILD_SA home{31} established with SPIs c7966f3d_i cc8af0d2_o and TS 10.30.0.1/32 === 10.1.0.0/24
[IKE] peer supports MOBIKE
initiate completed successfully

Ping test from carol to alice at moon-net (10.1.0.0/16)

ping 10.1.0.2

4.5 Terminate Connection

sudo swanctl --terminate --child home
sudo swanctl --terminate -i home

Debugging

Dump the SK_ei, SK_er, SK_ai, SK_ar of the IKE_SA

with the ipsec.conf setting

charondebug="ike 4"

SK_ei, SK_er, SK_ai, SK_ar are written to the log. As an alternative the command

ipsec stroke loglevel ike 4

achieves the same when the charon daemon is already running.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment