Authenticating VPN Users with FreeRADIUS
Fond of Simple
If you're new to RADIUS then the following configuration won't seem simple, but I think it is reduced enough to actually understand. I discovered by accident that man of the queries can be cut out of the SQL config altogether.
In this instance this service is only acting as a backup for one of our customers, so I placed the configuration under their user account and start it under rc.local listening on it's own IP.
radiusd -d /home/customer1/etc/raddb -l /home/customer1/var/log \
-a /home/customer1/var/log/radacct -y
radiusd.conf
There are two useful schemes that can be used for PAP: clear and crypt. If you set encryption_scheme to clear then plain passwords will work, otherwise you need to encode passwords with DES. One way to do this is to use Apache's htpasswd to build a list and then copy it into your database.
My users table looks like this:
> select * from vpn_users; id | username | password ----+----------+--------------- 1 | eric | sHuZgk2W607ZA 2 | laura | shJFKECSp027c
prefix = /usr
home = /home/customer1
exec_prefix = ${prefix}
sysconfdir = ${home}/etc
localstatedir = ${prefix}/var
sbindir = ${exec_prefix}/sbin
logdir = ${home}/var/log
raddbdir = ${sysconfdir}/raddb
radacctdir = ${logdir}
confdir = ${raddbdir}
run_dir = ${localstatedir}/run/radiusd
log_file = ${logdir}/radius.log
libdir = /usr/lib
pidfile = ${home}/var/run/radiusd.pid
user = customer1
group = users
max_request_time = 30
delete_blocked_requests = no
cleanup_delay = 5
max_requests = 512
bind_address = 10.23.0.1
port = 1645
hostname_lookups = no
allow_core_dumps = no
log_stripped_names = yes
log_auth = yes
log_auth_badpass = yes
log_auth_goodpass = yes
usercollide = no
wer_user = no
lower_pass = no
nospace_user = no
nospace_pass = no
security {
max_attributes = 200
reject_delay = 1
status_server = yes
}
proxy_requests = no
$INCLUDE ${confdir}/clients.conf
thread pool {
start_servers = 1
max_servers = 2
min_spare_servers = 1
max_spare_servers = 1
max_requests_per_server = 1
}
modules {
preprocess {
hints = ${confdir}/hints
}
pap {
encryption_scheme = crypt
md5 {
}
}
$INCLUDE ${confdir}/postgresql.conf
hints = ${confdir}/hints
}
pap {
encryption_scheme = crypt
md5 {
}
}
$INCLUDE ${confdir}/postgresql.conf
always fail {
rcode = fail
}
always reject {
rcode = reject
}
always ok {
rcode = ok
}
}
authorize {
preprocess
sql
}
authenticate {
Auth-Type PAP {
pap
}
}
postgresql.conf
When searching discussion groups it appears that everyone plases the attribute and op fields in the database, but there's no reason to do this in my applications, so I simple select a string and use AS to title the field.
sql {
driver = "rlm_sql_postgresql"
server = "localhost"
login = "customer1"
password = "password#"
radius_db = "site1"
authcheck_table = "vpn_users"
authreply_table = "vpn_users"
deletestalesessions = yes
sqltrace = yes
sqltracefile = ${logdir}/sqltrace.sql
num_sql_socks = 1
sql_user_name = "%{Stripped-User-Name:-%{User-Name:-none}}"
authorize_check_query = "SELECT id, username, \
'Crypt-Password' AS attribute, password, \
'==' AS op \
FROM ${authcheck_table} \
WHERE username = '%{SQL-User-Name}'"
authorize_reply_query = "SELECT id, username, \
'Crypt-Password' AS attribute, \
password, '==' AS op \
FROM ${authreply_table} \
WHERE username = '%{SQL-User-Name}'"
}
Cisco Changes
On the Cisco PIX/ASA you probably have inside, outside and perhaps dmz configured as your interfaces. Use the appropriate interface for launching RADIUS queries.
aaa-server RADIUS protocol radius aaa-server clientnet protocol radius aaa-server clientnet (inside) host 10.23.0.1 mysharedsecret timeout 10
References
GNU Radius IBM developerWorks
Build a RADIUS server on Linux
Outbound RADIUS AAA Sample Configuration Guide for Cisco Secure ACS and PIX Firewall
Cisco - PIX Configuration basics altoHiway Knowledge Base