Hi there, We've got FreeRADIUS Version 1.1.4, for host i386-portbld-freebsd5.5 using unixodbc/freetds connecting to a mssql DB. I've got a number of questions that I hope someone can answer. 1. If the user is found in the sql tables and has reply attributes etc, is it still possible to go through the 'users' file? if so how? I can't seem to get it to do it. 2. Is there an ability in any way to have a caching like feature or is DB failover and running 2 db servers with replication the only way to go? 3. Is there anyway to log the actual reason for rejection in 'Post-Auth-Type REJECT'? ie simultaneous use, invalid password etc? Cheers in Advance for any help. cya Andrew
Andrew D wrote:
1. If the user is found in the sql tables and has reply attributes etc, is it still possible to go through the 'users' file? if so how? I can't seem to get it to do it.
Yes, it's possible. The modules are completely independent, so you just configure both. In fact, if you just uncomment the "sql" entries in the default radiusd.conf, the server will do that. Or, try reading the FAQ for what information is needed in situations where "it doesn't work".
2. Is there an ability in any way to have a caching like feature or is DB failover and running 2 db servers with replication the only way to go?
Cache... what?
3. Is there anyway to log the actual reason for rejection in 'Post-Auth-Type REJECT'? ie simultaneous use, invalid password etc?
Module-Failure-Message often contains the reason, but not always. Alan DeKok. -- http://deployingradius.com - The web site of the book http://deployingradius.com/blog/ - The blog
Alan DeKok wrote:
Andrew D wrote:
1. If the user is found in the sql tables and has reply attributes etc, is it still possible to go through the 'users' file? if so how? I can't seem to get it to do it.
Yes, it's possible. The modules are completely independent, so you just configure both. In fact, if you just uncomment the "sql" entries in the default radiusd.conf, the server will do that.
Which it does, but doesn't work like I would expect it to, with the examples given in the docs. huntgroup file test NAS-IP-ADDRESS == some.ip testbad NAS-IP-ADDRESS == some.ip Group = suspend or test NAS-IP-ADDRESS == some.ip testbad NAS-IP-ADDRESS == some.ip, Group == suspend users file DEFAULT Group == "suspend" Framed-IP-Address := 172.16.32.0+, Session-Timeout := 600, Port-Limit := 1 DEFAULT Huntgroup-Name == "testbad" Framed-IP-Address := 172.16.32.0+, Session-Timeout := 600, Port-Limit := 1 DEFAULT Huntgroup-Name == "test" Port-Limit := 1, Fall-Through = 1 a quick snip from radiusd -X radius_xlat: 'SELECT radgroupreply.id,radgroupreply.GroupName,radgroupreply.Attribute,radgroupreply.Value,radgroupreply.op FROM radgroupreply,usergroup WHERE usergroup.Username = 'awd' AND usergroup.GroupName = radgroupreply.GroupName ORDER BY radgroupreply.id' rlm_sql (sql): Released sql socket id: 4 modcall[authorize]: module "sql" returns ok for request 0 users: Matched entry DEFAULT at line 26 users: Matched entry DEFAULT at line 43 users: Matched entry DEFAULT at line 61 modcall[authorize]: module "files" returns ok for request 0 modcall: leaving group authorize (returns ok) for request 0 rad_check_password: Found Auth-Type CHAP auth: type "CHAP" Processing the authenticate section of radiusd.conf modcall: entering group CHAP for request 0 rlm_chap: login attempt by "awd" with CHAP password rlm_chap: Using clear text password start for user awd authentication. It skips the 2 default entries before Huntgroup-Name == "test" line, even though the user is in the suspend group. I've tried swapping them around with no difference(both huntgroups and users file). It seems to be disregarding the group. I also ran the sql query and it returns the suspend group. Basically, depending on the huntgroup I need to send different reply attributes (different NAS types) and if the DB returns the group suspend, different reply attributes are sent.
Or, try reading the FAQ for what information is needed in situations where "it doesn't work".
2. Is there an ability in any way to have a caching like feature or is DB failover and running 2 db servers with replication the only way to go?
Cache... what?
Cache details that it gets from the DB for some configurable time, ie VOPradius caches unames/password and other reply attributes to send to the NAS for 24 hours since the user last connected.
3. Is there anyway to log the actual reason for rejection in 'Post-Auth-Type REJECT'? ie simultaneous use, invalid password etc?
Module-Failure-Message often contains the reason, but not always.
That seems to do the trick :) Some info is better than none, and so far in testing its been perfect. May I suggest mentioning this in the variables file. Cheers cya Andrew
Alan DeKok. -- http://deployingradius.com - The web site of the book http://deployingradius.com/blog/ - The blog - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Andrew D wrote:
Basically, depending on the huntgroup I need to send different reply attributes (different NAS types) and if the DB returns the group suspend, different reply attributes are sent.
I don't fully understand what you are trying to do and you snipped a lot of the debug log, but if the group is in sql, then the huntgroup file should look something like this: testbad NAS-IP-ADDRESS == some.ip SQL-Group = suspend ^^^^ Hopefully that helps.... -- Dennis Skinner Systems Administrator BlueFrog Internet http://www.bluefrog.com
Dennis Skinner wrote:
Andrew D wrote:
Basically, depending on the huntgroup I need to send different reply attributes (different NAS types) and if the DB returns the group suspend, different reply attributes are sent.
I don't fully understand what you are trying to do and you snipped a lot
We are a little ISP, we have a bunch of lines on the local network, and outsource our dsl and national lines. We have a patton here and cisco NASes at the outsourced mob. If a user dials into the patton then they get a basic setup of framed-user session-timeout etc. if they come in via the cisco then they get same basic setup as the patton + a bunch of cisco-avpairs. If however they are in the 'suspend' group and they dial into the patton then they get a 172.16.* ip or if they dial into the ciscos, they get a different set of cisco-avpairs.
of the debug log, but if the group is in sql, then the huntgroup file
full debug :) Starting - reading configuration files ... reread_config: reading radiusd.conf Config: including file: /usr/local/etc/raddb/proxy.conf Config: including file: /usr/local/etc/raddb/clients.conf Config: including file: /usr/local/etc/raddb/snmp.conf Config: including file: /usr/local/etc/raddb/eap.conf Config: including file: /usr/local/etc/raddb/sql.conf main: prefix = "/usr/local" main: localstatedir = "/var" main: logdir = "/var/log" main: libdir = "/usr/local/lib" main: radacctdir = "/var/log/radacct" main: hostname_lookups = no main: max_request_time = 30 main: cleanup_delay = 5 main: max_requests = 1024 main: delete_blocked_requests = 0 main: port = 0 main: allow_core_dumps = no main: log_stripped_names = no main: log_file = "/var/log/radius.log" main: log_auth = yes main: log_auth_badpass = yes main: log_auth_goodpass = no main: pidfile = "/var/run/radiusd/radiusd.pid" main: user = "nobody" main: group = "nobody" main: usercollide = no main: lower_user = "after" main: lower_pass = "after" main: nospace_user = "after" main: nospace_pass = "after" main: checkrad = "/usr/local/sbin/checkrad" main: proxy_requests = no proxy: retry_delay = 5 proxy: retry_count = 3 proxy: synchronous = no proxy: default_fallback = yes proxy: dead_time = 120 proxy: post_proxy_authorize = no proxy: wake_all_if_all_dead = no security: max_attributes = 200 security: reject_delay = 0 security: status_server = no main: debug_level = 0 read_config_files: reading dictionary read_config_files: reading naslist read_config_files: reading clients read_config_files: reading realms Using deprecated realms file. Support for this will go away soon. radiusd: entering modules setup Module: Library search path is /usr/local/lib Module: Loaded exec exec: wait = yes exec: program = "(null)" exec: input_pairs = "request" exec: output_pairs = "(null)" exec: packet_type = "(null)" rlm_exec: Wait=yes but no output defined. Did you mean output=none? Module: Instantiated exec (exec) Module: Loaded expr Module: Instantiated expr (expr) Module: Loaded PAP pap: encryption_scheme = "crypt" Module: Instantiated pap (pap) Module: Loaded CHAP Module: Instantiated chap (chap) Module: Loaded MS-CHAP mschap: use_mppe = yes mschap: require_encryption = no mschap: require_strong = no mschap: with_ntdomain_hack = no mschap: passwd = "(null)" mschap: ntlm_auth = "(null)" Module: Instantiated mschap (mschap) Module: Loaded eap eap: default_eap_type = "md5" eap: timer_expire = 60 eap: ignore_unknown_eap_types = no eap: cisco_accounting_username_bug = no rlm_eap: Loaded and initialized type md5 rlm_eap: Loaded and initialized type leap gtc: challenge = "Password: " gtc: auth_type = "PAP" rlm_eap: Loaded and initialized type gtc mschapv2: with_ntdomain_hack = no rlm_eap: Loaded and initialized type mschapv2 Module: Instantiated eap (eap) Module: Loaded preprocess preprocess: huntgroups = "/usr/local/etc/raddb/huntgroups" preprocess: hints = "/usr/local/etc/raddb/hints" preprocess: with_ascend_hack = no preprocess: ascend_channels_per_line = 23 preprocess: with_ntdomain_hack = no preprocess: with_specialix_jetstream_hack = no preprocess: with_cisco_vsa_hack = no preprocess: with_alvarion_vsa_hack = no Module: Instantiated preprocess (preprocess) Module: Loaded realm realm: format = "suffix" realm: delimiter = "@" realm: ignore_default = no realm: ignore_null = no Module: Instantiated realm (suffix) Module: Loaded SQL sql: driver = "rlm_sql_mysql" sql: server = "localhost" sql: port = "" sql: login = "root" sql: password = "" sql: radius_db = "radius" sql: nas_table = "nas" sql: sqltrace = no sql: sqltracefile = "/var/log/sqltrace.sql" sql: readclients = no sql: deletestalesessions = yes sql: num_sql_socks = 5 sql: sql_user_name = "%{User-Name}" sql: default_user_profile = "" sql: query_on_not_found = no sql: authorize_check_query = "SELECT id, UserName, Attribute, Value, op FROM radcheck WHERE Username = '%{SQL-User-Name}' ORDER BY id" sql: authorize_reply_query = "SELECT id, UserName, Attribute, Value, op FROM radreply WHERE Username = '%{SQL-User-Name}' ORDER BY id" sql: authorize_group_check_query = "SELECT radgroupcheck.id,radgroupcheck.GroupName,radgroupcheck.Attribute,radgroupcheck.Value,radgroupcheck.op FROM radgroupcheck,usergroup WHERE usergroup.Username = '%{SQL-User-Name}' AND usergroup.GroupName = radgroupcheck.GroupName ORDER BY radgroupcheck.id" sql: authorize_group_reply_query = "SELECT radgroupreply.id,radgroupreply.GroupName,radgroupreply.Attribute,radgroupreply.Value,radgroupreply.op FROM radgroupreply,usergroup WHERE usergroup.Username = '%{SQL-User-Name}' AND usergroup.GroupName = radgroupreply.GroupName ORDER BY radgroupreply.id" sql: accounting_onoff_query = "UPDATE radacct SET AcctStopTime='%S', AcctSessionTime=unix_timestamp('%S') - unix_timestamp(AcctStartTime), AcctTerminateCause='%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time}' WHERE AcctSessionTime=0 AND AcctStopTime=0 AND NASIPAddress= '%{NAS-IP-Address}' AND AcctStartTime <= '%S'" sql: accounting_update_query = "UPDATE radacct SET FramedIPAddress = '%{Framed-IP-Address}', AcctSessionTime = '%{Acct-Session-Time}', AcctInputOctets = '%{Acct-Input-Octets}', AcctOutputOctets = '%{Acct-Output-Octets}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress= '%{NAS-IP-Address}'" sql: accounting_update_query_alt = "INSERT into radacct (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', DATE_SUB('%S',INTERVAL (%{Acct-Session-Time:-0} + %{Acct-Delay-Time:-0}) SECOND), '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0')" sql: accounting_start_query = "INSERT into radacct (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', '%S', '0', '0', '%{Acct-Authentic}', '%{Connect-Info}', '', '0', '0', '%{Called-Station-Id}', '%{Calling-Station-Id}', '', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '%{Acct-Delay-Time}', '0')" sql: accounting_start_query_alt = "UPDATE radacct SET AcctStartTime = '%S', AcctStartDelay = '%{Acct-Delay-Time}', ConnectInfo_start = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}'" sql: accounting_stop_query = "UPDATE radacct SET AcctStopTime = '%S', AcctSessionTime = '%{Acct-Session-Time}', AcctInputOctets = '%{Acct-Input-Octets}', AcctOutputOctets = '%{Acct-Output-Octets}', AcctTerminateCause = '%{Acct-Terminate-Cause}', AcctStopDelay = '%{Acct-Delay-Time}', ConnectInfo_stop = '%{Connect-Info}' WHERE AcctSessionId = '%{Acct-Session-Id}' AND UserName = '%{SQL-User-Name}' AND NASIPAddress = '%{NAS-IP-Address}'" sql: accounting_stop_query_alt = "INSERT into radacct (AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay) values('%{Acct-Session-Id}', '%{Acct-Unique-Session-Id}', '%{SQL-User-Name}', '%{Realm}', '%{NAS-IP-Address}', '%{NAS-Port}', '%{NAS-Port-Type}', DATE_SUB('%S', INTERVAL (%{Acct-Session-Time:-0} + %{Acct-Delay-Time:-0}) SECOND), '%S', '%{Acct-Session-Time}', '%{Acct-Authentic}', '', '%{Connect-Info}', '%{Acct-Input-Octets}', '%{Acct-Output-Octets}', '%{Called-Station-Id}', '%{Calling-Station-Id}', '%{Acct-Terminate-Cause}', '%{Service-Type}', '%{Framed-Protocol}', '%{Framed-IP-Address}', '0', '%{Acct-Delay-Time}')" sql: group_membership_query = "SELECT GroupName FROM usergroup WHERE UserName='%{SQL-User-Name}'" sql: connect_failure_retry_delay = 30 sql: simul_count_query = "" sql: simul_verify_query = "SELECT RadAcctId, AcctSessionId, UserName, NASIPAddress, NASPortId, FramedIPAddress, CallingStationId, FramedProtocol FROM radacct WHERE UserName='%{SQL-User-Name}' AND AcctStopTime = 0" sql: postauth_query = "INSERT into radpostauth (id, user, pass, reply, date) values ('', '%{User-Name}', '%{User-Password:-Chap-Password}', '%{reply:Packet-Type} %{Module-Failure-Message}', NOW())" sql: safe-characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /" rlm_sql (sql): Driver rlm_sql_mysql (module rlm_sql_mysql) loaded and linked rlm_sql (sql): Attempting to connect to root@localhost:/radius rlm_sql (sql): starting 0 rlm_sql (sql): Attempting to connect rlm_sql_mysql #0 rlm_sql_mysql: Starting connect to MySQL server for #0 rlm_sql (sql): Connected new DB handle, #0 rlm_sql (sql): starting 1 rlm_sql (sql): Attempting to connect rlm_sql_mysql #1 rlm_sql_mysql: Starting connect to MySQL server for #1 rlm_sql (sql): Connected new DB handle, #1 rlm_sql (sql): starting 2 rlm_sql (sql): Attempting to connect rlm_sql_mysql #2 rlm_sql_mysql: Starting connect to MySQL server for #2 rlm_sql (sql): Connected new DB handle, #2 rlm_sql (sql): starting 3 rlm_sql (sql): Attempting to connect rlm_sql_mysql #3 rlm_sql_mysql: Starting connect to MySQL server for #3 rlm_sql (sql): Connected new DB handle, #3 rlm_sql (sql): starting 4 rlm_sql (sql): Attempting to connect rlm_sql_mysql #4 rlm_sql_mysql: Starting connect to MySQL server for #4 rlm_sql (sql): Connected new DB handle, #4 Module: Instantiated sql (sql) Module: Loaded files files: usersfile = "/usr/local/etc/raddb/users" files: acctusersfile = "/usr/local/etc/raddb/acct_users" files: preproxy_usersfile = "/usr/local/etc/raddb/preproxy_users" files: compat = "no" Module: Instantiated files (files) Module: Loaded Acct-Unique-Session-Id acct_unique: key = "User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port" Module: Instantiated acct_unique (acct_unique) Module: Loaded detail detail: detailfile = "/var/log/radacct/%{Client-IP-Address}/detail-%Y%m%d" detail: detailperm = 384 detail: dirperm = 493 detail: locking = no Module: Instantiated detail (detail) Module: Loaded radutmp radutmp: filename = "/var/log/radutmp" radutmp: username = "%{User-Name}" radutmp: case_sensitive = yes radutmp: check_with_nas = yes radutmp: perm = 384 radutmp: callerid = yes Module: Instantiated radutmp (radutmp) Listening on authentication *:1812 Listening on accounting *:1813 Ready to process requests. rad_recv: Access-Request packet from host 192.168.202.99:1066, id=0, length=111 User-Name = "awd" CHAP-Password = 0x4353f490bdd471db230b3a798e4cdc98ec NAS-Port = 8 NAS-Port-Type = Async NAS-Identifier = ""Patton2960"" Called-Station-Id = ""81122000"" Calling-Station-Id = ""unknown"" Framed-Protocol = PPP Service-Type = Framed-User NAS-IP-Address = 203.57.204.190 Processing the authorize section of radiusd.conf modcall: entering group authorize for request 0 modcall[authorize]: module "preprocess" returns ok for request 0 rlm_chap: Setting 'Auth-Type := CHAP' modcall[authorize]: module "chap" returns ok for request 0 modcall[authorize]: module "mschap" returns noop for request 0 rlm_realm: No '@' in User-Name = "awd", looking up realm NULL rlm_realm: No such realm "NULL" modcall[authorize]: module "suffix" returns noop for request 0 rlm_eap: No EAP-Message, not doing EAP modcall[authorize]: module "eap" returns noop for request 0 radius_xlat: 'awd' rlm_sql (sql): sql_set_user escaped user --> 'awd' radius_xlat: 'SELECT id, UserName, Attribute, Value, op FROM radcheck WHERE Username = 'awd' ORDER BY id' rlm_sql (sql): Reserving sql socket id: 4 radius_xlat: 'SELECT radgroupcheck.id,radgroupcheck.GroupName,radgroupcheck.Attribute,radgroupcheck.Value,radgroupcheck.op FROM radgroupcheck,usergroup WHERE usergroup.Username = 'awd' AND usergroup.GroupName = radgroupcheck.GroupName ORDER BY radgroupcheck.id' radius_xlat: 'SELECT id, UserName, Attribute, Value, op FROM radreply WHERE Username = 'awd' ORDER BY id' radius_xlat: 'SELECT radgroupreply.id,radgroupreply.GroupName,radgroupreply.Attribute,radgroupreply.Value,radgroupreply.op FROM radgroupreply,usergroup WHERE usergroup.Username = 'awd' AND usergroup.GroupName = radgroupreply.GroupName ORDER BY radgroupreply.id' rlm_sql (sql): Released sql socket id: 4 modcall[authorize]: module "sql" returns ok for request 0 users: Matched entry DEFAULT at line 26 users: Matched entry DEFAULT at line 66 users: Matched entry DEFAULT at line 84 modcall[authorize]: module "files" returns ok for request 0 modcall: leaving group authorize (returns ok) for request 0 rad_check_password: Found Auth-Type CHAP auth: type "CHAP" Processing the authenticate section of radiusd.conf modcall: entering group CHAP for request 0 rlm_chap: login attempt by "awd" with CHAP password rlm_chap: Using clear text password start for user awd authentication. rlm_chap: chap user awd authenticated succesfully modcall[authenticate]: module "chap" returns ok for request 0 modcall: leaving group CHAP (returns ok) for request 0 Processing the session section of radiusd.conf modcall: entering group session for request 0 radius_xlat: '/var/log/radutmp' radius_xlat: 'awd' modcall[session]: module "radutmp" returns ok for request 0 modcall: leaving group session (returns ok) for request 0 Login OK: [awd] (from client awd port 8 cli "unknown") Sending Access-Accept of id 0 to 192.168.202.99 port 1066 Session-Timeout := 43200 Port-Limit := 1 Framed-MTU = 1476 Service-Type = Framed-User Framed-Protocol = PPP Framed-Compression = Van-Jacobson-TCP-IP Finished request 0 Going to the next request --- Walking the entire request list --- Waking up in 6 seconds... hungroups file test NAS-IP-ADDRESS == 203.57.204.190 testbad NAS-IP-ADDRESS == 203.57.204.190 SQL-Group = suspend users file # # This is a complete entry for "steve". Note that there is no Fall-Through # entry so that no DEFAULT entry will be used, and the user will NOT # get any attributes in addition to the ones listed here. # #awd Auth-Type := Local, User-Password == "blah" # Fall-Through = Yes DEFAULT Group == "suspend" Framed-IP-Address := 172.16.32.0+, Port-Limit := 1 DEFAULT Huntgroup-Name == "testbad" Framed-IP-Address := 172.16.32.0+, Port-Limit := 1 DEFAULT Huntgroup-Name == "test" Port-Limit := 20, Fall-Through = 1
should look something like this:
testbad NAS-IP-ADDRESS == some.ip SQL-Group = suspend ^^^^
Hopefully that helps....
Sorry, that didn't work either :( -- Network Administrator / Manager Webzone Internet 1st Floor (Oakley Street Entrance) 167 Grote Street Adelaide SA, 5000 Phone 1300 303 932 Fax 08 8221 6204 Email andrewd@webzone.net.au manager@webzone.net.au
well, SQL-Group in the users file works. Thanks dennis. -- Network Administrator / Manager Webzone Internet 1st Floor (Oakley Street Entrance) 167 Grote Street Adelaide SA, 5000 Phone 1300 303 932 Fax 08 8221 6204 Email andrewd@webzone.net.au manager@webzone.net.au
participants (3)
-
Alan DeKok -
Andrew D -
Dennis Skinner