mrled / algo

Set up a personal IPSEC VPN in the cloud
https://blog.trailofbits.com/2016/12/12/meet-algo-the-vpn-that-works/
MIT License
0 stars 0 forks source link

13801: IKE authentication credentials are unacceptable. #1

Open mrled opened 6 years ago

mrled commented 6 years ago

When I deploy from the newtroy branch, Windows clients will not connect. The UI says "IKE authentication credentials are unacceptable", and the Event Log shows error 13801

However, when I deploy from the improve-windows-script branch (just the Windows script changes on top of algo/master), it works just fine.

I've tried setting DisableIKENameEkuCheck to 1 (see my StackExchange thread below) but it doesn't change the error message, leading me to believe that the Microsoft troubleshooting steps (see the technet article below) are incomplete.

https://blogs.technet.microsoft.com/rrasblog/2009/08/12/troubleshooting-common-vpn-related-errors/

Possible Causes: This error usually comes in one of the following cases:

The machine certificate used for IKEv2 validation on RAS Server does not have 'Server Authentication' as the EKU (Enhanced Key Usage).
The machine certificate on RAS server has expired.
The root certificate to validate the RAS server certificate is not present on the client.
VPN Server Name as given on client doesn’t match with the subjectName of the server certificate.

From my own StackExchange thread https://serverfault.com/questions/536092/strongswan-ikev2-windows-7-agile-vpn-what-is-causing-error-13801

The error message was "Error 13801: IKE authentication credentials are unacceptable", which sounded like my user credentials weren't working. However, this is a message about authenticating the server, which is done (per my configuration) by the server's SSL certificate.

mrled commented 6 years ago

I don't see anything in here that looks weird. Notably, in the second one, the Windows scripts don't change at all.

One avenue I would like to pursue are my changes to ipsec.conf, even though I can't think of a reason that it would have broken anything.

mrled commented 6 years ago

YEPPPP changing ipsec.conf caused the problem. Now to figure out if I can fix it without breaking functionality I need...

mrled commented 6 years ago

It appears that mobileconfig files for macOS/iOS do not have a very configurable setting for their ID.

Stuff I tried, stuff I read

Setting LocalIdentifier to /CN=USER

I tried setting LocalIdentifier to /CN=USER and the rightid on the server to the same, but the client refused to connect (tried on iOS)

Apple's official docs

https://developer.apple.com/library/content/featuredarticles/iPhoneConfigurationProfileRef/Introduction/Introduction.html

LocalIdentifier - Present only if AuthenticationMethod is SharedSecret. The name of the group to use. If Hybrid Authentication is used, the string must end with [hybrid]. Used for Cisco IPSec.

From the Strongswan wiki

The strongswan wiki says "

            <!-- Remote identity, can be a FQDN, a userFQDN, an IP or (theoretically) a certificate's subject DN. Can't be empty.
                 IMPORTANT: DNs are currently not handled correctly, they are always sent as identities of type FQDN -->
            <key>RemoteIdentifier</key>
            <string>vpn.example.org</string>
            <!-- Local IKE identity, same restrictions as above. If it is empty the client's IP address will be used -->
            <key>LocalIdentifier</key>
            <string></string>
            <!-- Optional, if it matches the CN of the root CA certificate (not the full subject DN) a certificate request will be sent
                 NOTE: If this is not configured make sure to configure leftsendcert=always on the server, otherwise it won't send its certificate -->

Some discussion on Apple forums

https://discussions.apple.com/thread/7481077

LocalID is the identifier used by the client device e.g. an iPhone. I used the name defined in the security certificate being used by the client device. Now I seem to recall that for IKEv2 Apple do not support using a FQDN for client devices which is what I had been using as the Distinguished Name for my certificates so I have been defining as a subject alternative name an additional name in the format of a (fake) email address e.g. serialnumber@domain.com and I use that as the LocalID. I do not have to define this specifically on the StrongSwan5 server as I currently use in /etc/ipsec.conf the line rightid="" with the asterisk meaning accept anything, I believe rightid=%any means the same thing. However something along the lines rightid=@domain.com might be better, I think the exact format to do this in StrongSwan is 'complex' and might be rightid=@@domain.com which is why I started off with it completely open.

Thoughts for future fixes

/CN=/CN=USER

PerhapsI could set a special SubjectAltName on all the certs, with /CN=/CN=USER (does x509 have escapes I could use?). Then, I could specify in the mobileconfig that the LocalIdentifier is /CN=USER, since /CN=USER is one valid SAN on the client cert, and perhaps iOS would accept that?

Then I would revert my strongswan fix (see the algo upstream PR below) so that it submits the id as /CN=USER, and leave Windows to its default behavior of doing the same thing as well, and everyone is happy.

But only if I can add that weird SAN to all certs, and only if iOS would allow it.

Modify Windows behavior?

I haven't looked to see if Windows' behavior could be modified at all, to submit just USER as the id and not /CN=USER

Ask Strongswan somehow?

Maybe someone on the strongswan team can help

My PR to algo upstream

So I can find it later, here's my fix for strongswan clients to submit USER as their ID: https://github.com/trailofbits/algo/pull/795/commits/acc3fe4c95ddc5a433c83a12f8887c8e428ada0a

mrled commented 6 years ago

I looked at options available for changing the ID submitted on Windows. Add-VpnConnection has a -CustomConfiguration flag which expects an XML file, but I couldn't find comprehensive documentation as to what is supported here, nor any examples that looked like it would allow you to set the local ID that is sent to the server

mrled commented 6 years ago

I have been researching IKEv2 identifiers.

In RFC5996 which defines the IKEv2 key exchange, it specifically calls out two terms that are used all over the Internet but frequently left undefined:

IDi         Identification - Initiator
IDr         Identification - Responder

Here is a fairly long mail about identities. From a (very) cursory reading, it appears to say that basically these IDs are allowed to be anything... and that jives with what I have been reading w.r.t e.g. iOS, which has multiple options for IDs, but cannot be configured to send an arbitrary ID.

Furthermore, according to this mail, apparently the initiator can request a certain type of IDr, but the responder is free to disregard this request and submit something else for the IDr; if the initiator doesn't like this, its only recourse is to close the connection.

Also, I found this mail regarding strongSwan's use of identifiers:

left|rightid must be either the subject distinguished name or a subjectAltName extension contained in the certificate. If you don't define leftid or if leftid is not defined in the certificate then automatically the subject DN is assumed as a default.

As a responder you can define rightid=%any, in that case any peer with a trusted and non-revoked certificate will be accepted.

mrled commented 6 years ago

Hmm. I have an idea for a different tactic.

So. It sounds like we can configure strongSwan to send MAC addresses to a DHCP server, and predict what those MAC addresses actually are. We can then write a config file for dnsmasq to use that maps the MAC addresses to IP addresses, and get the same static user<->IP mapping that I have in my current fork.

As a bonus, we eliminate the need for a separate conn stanza per user, and all of this rightid matching that's causing me so many problems. This would make upstream happy.

Finally, it would work just as well as my current solution in newtroy as well. I would need to run dnsmasq, which I'm not running now, but that's not a big deal. (I'd nuke ad blocking tho.)

Obstacles:

mrled commented 6 years ago

Use siphash: https://pypi.python.org/pypi/siphash

siphash.SipHash_2_4(b'0123456789', '/CN=magrassee').hash()
mrled commented 6 years ago

More notes on htonl:

mrled commented 6 years ago

dnsmasq.leases format: http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2005q1/000143.html

Example:

1522587855 7a:a7:bc:8b:b5:ec 10.19.48.55 * 30:14:31:12:30:10:06:03:55:04:03:0c:09:6d:61:67:72:61:73:73:65:65
mrled commented 6 years ago

Some strongswan links about identity matching:

mrled commented 6 years ago

Some strongswan links about identity matching: