View Full Version : HOWTO: WPA2-Enterprise with FreeRadius
bbzz
December 21st, 2011, 20:20
In this tutorial you will be able to successfully set up a home wireless network using FreeBSD and WPA2-Enterprise option on your wireless router. Notably, you will be able to use certificate based authentication to secure communication between your devices.
There are a couple of solid tutorials out there which show you how to do this (just google). Unfortunately I wasn't able to successfully set up a network following a single one only, and most of them seem to miss some critical information, notably, how to set up certificate revocation list.
So, I will do a small write-up on how I managed to do it (i.e. an amalgam of all them together).
There are no real reasons to set up a certificate based home network - a strong WPA2 password on your router will do as much for security with no hassle whatsoever. This is overkill if there was ever one. On the other hand, if you think this is cool and want this kind of security in your network, then you might benefit from this tutorial.
In this setup you will have wireless devices authenticate via wireless router to FreeBSD server running FreeRadius.
Before you begin, make sure your router is able to pass authentication requests with WPA2-Enterprise option. Most if not all new routers should have this option.
All of this is done on FreeBSD 9-RC3, but it can be done on earlier versions provided openssl and freeradius2 implementations don't differ (that, you will have to check).
bbzz
December 21st, 2011, 20:22
SETTING UP KEYS
---------------------
I will use openssl to create three pieces: CA, server key pair, and clients' key pairs.
Make a directory where you will be generating keys. I used root's home dir, but you can use any:
cd ~
mkdir .certs
mkdir .certs/CA
mkdir .certs/CA/private
mkdir .certs/new
mkdir .certs/crl
mkdir .certs/export
Then copy openssl config file to this dir:
cd .certs
cp /etc/ssl/openssl.cfg .
Open this copied file and edit following lines:
...
36 [ CA_default ]
37
38 dir = /root/.certs # Where everything is kept
39 certs = $dir # Where the issued certs are kept
40 crl_dir = $dir/crl # Where the issued crl are kept
41 database = $dir/index.txt # database index file.
42 #unique_subject = no # Set to 'no' to allow creation of
43 # several ctificates with same subject.
44 new_certs_dir = $dir/new # default place for new certs.
45
46 certificate = $dir/CA/cacert.pem # The CA certificate
47 serial = $dir/serial # The current serial number
48 crlnumber = $dir/crlnumber # the current crl number
49 # must be commented out to leave a V1 CRL
50 crl = $dir/crl.pem # The current CRL
51 private_key = $dir/CA/private/cakey.pem# The private key
52 RANDFILE = $dir/private/.rand # private random number file
...
101 [ req ]
102 default_bits = 2048
At the end of file add lines for Windows compatibility:
...
315 [ xpclient_ext ]
316 extendedKeyUsage = 1.3.6.1.5.5.7.3.2
317
318 [ xpserver_ext ]
319 extendedKeyUsage = 1.3.6.1.5.5.7.3.1
Create index file which will keep list of all issued/revoked certs:
touch index.txt
Optionally create serial file to specify starting numbering for new certificates:
echo '1001 ' > serial
Now, we will create CA we need to sign other public keys:
openssl req -new -x509 -extensions v3_ca -keyout CA/private/cakey.pem -out CA/cacert.pem -config ./openssl.cnf
You will be prompted for password for private key. You will need this password every time you want to sign other keys. You will also be presented with a series of different entries which will be saved in certificate. Most of these are not important, just use whatever you think it's appropriate. When asked for "Common Name" enter "CA". You should use different Common Name for each certificate in the future (eg. server, FreeBSD_laptop, etc).
You have just created cacert.pem and cakey.pem.
Windows platform can't read certificates in .pem format. Windows needs .der format for CA. To "export" out our cacert.pem use:
openssl x509 -inform PEM -outform DER -in CA/cacert.pem -out export/cacert.der
Additionally, my phone can only read certificates in .p12 format, so we again export .pem, now to .p12:
openssl pkcs12 -export -in CA/cacert.pem -inkey CA/private/cakey.pem -out export/cacert.p12 -cacerts
When converting to .p12 format, you will be prompted for CA private key password you already set up in previous step, and then asked to set export password which is password you will enter on device (in my case phone) when installing CA.
These are just different format containers that have same information as original .pem file.
Remember we do this because all clients need access to CA in order to compare the validity of public key signatures.
Next, create server keys:
openssl req -new -keyout new/server_key.pem -out new/server_req.pem -config openssl.cnf -nodes
Sign and create certificate:
openssl ca -out new/server_cert.pem -infiles new/server_req.pem -config ./openssl.cnf -extensions xpserver_ext
Next, let's create two key pairs for out FreeBSD and Windows7 hosts:
openssl req -new -keyout new/FreeBSD_laptop_key.pem -out new/FreeBSD_laptop_req.pem -config ./openssl.cnf
openssl req -new -keyout new/Windows_laptop_key.pem -out new/Windows_laptop_req.pem -config ./openssl.cnf
Again, to make these public keys valid certificates we sign them with CA:
openssl ca -out new/FreeBSD_laptop_cert.pem -infiles new/FreeBSD_laptop_req.pem -config ./openssl.cnf
openssl ca -out new/Windows_laptop_cert.pem -infiles new/Windows_laptop_req.pem -config ./openssl.cnf -extensions xpclient_ext
Notice additional x509 extension flag we used for windows based host key, as well as for server key.
Additionally, for windows host we need to export client certificate to .p12 format:
openssl pkcs12 -export -in newcerts/Windows_laptop_cert.pem -inkey newcerts/Windows_laptop_key.pem -out export/Windows_laptop_cert.p12 -clcerts
You will be prompted for password used to create this host's key pair, and then you will setup export password you'll need when you install this certificate on windows host. You don't need to enter password, but it's recommended you do; you'll only need to enter it once, when you install keys.
Note that I didn't create a key pair for my phone since it doesn't support EAP-TLS and client certificates. It will use other password-based authentication, but it will still need CA in .p12 format.
Certificate Revocation List
--------------------------------
If you ever need to revoke a certificate before it expires by itself (and the way I created all certificates and CA will expire in one year from moment they are created), you need to let radius server known where to look for. After lots of digging I managed to find solution described here (http://sites.google.com/site/techbobbins/home/articles/freeradius-and-crls), as the documentation on this is lacking.
At this point you don't have any certificates you need to revoke, but create the list anyway, it will make sense later. To create the revocation list use:
openssl ca -gencrl -keyfile CA/private/cacert.key -cert CA/cacert.pem -out crl/crl.pem -config ./openssl.cnf
Copy keys and certs
-------------------------
Copy server keys, CA, and crl list to new location (I like /var/db/certs):
mkdir /var/db/certs
cp CA/cacert.pem new/server_cert.pem new/server_key.pem crl/crl.pem /var/db/certs
Finally, create new file which will hold both CA and revoked certificates:
cd /var/db/certs
cat cacert.pem crl.pem > cacrl.pem
Copy cacert.der and Windows_laptop_cert.p12 from ~/.certs/export directory to your Windows laptop.
Copy cacert.pem, FreeBSD_laptop_cert.pem and FreeBSD_laptop_key.pem to your FreeBSD laptop (or Mac, it's same format).
Additionally, I copy cacert.p12 to my phone.
bbzz
December 21st, 2011, 20:23
INSTALLING RADIUS
------------------------
Use ports to compile from sources:
cd /usr/ports/net/freeradius2 && make install clean
or, download from packages:
pkg_add -r freeradius2
Make copy of installation dir in case you need to revert to original configuration files:
cp -Rvp /usr/local/etc/raddb /usr/local/etc/raddb.orig
Finally, create Diffie-Hellman and random crypto nounce file, both needed for secure communication:
cd /var/db/certs
dd if=/dev/urandom of=random count=2
openssl dhparam -check -text -5 1024 -out dh
Configuring radius
------------------
Default options for radiusd.conf are ok. The ones I changed myself:
Make radius listen on specific address only:
...
273 ipaddr = 192.168.2.254
...
316 ipaddr = 192.168.2.254
...
Increase number of potential clients (n * 256):
...
224 max_requests = 2560
...
Number of seconds trying to authenticate client:
...
186 max_request_time = 30
...
Next, open up clients.conf and add at the end:
client 192.168.2.2 {
secret = super_secret_sauce
shortname = MyWireless_AP
nastype = other
}
A radius "client" is your router which will pass authentication requests to server. Client IP is therefore IP of your router; a "secret" is password you will enter on your router; "shortname" is for logging, and leave your router as "nastype" other, appropriately.
Open up users file and add at the end:
FreeBSD_laptop
Windows_laptop
MyPhone Cleartext-Password := "PHEr33k#@_!.sS2!$"
DEFAULT Auth-type := Reject
Reply-Message := "Weak sauce, try harder..."
Users are actual clients.Server is smart enough to figure out what method client is using to authenticate. In first two cases clients are using certificates so there's no need to add anything. Last client uses password based authentication.
Finally, open eap.conf:
...
17 eap {
18 # Invoke the default supported EAP type when
19 # EAP-Identity response is received.
20 #
21 # The incoming EAP messages DO NOT specify which EAP
22 # type they will be using, so it MUST be set here.
23 #
24 # For now, only one default EAP type may be used at a time.
25 #
26 # If the EAP-Type attribute is set by another module,
27 # then that EAP type takes precedence over the
28 # default type configured here.
29 #
30 default_eap_type = tls
...
151 tls {
152 #
153 # These is used to simplify later configurations.
154 #
155 certdir = /var/db/certs
156 cadir = /var/db/certs
157
158 #private_key_password = whatever
159 private_key_file = ${certdir}/server_key.pem
160
161 # If Private key & Certificate are located in
162 # the same file, then private_key_file &
163 # certificate_file must contain the same file
164 # name.
165 #
166 # If CA_file (below) is not used, then the
167 # certificate_file below MUST include not
168 # only the server certificate, but ALSO all
169 # of the CA certificates used to sign the
170 # server certificate.
171 certificate_file = ${certdir}/server_cert.pem
172
173 # Trusted Root CA list
174 #
175 # ALL of the CA's in this list will be trusted
176 # to issue client certificates for authentication.
177 #
178 # In general, you should use self-signed
179 # certificates for 802.1x (EAP) authentication.
180 # In that case, this CA file should contain
181 # *one* CA certificate.
182 #
183 # This parameter is used only for EAP-TLS,
184 # when you issue client certificates. If you do
185 # not use client certificates, and you do not want
186 # to permit EAP-TLS authentication, then delete
187 # this configuration item.
188 CA_file = ${cadir}/cacrl.pem
189
190 #
191 # For DH cipher suites to work, you have to
192 # run OpenSSL to create the DH file first:
193 #
194 # openssl dhparam -out certs/dh 1024
195 #
196 dh_file = ${certdir}/dh
197 random_file = ${certdir}/random
...
227 check_crl = yes
...
262 # Set this option to specify the allowed
263 # TLS cipher suites. The format is listed
264 # in "man 1 ciphers".
265 cipher_list = "HIGH"
...
Notice line 188 where the pointer is to file containing both CA and crl, not just CA, and line 227 where we enable crl checking.
This pretty much covers radius configuration. You can do some "hardening" if you want, but keep in mind it's your home network...
chown -R freeradius:freeradius /var/db/certs
chmod 0400 /var/db/certs/*.pem
chmod 0600 /var/db/certs/dh
chmod 0600 /var/db/certs/random
Update your /etc/rc.conf with
radiusd_enable="YES"
At this point run your radius server with:
radiusd -X
If everything went right, you should see debug saying that server is now ready and listening. Otherwise, read up on errors. make install clean[/CMD]
bbzz
December 21st, 2011, 20:25
SETTING UP CLIENTS
-------------------------
With server now ready, all that is left is to install certificates and authentication method on clients.
1) FreeBSD host (EAP-TLS)
Edit your /etc/wpa_supplicant.conf file like so:
network={
ssid="Unbreakable"
proto=RSN
key_mgmt=WPA-EAP
eap=TLS
identity="FreeBSD_laptop"
ca_cert="/var/db/certs/cacert.pem"
client_cert="/var/db/certs/FreeBSD_laptop_cert.pem"
private_key="/var/db/certs/FreeBSD_laptop_key.pem"
private_key_passwd="wickedPa55"
}
Just like on server, I copied my certs on /var/db/certs.
Identity must match entry in users file on server that you configured.
Private key is a password you entered when you created your key pair for this host.
2) FreeBSD host (EAP-PEAP)
Configuration for EAP-TTLS and EAP-PEAP is similar (consult handbook (http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/network-wireless.html) it's all there). Lets say you want certs-less setup with EAP-PEAP. Then you would enter:
network={
ssid="Unbreakable"
proto=RSN
key_mgmt=WPA-EAP
eap=PEAP
identity="FreeBSD_laptop"
password="supersecret"
ca_cert="/var/db/certs/cacert.pem"
phase1="peaplabel=0"
phase2="auth=MSCHAPV2"
}
Notice that this time we only have CA we need to check for server authentication. We use password for our credentials - make sure users is updated properly. phase1 && phase2 specify communication inside tunnel.
That is what I would use on my phone since it doesn't support client certificates. I would copy cacert.p12 to phone root dir, install, and the rest is easy.
2) Windows host (EAP-TLS)
Windows needs CA in .der format and client cert in .p12 which contains both public/private key.
First, double click on cacert.der, confirm you want to install, and when prompted where to install, select "Place all certificates in the following store" and browse into "Trusted Root Certification Authorities".
Next, install .p12 cert, this time choosing different location for your client cert. Other options should be self explanatory.
Done! You can now delete .pem and .p12 files.
A word on CRL
----------------
When you want to revoke a certificate, you need to update your crl file, and notify radius (you must restart it). You need this every time you want to revoke a cert. I'm not aware of other easier methods to do this. Since this is your home network, you wouldn't do this often anyway, unless something bad happens (eg. your phone gets stolen).
To revoke a cert:
cd ~/.certs
openssl ca -revoke new/Windows_laptop.pem -keyfile CA/private/cacert.key -cert CA/cacert.pem -config ./openssl.cnf
Now, take a moment and open ~/.certs/index.txt and you should see "R" next to cert index number. If you ever need to make this cert valid again, you would edit
line with "R" to match other certs format.
Now you need to create crl list again, just like it was done at the beginning of tutorial:
openssl ca -gencrl -keyfile CA/private/cacert.key -cert CA/cacert.pem -out crl/crl.pem -config ./openssl.cnf
Finally, concatenate this file with original CA file:
cp crl/crl.pem /var/db/certs
cd /var/db/certs
cat cacert.pem crl.pem > cacrl.pem
/usr/local/etc/rc.d/radiusd restart
You must restart radius, updating crl file is not enough.
Final words
--------------
So there you go, I hope this helps at least one person.
Let me know of any errors you find.
vBulletin® v3.8.7, Copyright ©2000-2012, vBulletin Solutions, Inc.