Configuration Guide: X.509 Certificates --------------------------------------- Contents 1. Configuring the connections - ipsec.conf 1.1 Configuring local side 1.2 Multiple certificates 1.3 Configuring the peer side using CA certificates 1.4 Handling Virtual IPs and wildcard subnets 1.5 Protocol and port selectors 1.6 IPsec policies based on wildcards 1.7 IPsec policies based on CA certificates 1.8 Sending certificate requests 1.9 Enabling dynamic LDAP URL fetching 2. Configuring certificates and CRLS 2.1 CA certificates 2.2 Certificate revocation lists (CRLs) 2.3 Update of certificates and CRLs 2.4 CRL policy 2.5 Configuring the peer side using locally stored certificates 3. Monitoring functions 4. Firewall support functions 4.1 Environment variables in the updown script 5. Acknowledgements 1. Configuring the connections - ipsec.conf ---------------------------------------- 1.1 Configuring local side ---------------------- Usually the local side is the same for all connections. Therefore it makes sense to put the definitions characterizing the security gateway into the conn %default section of the configuration file /etc/ipsec.conf. If we assume throughout this document that the security gateway is left and the peer is right then we can write conn %default # use RSA based authentication with certificates authby=rsasig rightrsasigkey=%cert # my side is left - the security gateway left=160.85.22.2 leftcert=cert_nick_name #as specified in the NSS database # load connection definitions automatically auto=add The X.509 certificate by which the security gateway will authenticate itself by sending it in binary form to its peers as part of the Internet Key Exchange (IKE) is specified in the line leftcert=cert_nick_name You can use the certificate's Distinguished Name (DN) instead, which is an identifier of type DER_ASN1_DN and which can be written e.g. in the LDAP-type format conn rw right=%any rightid="CN=x.y.com" 1.2 Multiple certificates --------------------- The X.509 implementation supports multiple local host certificates and corresponding RSA private keys: conn rw1 right=%any rightid="CN=x.y.com" leftcert=cert_nick_name_1 conn rw2 right=%any rightid="CN=x.y.com" leftcert=cert_nick_name_2 1.3 Configuring the peer side using CA certificates ----------------------------------------------- Now we can proceed to define our connections. In many applications we might have dozens of mostly Windows-based road warriors connecting to a central security gateway. The following most simple statement: conn rw right=%any defines the general roadwarrior case. The line right=%any literally means that any IPSec peer is accepted, regardless of its current IP source address and its ID, as long as the peer presents a valid X.509 certificate signed by a CA the security gateway puts explicit trust in. Additionally the signature during IKE main mode gives proof that the peer is in possession of the private RSA key matching the public key contained in the transmitted certificate. With the roadwarrior connection definition listed above, an IPsec SA for the security gateway itself can be established. If any roadwarrior should be able to reach e.g. the two subnets 10.0.1.0/24 and 10.0.3.0/24 behind the security gateway then the following connection definitions will make this possible conn rw1 right=%any leftsubnet=10.0.1.0/24 conn rw3 right=%any leftsubnet=10.0.3.0/24 If not all peers in possession of a X.509 certificate signed by a specific certificate authority shall be given access to the Linux security gateway, then either a subset of them can be barred by listing the serial numbers of their certificates in a certificate revocation list (CRL) or as an alternative, access can be controlled by explicitly putting a roadwarrior entry for each eligible peer into ipsec.conf: conn soggy right=%any rightid=@soggy.strongsec.com conn ewa right=%any rightid=ewa@strongsec.com conn wroclaw right=%any rightid="C=CH, O=strongSec GmbH, CN=wroclaw.strongsec.com" When the IP address of a peer is known to be stable, it can be specified as well. This entry is mandatory when the Openswan host wants to act as the initiator an IPSec connection. conn soggy right=160.85.22.3 rightid=@soggy.strongsec.com conn ewa right=160.85.22.8 rightid=ewa@strongsec.com conn wroclaw right=160.85.22.8 rightid="C=CH, O=strongSec GmbH, CN=wroclaw.strongsec.com" conn frosch right=160.85.22.5 In the last example the ID types FQDN, USER_FQDN, DER_ASN1_DN and IPV4_ADDR, respectively, were used. Of course all connection definitions presented so far have included the lines in the conn %defaults section, comprising among other a left and leftcert entry, as well as a rightrsasigkey parameter set to the magic value %cert , signifying that the public key will be extracted from a X.509 certificates sent by the peer. 1.4 Handling Virtual IPs and wildcard subnets ----------------------------------------- Often roadwarriors are behind NAT-boxes with IPsec passthrough, which causes the inner IP source address of an IPsec tunnel to be different from the outer IP source address usually assigned dynamically by the ISP. Whereas the varying outer IP address can be handled by the right=%any construct, the inner IP address or subnet must always be declared in a connection definition. Therefore for the three roadwarriors rw1 to rw3 connecting to a security gateway the following entries are required in /etc/ipsec.conf: conn rw1 right=%any righsubnet=10.0.1.5/32 conn rw2 right=%any rightsubnet=10.0.1.5.47/32 conn rw3 right=%any rightsubnet=10.0.1.128/28 With the wildcard parameter rightsubnetwithin these three entries can be reduced to the single connection definition conn rw right=%any rightsubnetwithin=10.0.1.0/24 Any host will be accepted (of course after successful authentication based on the peer's X.509 certificate only) if it declares a client subnet lying totally within the brackets defined by the wildcard subnet definition (in our example 10.0.1.0/24). For each roadwarrior a connection instance tailored to the subnet of the particular client will be created,based on the generic rightsubnetwithin template. This new feature introduced with version 0.9.12 of the X.509 patch can also be helpful with VPN clients getting a dynamically assigned inner IP from a DHCP server located on the NAT router box. 1.5 Protocol and Port Selectors --------------------------- The X.509 implementation has been combined with the selectors implementation to offer the possibility to restrict the protocol and optionally the ports in an IPsec SA using the rightprotoport and leftprotoport parameter. Some examples: conn icmp right=%any rightprotoport=icmp left=%defaultroute leftid=@pluto.strongsec.com leftprotoport=icmp conn http right=%any rightprotoport=6 left=%defaultroute leftid=@pluto.strongsec.com leftprotoport=6/80 conn dhcp right=%any rightprotoport=udp/bootpc left=%defaultroute leftid=@pluto.strongsec.com leftsubnet=0.0.0.0/0 #allows DHCP discovery broadcast leftprotoport=udp/bootps rekey=no keylife=20s rekeymargin=10s auto=add Protocols and ports can be designated either by their numerical values or by their acronyms defined in /etc/services. ipsec auto --status shows the following connection definitions: "icmp": 160.85.106.10[@pulpo.strongsec.com]:1/0...%any:1/0 "http": 160.85.106.10[@pulpo.strongsec.com]:6/80...%any:6/0 "dhcp": 0.0.0.0/0===160.85.106.10[@pulpo.strongsec.com]:17/67...%any:17/68 Based on the protocol and port selectors appropriate eroutes will be set up, so that only the specified payload types will pass through the IPsec tunnel. 1.6 IPsec policies based on wildcards --------------------------------- In large VPN-based remote access networks there is often a requirement that access to the various parts of an internal network must be granted selectively, e.g. depending on the group membership of the remote access user. Version 0.9.24 of the X.509 patch makes this possible by applying wildcard filtering on the VPN user's distinguished name (ID_DER_ASN1_DN). Let's make a practical example: An organization has a sales department (OU=Sales) and a research group (OU=Research). In the company intranet there are separate subnets for Sales (10.0.0.0/24) and Research (10.0.1.0/24) but both groups share a common web server (10.0.2.100). The VPN clients use Virtual IP addresses that are either assigned statically or via DHCP-over-IPsec. The sales and research departments use IP addresses from separate DHCP address pools (10.1.0.0/24) and (10.1.1.0/24), respectively. An X.509 certificate is issued to each employee, containing in its subject distinguished name the country (C=CH), the company (O=ACME), the group membership(OU=Sales or OU=Research) and the common name (e.g. CN=Bart Simpson). The IPsec policy defined above can now be enforced with the following three IPsec security associations: conn sales right=%any rightid="C=CH, O=ACME, OU=Sales, CN=*" rightsubnetwithin=10.1.0.0/24 # Sales DHCP range leftsubnet=10.0.0.0/24 # Sales subnet conn research right=%any rightid="C=CH, O=ACME, OU=Research, CN=*" rightsubnetwithin=10.1.1.0/24 # Research DHCP range leftsubnet=10.0.1.0/24 # Research subnet conn web right=%any rightid="C=CH, O=ACME, OU=*, CN=*" rightsubnetwithin=10.1.0.0/23 # Remote access DHCP range leftsubnet=10.0.2.100/32 # Web server rightprotoport=tcp # TCP protocol only leftprotoport=tcp/http # TCP port 80 only Of course group specific tunneling could be implemented on the basis of the Virtual IP range specified by the rightsubnetwithin parameter alone, but the wildcard matching mechanism guarantees that only authorized user can access the corresponding subnets. The '*' character is used as a wildcard in relative distinguished names (RDNs). In order to match a wildcard template, the ID_DER_ASN1_DN of a peer must contain the same number of RDNs appearing in the exact order defined by the template. "C=CH, O=ACME, OU=Research, OU=Special Effects, CN=Bart Simpson" matches the templates "C=CH, O=ACME, OU=Research, OU=*, CN=*" "C=CH, O=ACME, OU=*, OU=Special Effects, CN=*" "C=CH, O=ACME, OU=*, OU=*, CN=*" but not the template "C=CH, O=ACME, OU=*, CN=*" which doesn't have the same number of RDNs. 1.7 IPsec policies based on CA certificates --------------------------------------- As an alternative to the wildcard based IPsec policies, access to specific client host and subnets can abe controlled on the basis of the CA that issued the peer certificate conn sales right=%any rightca="C=CH, O=ACME, OU=Sales, CN=Sales CA" rightsubnetwithin=10.1.0.0/24 # Sales DHCP range leftsubnet=10.0.0.0/24 # Sales subnet conn research right=%any rightca="C=CH, O=ACME, OU=Research, CN=Research CA" rightsubnetwithin=10.1.1.0/24 # Research DHCP range leftsubnet=10.0.1.0/24 # Research subnet conn web right=%any rightca="C=CH, O=ACME, CN=ACME Root CA" rightsubnetwithin=10.1.0.0/23 # Remote access DHCP range leftsubnet=10.0.2.100/32 # Web server rightprotoport=tcp # TCP protocol only leftprotoport=tcp/http # TCP port 80 only In the example above, the connection "sales" can be used by peers presenting certificates issued by the Sales CA, only. In the same way, the use of the connection "research" is restricted to owners of certificates issued by the Research CA. The connection "web" is open to both "Sales" and "Research" peers because the required "ACME Root CA" is the issuer of the Research and Sales intermediate CAs. If no rightca parameter is present then any valid certificate issued by one of the trusted CAs in /etc/ipsec.d/cacerts can be used by the peer. The leftca parameter usually doesn't have to be set explicitely because by default it is set to the issuer field of the certificate loaded via leftcert. The statement rightca=%same sets the CA requested from the peer to the CA used by the left side itself as e.g. in conn sales right=%any rightca=%same leftcert=mySalesCert.pem 1.8 Sending certificate requests ---------------------------- The presence of a rightca parameter also causes the CA to be sent as part of the certificate request message when Openswan is the initiator. As a responder FreeS/WAN sends the desired CA only for non-roadwarrior connections. 1.9 Enabling dynamic LDAP URL fetching ---------------------------------- By default LDAP support is compiled into Pluto with the version that is shipped with Fedora and RHEL. 'http', 'ftp', and 'file' URLs are fetched using the 'curl' command line tool. LDAP source code support is not required for these URLs. 2. Configuring certificates and CRLs --------------------------------- 2.1 CA certificates --------------- X.509 certificates received by FreeS/WAN during the IKE protocol are automatically authenticated by going up the trust chain until a self-signed root CA certificate is reached. Usually host certificates are directly signed by a root CA, but current implementation also supports multi-level hierarchies with intermediate CAs in between. All CA certificates belonging to a trust chain must be in NSS database. Multiple CAs are supported, but presently they just create a large pool of valid user or host certificates and cannot be assigned to specific connection definitions in /etc/ipsec.conf. 2.2 Certificate revocation lists (CRLs) ----------------------------------- CRLs contain the serial numbers of all user or host certificates that have been revoked due to various reasons. After successful verification of the X.509 trust chain, Pluto searches the directory /etc/ipsec.d/crls for the presence of a CRL issued by the CA that has signed the certificate. If the serial number of the certificate is found in the CRL then the public key contained in the certificate is declared invalid and the IPSec SA will not be established. If no CRL is found in the crls directory or if the deadline defined in the nextUpdate field of the CRL has been reached, a warning is issued but the public key will nevertheless be accepted. CRLs must be stored either in binary DER or base64 PEM format in the crls directory. 2.3 Update of certificates and CRLs ------------------------------- Pluto reads certificates and CRLs during system startup and keeps them in memory in the form of chained lists. X.509 certificates have a finite life span defined by their validity field. Therefore it must be possible to replace host and CA certificates kept in system memory without disturbing established ISAKMP SAs. Certificate revocation lists should also be updated in the regular intervals indicated by the nextUpdate field in the CRL body. The following interactive commands allow the manual replacement of the various files: +----------------------------------------------------------------------------+ | ipsec auto --rereadsecrets reload file /etc/ipsec.secrets | |----------------------------------------------------------------------------| | ipsec auto --rereadcrls reload files in /etc/ipsec.d/crls directory | |----------------------------------------------------------------------------| | ipsec auto --rereadall ipsec auto --rereadsecrets | | --rereadcrls | +----------------------------------------------------------------------------+ Starting with version 1.1.0 of the X.509 patch, CRLs can be automatically fetched from an HTTP or LDAP server using the CRL distribution points contained in X.509 certificates. The command ipsec auto --listcrls shows any pending fetch requests: Oct 31 00:29:53 2002, trials: 2 issuer: 'C=CH, O=strongSec GmbH, CN=strongSec Root CA' distPts: 'http://www.strongsec.com/ca/cert.crl' 'ldap://ldap.strongsec.com/o=strongSec GmbH, c=CH ?certificateRevocationList?base ?(objectClass=certificationAuthority)' In the example above, an http and an ldap URL were extracted from a received end certificate. An independent thread then tries to fetch a CRL from the designated distribution points. The same thread also periodically checks if any loaded CRLs are about to expire. The check interval can be defined in the "config setup" section of the ipsec.conf file: config setup crlcheckinterval=600 In our example the thread wakes up every 600 seconds or 10 minutes in order to check the validity of the CRLs or to retry any pending fetch requests: List of X.509 CRLs: Dec 19 09:35:31 2002, revoked certs: 40 issuer: 'C=CH, O=strongSec GmbH, CN=strongSec Root CA' distPts: 'http://www.strongsec.com/ca/cert.crl' updates: this Dec 19 09:35:00 2002 next Dec 19 10:35:00 2002 warning (expires in 19 minutes) List of fetch requests: Dec 19 10:15:31 2002, trials: 1 issuer: 'C=CH, O=strongSec GmbH, CN=strongSec Root CA' distPts: 'http://www.strongsec.com/ca/cert.crl' The first trial to update a CRL is started 2*crlcheckinterval before the nextUpdate time, i.e. when less than 20 minutes are left in our practical example. When crlcheckinterval is set to 0 (this is also the default value when the parameter is not set in ipsec.conf) then the CRL checking and updating thread is not started and dynamic CRL fetching is disabled. 2.4 CRL Policy ---------- By default Pluto is quite tolerant concerning the handling of CRLs. It is not mandatory for a CRL to be present in /etc/ipsec.d/crls and if the expiration date defined by the nextUpdate field of a CRL has been reached just a warning is issued but a peer certificate will always be accepted if it has not been revoked. If you want to enforce a stricter CRL policy then you can do this by setting the "strictcrlpolicy" option. This is done in the "config setup" section of the ipsec.conf file: config setup strictcrlpolicy=yes ... A certificate received from a peer will not be accepted if no corresponding CRL is present in /etc/ipsec.conf. And if an ISAKMP SA re-negotiation takes place after the nextUpdate deadline has been reached, the peer certificate will be declared invalid and the cached RSA public key will be deleted causing the connection in question to fail. Therefore if you are going to use the "strictcrlpolicy=yes" option make sure that the CRLs will always be updated in time. Otherwise a total standstill would ensue. As mentioned earlier the default setting is "strictcrlpolicy=no" 2.5 Configuring the peer side using locally stored certificates ----------------------------------------------------------- If you don't want to use trust chains based on CA certificates, you can alternatively import trusted peer certificates directly into Pluto. Thus you do not have to rely on the certificate to be transmitted by the peer as part of the IKE protocol. With the conn %default section stated above and the use of the rightcert keyword for the peer side, the connection definitions can alternatively be written as conn soggy right=%any rightid=@soggy.strongsec.com rightcert="right_cert_nick_name" #as specified in NSS database conn wroclaw right=160.85.22.8 rightcert="right_cert_nick_name" #as specified in NSS database If a peer certificate contains a subjectAltName extension, then an alternative rightid type can be used, as the example "conn soggy" shows. If no rightid entry is present then the subject distinguished name contained in the certificate is taken as the ID. 3. Monitoring functions -------------------- The command ipsec auto [--utc] --listcrls lists all CRLs that have been loaded from /etc/ipsec.d/crls. The output has the form Oct 30 22:57:51 2002, revoked certs: 37 issuer: 'C=CH, O=strongSec GmbH, CN=strongSec Root CA' distPts: 'http://www.strongsec.com/ca/cert.crl' updates: this Oct 15 23:42:12 2002 next Nov 14 22:42:12 2002 ok and shows - the date the CRL was installed either in local time or UTC (--utc) - the number revoked certificates - the issuer of the CRL - the URLs of the distribution points where the CRL can be fetched from. - the dates when the CRL was issued and when the next update is expected, respectively, expressed either in local time or UTC (--utc). It is automatically checked if the next update deadline has passed, resulting either in an "ok" message, a a "warning" message when strictcrlpolicy=no or a "fatal" message when strictcrlpolicy=yes. The command ipsec auto [--utc] -listall is equivalent to ipsec auto [--utc] -listpubkeys ipsec auto [--utc] -listcerts ipsec auto [--utc] -listcacerts ipsec auto [--utc] -listcrls ipsec auto [--utc] -listcards 4. Firewall support functions -------------------------- 4.1 Environment variables in the updown script ------------------------------------------ The X.509 patch makes the following environment variables available in the updown script indicated by the leftupdown option: +------------------------------------------------------------------+ | Variable Example Comment | |------------------------------------------------------------------| | $PLUTO_PEER_ID ewa@strongsec.com USER_FQDN (1) | |------------------------------------------------------------------| | $PLUTO_PEER_PROTOCOL 17 udp (2) | |------------------------------------------------------------------| | $PLUTO_PEER_PORT 68 bootpc (3) | |------------------------------------------------------------------| | $PLUTO_PEER_CA C=CH, O=ACME, CN=Sales CA (4) | |------------------------------------------------------------------| | $PLUTO_MY_ID @pulpo.strongsec.com FQDN (1) | |------------------------------------------------------------------| | $PLUTO_MY_PROTOCOL 17 udp (2) | |------------------------------------------------------------------| | $PLUTO_MY_PORT 67 bootps (3) | +------------------------------------------------------------------+ (1) $PLUTO_PEER_ID/$PLUTO_MY_ID contain the IDs of the two ends of an established connection. In our examples these correspond to the strings defined by rightid and leftid, respectively. (2) $PLUTO_PEER_PROTOCOL/$PLUTO_MY_PROTOCOL contain the protocol defined by the rightprotoport and leftprotoport options, respectively. Both variables contain the same protocol value. The variables take on the value '0' if no protocol has been defined. (3) $PLUTO_PEER_PORT/$PLUTO_MY_PORT contain the ports defined by the rightprotoport and leftprotoport options, respectively. The variables take on the value '0' if no port has been defined. (4) $PLUTO_PEER_CA contains the distinguished name of the CA that issued the peer's certificate. 5. Acknowledgements ---------------- Major contributions to the X.509 patch for Linux FreeS/WAN have come from Marco Bertossa, Andreas Hess, Patric Lichtsteiner, Andreas Schleiss, and Roger Wegmann, all present or former students of the Zurich University of Applied Sciences in Winterthur (Switzerland). The support of Virtual IPs and the DHCP-over-IPsec protocol has been developed and coded by Mario Strasser, former research assistant at the ZHW. Smartcard support has been provided by the ZHW students Christoph Gysin and Simon Zwahlen. Stephane Laroche from Colubris has contributed dynamic CRL fetching. Stephen J. Bevan has contributed the enforcement of port and protocol selectors on outbound traffic based on extended eroutes. The development of the patch is coordinated by Andreas Steffen, professor for Security and Communications at the ZHW.