understanding the process of setting up eap-tls server/client certs

Michael Martinez mwtzzz at gmail.com
Sun Mar 20 17:42:20 CET 2016


I got this working. I'll share what I did, maybe it will help someone
else down the line.

First thing I did is refresh myself on how digital certificates and
public key infrastructure works (asymmetric public/private keys). It
had been a long time since I had worked with any of it, but for radius
you need more than just "what is a basic private/public key pair." You
need to know what the certificates do and what they contain.

Next I ran the make ca.pem, make server.pem, make client.pem commands
found in the freeradius certs folder and I looked at the openssl
commands that these ran. Each make runs several openssl commands and
you need to understand what each of these is doing.

Next is to edit the ca.cnf, server.cnf and client.cnf files. A note
about the password fields in these files:
  *for ca.cnf, the "output password" is used to encrypt the ca.key
private key that gets created

  * for server.cnf, the "output password" is first used to encrypt the
server.key private key that gets created. It is also subsequently used
to encrypt the outputted private key when the p12 (pkcs12) file is
created, but this step does not create any new private keys, so it is
ignored at that point. the "input password" is used during the p12
creation to decrypt server.key, so therefore it needs to have the same
value as output password.

so: "input password" must equal "output password"

  * for client.cnf, same thing. output password is used to encrypt
client.key, then later it is used as "input password" to decrypt it to
create the p12 file, so:

"input password" must equal "output password" here too.

For sanity checks, after you have run the three make commands, you can
look at passwords.mk file. And of course you should use a different
password for each of these three things.

After this, you can go into the etc/raddb/certs directory that is used
by freeradius, and you can nuke everything in there and then populate
it with four new files: dh, ca.pem, server.key and server.pem. Then go
into mods-enabled/eap and set the following:

  private_key_password: this is the password for "server.key"
  private_key_file: the server.key file
  certificate file: server.pem
  ca_file: ca.pem

server.key and server.pem are what freeradius uses to identify itself
and encrypt traffic, so this pair needs to be unique for each radius
server. In order to validate other certs (client certs), it needs the
ca.pem file.

now to use eapol_test for testing, you need several things:
  * a configuration file
  * the CA file
  * the client certificate which includes its public key
  * the client private key

the EAP-TLS client needs to be able to validate the radius server
certificate, therefore the client needs the CA file (ca.pem).
the client of course also needs its own certificate with
private/public key pair, in order to identify itself and encrypt
traffic

Now, if you look at the contents of client.pem, you will see it
contains both the client public key and private key. You can leave
these in one file, or you can split them apart and put them into two
separate .pem files. If you choose the first method, then a bare-bones
configuration file looks like this:

# WPA2-EAP/CCMP using EAP-TLS
ctrl_interface=/var/run/wpa_supplicant
network={
        key_mgmt=WPA-EAP
        identity="myusername"
        proto=WPA2
        eap=TLS
        ca_cert="/tmp/clients/ca.pem
        private_key="/tmp/clients/client.p12"
        private_key_passwd="xxxxx"
}

Notice two things: first, eapol_test is smart enough to look at the
private key file and realize that it also contains the client
certificate, and is able to parse it out and deal with it correctly.
Secondly, notice that I'm using the p12 file instead of the pem file.
For some reason this doesn't work with the pem file, even though it
contains the same information, just in a different format.

If instead you want to split the client cert and private key, you can
use separate pem files as follows:
# WPA2-EAP/CCMP using EAP-TLS
ctrl_interface=/var/run/wpa_supplicantnetwork={
        key_mgmt=WPA-EAP
        identity="myusername"
        proto=WPA2
        eap=TLS
        ca_cert="/tmp/clients/ca.pem"
        client_cert="/tmp/clients/clientcertpem"
        private_key="/tmp/clients/clientkey.pem"
#      private_key="/tmp/clients/client.key"
        private_key_passwd="xxxxx"
}

Or you can even use the "key" file as shown above. The "identity" is
required, but it can be any arbitrary string. This shows up as the
radius 'User-Name' attribute. At first I was thinking this would have
to match the commonName of the client certificate, but it turns out it
doesn't.

To test from any machine where you have eapol_test installed:
./eapol_test -c /tmp/conffile -a<radius server ip> -s<secret> -o
/tmp/eap_cert.out

Take a look at /tmp/eap_cert.out. It should contain both the CA cert
and the Radius server cert, which means your client successfully
downloaded these certs across the wire.

If you are issuing client certs yourself, you can use the above
procedure. Or if the client prefers to keep their private key private
then they can generate their own CSR, give the csr to you, you can use
"openssl ca" to generate and sign their cert and hand it back to them.
-- 
---
Michael Martinez
http://www.michael--martinez.com


More information about the Freeradius-Users mailing list