SMUS Wireless Configuration: Difference between revisions
(→EAP) |
|||
Line 589: | Line 589: | ||
=== EAP === | === EAP === | ||
Now configure EAP to use the certificate along with other parameters. | |||
sudo vi /etc/freeradius/eap.conf | |||
Inside the eap block, set the following: | |||
default_eap_type = peap | |||
Inside the eap/tls block, set the following: | |||
private_key_password = | |||
private_key_file = ${certdir}/<server_name>.key | |||
certificate_file = ${certdir}/<server_name>.crt | |||
Inside the eap/tls/cache block, set the following: | |||
enable = yes | |||
lifetime = 4 # hours | |||
max_entries = 1000 | |||
=== Radius Accounting === | === Radius Accounting === |
Revision as of 12:29, 17 November 2011
Introduction
This page will discuss the backend for the SMUS wireless configuration.
Prerequisites
Our requirements for wireless on campus are fairly complex. We decided on several prerequisites, for a variety of reasons.
802.1x
We wanted staff and students to be able to sign into the wireless system themselves without any help from the MIS department. Several implementations use a captive portal mechanism to do this, but that results in an SSID with no encryption. By using 802.1x, we can use WPA2-Enterprise encryption on the SSIDs, and staff and students can still configure the connection themselves.
Active Directory Integration
Wherever possible, we have staff and students use their active directory credentials to log into whatever they're trying to access. We wanted this system to also use the active directory credentials. The AD server had preexisting groups we wanted to take advantage of as well, and we added more groups later to further separate out our users.
Different Student and Staff IP addresses
Students on our campus are subject to bandwidth limitations and packet shaping. We do not want to apply these restrictions to staff members. Our packet shaper uses a simple IP range to track which machines to apply restrictions to, so we needed our students to be assigned a different set of IP addresses than our staff.
VLANs for mobile labs
Our mobile laptop labs also need different IP ranges. As we have a senior and middle school, we apply different web filtering to each set of computers. We achieved this using VLAN assignments in freeradius after the machines logged in, based on a regular expression check on the computer name.
Single simultaneous login for students
Our students are limited to one simultaneous wireless connection. This is to discourage password sharing (one student using another student's account will then stop the original student from being able to log in). As different grades have different access times, we didn't want grade 12 students sharing their credentials to students in lower grades. This is also potentially a bandwidth saving measure, as a single student can't have their iPod, iPhone, computer, etc. clogging up the same access point simultaneously. Again, these restrictions do not apply to staff.
Login times by grade
We apply different login hours by grade. Grade 12s can use the wireless longer into the evening than grade 11s, which can use it longer than grade 10s, etc.
Guest logins
As there are frequently parents and other guests on campus, we wanted it to be fairly simple for them to get their wireless device onto our network. These devices are sometimes not as secure as other devices, so they are separated out onto their own network, and we check their computers for up-to-date antivirus protection through a captive portal before allowing them to login. Antivirus protection is not checked on smartphones and similar devices, only full computers.
Software Used
We use a combination of Freeradius (to do radius authentication and accounting), and Samba (for active directory integration) on the backend. The wireless access points are configured using the Meraki cloud controller, although other wifi systems can also tap into the same radius configuration (we tested with Dlink access points as well). Whatever wifi system is selected must support 802.1x authentication through WPA2-Enterprise encryption, as well as radius accounting packets (to track simultaneous logins).
Simultaneous logins are tracked using a MySQL database, although it should also be possible to use Postgres as Freeradius supports it. The automated scripts we run would need to be modified slightly to support Postgres.
Bug-free support for the functions we're using arrived recently to Samba and Freeradius, and older versions definitely don't work properly. We are running Debian 6 with the stock versions of all packages. We were previously running Ubuntu 10.04 and the versions included there did not work. Freeradius 2.1.10 and Samba 3.5.6 are included with Debian 6, so those are the recommended versions.
Our VLANs are routed through a PFSense 2.0.0 virtual machine. This VM can apply firewalls to any combination of subnet connections, and has good performance for the throughput we need. Routing and firewalling can also be done through a dedicated router.
Hardware Used
Our radius server runs as a VMWare ESXi 5.0 virtual machine. It has a single virtual processor (2.53 GHz) with 256 MB of ram. This is more than sufficient to handle our incoming connections. Our MySQL database server, which handles many other databases as well, has 4 virtual processors and 3 GB of ram.
We use Meraki MR16 access points.
Clients we have successfully authenticated on this network include Windows XP, Vista, and 7; Mac OS X; Android, Blackberry, and iOS smartphones; etc. Through MAC address whitelisting, we have also put other devices onto the guest network.
Samba Configuration
Samba must be installed and the Linux machine must be joined to the active directory domain before radius can do NTLM authentication.
sudo apt-get install samba winbind smbclient krb5-user sudo vi /etc/krb5.conf
- Ensure default realm is set to your active directory DNS name (ours is SMUS.LOCAL)
- Under realms, add a section:
SMUS.LOCAL = { kdc = <domain controller DNS name> kdc = <backup domain controller DNS name> admin_server = <domain controller DNS name> }
- Now test that your Kerberos settings are correct
sudo kinit Administrator
- Enter your domain administrator password, and if it comes back without any errors you've set up Kerberos correctly
- Now configure Samba
sudo vi /etc/samba/smb.conf
- Change workgroup to your active directory short name (Ours is "SMUSLOCAL")
- Uncomment "security = user" and change to "security = ads"
- Immediately underneath, add the following lines:
password server = <domain controller DNS name>
Now join the Active Directory domain:
sudo net ads join -U Administrator
Then restart Samba and Winbind so that you can authenticate against the AD domain:
sudo /etc/init.d/smbd stop; sudo /etc/init.d/nmbd stop; sudo /etc/init.d/winbind stop sudo /etc/init.d/smbd start; sudo /etc/init.d/nmbd start; sudo /etc/init.d/winbind start
Freeradius Configuration
Installation
sudo apt-get install freeradius freeradius-ldap freeradius-mysql
- Allow the freerad user access to query winbind
sudo adduser freerad winbindd_priv
Clients
We must set up clients that are allowed to authenticate via radius. We have set up one client definition for senior/middle school Meraki access points, another definition for junior school Meraki access points, and a several definitions for the Meraki cloud controller, which does the guest authentication.
client <ip range>/24 { secret = <radius secret> shortname = meraki_ap nastype = other } client <ip range>/24 { secret = <radius secret> shortname = meraki_jr_ap nastype = other } client 64.156.192.220/32 { secret = <radius secret> shortname = meraki_cloud1 nastype = other } client 64.156.192.245/32 { secret = <radius secret> shortname = meraki_cloud2 nastype = other } client 74.50.51.16/32 { secret = <radius secret> shortname = meraki_cloud3 nastype = other } client 74.50.53.101/32 { secret = <radius secret> shortname = meraki_cloud4 nastype = other }
Policies
Add each of these policies under /etc/freeradius/policy.conf
Require_staff Policy
This ensures that the Huntgroup-Name variable is set when we actually authenticate the user later.
require_staff { update request { Huntgroup-Name := "<staff group name>" } }
Require_student Policy
This ensures that the Huntgroup-Name variable is set when we actually authenticate the user later. We also update any replies to indicate that the student's session timeout is 5 minutes to force them to reauthenticate every 5 minutes.
require_student { update request { Huntgroup-Name := "<student group name>" } update reply { Session-Timeout = 300 } }
Require_guest Policy
Guests are authenticated differently because they are not doing 802.1x EAP/MSCHAP authentication. Instead, they use NTLM authentication (a username and hashed password). We will set up the auth module later.
require_guest { update request { Huntgroup-Name := "<guest group name>" } update control { Auth-Type := "ntlm_auth_guest" } }
Single_login Policy
This just adds a check to ensure that the user only has one device on at a time. We haven't configured how to check that yet, but we must have a policy in place before the next steps.
single_login { update control { Simultaneous-Use := 1 } }
Logintime Policy
In the require_student policy, we also place an LDAP group check to see what times the user should be allowed to log in. Here is the full require_student policy after adding the LDAP group checks. Note that the Huntgroup-Name group check is done through the active directory login, and so supports recursive group checking, but the LDAP group checks do not support recursive group checking.
require_student { update request { Huntgroup-Name := "<student group name>" } if (Ldap-Group == "Grade 12 Board") { # special group, 6 AM - 12 AM Su - Th, 6 AM - 1 AM (next day) Fr - Sa update control { Login-Time := "Su0600-0100,Mo0600-0000,Tu0600-0000,We0600-0000,Th0600-0000,Fr0600-0000,Sa0600-0100" } } elsif (Ldap-Group == "Grade 11 Board") { # special group, 6 AM - 11 PM Su - Th, 6 AM - 12 AM Fr - Sa update control { Login-Time := "Su0600-2300,Mo0600-2300,Tu0600-2300,We0600-2300,Th0600-2300,Fr0600-0000,Sa0600-0000" } } elsif (Ldap-Group == "Grade 10 Board") { # special group, 6 AM - 10:30 PM Su - Th, 6 AM - 11:30 PM Fr - Sa update control { Login-Time := "Su0600-2230,Mo0600-2230,Tu0600-2230,We0600-2230,Th0600-2230,Fr0600-2330,Sa0600-2330" } } else { # default group, 6 AM - 10 PM daily update control { Login-Time := "All0600-2200" } } update reply { Session-Timeout = 300 } }
Special_vlan Policy
When we authenticate computers, we also check to see if the machine should go onto a special VLAN. We check computer names for the computer lab VLANs, and we also check which access point they're binding to to check for Junior School machines, which are assigned different VLANs as they are a separate campus.
check_special_vlan { if ("%{User-Name}" =~ /N7-MIDD-205-/i) { update reply { Tunnel-Private-Group-ID = 50 Tunnel-Type = "VLAN" Tunnel-Medium-Type = "IEEE-802" } } if ("%{User-Name}" =~ /N7-MIDD-CAR-/i) { update reply { Tunnel-Private-Group-ID = 50 Tunnel-Type = "VLAN" Tunnel-Medium-Type = "IEEE-802" } } if ("%{User-Name}" =~ /N7-SCHO-CAR-/i) { update reply { Tunnel-Private-Group-ID = 51 Tunnel-Type = "VLAN" Tunnel-Medium-Type = "IEEE-802" } } if ("%{User-Name}" =~ /N7-SCHO-LIB-/i) { update reply { Tunnel-Private-Group-ID = 51 Tunnel-Type = "VLAN" Tunnel-Medium-Type = "IEEE-802" } } if ("%{Client-Shortname}" == "meraki_jr_ap") { # authenticating from JR school, change up the VLAN numbers if ("%{Huntgroup-Name}" == "<student group name>") { # was going to be on student VLAN, put on JR student VLAN update reply { Tunnel-Private-Group-ID = 204 Tunnel-Type = "VLAN" Tunnel-Medium-Type = "IEEE-802" } } else { # otherwise put on JR staff VLAN update reply { Tunnel-Private-Group-ID = 200 Tunnel-Type = "VLAN" Tunnel-Medium-Type = "IEEE-802" } } } }
Virtual Hosts
We use virtual hosts so that there are different radius servers available to authenticate staff, students, and guests.
sudo vi /etc/freeradius/radiusd.conf
- Comment out all of the listen blocks, as we will be setting these up for each virtualhost
- Now set up your virtualhosts
cd /etc/freeradius/sites-available cp default staff cp default student cp default guest cd /etc/freeradius/sites-enabled rm default ln -s ../sites-available/staff . ln -s ../sites-available/student . ln -s ../sites-available/guest .
Staff Virtual Host
sudo vi /etc/freeradius/sites-enabled/staff
- Set the server alias to "server staff" rather than "server default"
- Add a listen block immediately under "server staff {"
- The port is set to 0 as that makes it the default (1812 for radius and 1813 for accounting)
- Note that the staff server handles the radius accounting for all IP addresses, but you can configure them separately if desired
listen { port = 0 type = auth ipaddr = <ip address> } listen { port = 0 type = acct ipaddr = * }
- Update the authorize block so that it has the following items:
preprocess require_staff suffix eap { ok = return } files
- Update the authentication block so that it has the following items:
eap
- Update the preacct block so that it has the following items:
preprocess acct_unique suffix
- Update the accounting block so that it has the following items:
sql attr_filter.accounting_response
- Update the session block so that it has the following items:
sql
- Update the post-auth block so that it has the following items:
check_special_vlan exec Post-Auth-Type REJECT { attr_filter.access_reject }
- Update the post-proxy block so that it has the following items:
eap
Student Virtual Host
sudo vi /etc/freeradius/sites-enabled/student
- Set the server alias to "server student" rather than "server default"
- Add a listen block immediately under "server student {"
- The port is set to 0 as that makes it the default (1812 for radius and 1813 for accounting)
listen { port = 0 type = auth ipaddr = <ip address> }
- Update the authorize block so that it has the following items:
preprocess ldap require_student single_login suffix eap { ok = return } files expiration logintime
- Update the authentication block so that it has the following items:
eap
- Comment out the preacct and accounting blocks, as they are not used
- Update the session block so that it has the following items:
sql
- Update the post-auth block so that it has the following items:
check_special_vlan exec Post-Auth-Type REJECT { attr_filter.access_reject }
- Update the post-proxy block so that it has the following items:
eap
Guest Virtual Host
sudo vi /etc/freeradius/sites-enabled/guest
- Set the server alias to "server guest" rather than "server default"
- Add a listen block immediately under "server guest {"
- The port is set to 0 as that makes it the default (1812 for radius and 1813 for accounting)
listen { port = 0 type = auth ipaddr = <ip address> }
- Update the authorize block so that it has the following items:
preprocess require_guest suffix eap { ok = return } files
- Update the authentication block so that it has the following items:
ntlm_auth_guest
- Comment out the preacct and accounting blocks as they are not used
- Update the session block so that it has the following items:
sql
- Update the post-auth block so that it has the following items:
check_special_vlan exec Post-Auth-Type REJECT { attr_filter.access_reject }
- Update the post-proxy block so that it has the following items:
eap
Inner-Tunnel Virtual Host
The inner-tunnel vhost should already be mostly set up, as it's generally included with Freeradius' default configuration. If it's not, symlink it from the sites-available:
sudo ln -s /etc/freeradius/sites-available/inner-tunnel /etc/freeradius/sites-enabled
Now start editing:
sudo vi /etc/freeradius/sites-enabled/inner-tunnel
- Update the authorize block so that it has the following items:
chap mschap suffix update control { Proxy-To-Realm := LOCAL } eap { ok = return } files expiration logintime pap
- Update the authentication block so that it has the following items. Note that if mschap authentication fails (this means that the user isn't a member of the huntgroup we set earlier), we also check whether mschap_computers authenticates the user correctly.
Auth-Type PAP { pap } Auth-Type CHAP { chap } Auth-Type MS-CHAP { mschap { reject = 2 } if (reject) { mschap_computers } } unix eap
- Comment out the accounting, preacct, and session blocks, as they are not used
- Update the post-auth block so that it has the following items:
Post-Auth-Type REJECT { attr_filter.access_reject }
- Update the post-proxy block so that it has the following items:
eap
Certificates
We need to generate a CSR and get a real certificate for this server. Here are the steps from memory, so they may not be 100% correct.
cd /etc/freeradius/certs openssl req -out <server_name>.csr -new -newkey rsa:2048 -nodes -keyout <server_name>.key
Now send the CSR to a certificate authority and get it signed. If the CA uses a certificate chain, you need to put all of the certificates into one file, with the server's certificate at the top, then the CA that signed that cert, then the next CA up the chain, etc. Upload the resulting certificate file as <server_name>.crt .
EAP
Now configure EAP to use the certificate along with other parameters.
sudo vi /etc/freeradius/eap.conf
Inside the eap block, set the following:
default_eap_type = peap
Inside the eap/tls block, set the following:
private_key_password = private_key_file = ${certdir}/<server_name>.key certificate_file = ${certdir}/<server_name>.crt
Inside the eap/tls/cache block, set the following:
enable = yes lifetime = 4 # hours max_entries = 1000