Server Fault Asked by Matthew Exon on December 30, 2021
I have an AWS server running Ubuntu that has a pptpd server for VPNs, and many clients with different credentials. It works great. But apparently I’m not supposed to be using that any more, I’m supposed to be using ipsec. I’m trying this out on a local computer running Ubuntu 16.04 first before attempting to do it on the live server.
The only relevant tutorial I could find was this one. Others seem to be for site-to-site VPNs when I have a “road warrior” setup, or for other operating systems, or just generally seem to be targeted at sysadmins who do this every day (no-one’s paying me to do this).
https://raymii.org/s/tutorials/IPSEC_vpn_with_Ubuntu_16.04.html
The tutorial says to use certificates for authentication because they’re “easier to use”.
I followed the instructions. The server is called “winter” and is at 192.168.3.144. The client is called “charly” and is at 192.168.3.138. I generated the server certificate like this:
ipsec pki --pub --in private/vpnHostKey.der --type rsa | ipsec pki --issue --lifetime 730 --cacert cacerts/strongswanCert.der --cakey private/strongswanKey.der --dn "C=CN, O=Winter, CN=winter.lan" --san winter --san 192.168.3.144 --san @192.168.3.144 --flag serverAuth --flag ikeIntermediate --outform der > certs/vpnHostCert.der
The syslog shows:
May 30 20:34:36 winter charon: 03[CFG] adding virtual IP address pool 2002:25f7:7489:3::/112
May 30 20:34:36 winter charon: 03[CFG] loaded certificate "C=CN, O=Winter, CN=winter.lan" from 'vpnHostCert.der'
May 30 20:34:36 winter charon: 03[CFG] id 'winter.lan' not confirmed by certificate, defaulting to 'C=CN, O=Winter, CN=winter.lan'
The connections section of “sudo ipsec statusall” looks like this:
Connections:
IPSec-IKEv2: %any...%any IKEv2, dpddelay=300s
IPSec-IKEv2: local: [C=CN, O=Winter, CN=winter.lan] uses public key authentication
IPSec-IKEv2: cert: "C=CN, O=Winter, CN=winter.lan"
IPSec-IKEv2: remote: uses public key authentication
IPSec-IKEv2: child: 0.0.0.0/0 === dynamic TUNNEL, dpdaction=clear
I generated a client certificate like this:
cat Charly-public.der | sudo ipsec pki --issue --lifetime 730 --cacert /etc/ipsec.d/cacerts/strongswanCert.der --cakey /etc/ipsec.d/private/strongswanKey.der --dn "C=CN, O=Winter, [email protected]" --san "mat@winter" --san "[email protected]" --outform der > Charly-cert.der
…and now I’m trying to connect using my Macbook running macOS 10.13.4. I configure the macintosh VPN as:
…and give it the certificate I created under Authentication Settings.
When I try to connect it fails immediately with no error message. In the server log:
May 30 20:53:15 winter charon: 06[CFG] looking for peer configs matching 192.168.3.144[[email protected]]...192.168.3.138[192.168.3.138]
May 30 20:53:15 winter charon: 06[CFG] peer config match local: 0 (ID_RFC822_ADDR -> 6d:61:74:40:77:69:6e:74:65:72:2e:6c:61:6e)
May 30 20:53:15 winter charon: 06[CFG] peer config match remote: 1 (ID_IPV4_ADDR -> c0:a8:03:8a)
May 30 20:53:15 winter charon: 06[CFG] ike config match: 28 (192.168.3.144 192.168.3.138 IKEv2)
May 30 20:53:15 winter charon: 06[CFG] no matching peer config found
Here’s the left and right config:
mat@winter:~$ sudo grep -E 'left|right' /etc/ipsec.conf
left=%any
leftid=winter.lan
leftsubnet=0.0.0.0/0
leftcert=vpnHostCert.der
leftsendcert=always
right=%any
rightsourceip=10.42.42.0/24,2002:25f7:7489:3::/112
rightdns=8.8.8.8,2001:4860:4860::8888
My real question is, what does “looking for peer configs matching 192.168.3.144[mat@winter]…192.168.3.138[192.168.3.138] / no matching peer config found” mean? I don’t understand how the matching works – what values would be acceptable, what values are being sent by the client, and how I control those on the client and server side. And I don’t understand how to parse that line, what each of the sections represents.
Thanks!
This was correctly answered below, but here’s my explanation of what I did wrong in terms I understand. tl;dr : the leftid needs to be in the certificate as a SAN, not just as the CN in the DN.
The idea is to connect two certificates, a server certificate and a client certificate, such that the two parties can trust each other. Both certificates were signed by a certificate authority (“CA”), and both parties have the CA public key. If the two parties recognise that each other’s certificates were signed by the same CA, they will be happy. The trouble is convincing StrongSwan to recognise that the incoming client connection wants to connect to a particular server certificate. To me, this seems like a no-brainer, since I only configured one certificate. But StrongSwan is designed for more complex setups.
The crucial component is the “leftid” configured in ipsec.conf. You can configure any number of distinct VPNs in StrongSwan, each distinguished by a different leftid. When a client connects, it asks for a VPN with this name, which in my case is configured in VPN settings under “Remote ID”. It then expects the server to send it a certificate, and that certificate should identify itself as being that same VPN name / leftid / Remote ID.
So StrongSwan needs a certificate for its leftid. You generate a server certificate with ipsec. You supply a “Distinguished Name” (“DN”) which is a long string of components like “C=CN, O=Winter, CN=winter.lan”. You can also supply any number of Subject Alternate Names (“SAN”). When the server starts, it reads in the “leftid” and “leftcert” configuration. It tries to find the leftid in either the DN or the SANs.
Here’s the trick: if it can’t find the leftid, it throws away the leftid and just uses the entire DN instead. This looks like:
May 30 20:34:36 winter charon: 03[CFG] id 'winter.lan' not confirmed by certificate, defaulting to 'C=CN, O=Winter, CN=winter.lan'
That means the VPN is now not named “winter.lan” any more, it’s named “C=CN, O=Winter, CN=winter.lan”. If a client wants to connect, it has to ask for that name, not “winter.lan”. It sorta makes sense that it does this, because if the name doesn’t match there’s no point even running. Clients can connect to winter.lan, but if the server sends that certificate it won’t match what the client asked for, and the client will abort the connection. On the other hand, it’s a real bummer it does this, because there’s no way to convince a Macintosh to ask for that leftid.
The big problem in the tutorial I was following is that the leftid it uses is “vpn.example.org”, and in the suggested ipsec command to generate the server certificate, that is only used in the DN, not added as a SAN. If I do that with “winter.lan”, it fails. The id does not match the certificate.
May 31 21:32:00 winter charon: 05[CFG] loaded certificate "C=CN, O=Winter, CN=winter.lan" from 'vpnHostCert.der'
May 31 21:32:00 winter charon: 05[CFG] id 'winter.lan' not confirmed by certificate, defaulting to 'C=CN, O=Winter, CN=winter.lan'
It only works if I also supply the leftid as a SAN with –san. The tutorial even says “you need to make sure the leftid= is the same as the CN in your certificate”. I don’t know if they’re using a different version of strongswan than me, or what the problem is there.
An extra layer of confusion arises because it’s not clear when and where the string “C=CN, O=Winter, CN=winter.lan” matches the string “winter.lan”. This may be because these identifiers also have “types” attached, which have to match, and the types are usually invisible in the logs.
Anyway, the crucial thing to look out for is the “not confirmed by certificate” line at server startup. Don’t bother trying to connect with a client until that’s fixed.
One of the subjectAltName extensions you added to the certificate is [email protected]
, however, you configured leftid=mat@winter
. Since that doesn't match, the local identity will fall back to the subject DN of the certificate (i.e. C=HK, O=Winter, CN=mat@winter
). This, in turn, doesn't match the remote identity proposed by the client (looking for peer configs matching 192.168.3.144[mat@winter]
).
So either configure [email protected]
and change the remote identity in the client config accordingly, or configure the full subject DN as remote identity on the client (but some IKEv2 clients don't actually support that, most notably those by Apple).
With your updated config, winter.lan
has to be contained as subjectAltName. It won't be matched against the CN
relative DN of the subject DN. So you have to explicitly add --san winter.lan
when issuing the server certificate.
When the local identity that's configured doesn't match any of the identities in the local certificate (subject DN or any of the subjectAltNames - note that the type must match too) the subject DN will be used as identity. There is an appropriate message in the log when the config is loaded (something like id 'mat@winter' not confirmed by certificate, defaulting to 'C=HK, O=Winter, CN=mat@winter'
) and this can also be seen in the output of ipsec statusall
in the Connections
section, where the configured IPs and identities are listed. So make sure the identity you configured is what the IKE daemon will actually use during authentication.
The components of the looking for peer config...
log message are really quite simple. For example 192.168.3.144[mat@winter]...192.168.3.138[192.168.3.138]
:
Note that the type of compared identities (e.g. FQDN vs. USER_FQDN or KEY_ID) must match too (identities might look the same in the log and e.g. ipsec statusall
but their type could be different). More details about this comparison (including the type) are logged only if the log level for cfg is increased to 3.
Identities matter for two things. One, they allow the selection of a specific configuration. So by sending a specific identity in the IDr payload the client states it wants to connect to the server with that particular identity and the server will select a config that matches that identity. The payload is optional and some clients don't send it (e.g. Windows clients), which allows the server to select whichever configuration it deems fit. Same goes for client identities, which allow the server to switch to a particular config if it doesn't match (however, with rightid=%any, the default, the client identity will be ignored when selecting configs - but it must be confirmed by the client certificate).
Second, identities are important to prevent just anybody with a valid certificate to authenticate themselves with whatever identity they like. For instance, if your client has other CAs installed besides your CA "X" and you don't enforce a particular identity (they are usually made to match the hostname of the server), the client would accept any certificate issued by any of these CAs, not just one issued specifically for that identity/hostname (it would even accept another client certificate as server certificate if CA "X" is the only CA that's trusted if it woulnd't enforce a particular server identity). Same goes for clients. You don't want your client "Y" to authenticate itself as client "Z" with the certificate that was specifically issued to client "Y". That's particularly important if there are multiple connection definitions with different rightid settings and e.g. different subnets or virtual IP ranges to allow access to different networks via VPN based on the client identity.
The big problem in the tutorial I was following is that the leftid it uses is "vpn.example.org", and in the suggested ipsec command to generate the server certificate, that is only used in the DN, not added as a SAN.
Yes, for some reason they add two unrelated SANs with different TLDs (.com
and .net
) to the certificate.
The tutorial even says "you need to make sure the leftid= is the same as the CN in your certificate". I don't know if they're using a different version of strongswan than me, or what the problem is there.
It doesn't depend on the strongSwan version, but the client. If it doesn't send a remote identity, the server is free to select a config that uses the full subject DN as identity. It's then up to the client whether it accepts that identity when it's returned by the server. So clients that match the remote identity they want to enforce (e.g. the server's FQDN) against the CN of the DN sent by the server will be fine. Windows clients do this, Apple clients possibly too (although some versions of macOS also require a matching SAN). But strongSwan, as client, does not and will require that the configured remote identity fully matches the identity returned by the server (and its type). There is a special client configuration (rightid=%vpn.example.com), in which strongSwan doesn't send a remote identity and also matches the configured identity against all identities in the server certificate. This allows the client to enforce an FQDN as identity while the server identifies itself with the full subject DN, as long as that FQDN is also contained as subjectAltName in the server certificate.
An extra layer of confusion arises because it's not clear when and where the string "C=CN, O=Winter, CN=winter.lan" matches the string "winter.lan". This may be because these identifiers also have "types" attached, which have to match, and the types are usually invisible in the logs.
That's mainly because strongSwan doesn't match identities against parts of DNs. But as mentioned above, some clients do that (at least they match FQDNs against CNs).
Anyway, the crucial thing to look out for is the "not confirmed by certificate" line at server startup. Don't bother trying to connect with a client until that's fixed.
It's definitely a good idea to check for that log message, or whether the output of ipsec statusall
matches the intended configuration.
And if clients fail to connect with no matching peer config found
, make sure to compare the IPs and identities listed in the looking for peer configs...
log message against the IPs and identities of the configured connections in ipsec statusall
.
Answered by ecdsa on December 30, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP