Freeradius replacing Cisco ACS in an Active Directory Environment (Wifi PEAP+MSCHAP and other uses)
George Shearer
george at theshearerfamily.com
Tue Feb 2 21:00:28 CET 2010
Ugh. Please ignore my previous post to the list, gmail 'plain text' mode ate
most of the message.
All, this is my attempt at giving back to the freeradius community. Maybe
others will find my configuration useful in their efforts.
I'm a network guy, and I do quite a bit of consulting work for
various companies. I have a customer in particular who (prior to this)
wasusing a very out-of-date Cisco ACS Server, and couldn't afford
the renewal/licensing fees to bring it uptodate. They are using Microsoft's
Active Directory on Windows Server 2000 as the primary database for all
identities/passwords.
The goals of this configuration are:
1. Provide AAA for administrative access to network devices (mostly, SSH
access to Cisco routers/switches/firewalls)
2. Provide AAA for 802.11 WLAN users who are using Windows XP and "Wireless
Zero" clients. (Cisco 1231 series access points)
3. Provide AAA for VPN Users who use cisco Secure VPN client from remote
locations (cisco 3000 series concentrators)
The freeradius server itself will run on a CentOS 5.4 Linux box. The company
doesn't like "make install" application installs (nor do I), so I simply
grabbed the SRPM from the Fedora project's KOJI build server for the latest
freeradius, and built it. This process is outside the scope of this
particular posting, as I want to focus on Freeradius itself.
The Fedora spec file builds multiple binary packages that you can install
based on what you want to do with freeradius. These are the packages I'm
using:
freeradius-utils-2.1.8-2
freeradius-2.1.8-2
freeradius-ldap-2.1.8-2
The company has one Active Directory forest, and one subdomain. Users exist
under both. So, for this configuration, we'll call the primary zone
COMPANY.COM and SUB.COMPANY.COM <http://SUB.COMPANY.COM>. Both domains must
be queried for authorization & authentication. The following rules apply for
access:
1. User must exist within the AD forest. (as defined by my LDAP
search parameters)
2. User must be a member of a particular group (defined by the Users file)
for certain types of access:
a) For administrative access to network device, the user must be a member
of the group networkteam.
b) Access to use the VPN, user must be a member of the group vpnusers.
c) Access to the Wireless network, user must be a member of group
wifiusers.
VPN and Network-Admin users achieve both Authorization and Authentication
using nothing more than the rlm_ldap module. Wireless users do not use ldap
at all, but instead, they use the eap and mschap modules. The mschap module
is configured to use ntlm_auth which requires samba's winbind to be
configured on the backend.
It took me some time (and I will not admit how much time) to figure out how
to make this all work. I blame most of this on the fact that freeradius has
been around a long time, and as result there's lots of obsolete
documentation out there for google to find. I believe this configuration
uses mostly uptodate syntax, however I'm always interested in advice on
improvements.
Interestingly, this process gave me quite a case of dejavu. I wrote a
combination tacacs/radius server WAY back when the Livingston Portmaster 2
series was king of dialup. Many sers on the livingston mailing list used my
source code. This really made me feel old. :(
Anyway, on to the good stuff:
Annoyances:
1. Cisco does not support command accounting via Radius. Only Tacacs. Why?
They want you to buy ACS ! Sorry Cisco, I love ya, but.. cmon!
2. Cisco PIX/ASA do not support radius for command authorization. So, you
have to type 'enable' and your AD account password AGAIN.
3. Cisco 1231-series access points running IOS 12.3(8)JED or earlier do not
include NAS-Port-Type in subsequent password attempts for SSH access. So,
you only get one shot at typing your password right when you SSH for admin
access into a WAP. It'll ask you for your password again, and it'll try to
get approval from your Radius server, however, it will not include the port
type in the request. So freeradius will not classify the request in the
proper huntgroup. Unfortunately, you may think you just keep fat fingering
your password, so you just keep trying. This will eventually get your AD
account locked and you'll have to bug the windows guys to re-enable it. :)
4. Cisco 3000 platform does not support AAA for admin access.. again, only
with tacacs. I know, I know, this platform is OLD, but... you have to admit,
it has to be one of the most reliable platforms cisco has ever sold. It's
hard to say goodbye.
radiusd.conf
---------------------------------------------------------------------------------------------
# freeradius config for a typical company using Active Directory for
password management
# George Shearer (doc at lame dot org)
# Primary uses:
# 1. AAA for admin access to network devices (ldap)
# 2. AAA for user access to 802.11 Wireless Networks (WPA2-Enterprise /
EAP-PEAP / EAP-MSCHAPv2)
# 3. AAA for remote user access to VPN (ldap)
name = radiusd
# Locations
prefix = /usr
exec_prefix = /usr
sysconfdir = /etc
localstatedir = /var
sbindir = /usr/sbin
logdir = ${localstatedir}/log/radius
raddbdir = ${sysconfdir}/raddb
radacctdir = ${logdir}/radacct
confdir = ${raddbdir}
run_dir = ${localstatedir}/run/${name}
db_dir = ${raddbdir}
libdir = /usr/lib/freeradius
pidfile = ${run_dir}/${name}.pid
# Security
#chroot = /path/to/chroot/directory
user = radiusd
group = radiusd
security {
max_attributes = 200
reject_delay = 1
status_server = yes
}
# Network
hostname_lookups = yes
proxy_requests = no
listen {
type = auth
ipaddr = ip-addr-of-eth0
port = 1812
}
listen {
type = acct
ipaddr = ip-addr-of-eth0
port = 1813
}
listen {
type = control
socket = ${run_dir}/${name}.sock
mode = ro
}
# Performance
max_request_time = 10
cleanup_delay = 5
max_requests = 1024
allow_core_dumps = no
regular_expressions = yes
extended_expressions = yes
thread pool {
start_servers = 5
max_servers = 15
min_spare_servers = 3
max_spare_servers = 5
max_requests_per_server = 0
}
# Logging
log {
destination = syslog
syslog_facility = authpriv
stripped_names = no
auth = yes
auth_badpass = yes
auth_goodpass = no
}
# freeradius modules
modules {
# Create unique acct ID's per session -- so tell network devices to
use common id's and let radiusd handle
acct_unique {
key = "User-Name, Acct-Session-Id, NAS-IP-Address,
Client-IP-Address, NAS-Port"
}
preprocess {
huntgroups = ${confdir}/huntgroups
}
detail {
detailfile = ${radacctdir}/%{Huntgroup-Name}/detail-%Y%m%d
detailperm = 0600
header = "%t"
}
files {
usersfile = ${confdir}/users
acctusersfile = ${confdir}/acct_users
compat = no
}
ldap {
server = "ip-addr-of-domain-contoller"
port = 3268
# Global Catalog port not LDAP. This allows combined searches of both
SUB.MYCOMPANY.COM and MYCOMPANY.COM
identity = "CN=myqueryacct,OU=System
Accounts,DC=mycompany,DC=com"
password = "mypassword"
basedn = "DC=mycompany,DC=com"
filter =
"(&(objectCategory=person)(sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}}))"
groupname_attribute = "cn"
groupmembership_filter =
"(&(objectClass=group)(member=%{control:Ldap-UserDn}))"
groupmembership_attribute = memberOf
ldap_connections_number = 3
timeout = 4
timelimit = 3
net_timeout = 1
directory_mappings = ${confdir}/ldap.attrmap
}
eap {
default_eap_type = peap
timer_expire = 60
max_sessions = 500
ignore_unknown_eap_types = no
tls {
cert_dir = ${confdir}/certs
rsa_key_length = 2048
dh_key_length = 2048
private_key_password = password-for-my-encrypted-key
private_key_file =
${cert_dir}/combined-cert-and-key-file.pem
certificate_file = ${private_key_file}
CA_file = ${cert_dir}/my-ca-cert-file.pem
dh_file = ${cert_dir}/dh
random_file = ${cert_dir}/random
fragment_size = 1024
include_length = yes
cipher_list = "DEFAULT"
cache {
enable = yes
lifetime = 24
max_entries = 500
}
}
peap {
default_eap_type = mschapv2
}
mschapv2 {
}
}
mschap {
use_mppe = yes
require_encryption = yes
require_strong = yes
with_ntdomain_hack = yes
ntlm_auth = "/usr/bin/ntlm_auth --request-nt-key
--username=%{%{mschap:User-Name}:-None}
--domain=%{%{mschap:NT-Domain}:-EDLENDING}
--challenge=%{%{mschap:Challenge}:-00}
--nt-response=%{%{mschap:NT-Response}:-00}
--require-membership-of=wifiusers"
}
radutmp {
filename = ${logdir}/radutmp
username = %{%{Stripped-User-Name}:-%{User-Name}}
case_sensitive = yes
check_with_nas = yes
perm = 0600
}
realm ntdomain {
format = prefix
delimiter = "\\"
}
}
instantiate {
}
authorize {
preprocess
eap {
ok = return
updated = return
}
# The eap {} stuff above prevents your ldap server from being used for
wireless users. Since we handle this via ntlm, no need to bug ldap.
# also, the ntdomain stuff isnt even needed because the mschap module has
variables to do the stripping built in..
ntdomain
files
ldap
}
authenticate {
Auth-Type LDAP {
ldap
}
Auth-Type MS-CHAP {
mschap
}
eap
}
preacct {
preprocess
update request {
NAS-Port = 1
# Cisco ASA's annoyingly do not include NAS-Port for administrative logins.
This breaks radwho. The
# above statement forces Nas-Port to be '1' if it doesn't already exist.
}
ntdomain
acct_unique
}
accounting {
detail
radutmp
}
session {
radutmp
}
# Realms (domains)
realm MYCOMPANY {
authhost = LOCAL
accthost = LOCAL
type = radius
}
realm SUB {
authhost = LOCAL
accthost = LOCAL
type = radius
}
realm NULL {
authhost = LOCAL
accthost = LOCAL
type = radius
realm = MYCOMPANY
}
# Include our clients
$INCLUDE clients.conf
---------------------------------------------------------------------------------------------
huntgroups
# All devices that network-admins want to log into for administrative access
# Cisco sends "Virtual" for type on most things I've tried for SSH access
network-admin NAS-IP-Address == ipaddr1, NAS-Port-Type == "Virtual"
network-admin NAS-IP-Address == ipaddr2, NAS-Port-Type == "Virtual"
network-admin NAS-IP-Address == ipaddr3, NAS-Port-Type == "Virtual"
network-admin NAS-IP-Address == ipaddr4, NAS-Port-Type == "Virtual"
# Cisco 1200 series WAPs
# Since I handle AAA for wireless via ntlm_auth (not LDAP), this group isnt
even necessary
# However you could expand upon my config and use this group to create a
seperate
# accounting file, or various other uses.
wireless NAS-IP-Address == ipaddr1, NAS-Port-Type ==
"Wireless-802.11"
wireless NAS-IP-Address == ipaddr2, NAS-Port-Type ==
"Wireless-802.11"
wireless NAS-IP-Address == ipaddr3, NAS-Port-Type ==
"Wireless-802.11"
# Cisco 3000 Concentrators
# These also send "VirtuaL" as type for users connecting via IPsec.
Unfortunately,
# the 3000 platform does not support radius AAA for administrative access
:(
vpn NAS-IP-Address == ipaddr1, NAS-Port-Type == "Virtual"
vpn NAS-IP-Address == ipaddr2, NAS-Port-Type == "Virtual"
---------------------------------------------------------------------------------------------
users
# this 'locally managed' account matches the same account thats in the local
configs on the devices
# various scripts use this account for things like downloading configs or
whatever. And its not in
# active directory. It also has a limited security level.
admin Huntgroup-Name == "network-admin", Cleartext-Password :=
"localadminaccountpw"
Service-Type := NAS-Prompt-User,
cisco-avpair := "shell:priv-lvl=2"
# This drops all users who are a member of the 'networkteam' group right
into an "enabled" prompt
# Unfortunately, PIX/ASA's do not support this cisco-avpair on Radius, so
you'll still type 'enable'
# but when you're asked for a password, you'll give your AD account password
again as opposed to
# the real enable password. The only time you should need the real enable
password for any device
# is when the radius server is down
DEFAULT Huntgroup-Name == "network-admin", Ldap-Group ==
"networkteam"
Service-Type := NAS-Prompt-User,
cisco-avpair := "shell:priv-lvl=15",
Auth-Type := LDAP
DEFAULT Huntgroup-Name == "vpn", Ldap-Group == "vpnusers"
Auth-Type := LDAP
DEFAULT Auth-Type := Reject
Reply-Message := "Access Denied. Your attempt has been
logged.",
---------------------------------------------------------------------------------------------
Cisco IOS based device config: (relevant parts, anyway)
aaa new-model
aaa authentication login networkteam group radius local-case
aaa authentication login wifi-access group radius
aaa authorization exec default group radius local
aaa accounting session-duration ntp-adjusted
aaa accounting exec default start-stop group radius
aaa accounting network default start-stop group radius
aaa session-id common
!
! Obviously you dont need the wireless stuff for non-access points
dot11 ssid OURSSID
authentication open eap wifi-access
authentication key-management wpa
accounting default
!
! The "accounting-default" statement is what causes IOS to send accounting
packets for that SSID
radius-server host my-radius-server auth-port 1812 acct-port 1813 key
myradiuskey
!
line con 0
login authentication networkteam
line vty 0 15
login authentication networkteam
---------------------------------------------------------------------------------------------
Cisco ASA/PIX config:
username admin password whatever
aaa-server radius protocol radius
max-failed-attempts 3
aaa-server radius (INSIDE) host my-radius-server
timeout 3
key slxradkey2010
authentication-port 1812
accounting-port 1813
aaa authentication ssh console radius LOCAL
aaa authentication enable console radius LOCAL
aaa authentication serial console radius LOCAL
aaa authentication telnet console radius LOCAL
aaa authentication http console radius LOCAL
aaa accounting ssh console radius
aaa accounting telnet console radius
aaa accounting serial console radius
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freeradius.org/pipermail/freeradius-users/attachments/20100202/28fd2823/attachment.html>
More information about the Freeradius-Users
mailing list