/dev/null proxy accounting while proxy sink is unresponsive
jared r r spiegel
jrrs at ice-nine.org
Wed Nov 16 00:54:58 CET 2011
hi.
thanks for freeradius. we converted from Radiator to freeradius and
were able to halve the size of our radius cluster while still handling
more load.
we're using multiple detail files defined in radiusd.conf, which
then sites-enabled/default defines as redundant-load-balance, so
accounting gets written to them round-robin by freeradius.
then we have another sites-enabled/ "site" defining multiple
servers each listen to one of the accounting files and Proxy-To-Realm
them to a realm which is defined in proxy.conf.
the realm in proxy.conf has home_servers and home_server_pools
defined for multiple different realms, each sending to different
proxy sinks. some sinks are just one host, some are multiple.
this all works pretty much great, except when a proxy-sink fails to
ACK the accounting we send it (thus being seen as dead or zombie).
there are a small number of cases where we would love it if we could just
/dev/null this proxy accounting if the remote server is dead/zombie,
however i haven't figured out a way to actually configure this.
it seems like i want to use a "fallback" server in the home_server_pool,
where that fallback server would just 'ok' accounting or otherwise toss it
in the trash, but after a few iterations of trying to make this work
i have come up empty handed.
if anyone can help, i'd be enormously grateful.
here are the sanitized configs.
so for example, i'd like to add a virtual server to the
'home_server_pool proxy-whatever' that would toss the accounting from the
detail file into /dev/null for whatever period of fime site-1 and site-2
were dead/zombie.
[proxy.conf]
------------------------------------------------------------------------------
# $Id: proxy.conf 34303 2011-10-26 20:31:34Z jrrs $
# This entry controls the behavior towards ALL other servers we proxy
# requests to.
proxy server {
# Never, ever fall back to the DEFAULT realm when no
# home servers are alive for a given ream.
default_fallback = no
}
home_server proxy-whatever01-site-1 {
type = acct
ipaddr = 1.1.1.1
port = 1845
secret = "zz"
status_check = none
response_window = 10
}
home_server proxy-whatever01-site-2 {
type = acct
ipaddr = 2.2.2.2
port = 1845
secret = "zz"
status_check = none
response_window = 10
}
home_server_pool proxy-whatever {
type = fail-over
home_server = proxy-whatever01-site-1
home_server = proxy-whatever01-site-2
}
realm proxy-whatever {
acct_pool = proxy-whatever
nostrip
}
[sites-enabled/default]
# $Id: default 34587 2011-11-15 22:45:31Z jrrs $
authorize {
preprocess
update request {
Client-IP-Address := "%{Client-IP-Address}"
}
chap
mschap
suffix
perl
switch "%{Auth-Type}" {
case 'sql.auth.wifi.site3' {
redundant {
sql.auth.wifi.site2
sql.auth.wifi.site1
}
}
case 'sql.auth.wifi.site2' {
redundant {
sql.auth.wifi.site2
sql.auth.wifi.site1
}
}
case 'sql.auth.wifi.site1' {
redundant {
sql.auth.wifi.site1
sql.auth.wifi.site2
}
}
}
pap
}
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
Auth-Type ldap.site3 {
redundant {
ldap.site3
ldap.site2
ldap.site1
}
}
Auth-Type ldap.site2 {
redundant {
ldap.site2
ldap.site1
ldap.site3
}
}
Auth-Type ldap.site1 {
redundant {
ldap.site1
ldap.site2
ldap.site3
}
}
}
preacct {
perl
}
accounting {
perl
redundant-load-balance {
detail.proxy-whatever0
detail.proxy-whatever1
detail.proxy-whatever2
detail.proxy-whatever3
detail.proxy-whatever4
}
attr_filter.accounting_response
}
session {
}
post-auth {
Post-Auth-Type REJECT {
sql.authlog
attr_filter.access_reject
}
}
pre-proxy {
}
post-proxy {
if ("%{proxy-reply:Packet-Type}" == "Access-Accept") {
attr_filter.post-proxy
}
}
[sites-enabled/proxy-tee]
# $Id: proxy-tee 34011 2011-10-18 02:35:39Z jrrs $
server buffered-proxy-whatever0 {
listen {
type = detail
filename = ${radacctdir}/proxy-whatever0
load_factor = 100
}
preacct {
if ("%{%{#User-Name}:-0}" <= 63 && "%{User-Name}" != "@") {
attr_filter.proxy_whatever
update control {
Proxy-To-Realm := "proxy-whatever"
}
}
}
accounting {
ok
}
}
server buffered-proxy-whatever1 {
listen {
type = detail
filename = ${radacctdir}/proxy-whatever1
load_factor = 100
}
preacct {
if ("%{%{#User-Name}:-0}" <= 63 && "%{User-Name}" != "@") {
attr_filter.proxy_whatever
update control {
Proxy-To-Realm := "proxy-whatever"
}
}
}
accounting {
ok
}
}
server buffered-proxy-whatever2 {
listen {
type = detail
filename = ${radacctdir}/proxy-whatever2
load_factor = 100
}
preacct {
if ("%{%{#User-Name}:-0}" <= 63 && "%{User-Name}" != "@") {
attr_filter.proxy_whatever
update control {
Proxy-To-Realm := "proxy-whatever"
}
}
}
accounting {
ok
}
}
server buffered-proxy-whatever3 {
listen {
type = detail
filename = ${radacctdir}/proxy-whatever3
load_factor = 100
}
preacct {
if ("%{%{#User-Name}:-0}" <= 63 && "%{User-Name}" != "@") {
attr_filter.proxy_whatever
update control {
Proxy-To-Realm := "proxy-whatever"
}
}
}
accounting {
ok
}
}
server buffered-proxy-whatever4 {
listen {
type = detail
filename = ${radacctdir}/proxy-whatever4
load_factor = 100
}
preacct {
if ("%{%{#User-Name}:-0}" <= 63 && "%{User-Name}" != "@") {
attr_filter.proxy_whatever
update control {
Proxy-To-Realm := "proxy-whatever"
}
}
}
accounting {
ok
}
}
server buffered-proxy-whatever-catchup {
listen {
type = detail
filename = ${radacctdir}/proxy-whatever-catchup
load_factor = 100
}
preacct {
if ("%{%{#User-Name}:-0}" <= 63 && "%{User-Name}" != "@") {
attr_filter.proxy_whatever
update control {
Proxy-To-Realm := "proxy-whatever"
}
}
}
accounting {
ok
}
}
[radiusd.conf]
------------------------------------------------------------------------------
# -*- text -*-
##
## radiusd.conf -- FreeRADIUS server configuration file.
##
## http://www.freeradius.org/
## $Id: radiusd.conf.in,v 1.272 2008/04/26 15:14:33 aland Exp $
##
prefix = /usr
exec_prefix = /usr
sysconfdir = /etc
localstatedir = /var
sbindir = ${exec_prefix}/sbin
logdir = /var/log/freeradius
raddbdir = /etc/freeradius
radacctdir = ${logdir}/radacct
confdir = ${raddbdir}
run_dir = ${localstatedir}/run/freeradius
db_dir = ${raddbdir}
libdir = /usr/lib/freeradius
pidfile = ${run_dir}/freeradius.pid
user = freerad
group = freerad
max_request_time = 30
cleanup_delay = 5
max_requests = 131072
listen {
type = auth
ipaddr = *
port = 0
}
listen {
ipaddr = *
port = 0
type = acct
}
hostname_lookups = no
allow_core_dumps = no
regular_expressions = yes
extended_expressions = yes
log syslog {
destination = syslog
syslog_facility = daemon
stripped_names = no
auth = no
auth_badpass = no
auth_goodpass = no
}
checkrad = ${sbindir}/checkrad
security {
max_attributes = 200
reject_delay = 0
status_server = yes
}
proxy_requests = yes
$INCLUDE proxy.conf
$INCLUDE clients.conf
thread pool {
start_servers = 32
max_servers = 160
min_spare_servers = 16
max_spare_servers = 32
max_requests_per_server = 0
}
modules {
pap {
auto_header = no
}
chap {
authtype = CHAP
}
mschap {
}
ldap ldap.site3 {
server = "ldap.pool.example.com ldap.site3.example.com"
identity = "cn=Radiusd,o=example"
password = "xx"
basedn = "o=nonexistent"
ldap_connections_number = 3
timeout = 6
timelimit = 5
net_timeout = 1
dictionary_mapping = ${confdir}/ldap.attrmap
password_attribute = userPassword
}
ldap ldap.site2 {
server = "ldap.pool.example.com ldap.site2.example.com"
identity = "cn=Radiusd,o=example"
password = "xx"
basedn = "o=nonexistent"
ldap_connections_number = 3
timeout = 6
timelimit = 5
net_timeout = 1
dictionary_mapping = ${confdir}/ldap.attrmap
password_attribute = userPassword
}
ldap ldap.site1 {
server = "ldap.pool.example.com ldap01.vip.example.com ldap02.vip.example.com"
identity = "cn=Radiusd,o=example"
password = "xx"
basedn = "o=nonexistent"
ldap_connections_number = 3
timeout = 6
timelimit = 5
net_timeout = 1
dictionary_mapping = ${confdir}/ldap.attrmap
password_attribute = userPassword
}
perl {
module = /etc/freeradius/IT_group.pm
func_authorize = authorize
func_preacct = preacct
func_accounting = accounting
max_clones = 160
start_clones = 32
min_spare_clones = 16
max_spare_clones = 32
cleanup_delay = 5
max_request_per_clone = 0
}
realm suffix {
format = suffix
delimiter = "@"
}
preprocess {
}
detail detail.proxy-whatever0 {
detailfile = ${radacctdir}/proxy-whatever0
detailperm = 0640
header = "%t"
}
detail detail.proxy-whatever1 {
detailfile = ${radacctdir}/proxy-whatever1
detailperm = 0640
header = "%t"
}
detail detail.proxy-whatever2 {
detailfile = ${radacctdir}/proxy-whatever2
detailperm = 0640
header = "%t"
}
detail detail.proxy-whatever3 {
detailfile = ${radacctdir}/proxy-whatever3
detailperm = 0640
header = "%t"
}
detail detail.proxy-whatever4 {
detailfile = ${radacctdir}/proxy-whatever4
detailperm = 0640
header = "%t"
}
sql_log sql.authlog {
path = "${logdir}/failedauth/%Y%m%d-%H"
Post-Auth = "%l %{NAS-IP-Address} %{%{reply:Reply-Message}:-%{Module-Failure-Message}} %{User-Name} %{%{User-Password}:-%{Chap-Password}}"
}
sql sql.acct {
database = "mysql"
driver = "rlm_sql_${database}"
server = "write.sql.example.com"
login = "radiusd"
password = "yy"
radius_db = "radius"
acct_table = "ACCOUNTING"
sqltrace = no
sqltracefile = ${logdir}/sqltrace.sql
num_sql_socks = 5
connect_failure_retry_delay = 5
lifetime = 0
max_queries = 0
sql_user_name = "%{User-Name}"
accounting_start_query = " \
INSERT INTO ${acct_table} ( \
USERNAME, TIME_STAMP, ACCTSTATUSTYPE, ACCTDELAYTIME, \
ACCTINPUTOCTETS, ACCTOUTPUTOCTETS, ACCTSESSIONID, \
ACCTSESSIONTIME, ACCTTERMINATECAUSE, NASIP, NASPORT, \
FRAMEDIPADDRESS, CALLED_STATION, CALLING_STATION \
) VALUES( \
'%{SQL-User-Name}', '%l', '%{Acct-Status-Type}', \
'%{Acct-Delay-Time}', '%{Acct-Input-Octets}', \
'%{Acct-Output-Octets}', '%{Acct-Session-Id}', \
'%{Acct-Session-Time}', '%{Acct-Terminate-Cause}', \
'%{NAS-IP-Address}', '%{NAS-Port}', \
'%{Framed-IP-Address}', '%{Called-Station-Id}', \
'%{Calling-Station-Id}');"
accounting_stop_query = " \
INSERT INTO ${acct_table} ( \
USERNAME, TIME_STAMP, ACCTSTATUSTYPE, ACCTDELAYTIME, \
ACCTINPUTOCTETS, ACCTOUTPUTOCTETS, ACCTSESSIONID, \
ACCTSESSIONTIME, ACCTTERMINATECAUSE, NASIP, NASPORT, \
FRAMEDIPADDRESS, CALLED_STATION, CALLING_STATION \
) VALUES( \
'%{SQL-User-Name}', '%l', '%{Acct-Status-Type}', \
'%{Acct-Delay-Time}', '%{Acct-Input-Octets}', \
'%{Acct-Output-Octets}', '%{Acct-Session-Id}', \
'%{Acct-Session-Time}', '%{Acct-Terminate-Cause}', \
'%{NAS-IP-Address}', '%{NAS-Port}', \
'%{Framed-IP-Address}', '%{Called-Station-Id}', \
'%{Calling-Station-Id}')"
}
sql sql.auth.wifi.site2 {
database = "mysql"
driver = "rlm_sql_${database}"
server = "3.3.3.3"
login = "radiusd"
password = "yy"
num_sql_socks = 3
connect_failure_retry_delay = 60
radius_db = "backend"
authcheck_table = "wifi_users"
authreply_table = "wifi_users"
sqltrace = no
sqltracefile = ${logdir}/sqltrace.sql
sql_user_name = "%{User-Name}"
authorize_check_query = " \
SELECT NULL as id, \
'%{SQL-User-Name}' as username, \
'Cleartext-Password' AS attribute, \
userPassword AS value, \
':=' AS op \
FROM ${authcheck_table} \
WHERE uid = '%{SQL-User-Name}'"
authorize_reply_query = " \
SELECT NULL as id, \
'%{SQL-User-Name}' as username, \
'Whatever-Service-Bundle' AS attribute, \
serviceType AS value, \
':=' AS op \
FROM ${authcheck_table} \
WHERE uid = '%{SQL-User-Name}'"
}
sql sql.auth.wifi.site1 {
database = "mysql"
driver = "rlm_sql_${database}"
server = "authread.sql.example.com"
login = "radiusd"
password = "yy"
num_sql_socks = 3
connect_failure_retry_delay = 60
radius_db = "backend"
authcheck_table = "wifi_users"
authreply_table = "wifi_users"
sqltrace = no
sqltracefile = ${logdir}/sqltrace.sql
sql_user_name = "%{User-Name}"
authorize_check_query = " \
SELECT NULL as id, \
'%{SQL-User-Name}' as username, \
'Cleartext-Password' AS attribute, \
userPassword AS value, \
':=' AS op \
FROM ${authcheck_table} \
WHERE uid = '%{SQL-User-Name}'"
authorize_reply_query = " \
SELECT NULL as id, \
'%{SQL-User-Name}' as username, \
'Whatever-Service-Bundle' AS attribute, \
serviceType AS value, \
':=' AS op \
FROM ${authcheck_table} \
WHERE uid = '%{SQL-User-Name}'"
}
attr_filter attr_filter.pre-proxy {
attrsfile = ${confdir}/attrs.pre-proxy
}
attr_filter attr_filter.post-proxy {
attrsfile = ${confdir}/attrs.post-proxy
}
attr_filter attr_filter.access_reject {
key = %{User-Name}
attrsfile = ${confdir}/attrs.access_reject
}
attr_filter attr_filter.accounting_response {
key = %{User-Name}
attrsfile = ${confdir}/attrs.accounting_response
}
attr_filter attr_filter.proxy_whatever {
key = "DEFAULT"
attrsfile = ${confdir}/attrs.proxy_whatever
}
always ok {
rcode = ok
}
}
$INCLUDE sites-enabled/
--
jared
More information about the Freeradius-Users
mailing list