Skip to content

Latest commit

 

History

History
301 lines (211 loc) · 9.35 KB

802.1xOnOpenWRTUsingFreeRadius.md

File metadata and controls

301 lines (211 loc) · 9.35 KB

OpenWRT : 802.1x EAP-TLS using Free Radius & OpenSSL CA

This is a quick guide on setting up certificate-based wireless 802.1x authentication on OpenWRT with FreeRADIUS and generating certificates on a desktop PC with OpenSSL Demo CA, using decent cryptographic configuration : strong curves & strong cipher suite list.

This guide could easily be adapted to use EAP-TTLS+EAP-TLS which was my initial intent, but most of the client UIs (Android, iOS, Windows, NetworkManager, etc.) do not propose EAP-TLS authentication when chosing EAP-TTLS connection.
At the time of this writing, the current version of OpenWRT is 'Barrier Breaker/14.07' and will use this as a reference, future versions should require simliar configuration with minimal modifications.

  1. Initial OpenWRT configuration

Make sure you have all the OpenWRT's source repositories available in your /etc/opkg.conf file.

src/gz barrier_breaker_base http://downloads.openwrt.org/barrier_breaker/14.07/ar71xx/generic/packages/base
src/gz barrier_breaker_luci http://downloads.openwrt.org/barrier_breaker/14.07/ar71xx/generic/packages/luci
src/gz barrier_breaker_packages http://downloads.openwrt.org/barrier_breaker/14.07/ar71xx/generic/packages/packages
src/gz barrier_breaker_oldpackages http://downloads.openwrt.org/barrier_breaker/14.07/ar71xx/generic/packages/oldpackages

dest root /
dest ram /tmp
lists_dir ext /var/opkg-lists
option overlay_root /overlay

And update your sources :

$ opkg update

Replace wpad-mini with wpad :

$ opkg remove wpad-mini
$ opkg install wpad

Update the installed OpenSSL version (this should be done regularly anyways):

$ opkg install openssl-util libopenssl

Install the FreeRADIUS packages.

$ opkg install freeradius2 freeradius2-common freeradius2-democerts freeradius2-mod-always freeradius2-mod-attr-filter freeradius2-mod-attr-rewrite freeradius2-mod-chap freeradius2-mod-detail freeradius2-mod-eap freeradius2-mod-eap-gtc freeradius2-mod-eap-md5 freeradius2-mod-eap-mschapv2 freeradius2-mod-eap-peap freeradius2-mod-eap-tls freeradius2-mod-eap-ttls freeradius2-mod-exec freeradius2-mod-expiration freeradius2-mod-expr freeradius2-mod-files freeradius2-mod-logintime

$ opkg install freeradius2-mod-mschap freeradius2-mod-pap freeradius2-mod-passwd freeradius2-mod-preprocess freeradius2-mod-radutmp freeradius2-mod-realm freeradius2-mod-sql freeradius2-mod-sql-pgsql freeradius2-mod-sql-sqlite freeradius2-mod-sqlcounter freeradius2-mod-sqllog freeradius2-utils
  1. Creating the EC CA

On your Desktop PC use your already-installed OpenSSL (if not, install it using your preferred distro's package manager).

This will create your root key, so make sure the directory you're working in is not world readable and the PC you're using is somewhat trustworthy.

You will need to chose a CN/Organization Name for your Root CA and for your subsequent certificates.

First, generate key curve parameters, as a curve reference for later OpenSSL commands:

$ openssl ecparam -out ecca.param -name secp384r1

Then generate your CA's EC Root key:

$ openssl req -nodes -newkey ec:ecca.param -days 3650 -x509 -sha256 -keyout ecca.key -out ecca.crt

Generate the server's own EC key:

$ openssl req -nodes -newkey ec:ecca.crt -days 3650 -sha256 -keyout serverec.key -out serverec.csr

Then, in order to use the OpenSSL Demo CA, you need to create the directory architecture for it and initialize the serial number to 01 for the first signed certificate :

$ mkdir ./demoCA/
$ mkdir ./demoCA/newcerts
$ touch ./demoCA/index.txt
$ echo 01 > ./demoCA/serial

Using OpenSSL's demo CA, sign your server's key with your Root CA key :

$ openssl ca -extensions v3_ca -days 3650 -out serverec.crt -in serverec.csr -cert ecca.crt -keyfile ecca.key

When the signing operation is complete, do verify your certificate's content using :

$ openssl x509 -in serverec.crt -text

You can also combine your Root CA key & self-signed certificate in a .pem format, but it's not necessarily mandatory :

$ cat ecca.crt ecca.key > ecca.pem

The same goes for the server's key signed with the EC Root CA's key :

$ cat serverec.crt serverec.key > serverec.pem
  1. Configure FreeRADIUS on OpenWRT

First you will probably need to make sure the certificate directory exists.

$ mkdir /etc/freeradius/certs

Then SCP the necessary files over to your /etc/freeradius/certs directory, namely the ca.crt file and the server.pem bundle file.

The configuration can now be modified, starting with the eap.conf file :

eap {
    ...

    default_eap_type = tls # Use EAP-TLS

    ...

    tls {
        ...
	
	private_key_password = # Empty since we did not specify one at creation in OpenSSL
        private_key_file = ${certdir}/server.pem
        certificate_file = ${certdir}/server.pem
        CA_file = ${cadir}/ca.pem
        dh_file = ${certdir}/dh2048.pem # Not really needed since we'll use ECDHE only

	# Decent Cipher Suite List, taken from 
	# https://github.com/ouaibe/duraconf/blob/master/configs/nginx/nginx.COMPAT_MEDIUM_SECURITY.conf
        cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA256:ECDHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;"

	random_file = /dev/urandom # Be careful of not chosing a non-blocking random source

	# This selects the strongest curve available 
	ecdh_curve = "secp384r1"
	
        ...
	verify {

		tmpdir = /tmp/radiusd # Used for caching

		# Set the right command to verify client certificate.
		client = "/usr/bin/openssl verify -CAfile /etc/freeradius2/certs/ca.pem  %{TLS-Client-Cert-Filename}"
                                                                                      
		}
	}

    ...

}

Then we will modify radiusd.conf to add the right listening parameters :

listen {
        type = auth
        ipaddr = 127.0.0.1
        port = 0
        interface = lo
}

In order to configure the security between the AP and FreeRADIUS locally on the router, first generate a long password, it can be done on your desktop PC using the following command :

$ apg -a 1 -m 60 -x 60 -E \'\"\`

And use one of the chosen passwords in your clients.conf file :

client localhost {
	secret = <long_pw> # <-- Password goes here, without quotes
	ipaddr = 127.0.0.1
	require_message_authenticator = yes
	nastype = other                                     
}

Then you need to create the authenticator logic for this site, first of all create the localhost site :

$ touch /etc/freeradius2/sites/localhost

And add the following configuration lines :

authorize {
	preprocess
	auth_log
	eap {
		ok = return
	}

	expiration
	logintime
}

authenticate {
	eap
}

preacct {
	preprocess
	suffix
	files
}

session {
	radutmp
}

post-auth {
	exec
	Post-Auth-Type REJECT {
		attr_filter.access_reject
	}
}

Finally, edit the radiusd startup script (/etc/init.d/radiusd), replace or comment out the line radiusd -i $IPADDR -p 1812,1813 $OPTIONS with radiusd $OPTIONS and add the following line :

mkdir -p /tmp/radiusd                    

** WARNING ** This is something you might need to re-do when updating the freeradius package on OpenWRT (since updates might replace the startup script with the original one).

  1. Configure OpenWRT in 802.1x

Edit the /etc/config/wireless file, and chose the right authentication mode :

config wifi-iface
        option device 'radio0'
        option mode 'ap'
        option network 'lan'
        option ssid '<YOUR_SSID>'
        option encryption 'wpa2+ccmp'
        option auth_server '127.0.0.1' # <-- Same IP as clients.conf/radiusd.conf
        option auth_secret '<long_pw>' # <-- Same long pw as clients.conf

Finally, you can test your config for mistakes/errors, manually starting radiusd as follows :

$ radiusd -XX

Errors are usually pretty self-explanatory, but be ready to pop wireshark if need be...

  1. Manage Client Certs.

Since we're still waiting for let's encrypt we'll have to manage clients certificates by hand using OpenSSL's bundled Demo CA (not production ready).

Don't forget to copy your self-signed ecca.crt file to your different clients that need a client certificate to authenticate.

Create certificates for each client using the following OpenSSL Demo CA commands :

$ openssl req -nodes -newkey ec:ecca.crt -days 3650 -sha256 -keyout CLIENT.key -out CLIENT.csr
$ openssl ca -extensions v3_ca -days 3650 -out CLIENT.crt -in CLIENT.csr -cert ecca.crt -keyfile ecca.key

Sometimes (Android) you will need to bundle the client certificate in P12 format, use the following command to do so :

$ openssl pkcs12 -export -in CLIENT.crt -inkey CLIENT.key -out CLIENT.p12 -certfile ecca.crt

Sources / interesting notes : http://www.blog.10deam.com/2015/01/08/install-freeradius2-on-a-openwrt-router-for-eap-authentication/

http://blog.epijunkie.com/2013/12/freebsd-freeradius2-eap-tls-ssl-admin-a-wpa2-enterprise-guide/

https://fossjon.wordpress.com/2013/12/30/finally-able-to-run-my-own-wpa2-aes-eap-ttls-freeradius-server-raspi/

http://blog.packetheader.net/2009/06/8021x-peap-dance.html