Fortinet Devices
RSA-PSS Authentication
We describe how to set up a dialup connection from one or serveral strongSwan VPN clients to a central FortiGate Gateway using RSA-PSS authentication. We assume static IP addresses so that no NAT traversal and no virtual IP addresses are needed.
Network Topology
Up to 253
strongSwan VPN clients can connect to the fortiGate gateway
in order access the 10.1.0.0/16
network
+-----------+ | client1 |--------------+ +-----------+ 192.168.0.1 | | +-----------+ | +-----------+ +-------------+ | client2 |--------------+----------------| fortigate |-----| 10.1.0.0/16 | +-----------+ 192.168.0.2 | 192.168.0.254 +-----------+ .1 +-------------+ . . +-----------+ | | client<n> |--------------+ +-----------+ 192.168.0.n
Fortigate Gateway Configuration
We use a two-tier X.509 certificate hierarchy with a Root CA certificate
(CA_CERT_1
) and an Issuing CA certificate (CA_CERT_2
)
# show vpn certificate ca config vpn certificate ca edit "CA_Cert_1" set range global next edit "CA_Cert_2" set range global next end
We load the corresponding CRLs statically as files
# show vpn certificate crl config vpn certificate crl edit "CRL_1" set range global next edit "CRL_2" set range global next end
The RSA private key and the matching fortiGate X.509 gateway certificate is loaded via PKCS#12 protected by a password
# show vpn certificate local "fortigate" config vpn certificate local edit "fortigate" set password ENC bYmZ...pw== set range global next
Any client possessing a valid X.509 certificate issued by the Issuing CA is allowed to connect to the network behind the fortiGate gateway
# show user peer config user peer edit "strongswan_peer" set ca "CA_Cert_2" next end
The IKEv2 connection definition with the fortiGate gateway acting as a passive
responder using RSA-PSS
authentication with either a SHA2-256
or SHA2-384
hash
# show vpn ipsec phase1-interface config vpn ipsec phase1-interface edit "strongswan" set type dynamic set interface "internal3" set ike-version 2 set local-gw 192.168.0.254 set authmethod signature set net-device disable set proposal aes128-sha256 aes256-sha384 set localid "fortigate.strongswan.org" set localid-type fqdn set dpd on-idle set comments "VPN: strongswan (Created by AS)" set dhgrp 31 15 14 set nattraversal disable set digital-signature-auth enable set signature-hash-alg sha2-256 sha2-384 set rsa-signature-format pss set certificate "fortigate" set peer "strongswan_peer" set dpd-retryinterval 60 next end
The traffic selectors src-subnet
and dst-subnet
allow any client in the
192.168.0.0/24
network to connect to the 10.1.0.0/16
subnet protected by
the FortiGate gateway
# show vpn ipsec phase2-interface config vpn ipsec phase2-interface edit "strongswan" set phase1name "strongswan" set proposal aes128gcm aes256gcm aes128-sha256 aes256-sha256 set dhgrp 31 15 14 set comments "VPN: strongswan (Created by AS)" set src-subnet 10.1.0.0 255.255.0.0 set dst-subnet 192.168.0.0 255.255.255.0 next end
strongSwan Client Configuration
This is swanctl.conf
connection definition
for client1
connections { fortigate { remote_addrs = 192.168.0.254 local_addrs = 192.168.0.1 local { auth = pubkey-sha256-sha384 certs = client1Cert.der id = client1.strongswan.org } remote { auth = pubkey-sha256-sha384 id = fortigate.strongswan.org cacerts = issuingCaCert.pem } children { fortigate { local_ts = 192.168.0.1 remote_ts = 0.0.0.0/0 esp_proposals = aes128gcm16-aes256gcm16-x25519 rekey_time = 3600 } } version = 2 mobike = no reauth_time = 10800 proposals = aes128-aes256-sha256-sha384-x25519 } }
The following credential files must be stored in the
swanctl
directory
rsa/client1Key.der x509/client1Cert.der x509ca/rootCaCert.pem x509ca/issuingCaCert.pem x509crl/rootCaCrl.der x509crl/issuingCaCrl.der
The following strongswan.conf
options have
to be set to enable RSA-PSS authentication
charon-systemd { rsa_pss = yes rsa_pss_trailerfield = yes }
The rsa_pss_trailerfield option is needed to fix a
Fortinet quirk when using RSA-PSS with either SHA256,
SHA384 or SHA512.
|
Initiating the Connection
The IPsec connectiong is initiated by the strongSwan VPN client with the
swanctl --initiate
command
# swanctl --initiate --child fortigate [IKE] initiating IKE_SA fortigate[1] to 192.168.0.254 [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.1[500] to 192.168.0.254[500] (264 bytes) [NET] received packet: from 192.168.0.254[500] to 192.168.0.1[500] (181 bytes) [ENC] parsed IKE_SA_INIT response 0 [ SA KE No CERTREQ N(FRAG_SUP) N(HASH_ALG) ] [CFG] selected proposal: IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/CURVE_25519 [IKE] received cert request for "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA" [IKE] sending cert request for "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA" [IKE] authentication of 'client1.strongswan.org' (myself) with RSA_EMSA_PSS_SHA2_256_SALT_32 successful [IKE] sending end entity cert "C=CH, O=strongSwan Project, CN=client1.strongswan.org" [IKE] establishing CHILD_SA fortigate{1} [ENC] generating IKE_AUTH request 1 [ IDi CERT N(INIT_CONTACT) CERTREQ IDr AUTH SA TSi TSr N(EAP_ONLY) N(MSG_ID_SYN_SUP) ] [ENC] splitting IKE message (1936 bytes) into 2 fragments [ENC] generating IKE_AUTH request 1 [ EF(1/2) ] [ENC] generating IKE_AUTH request 1 [ EF(2/2) ] [NET] sending packet: from 192.168.0.1[500] to 192.168.0.254[500] (1444 bytes) [NET] sending packet: from 192.168.0.1[500] to 192.168.0.254[500] (580 bytes) [NET] received packet: from 192.168.0.254[500] to 192.168.0.1[500] (1124 bytes) [ENC] parsed IKE_AUTH response 1 [ EF(1/5) ] [ENC] received fragment #1 of 5, waiting for complete IKE message [NET] received packet: from 192.168.0.254[500] to 192.168.0.1[500] (1124 bytes) [ENC] parsed IKE_AUTH response 1 [ EF(2/5) ] [ENC] received fragment #2 of 5, waiting for complete IKE message [NET] received packet: from 192.168.0.254[500] to 192.168.0.1[500] (1124 bytes) [ENC] parsed IKE_AUTH response 1 [ EF(3/5) ] [ENC] received fragment #3 of 5, waiting for complete IKE message [NET] received packet: from 192.168.0.254[500] to 192.168.0.1[500] (1124 bytes) [ENC] parsed IKE_AUTH response 1 [ EF(4/5) ] [ENC] received fragment #4 of 5, waiting for complete IKE message [NET] received packet: from 192.168.0.254[500] to 192.168.0.1[500] (500 bytes) [ENC] parsed IKE_AUTH response 1 [ EF(5/5) ] [ENC] received fragment #5 of 5, reassembled fragmented IKE message (4704 bytes) [ENC] parsed IKE_AUTH response 1 [ IDr CERT CERT CERT AUTH SA TSi TSr ] [IKE] received end entity cert "C=CH, O=strongSwan Project, CN=fortigate.strongswan.org" [IKE] received issuer cert "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA" [IKE] received issuer cert "C=CH, O=strongSwan Project, CN=strongSwan Root CA" [CFG] using certificate "C=CH, O=strongSwan Project, CN=fortigate.strongswan.cor" [CFG] using trusted intermediate ca certificate "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA" [CFG] checking certificate status of "C=CH, O=strongSwan Project, CN=fortigate.strongswan.org" [CFG] using trusted certificate "C=CH, O=strongSwan Project, CN=strongSwanIssuing CA" [CFG] using trusted ca certificate "C=CH, O=strongSwan Project, CN=strongSwan Root CA" [CFG] reached self-signed root ca with a path length of 0 [CFG] crl correctly signed by "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA" [CFG] crl is valid: until Oct 09 10:35:35 2022 [CFG] using cached crl [CFG] certificate status is good [CFG] using trusted ca certificate "C=CH, O=strongSwan Project, CN=strongSwan Root CA" [CFG] checking certificate status of "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA" [CFG] using trusted certificate "C=CH, O=strongSwan Project, CN=strongSwan Root CA" [CFG] crl correctly signed by "C=CH, O=strongSwan Project, CN=strongSwan Root CA" [CFG] crl is valid: until Oct 09 10:34:13 2022 [CFG] using cached crl [CFG] certificate status is good [CFG] reached self-signed root ca with a path length of 1 [IKE] authentication of 'fortigate.strongswan.org' with RSA_EMSA_PSS_SHA2_256_SALT_32 successful [IKE] IKE_SA fortigate[1] established between 192.168.0.1[client1.strongswan.org]...192.168.0.254[C=CH, O=strongSwan Project, CN=fortigate.strongswan.org] [IKE] scheduling reauthentication in 9993s [IKE] maximum IKE_SA lifetime 11073s [CFG] selected proposal: ESP:AES_GCM_16_128/NO_EXT_SEQ [IKE] CHILD_SA fortigate{1} established with SPIs ce664504_i e538cd87_o and TS 192.168.0.1/32 === 10.10.5.0/24 initiate completed successfully
Another FortiGate Quirk is seen in the IKE_AUTH response above where the FortiGate gateway sends the self-signed Root CA certificate in a separate CERT payload besides the server certificate and the Issuing CA certificate. [ENC] parsed IKE_AUTH response 1 [ IDr CERT CERT CERT AUTH SA TSi TSr ] [IKE] received end entity cert "C=CH, O=strongSwan Project, CN=fortigate.strongswan.org" [IKE] received issuer cert "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA" [IKE] received issuer cert "C=CH, O=strongSwan Project, CN=strongSwan Root CA" This doesn’t break the negotiation in any way but just takes up network bandwidth because additional IKEv2 fragments are needed to transmit the unnecessary Root CA certificate. The sending of the Root CA and any intermediate CA certificates by the FortiGate gateway can be suppressed by setting config vpn ipsec phase1-interface edit "strongswan" ... set send-cert-chain disable next end Of course this requires the strongSwan client to load the needed intermediate CA certificates locally. |
Connection Status
The IPsec connectiong is initiated by the strongSwan VPN client with the
swanctl --list-sas
command
# swanctl --list-sas fortigate: #1, ESTABLISHED, IKEv2, 41188a5051bf3473_i* 009b2e2e7f9247c8_r local 'client1.strongswan.org' @ 192.168.0.1[500] remote 'fortigate.strongswan.org' @ 192.168.0.254[500] AES_CBC-128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/CURVE_25519 established 1939s ago, reauth in 8054s fortigate: #1, reqid 1, INSTALLED, TUNNEL, ESP:AES_GCM_16-128 installed 1939s ago, rekeying in 1380s, expires in 2021s in ce664504, 95928 bytes, 1142 packets, 1s ago out e538cd87, 95928 bytes, 1142 packets, 1s ago local 192.168.0.1/32 remote 10.1.0.0/16
Similar to strongSwan which always generates an inbound SPI starting with
0xc..
, FortiGate SPIs always start with 0xe..
.
Other Known Quirks
-
IKEv2 is only supported with a single set of subnets per CHILD_SA. Thus a separate child definition has to be created in the
children
subsection ofswanctl.conf
for each additional subnet. -
When the device receives an IKE_SA_INIT from any valid peer, it initiates a tunnel on its own to that peer. This leads to CHILD_SA duplication.
-
The FortiGate device sometimes sends an invalid checksum, causing strongSwan to switch to NAT-T encapsulated ESP while the FortiGate device remains unchanged, resulting in strongSwan not processing inbound traffic. The workaround is to force ESPinUDP encapsulation, i.e. to set
connections.<conn>.encap = yes
inswanctl.conf
.