Re: EAP-AKA testing without HLR/HSS
On Tue, Apr 30, 2013 at 02:04:59AM -0700, Antoni Milton wrote: Now I am trying to download the source code but i am not able to get as a package within freeradius and android-wpa_supplicant. That statement doesn't mean anything to me. There is no package within freeradius containing hostapd - they are separate. And I don't know what android-wpa_supplicant has to do with it. Sorry if I wasn't clear before, but I was saying that I think you will need to write your own code to do this authentication within freeradius, I was just pointing out that there are parts in hostapd which may serve as a guide. If you're not able to do this you might be able to find someone else in your organisation who can. Could you please point me the location/ repository to get the source code ? Enter hostapd into google. The first hit is http://hostap.epitest.fi/hostapd/ There are download links and a link to the GIT repo. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: EAP-AKA testing without HLR/HSS
Incidentally, there is some discussion about EAP-AKA on freeradius-devel at the moment: http://lists.freeradius.org/pipermail/freeradius-devel/2013-April/008016.html If that user gets it working, they may be able to help you. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: EAP-AKA testing without HLR/HSS
On Wed, Apr 24, 2013 at 08:11:11AM -0700, antoni milton wrote: Please let me know , if its possible to test EAP-AKA authentication without HLR/HSS using freeradius. Please don't cross-post. There is code in hostapd which you may be able to modify to do what you want: $ grep -R USIM_SIM . ./src/eap_peer/eap_aka.c:#ifdef CONFIG_USIM_SIMULATOR ./src/eap_peer/eap_aka.c:#endif /* CONFIG_USIM_SIMULATOR */ ./wpa_supplicant/android.config:#CONFIG_USIM_SIMULATOR=y ./wpa_supplicant/Android.mk:ifdef CONFIG_USIM_SIMULATOR ./wpa_supplicant/Android.mk:L_CFLAGS += -DCONFIG_USIM_SIMULATOR ./wpa_supplicant/ChangeLog: enable with CONFIG_SIM_SIMULATOR=y/CONFIG_USIM_SIMULATOR=y in .config ./wpa_supplicant/defconfig:#CONFIG_USIM_SIMULATOR=y ./wpa_supplicant/Makefile:ifdef CONFIG_USIM_SIMULATOR ./wpa_supplicant/Makefile:CFLAGS += -DCONFIG_USIM_SIMULATOR 2008-11-23 - v0.6.6 * added Milenage SIM/USIM emulator for EAP-SIM/EAP-AKA (can be used to simulate test SIM/USIM card with a known private key; enable with CONFIG_SIM_SIMULATOR=y/CONFIG_USIM_SIMULATOR=y in .config and password=Ki:OPc/password=Ki:OPc:SQN in network configuration) It looks like src/crypto/milenage.c does the actual checking, and that's what you'd have to move into radius. Any questions about that code need to go to the hostapd list of course. HTH, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
rlm_detail and locking
I have an application where I would like to read and process rlm_detail records in near-real-time (specifically to turn them into JSON and stuff them into a local database). I'm familiar with rlm_sql_log + radsqlrelay, and I know this is robust. So I was hoping to modify radsqlrelay to work with files being appended to by rlm_detail, but I turned up a wrinkle when checking the file locking in 2.2.x code. rlm_sql_log uses fcntl() locking only; but rlm_detail is different. It calls rad_lockfd_nonblock(), which uses lockf if available, else flock, and only uses fcntl if the other two are not available. It looks like fcntl and flock locks are independent of each other: http://www.mjmwired.net/kernel/Documentation/filesystems/locks.txt Question: what's the safe way to process detail files? Is there a Perl implementation of radrelay I can hack from? Looks like the original C implementation of radrelay was removed in 2005 (acd40e2e) I am aware of raddb/sites-available/buffered-sql, but that only shows how to get freeradius to read a detail file, not a standalone program. Thanks in advance, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: rlm_detail and locking
Personally, I would just backport the fcntl-only commit - that way you know you're getting fcntl locking: That looks perfect, thank you. I had another thought: would it be sane to get rlm_detail to write to a named pipe? I guess the problem then is it could block if the listener goes away. You could use a second freeradius instance as file reader / pipe writer. But reading the file directly and using fcntl locking sounds a much better solution anyway. Cheers, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Recursive modules?
I was wondering if an unlang module in 2.2.x could call itself recursively. For example, I have a reply list with potentially large number of Framed-Route attributes and I want to replace each one with something else. Could I do the following? rewriteFramedRoutes { if (%{reply:Framed-Route}) { update reply { Cisco-AVPair += ip:route=...etc... Framed-Route -= %{reply:Framed-Route} } rewriteFramedRoutes } } Unfortunately a quick test suggests that the module can't find itself. /etc/freeradius/policy.conf[310]: Failed to find rewriteFramedRoutes in the modules section. Does this mean that module can only invoke other modules which have been previously declared? Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Oddity with configurable failover
This is with freeradius 2.2.0. Support in policy.conf I define a module: policy { mymodule { update reply { Reply-Message += boo } } ... } Now in sites-available/default, I can happily do authorize { mymodule ... } But if I write it as authorize { mymodule { ok = return } ... } then the server fails to load at all, and freeradius -X reports: ... Module: Checking authorize {...} for more modules to load /etc/freeradius/sites-enabled/default[20]: Failed to find mymodule in the modules section. /etc/freeradius/sites-enabled/default[19]: Errors parsing authorize section. However, authorize { chap { ok = return } } is fine. Is configurable failover not available for user-defined modules? (If so, I couldn't find this in doc/configurable_failover.rst ) What I'm actually trying to do is run a user-defined module up to 20 times, but stop after the first return of 'notfound' - without making a horrible 20-deep nested if statement. It's not important to do it this way, but I was surprised I couldn't. Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Concatenating/inserting strings with backslashes
Here's something weird. I'm trying to concatenate some strings which contain backslash n (i.e. not a newline). In a normal string literal, I have to enter four backslashes: update reply { Reply-Message := anb } (\\n gives a newline, \\\n gives backslash followed by newline) But when I try to insert one string into another it goes completely haywire. update reply { Reply-Message := foonbar } update reply { Reply-Message := %{reply:Reply-Message}nbaz } This gives me foo newline bar newline baz. That is, even the second n is being collapsed into a newline! Some more test cases: update reply { Reply-Message := foonbar } update reply { Reply-Message := quxnbaz } correctly gives me qux backslash n baz update reply { Reply-Message := foonbar } update reply { Reply-Message := %{Wibble:-qux}nbaz } gives me newline baz. In fact, I need *eight* backslashes to get a literal backslash here: Reply-Message := %{Wibble:-qux}nbaz So somehow, the presence of a string expansion within a string affects the interpretation of subsequent backslashes within that string. Now, this works: update reply { Reply-Message := foonbar } update reply { Reply-Message := %{reply:Reply-Message}nbaz } But then if I do another layer of string insertion they get translated to newlines again. update reply { Reply-Message := foonbar } update reply { Reply-Message := %{reply:Reply-Message}nbaz } update reply { Reply-Message := %{reply:Reply-Message} } This seems pretty broken to me, but if someone would care to explain how to deal with it, please do. Or is there another way I can concatenate strings, which doesn't involve expanding them into another string? Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Concatenating/inserting strings with backslashes
try: if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message = stuff %{1} } } Nice idea, but it appears to suffer the same expansion problem. As you have written it gives this error: Bare %{...} is invalid in condition at: %{reply:Reply-Message} =~ /(.*)/) Adding the double quotes: update reply { Reply-Message := foo } if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message := %{1}nbar } } if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message := %{1}nbaz } } This gives foo newline bar newline baz update reply { Reply-Message := foo } if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message := %{1}nbar } } if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message := %{1}nbaz } } This gives foo newline bar backslash n baz Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
2.2.0 config files
A colleague was upgrading some boxes from (I think) 2.1.10 to 2.2.0, and says that expansions of the form %{Foo:-0} stopped working, and had to be replaced with %{%{Foo}:-0} Is that expected? I don't see anything in the ChangeLog, apart from 2.2.0 claims to be 100% configuration file compatible with 2.1.x Thanks, Brian - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Setting final response attributes for EAP
Yes, in post-auth. post-auth { update reply { ... } } Thank you, that's an easy way to set it globally for all users - or I can do a database dip there if required. Generally people will do this kind of thing in the inner-tunnel virtual server and set use_tunneled_reply = yes to copy the attributed back. You need to exercise caution if you're using session resumption here, because resumed sessions don't use the inner-tunnel. Right, I see that it defaults to 'no' which is why it wasn't working originally when I just attached the reply attribute directly to the user. Thanks again, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Setting final response attributes for EAP
When a user logs into a wireless AP, I would to include some per-user response attributes, in particular Acct-Interim-Interval = 600 However freeradius -X shows that this isn't happening, and it appears to be because of the following stanza in the default config: # The example below uses module failover to avoid querying all # of the following modules if the EAP module returns ok. # Therefore, your LDAP and/or SQL servers will not be queried # for the many packets that go back and forth to set up TTLS # or PEAP. The load on those servers will therefore be reduced. # eap { ok = return } What's the recommended solution here? Is it possible to distinguish between the final EAP accept and the earlier Access-Challenge, so that just the final response does a database lookup for the required user response attributes? Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Logging raw accounting packets
There's no module to do this. There are very few reasons to do this, IMHO. The reason: vendors have bugs in their accounting implementations, and we want to be able to show them the original raw packets to prove it's not our accounting collectors which are mis-interpreting the data. The problem with tcpdump is being able to find quickly the packets of interest (e.g. given a username, or given a FreeRadius Acct-Unique-Session-Id which is an MD5 across multiple attributes). So I want to extract the attributes of interest and index them alongside the raw data, or offsets into the raw data. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Logging raw accounting packets
I would like to put accounting logs into some sort of database, but store the entire raw binary packet as well as some decoded attributes. I can think of plenty of options for the storage: e.g. mysql Blob column, CouchDB binary attachment, MongoDB etc. But I can't see how to get at the raw packet from the freeradius config. Even rlm_perl doesn't seem to receive the raw packet, only a hash of decoded attributes. Is there a module which can do this already, or should I be looking to hack something up in C? Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: RADIUS Billing MVTS Pro
Please note that it's rude to cross-post. This is a 'users' question, not a 'developers' question. On Fri, Jan 20, 2012 at 03:18:53PM +0200, Mohamed Daif wrote: all calls must be checked firstly from two tables then go to Specific Gateways like below : ... how can i add both tables to FreeRADIUS and make configuration to check before sending calls to MVTS Servers. What database backend are you using? If you are using mysql (possibly others) then you can use stored procedures. Each one must return a single result set, with 5 columns in the correct order. However is can take as many arguments as you like. e.g. authorize_check_query = Call getCheck('%{User-Name}'); authorize_reply_query = Call getReply('%{User-Name}'); group_membership_query = Call getGroups('%{User-Name}'); authorize_group_check_query = Call getGroupCheck('%{Sql-Group}'); authorize_group_reply_query = Call getGroupReply('%{Sql-Group}'); So you write the logic within the stored procedure to query as many different tables as you like, in whatever order you like. The other option is to have multiple instances of rlm_sql, and call them at different points as required. (However each instance of the module might keep its own pool of connections to your SQL database) sql sql_blacklist { ... blacklist queries go here } sql sql_whitelist { ... whitelist queries go here } Then you can call both sql_blacklist and sql_whitelist at whatever points you require in your authorize { ... } block. HTH, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Restrict user only to a NAS
On Tue, May 10, 2011 at 01:59:44PM -0300, Marcos TP wrote: Huntgroups I know, but the functionality it provides me not for me. I need the user only has permission to access a NAS, as much as I could with Huntgroups was to restrict the access group, because several groups have access, containing their speed and can not do the search for access group, but by concentrator. Read the unlang documentation; then add some logic in the authorize section of your server config. You don't even need huntgroups if you're just authorizing a single NAS-IP-Address: if (%{control:Permitted-NAS} %{control:Permitted-NAS} != NAS-IP-Address) { reject } However I'd suggest you use huntgroups for greater flexibility. if (%{control:Permitted-Huntgroup} %{control:Permitted-Huntgroup} != Huntgroup-Name) { reject } Using this approach, you'd need to add a new attribute in your dictionary, such as Permitted-NAS and Permitted-Huntgroup in the examples above (I just picked these at random) Then in the radcheck table for the user, set the control attribute: Permitted-NAS := 1.2.3.4 That's one way to do it anyway. I think the lock should be in the Login table, where I have a field to indicate which NAS that User has access. Ah, well if you have a custom schema, then you need to show the schema. If you have a users table and you do a join to select the radcheck attributes, then you could just change the query you're using, limiting it to only matching the expected NAS-IP-Address or Huntgroup-Name: ... AND (permitted_nas = '%{NAS-IP-Address}' OR permitted_nas IS NULL) alternatively: ... AND (permitted_huntgroup = '%{Huntgroup-Name}' OR permitted_huntgroup IS NULL) Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: can attr_filter.accounting_response be used in post-proxy section ?
On Mon, Apr 18, 2011 at 09:13:47PM +0800, 魏景鹏 wrote: In post-proxy section, I wrote lines as follows: post-proxy { if(cond) { attr_filter.accounting_response } } But it seems not work as expected. Any Ideas? How does it not work as expected? What does radiusd -X show when proxying? attr_filter acts on different lists depending on where it's invoked. preacct: request accounting: reply preproxy: proxy request postproxy: proxy reply postauth: reply authorize: request Unfortunately this is hard-coded. There have been times where I've wanted to filter out reply attributes in the 'authorize' section, for example, and I've been forced to move this to postauth. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Installing to pfsense
On Wed, Mar 30, 2011 at 06:37:59PM -0400, Franz wrote: /usr/local/etc/raddb/sql.conf[22]: Instantiation failed for module sql /usr/local/etc/raddb/sites-enabled/inner-tunnel[131]: Failed to load module sql. /usr/local/etc/raddb/sites-enabled/inner-tunnel[47]: Errors parsing authorize section. and when I check all fles are in here: /usr/local/lib/freeradius-2.1.10 [1]rlm_sql_mysql-2.1.10.la rlm_sql_mysql.so [2]rlm_sql_mysql.la rlm_sql_mysql.a [3]rlm_sql_mysql-2.1.10.so under radiusd.conf the shared lib points to: libdir = /usr/local/lib/freeradius-2.1.10 Any clue as to why it does not see the files? I note that the error above is for failing to load sql (i.e. rlm_sql), but your listing above shows only rlm_sql_mysql. You need both. Anyway, what do these commands show? ldd /usr/local/lib/rlm_sql.so ldd /usr/local/lib/rlm_sql_mysql.so Possibly you are missing some library which rlm_sql_mysql in turn depends on (such as the correct version of libmysqlclient) Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: same username different password on different NAS
On Wed, Mar 16, 2011 at 01:16:22PM -0700, Richard Thornton wrote: Without using virtual servers, is there a way to link the username manager to the NAS name or IP of the location? Yep. I suggest you first map the NAS-IP-Address to a Huntgroup-Name (see the 'preprocess' module and 'huntgroups' file for one way of doing this). This allows you to control the NAS-IP-Address mappings separately. Then use a combination of (Huntgroup-Name, User-Name) when looking up the user in whatever database you're using. For example, if it's SQL you can use a query like: authorize_check_query = SELECT id, username, attribute, value, op \ FROM ${authcheck_table} \ WHERE username = '%{SQL-User-Name}' \ AND huntgroup = '%{Huntgroup-Name}' \ ORDER BY id HTH, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Sending accounting packets to more than one server?
On Sat, Mar 12, 2011 at 11:06:51AM +, Brian Candler wrote: Tim McNabb wrote: I was wondering if it is possible to forward accounting packets to another server while also keeping the packets on the local machine. I’m working on integrating a Netsweeper appliance and the company is saying that I need to forward accounting packets to the appliance in order for it to set policies correctly. Has anyone ever done this or would be willing to forward some good documentation on how this can be done? I have a local module here which blindly sends out an extra copy of an accounting packet to target host(s) you specify, without waiting for any acknowledgement. We use it for teeing off accounting to various packet shapers. Because the module doesn't maintain any state, i.e. wait for acknowledgement or resend if no ack received, it's very lightweight and there are no queues or buffers to overflow. I can probably get permission to release the code if you're interested. I have now secured this permission. The module is available as an attachment to this ticket: https://bugs.freeradius.org/bugzilla/show_bug.cgi?id=151 and also on github: https://github.com/candlerb/freeradius-server/tree/candlerb/packetblast Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Calling-Station-Id problem
On Sun, Mar 13, 2011 at 04:37:06AM -0700, ziko wrote: I tried both format together like this: user1 Calling-Station-Id == 00-00-00-00-00 user1 Calling-Station-Id == 00:00:00:00:00 but no success. You could do a rewrite: if (Calling-Station-Id =~ /^([0-9a-f]{2})-([0-9a-f]{2})-([0-9a-f]{2})-([0-9a-f]{2})-([0-9a-f]{2})$/i) { update request { Calling-Station-Id = %{1}:%{2}:%{3}:%{4}:%{5}:%{6} } } - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Packet tracing web interface
On Sat, Mar 12, 2011 at 11:08:27PM +, Phil Mayers wrote: On 03/12/2011 01:02 PM, Brian Candler wrote: I'd like to build a packet tracer web interface for freeradius: that is, somewhere where you can paste in a set of AV pairs (perhaps caught from radsniff), and you get back the AV responses plus all the decision-making logic that took place. Basically what freeradius -X shows. Have you seen radmin I can't see how radmin would help here. Is it possible to use it to inject a test packet? I can't see how, in which case I need to use radclient anyway. radmin can turn debugging on and off, but I'd probably run a separate instance of radiusd for the web test interface - otherwise lots of live debugging traffic would get intermingled with it. Hence I could leave debugging turned on permanently. I'm thinking about this design: post AV pairs browser -- web app * lock * radclient req radiusd -X --- reply --- * gen HTML - [debug file] HTML page * unlock -- If I run radiusd -X as a child from another process I can capture its output without writing it to a file. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Packet tracing web interface
On Mon, Mar 14, 2011 at 10:27:00AM +, Alan Buxey wrote: radmin can indeed inject packets and give you reply ie radmin inject ? inject to ipaddr port - Inject packets to the destination IP and port. inject from ipaddr - Inject packets as if they came from ipaddr inject file input-file output-file - Inject packet from input-file, with results sent to output-file Thank you. For what it's worth, I *did* go and read the manpage, carefully, before replying. The 'inject' option is not mentioned there. Have you got an example of its use? It seems rather broken to me. I do have mode=rw set. radmin inject inject to ipaddr port - Inject packets to the destination IP and port. inject from ipaddr - Inject packets as if they came from ipaddr inject file input-file output-file - Inject packet from input-file, with results sent to output-file radmin inject to 127.0.0.1 1812 ERROR: Unknown socket type radmin inject from 127.0.0.1 ERROR: You must specify inject to before using inject from radmin inject file /home/brian/test.in /home/brian/test.out $ Meanwhile, radiusd -X running in a different window shows: radmin inject to 127.0.0.1 1812 Ready to process requests. radmin inject from 127.0.0.1 Ready to process requests. radmin inject file /home/brian/test.in /home/brian/test.out Segmentation fault $ The contents of /home/brian/test.in are simply: User-Name = steve User-Password = testing If I rerun radiusd -X under gdb, here's where it crashes: Ready to process requests. radmin inject file /home/brian/test.in /home/brian/test.out Program received signal SIGSEGV, Segmentation fault. 0x00411b74 in command_inject_file (listener=0x7b11b0, argc=value optimised out, argv=0x7fffdaf0) at /usr/include/bits/string3.h:52 52return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); (gdb) bt #0 0x00411b74 in command_inject_file (listener=0x7b11b0, argc=value optimised out, argv=0x7fffdaf0) at /usr/include/bits/string3.h:52 #1 0x00415fc5 in command_domain_recv (listener=0x7b11b0, pfun=value optimised out, prequest=value optimised out) at command.c:2196 #2 0x0042a050 in event_socket_handler (xel=value optimised out, fd=value optimised out, ctx=value optimised out) at event.c:3423 #3 0x77bd1bdb in fr_event_loop (el=0x7a8810) at event.c:411 #4 0x0041c74a in main (argc=2, argv=value optimised out) at radiusd.c:406 (gdb) Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Packet tracing web interface
On Mon, Mar 14, 2011 at 12:47:36PM +, Phil Mayers wrote: Ok, correct usage is: radmin inject to (auth|acct) dstip dstport Aha. The 'help' message is decidedly unhelpful there (so is the error Unknown socket type). It works when I add 'auth', thank you. inject from srcip inject file input output And it turns out radiusd forces a prepend onto the output path, but not the input path: ++[exec] returns noop Failed to send injected file to /v/build/fr/var/log/radius//home/brian/test.out: No such file or directory It would be nice to allow '-' for input and output, so you didn't have to mess with temporary files, but that would involve sending the request and response across the socket. I'll probably stick to radclient + loopbacks for now, although the ability to set an arbitrary source IP using radmin inject is nice. Simple GUI app attached. It's quite neat what you can do in 70 lines of ruby :-) Regards, Brian. --- require 'rubygems' require 'sinatra' require 'haml' RADCLIENT = /usr/bin/radclient RADIUSD = /usr/sbin/freeradius # List available loopback interfaces [Label, IP address, secret] SOURCES = [ ['Default', '127.0.0.1', 'testing123'], ['Test LAC', '192.0.2.1', 'anothersecret'], ] $radiusd = IO.popen(#{RADIUSD} -X -i 127.0.0.1 -p 18123,w+) begin exit unless (line = $radiusd.gets) print line end until line =~ /Ready to process requests/ set :lock, true # prevent concurrent requests get '/' do haml :root end post '/' do # Flush any remaining debug info $radiusd.gets while select([$radiusd], nil, nil, 0) @radclient = @radiusd = source = SOURCES.find { |src| src[1] == params[:source] } || SOURCES.first IO.popen(#{RADCLIENT} -x 127.0.0.1:18123 auth '#{source[2]}' 21,w+) do |io| io.puts Packet-Src-IP-Address = #{source[1]} io.puts params[:avp] io.close_write loop do ready, _ = select([io, $radiusd], nil, nil, 10) unless ready @radiusd ** TIMEOUT ** break end if ready.include?(io) break unless (line = io.gets) @radclient line end if ready.include?($radiusd) exit unless (line = $radiusd.gets) @radiusd line end end end haml :root end __END__ @@ root %html %head %title radtest GUI %body %form{:action='/',:method='post'} %ul - SOURCES.each do |label, ip, secret| %li %input{:type='radio',:name='source',:value=ip,:checked=params[:source]==ip}= label %textarea{:name='avp',:rows=12, :cols=60}= params[:avp] %input{:type='submit'} - if @radclient %h1 radclient response %pre= @radclient - if @radiusd %h1 radiusd debug output %pre= @radiusd - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Sending accounting packets to more than one server?
On Sun, Mar 13, 2011 at 09:25:23AM +0100, Alan DeKok wrote: We use it for teeing off accounting to various packet shapers. Which do... what? Some sort of class-of-service stuff, I believe, which requires knowing which username is on which (dynamic) IP. There is periodic interim accounting, so if the occasional stop or start packet is lost, eventually it will correct itself. Quite possibly using type=detail would be better. But if I were sending to, say, three remote servers, would I need to write to three separate detail files? A comment in the 'robust-proxy-accounting' example says: # Note that you can have only ONE listen section reading # detail files from a particular directory. ... # ... Having two listen sections reading detail files # from the same directory WILL cause problems. The packets # may be read by one, the other, or both listen sections. I'm having difficulty locating any documentation for type = detail, and in particular, whether it deletes files after using them. Digging around I found src/main/detail.c and as far as I can see it first renames the detail file, then deletes it when complete. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Failover for SQL lookup expansions?
Phil Mayers wrote: Correct. Virtual modules (e.g. redundant) do not implement the xlat function. ... Unfortunately the xlat functions in FR don't return error/success codes. They return length of result string, and 0 for any failure condition, which means it's impossible to distinguish a failure from an empty result, and also that you can't use if (ok) constructs. OK, thanks for that. I wonder if it would be worth coding for this, e.g. return -1 for fail? (although that would break everything which blindly uses it as length of string :-) It does seem that some string expansions fail silently at the moment, which could perhaps do with being a bit more strict. e.g. I once wrote %{Reply:AttrName} instead of %{reply:AttrName} and it produced nothing more than a 'Warning' at freeradius -X. You will probably need something like this: update request { Attrib := %{sql1:select ...} } if (!Attrib) { update request { Attrib := %{sql2:select ...} } } Thank you. I'll see what I can do. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Sending accounting packets to more than one server?
Tim McNabb wrote: I was wondering if it is possible to forward accounting packets to another server while also keeping the packets on the local machine. I’m working on integrating a Netsweeper appliance and the company is saying that I need to forward accounting packets to the appliance in order for it to set policies correctly. Has anyone ever done this or would be willing to forward some good documentation on how this can be done? I have a local module here which blindly sends out an extra copy of an accounting packet to target host(s) you specify, without waiting for any acknowledgement. We use it for teeing off accounting to various packet shapers. Because the module doesn't maintain any state, i.e. wait for acknowledgement or resend if no ack received, it's very lightweight and there are no queues or buffers to overflow. I can probably get permission to release the code if you're interested. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Packet tracing web interface
I'd like to build a packet tracer web interface for freeradius: that is, somewhere where you can paste in a set of AV pairs (perhaps caught from radsniff), and you get back the AV responses plus all the decision-making logic that took place. Basically what freeradius -X shows. Has anyone done this before? I have a few considerations. (1) If I had a single persistent freeradius daemon running, and multiple users were submitting requests to this web interface, I'd need to separate out the debug data for each of the requests. I guess I could have a locking system so that only one person could be using it at once. (Alternatively I'd have to fire off a new foreground radiusd for each request as it came in, and kill it afterwards) (2) What's the best way to submit the request so that it looks like it's coming from a particular IP address? The Client-IP-Address attribute is internal only, not on-the-wire. At the moment the best I've been able to do is to create loopback interfaces on my box with examples of the source IPs I'm interested in, then use radclient to send the packet with a Packet-Src-IP-Address of one of those loopbacks. Is there a better way I've overlooked? (Before you say it, I know a well-behaved radius server should be looking at NAS-IP-Address not Client-IP-Address. Unfortunately there are some cases where we have to make logic decisions based on the Client-IP-Address) Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Failover for SQL lookup expansions?
With freeradius 2.1.10 I can configure failover for SQL lookups like this: # in policy.conf sql_foo { redundant { sql_foo_local sql_foo_remote } } # in sites-available/foo authorize { sql_foo } However, it looks like I can't use this redundant module inside a string expansion: authorize { update request { Huntgroup-Name = %{sql_foo:SELECT groupname FROM radhuntgroup where nasipaddress='%{NAS-IP-Address}' limit 1} } } --- Error logged: WARNING: Unknown module sql_foo in string expansion % How could I get the same level of redundancy for string expansions? Could I do the expansion multiple times inside a redundant section? I am thinking of perhaps: huntgroup_local { update request { Huntgroup-Name = %{sql_foo_local:SELECT groupname FROM radhuntgroup where nasipaddress='%{NAS-IP-Address}' limit 1} } } huntgroup_remote { update request { Huntgroup-Name = %{sql_foo_remote:SELECT groupname FROM radhuntgroup where nasipaddress='%{NAS-IP-Address}' limit 1} } } ... authorize { redundant { huntgroup_local huntgroup_remote } } However, I'm just not sure whether the ok/notfound/fail status would propagate through a string expansion in this case. The examples in configurable_failover.rst talk only about normal modules. Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Logging the matched SQL-Group
Phil Mayers wrote: When rlm_sql is running through each of a user's groups, the value %{SQL-Group} is set for each iteration. However it's cleared at the end. I assume you're talking about the authorize method where it searches radgroupcheck/radgroupreply, rather than: if (SQL-Group == ...) ...yes? That's right. I'm talking about step 5 at http://wiki.freeradius.org/Rlm_sql#SQL_Schema_and_usage It doesn't mention there that Sql-Group is set, but I found it in the source (grep for PW_SQL_GROUP, attribute 1079) Is there a straightforward way of doing this? Because I can't see one right now... You could add: My-Matched-Group += GROUPNAME ...to the radgroupreply, then log this attribute? Ah yes, of course - I can make a UNION query which always adds this attribute, but the reply will only be appended if the group is matched. Or I could do it in the radgroupcheck, to add a control attribute. Cheers! Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Logging the matched SQL-Group
When rlm_sql is running through each of a user's groups, the value %{SQL-Group} is set for each iteration. However it's cleared at the end. I would like to be able to capture the value of SQL-Group which was successfully matched (if any), so that I can log it in rlm_sql_log. Is there a straightforward way of doing this? Because I can't see one right now... Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Parallel running RADIUS servers
This is only going to work for the simpler authentication mechanisms - PAP and so forth. It won't work for EAP, because the server challenge state incorporates random numbers. Absolutely. This is for a broadband aggregation environment with CHAP. Honestly, I think you are better off relying on proper testing change control. Getting full test coverage involves having a complete corpus of representative test cases (positive and negative). As I said, I'm working towards that, but it's always possible that there are cases which are not covered, especially when refactoring a complex configuration. comparison-tee looks interesting, I'll take a look at it. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Parallel running RADIUS servers
I wonder if anyone has implemented anything like the following, and if so, if they can share their experiences of how they did it. When rolling out a new RADIUS config, I would like to be able to run both the current and new configs side by side, processing the same packets in real time in both servers, and highlight if and where the responses differ. This would give a very high confidence level that the new config didn't break things in unexpected ways. (I already have an off-line test suite, which uses radclient to send a number of test cases to the development RADIUS server, but there is a lot of legacy traffic and I can never be sure that it the suite completely captures all possible cases) I can think of a few ways of implementing this: * Using bpf (like radsniff) to capture the live requests and responses. Forward a copy of the request to a second process, which would somehow be jailed to a loopback interface, and then compare the responses. * Have some sort of forking proxy, which takes one input packet and sends it to two places, A and B. It would take either the A or B response and return it to the client. It could even vote on them (e.g. Access-Accept takes precedence over Access-Reject) Some of the existing logic I work with makes use of the source IP address of the packet (i.e. Client-IP-Address), so a simple proxy which resends the packet would be a problem. I suppose I could put Client-IP-Address into a real AV. Anybody doing anything like this today, or know of any projects which do this? Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Authenticating SSH login on a Cisco IOS switch to AD
On Wed, Feb 09, 2011 at 04:24:05PM +0100, Schaatsbergen, Chris wrote: We have a couple of Cisco switches that we administer using SSH sessions. Now I have been asked if we can authenticate the SSH login on our Windows 2008 Active Directory using our Freeradius (2.1.10) installation. The solution I have built is to configure freeradius as a proxy, and install IAS on the Windows AD server. You can use AD groups to configure specific reply attributes for specific users in IAS. Windows AD is limited to 50 clients (unless you have Enterprise edition) - but that is client IPs. Your freeradius server counts as only one, no matter how many Cisco boxes are authenticating through it. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: AW: Authenticating SSH login on a Cisco IOS switch to AD
On Wed, Feb 09, 2011 at 09:35:35AM -0800, Brett Littrell wrote: I think it is always a good idea to keep the switch management on a separate management vlan, regardless of wether you encrypt the info or not. Between Cisco and Radius servers it does encrypt the password but I don't think it does much else. For regular logins, you will get User-Password attribute which is encrypted with the RADIUS shared secret. I'm pretty sure the Cisco won't do CHAP. The response attributes will be signed using the shared secret, so they cannot be tampered with. So, the important thing is to choose strong shared secrets, and to limit access to any places where your switch configs are stored. Someone sniffing the RADIUS traffic will be able to see (a) who is logging in, and (b) what privilege level they have been given. If they are able to sniff your network then you probably have worse problems to worry about. Incidentally, it's quite reasonable to use RADIUS for authentication and authorization, and TACACS for accounting (e.g. point your aaa accounting at an instance of tac_plus). Then you have a real-time log of individual commands run. Having a management network is a good idea too though. Having a separate vlan for switch management is a lot like a hidden SSID, it is by no means the most secure way to protect a network but it keeps the rif-raf from trying to hack your network. People who know how to flood the arp tables can bypass vlans if need be It sounds like you have pretty broken switches then. VLANs are always separate, floods or no floods. Also, true switches don't care about ARP at all (as opposed to layer 3 switches). Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: issue with dialup.conf
On Mon, Feb 07, 2011 at 08:48:27AM +0200, Tyller D wrote: if ( $device =~ /^nomadix/i ) { if ($DATABANK != '') { if ( $DATABANK le 0 ) { $RAD_REPLY{'Reply-Message'} = You have no more Data Left; return RLM_MODULE_REJECT; }else { return RLM_MODULE_REJECT; $RAD_REPLY{'Nomadix-MaxBytesDown'} = $DATABANK; } That logic returns RLM_MODULE_REJECT in both branches of the if statement, so I imagine you haven't copy-pasted it correctly. But I think I see what you're getting at. exctract from radcheck: +--+--+++--+ | id | username | attribute | op | value| +--+--+++--+ | 3069 | Joe | databank | := | 52428800 | | 3068 | Joe | Cleartext-Password | := | Joe123 | | 3070 | Joe | Auth-Type | := | Perl | +--+--+++--+ OK, so you're using radcheck as a convenient place to store the user's remaining quota. I guess that should work. but it not always exectuting stop request correctly because mysql select sum(acctinputoctets + acctoutputoctets) from radacct where username='scotty'; +-+ | sum(acctinputoctets + acctoutputoctets) | +-+ | 1840263628 | +-+ mysql select value from radcheck where username='scotty' and attribute='databank'; ++ | value | ++ | -302340151 | ++ Well, those are two different things. The databank value will be whatever original value you put in databank (which you haven't told us), minus the bytes in and bytes out. So that would be correct if the initial value was 1537923477 I have to say this looks like a pretty fragile way of doing accounting, because you are relying 100% on Stop packets. This means: (1) A lost stop packet will not update databank (2) If a user stays online solidly for months, they won't get their quota updated in the database Doing accounting based on interim-update packets is more robust. However, they are cumulative (each interim-update packet shows the *total* used so far for that session, just as if it were a Stop packet), so you can't just subtract them from an accumulator. You need to add together the last values seen for each session. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: FREE RADIUS client
On Mon, Feb 07, 2011 at 04:05:41PM +0530, karnik jain wrote: Can any one tell me that FREE RADIUS client is inernally doing UTF-8 conversion for the multilingual characters or It is replying on some other underlying module I think that's a meaningless question. RADIUS deals with bytes. It will send as User-Name whatever chunk of bytes you give it. It doesn't mangle values. who is suppling credentials like username and password? What exactly are you asking about - the program called radclient? In that case it is you, the person who invokes radclient, who supplies the username and password on stdin. If you're asking about something else, please be more specific. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: FREE RADIUS client
On Mon, Feb 07, 2011 at 05:07:03PM +0530, karnik jain wrote: I am talking about radclient only. If supplied USER-NAme is not UTF-8 encoded by some means suppose the scenario where UTF-8 support is not there then at that time what radclient does. Does it send the same multilingual charcters to the RADIUS server or first of all convert that into UTF-8 as per RFC 2865 and send it to RADIUS server in ACCESS REQUEST packet as attribute or just send as it is to RADIUS server? It just sends the bytes as-is. If you have data in another encoding, which you want to convert to UTF-8 for sending, then you need to transcode it yourself first using something like 'iconv'. In any case, the data which you provide to radclient needs to use the standard ASCII characters for equals, double-quotes and so on, so that it can parse the lines. UTF-8 fulfils that requirement. HTH, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Radius Client UDP port selection
On Sun, Feb 06, 2011 at 10:06:01AM -, vijay s sheelavantar wrote: I am talking about pam_radius_client. I want this pam_radius_auth.so client to select a particular UDP port to communicate with external radius server. so that server can send authentication responce on the same port back to client. Of course, the server will always send the authentication response back to whatever port the client selected. Your options are: 1. If pam_radius_client doesn't have the ability to bind to a particular port, then you can modify the source code to do so. The call you need is bind() after the socket has been created. Warning: hacking C code in security-sensitive modules (especially those running as root) is a risky business. Get an expert to make this change for you, or become an expert first. (Recommended reading: Unix Network Programming vol 1, and Advanced Programming in the Unix Environment, both by Richard Stevens) 2. I think you said before you only wanted to make sure that the port was 32768. So you can configure your OS so that *all* outbound connections bind to ports 32768. Google linux ephemeral port range for details. On my system: $ cat /proc/sys/net/ipv4/ip_local_port_range 32768 61000 So in fact, all connections from my machine would be =32768 anyway. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Radius Client UDP port selection
On Sun, Feb 06, 2011 at 11:11:58AM +, Brian Candler wrote: 1. If pam_radius_client doesn't have the ability to bind to a particular port, then you can modify the source code to do so. The call you need is bind() after the socket has been created. Ah, it turns out the code to do this is already there: (pam_radius_auth.c) /* * Use our process ID as a local port for RADIUS. */ local_port = (getpid() 0x7fff) + 1024; do { local_port++; s_in-sin_port = htons(local_port); } while ((bind(conf-sockfd, salocal, sizeof (struct sockaddr_in)) 0) (local_port 64000)); if (local_port = 64000) { close(conf-sockfd); _pam_log(LOG_ERR, No open port we could bind to.); return PAM_AUTHINFO_UNAVAIL; } As you can see, the initial local_port is currently chosen in the range 1024 to 33791 (1024+32767), essentially at random, and if that one is in use then it keeps incrementing until it finds a free one under 64000. Adjust to use whatever range you like. 2. I think you said before you only wanted to make sure that the port was 32768. So you can configure your OS so that *all* outbound connections bind to ports 32768. Sorry, that won't work here, because the code is choosing its local port explicitly. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: free radius implementation for big ISP
On Sun, Feb 06, 2011 at 02:13:40PM +0330, Mohamad A wrote: 1. Handling about 100,000 acc requests and 10,000 auth requests hourly! I know a freeradius installation much bigger than that. You can scale freeradius easily: a multicore machine with lots of RAM will be able to handle hundreds of requests per second (depending on whether it's using in-RAM tables or mysql queries or whatever), and you can scale horizontally by adding more RADIUS servers. For your 200K users you might want to use mysql or LDAP as your source of authorization and authentication data. You can scale that using replication. 2. Accounting Of course. Using something like rlm_log_sql you can write the 'INSERT' statements to a log file, then periodically collect them and push them into your accounting DB. Using that approach, the accounting DB doesn't become a real-time bottleneck. For real-time accounting (i.e. which user is on this IP address right now?) support for Redis has just been added. It should appear in 2.1.11. 3. Control and limit user traffic. That's a function of the NAS. The RADIUS server is not involved, except in sending attributes to control that activity. FreeRADIUS can send whatever attributes you like. 4. Control and limit user concurrent logins. That's a bit trickier but doable. I believe there are example configs for doing this using mysql, and you could use the new Redis support for it too. But (1) it is difficult to scale, because there will have to be a central real-time database updated when people connect and disconnect; and (2) this service is designed to prevent people logging in under certain circumstances, and therefore can become a source of increased user problems and support calls. You have to decide whether the abuse of multiple concurrent logins is outweighed by the risks of accidentally locking out legitimate users (e.g. because of lost accounting packets showing that the users' previous session has ended) IMO a better solution is just to analyse accounting logs periodically, and identify people logging in concurrently. Then you can send them a gentle warning to mend their ways, and if they persist then you terminate them under the TCs of the service you provide them. 5. CoA for changing user speed over different times of day. 6. CoA to disconnect user when the account validation is over (eg. Traffic quota exceeds). radclient can send the CoA packets, but the actual logic of *when* to send them is entirely outside of FreeRADIUS. You would need your own systems to do that. Your NAS might support an attribute to disconnect the user once a certain amount of traffic has been sent or received (similar to Session-Timeout, which disconnects them after a certain number of seconds) 7. Calculate traffic usage differently depending on day-time (ie. our service in nights does not calculate any traffic or some times as half for users). FreeRADIUS doesn't calculate traffic usage. You need to build a system to do that, using accounting records as the raw input. 8. Tracking online users and disconnect user if Accounting packet is not received in prefixed amount of time (currently 10 mins). That seems a strange requirement. If you have configured your NAS to send periodic interim updates, and the NAS hasn't sent one for 2 or 3 times the update interval, then the reason is almost certainly that the user has disconnected anyway. Anyway, this falls into the same as CoA above. You can use radclient to send the disconnect packet (or more standard, use SNMP to do this), but the systems to work out if and when to do this are your own. 9. Spliting database traffic over multiple servers. Yes that's easy. Multiple RADIUS servers can point to different database backends; a single RADIUS server can also share load between multiple database backends using a load-balance section. man unlang for more info. 10. Designing one interface to manage all users. Building user management is your problem. This encompasses everything from CRM (contact info), signup, rating, billing and payment collection, selfcare, mapping products to RADIUS attributes, product upgrades, service termination, and so on. FreeRADIUS doesn't even provide you with a user management API, that's up to you too. For example, if you put your user radius data into a mysql database, you might expose some stored procedures that the higher-level systems can call to add/delete/modify a user; or you might have a separate system which takes SOAP or JSON requests and turns them into mysql inserts and updates. Do you really suggest to switch to FreeRadius or stick to the current problematic solution ? FreeRADIUS is a comprehensive, reliable and flexible toolkit for building RADIUS servers and clients. It can query databases for generating RADIUS responses, but the way you enter and manage that data is out of its scope. Hence depending on what your existing solution does for you, you may find you have to build quite a lot more
Re: issue with dialup.conf
On Sun, Feb 06, 2011 at 04:55:34PM +0200, Tyller D wrote: freeradius is used to authenticate users at our hotspots, as we are using different nas devices and we must cater for them all i did this. in dictionary file I added an attribute called databank, then I created a perl script to check which type of nas the user is coming from and renaming databank to the correct attribute, now that works fine. Not sure what you mean by renaming databank to the correct attribute - are you actually changing the authentication database? If so that's scary. If you simply want to send a different attribute based on what type of NAS they are connecting from, then you can change the response attribute sent, without modifying the underlying database. For identifying the NAS: the simplest way is to use the preprocess module. It reads the huntgroups file which maps NAS-IP-Address to control attribute Huntgroup-Name, and then you can use a regular users file to add an appropriate attribute, or do it in unlang: sql if ( %{control:Huntgroup-Name} == Foo %{reply:Databank} ) { update reply { OtherAttr = %{reply:Databank} Databank !* } } Or you can do anything in perl of course. The point is, I don't think you should be updating the database simply to change which reply attribute is sent based on which NAS they're connecting from at this instant. Then on the stop request I need to update the value associated to databank to be (databank - (acctinputoctets+acctoutputoctets)). that way limiting users to only as much data as we stipulated in the begining. I'm guessing your databank is some sort of data limit attribute, a bit like a Session-Timeout but for bytes transferred? my problem is that it doesn't always update the databank value, I can see how much traffic a users used in his session (i.e. in the radacct table) so the accounting_stop_query accounting_stop_query_alt are not failing, its just not updating the databank value in radcheck. ... here are the two queries accounting_stop_query = \ UPDATE radacct,radcheck SET \ radacct.acctstoptime = '%S', \ radacct.acctsessiontime= '%{Acct-Session-Time}', \ radacct.acctinputoctets= '%{%{Acct-Input-Gigawords}:-0}' 32 | \ '%{%{Acct-Input-Octets}:-0}', \ radacct.acctoutputoctets = '%{%{Acct-Output-Gigawords}:-0}' 32 | \ '%{%{Acct-Output-Octets}:-0}', \ radacct.acctterminatecause = '%{Acct-Terminate-Cause}', \ radcheck.value = radcheck.value - '%{Acct-Output-Octets}' - '%{Acct-Input-Octets}', \ radacct.acctstopdelay = '%{%{Acct-Delay-Time}:-0}', \ radacct.connectinfo_stop = '%{Connect-Info}' \ WHERE radacct.acctsessionid = '%{Acct-Session-Id}' \ AND radcheck.username = '%{SQL-User-Name}' \ AND radcheck.attribute = 'databank' \ AND radacct.username = '%{SQL-User-Name}' \ AND radacct.nasipaddress = '%{NAS-IP-Address}' That's a scary update: updating two independent tables with the same query. What database are you using? Calling a stored procedure would be a much cleaner way of doing this, if your database supports it. (I use mysql which does) accounting_stop_query = CALL process_stop_packet(...) Then you can do two separate updates, which I think is what you really want. does anyone know how this can happen? Watch radiusd -X until you see it happen. Look at exactly what SQL updates are being done. could it be something to do with interim-updates (grasping at straws here). Sounds highly unlikely to me. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: issue with dialup.conf
On Sun, Feb 06, 2011 at 09:41:36PM +0200, Tyller D wrote: Sorry, maybe i didn't explain correctly. Im not updating the database. I am using auth-type perl and when the user authenticates my perl script looks in the db to see what nas is bieng used on that IP and then checks the value for databank for the user and then send the correct attribute with the correct value like so $RAD_REPLY{'Nomadix-MaxBytesDown'} = $DATABANK; (in this example its a nomadix gateway) Which DB is Perl looking into to find $DATABANK? You mention the radcheck table. Does that mean you're using rlm_sql for authorization too? In which case, does the perl code look in a different set of SQL tables, or the same ones? Normally, reply attributes would go in radreply not radcheck - although radcheck is a good place to set control attributes. Or is all of the database access being done from Perl (in which case radcheck is just a coincidental name?) I don't think so, because you said you're using rlm_sql to update your accounting tables. I think it might be sensible for you to post actual code and configs, and specifics such as what database you're using. Otherwise we're just playing a game of twenty questions. That part works perfectly. The issue im having is when the stop request comes in, it doesn't update the value in the radcheck table, well it does but only sometimes.. If sometimes means 99.9% of the time, then that's the sort of bug which can be hard to debug. If it means 50% of the time, then it should be quite easy for you to replicate it and nail it down. If your database supports query logging, turn it on. Then you can see *exactly* what update is being sent, and whether it's being rejected for some reason at the database side. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Proxy Maintenance Process
On Sat, Feb 05, 2011 at 07:18:52AM +0100, Alan DeKok wrote: Brian Candler wrote: WARNING This tool is experimental and should not be used in production environments. (Just quoting the manpage... maybe it's more paranoid than necessary) From an old version of the server. It no longer says that. I took that from http://freeradius.org/radiusd/man/radmin.html I see this was removed from git in July 2010. B. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Radius Client UDP port selection
On Fri, Feb 04, 2011 at 04:17:11AM -, vijay s sheelavantar wrote: Now the radius client UDP port is selected randomly, Is there a way by which i can mention the server to use perticular UDP port as client port. Are you talking about when freeradius is used as a proxy (and thus sending outbound RADIUS packets?) Or are you talking about radclient? Or something else? - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Proxy Maintenance Process
On Fri, Feb 04, 2011 at 07:44:41PM +0100, Alan DeKok wrote: what is the “best practice” in regards to putting home_servers into maintenance so that freeradiusd doesn’t attempt to send traffic to them? Use radmin radmin set home server state IP PORT dead WARNING This tool is experimental and should not be used in production environments. (Just quoting the manpage... maybe it's more paranoid than necessary) - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: MAC Authentication - Bad Idea?
On Wed, Feb 02, 2011 at 02:00:52PM -0600, Gary Gatten wrote: On shared medium, I don't *think* dupe macs will cause much problem, unless maybe a congestion algorithm tweaks traffic to/from that mac. I'm not an expert in that area, just speaking from experience. Layer 1 --- I have little experience with radio, and if it's a single radio cell with omnidirectional antenna it might not make much difference (*). Layer 2 --- With switches: they learn which port owns the MAC address, and then only send traffic to the latest seen port. If it keeps changing, there will be substantial packet loss. Layer 3 --- If two people are on the same IP address then of course that will mess things up royally, so one will have to manually choose a different one. Now, if two different IPs share the same MAC address, it will usually work unless one of the devices has IP forwarding enabled. If they do, then when terminal A sees frames for B's IP address will forward them to its default route. The router will then re-send the packet to B, and hence you will get a storm of duplicate packets (multiplied by the TTL). Regards, Brian. (*) If the radio station has multiple antennas to beam the signal in the correct direction, I imagine it might not work well if it sees the same client in two places at once. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Active Directory and authorize section
On Tue, Feb 01, 2011 at 02:33:33PM -0800, Brett Littrell wrote: The authenticate section is used to just verify that you are who you are, via certs, username/password, token etc. The authorize section is where you define the sources for all the information you want FR to respond to. I'd say that's not exactly true, or is not very clear anyway. (1) freeradius always runs the authorize section first, then then authenticate section (2) the authorize section is where you do any sort of database lookups needed, both to determine the reply attributes to send (in case the user does authenticate successfully), and at the same time to find any information needed to perform user authentication, such as the expected password (Cleartext-Password in the control list) (3) the authenticate section normally uses that extra info to perform the authentication. If it fails, the reply attributes are stripped out and a reject is sent. Using ntlm_auth is a special case, in that it can authenticate without knowing the password: it delegates the whole authentication to a different database. That's fine, but if you don't have anything in your authorize section then you'll just be sending back an empty Access-Accept without any reply attributes. In some applications this may be sufficient. This sort of delegation is rather like proxying, and indeed, you can run IAS on your AD box and just proxy to it. IAS has a limitation of 50 RADIUS client IPs (unless you have Windows Server Enterprise edition), but fortunately each freeradius server you put in front of it only counts as one client :-) Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Active Directory and authorize section
On Wed, Feb 02, 2011 at 07:23:39AM -0800, Brett Littrell wrote: Very interesting, I would have thought Authenticate came first then Authorize since you need to authenticate in order to be authorized. The RADIUS protocol kind of fuzzes the two concepts: an Accept-Request is both a request for authentication and authorization. An Access-Reject could mean either that you weren't authenticated, or that you're not authorized for the service you wanted. FreeRADIUS runs boths sections of its config before sending the reply, because generally authentication needs some data to authenticate, and that data normally comes from the same place as the authorization data. If that is the case and say you pull the vlan ids from ldap, or some other directory, how would Freeradius know what those values are prior to knowing who you are? It knows who you *claim* to be (User-Name), so can use that to look up the reply attributes. It doesn't know you actually *are* that person yet, but it won't send back an Access-Accept until it does. Or are you saying that the way the program loads the config the authorize section simply gets read first? The authorize section gets executed first; I don't think it makes any difference what order you put them in the config file. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: MAC Authentication - Bad Idea?
On Wed, Feb 02, 2011 at 11:15:13AM -0800, Jim Rice wrote: Do I need to be concerned with MAC spoofing? It's easy to do, so it will probably happen; this risk is weighed against providing a service which is easy for your customers to use. What happens if two people try to use the same MAC address simultaneously on your wireless network? I suspect it will break service for both of them, which means that it's actually not very useful for freeloading. They'd have to coordinate to use it at different times. You could also look for simultaneous users in your RADIUS accounting logs. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Question on Radius logs
The debugging side was a little different, I was thinking about inputting text strings in the middle of unlang scripts If you run radiusd -X you will see the output of expansions, so you can do if (DEBUG: I am looking at %{foo} and %{bar}) { } and you'll see the text in the log. Experimentation suggests that the closing brace can't be on the same line as the opening brace though. Actually, there is a %{debug:} expansion, but it just sets the debug level to the (integer) argument, and doesn't actually send a debug message. Setting the Reply-Message attribute can be useful for debugging too. HTH, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Different Installation paths between source and yum giving error of missing directory
On Tue, Feb 01, 2011 at 09:15:52PM +, Samuel wrote: Please pardon me if this has been addressed before; my search on the site has not helped me solve my problem. I installed freeradius 2.1.10 from source and the raddb folder was put in /usr/local/etc whereas yum put it in /etc. I deleted the files in /usr/local/etc/ and used yum to install but i get an error that /usr/local/etc/raddb cannot be found when I run radiusd -X. Where is radiusd picking that path from ? You are still running the radiusd you installed from source (which has that part hard-coded into it) rm /usr/local/sbin/radiusd -- and also any other bits put into /usr/local/bin and /usr/local/sbin by -- your source install You may need to logout/login again for your shell to realise that it should look for a radiusd in another directory. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Treating octets as string
I notice that recently a %{integer:...} expansion was added. Is there perhaps a case for a corresponding %{string:...} expansion? Yes. Editing the dictionaries is not recommended, as it can have additional side effects. Adding %{string:Class} is pretty specific. OK, I've had a go at a patch. You can find it at https://github.com/candlerb/freeradius-server/tree/candlerb/string_expansion Aside: I guess you can't use this if you have an 'octets' value with an embedded null. If I set Class = 0x666f6f00626172 then Reply-Message = %{string:Class} expands to Reply-Message = foo Also, while doing this I also discovered a bug in the %{integer:...} expansion: it will cause freeradius to segfault if the vp is known in the dictionary but is not present in the request (radius_get_vp will return true but set vp to NULL). The fix is also in that branch, but I'll post it here too: diff --git a/src/main/xlat.c b/src/main/xlat.c index 0a02064..f1818e1 100644 --- a/src/main/xlat.c +++ b/src/main/xlat.c @@ -420,7 +420,7 @@ static size_t xlat_integer(void *instance, REQUEST *request, while (isspace((int) *fmt)) fmt++; - if (!radius_get_vp(request, fmt, vp)) { + if (!radius_get_vp(request, fmt, vp) || !vp) { *out = '\0'; return 0; } Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Treating octets as string
In an accounting server, I would like to be able to parse the Class attribute with a regexp to pull parts out. However the standard dictionary defines it as 'octets' which makes it hard to parse - and I'd like to avoid modifying the dictionary if possible. Copying it to a 'string' attribute doesn't help, because it gets hex-expanded at that point. e.g. Reply-Message := %{Class} } gives Class = 0x466f6f7c426172 Reply-Message = 0x466f6f7c426172 I notice that recently a %{integer:...} expansion was added. Is there perhaps a case for a corresponding %{string:...} expansion? Or is there a better way to do this? Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Possible memory leak in rlm_sql?
I noticed something in rlm_sql.c function rlm_sql_process_groups(). group_list is allocated at the top of the function, but sql_grouplist_free(group_list) is only called at the end. All the various error exits don't call it. ISTM that's going to leak memory in event of errors, but perhaps I have overlooked something which prevents that. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
radsniff behaviour change?
As of 2.1.10, radsniff doesn't decode packets automatically without -x: $ sudo bin/radsniff -i lo -c 1 Access-Request Id 17127.0.0.1:43171 - 127.0.0.1:1812 +0.000 Attr-1 = 0x7374657665 Attr-2 = 0x98f7337df71223dc220a3a682c5f0a7f Attr-4 = 0x7f01 Attr-5 = 0x0001 Looking at the code, it doesn't even read the dictionary unless you add -x (debug) or -F (filter). This change was made in commit 7a85628d I wonder if this logic is unintentionally broken, and in fact you meant to load the dictionary *unless* -F is present? Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: radsniff behaviour change?
On Thu, Dec 02, 2010 at 02:32:16PM +, Brian Candler wrote: I wonder if this logic is unintentionally broken, and in fact you meant to load the dictionary *unless* -F is present? This appears to fix it. diff --git a/src/main/radsniff.c b/src/main/radsniff.c index 935d2ce..6c3ca14 100644 --- a/src/main/radsniff.c +++ b/src/main/radsniff.c @@ -422,7 +422,7 @@ int main(int argc, char *argv[]) /* * There are many times where we don't need the dictionaries. */ - if (fr_debug_flag || radius_filter) { + if (fr_debug_flag || !radius_filter) { if (dict_init(radius_dir, RADIUS_DICTIONARY) 0) { fr_perror(radsniff); return 1; - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: use existing sql table for user-password
But for radcheck, i need to add attribute and value fields as i see. How can i check just username and password from one table, and check other attributes (AuthType etc) from another?? Write an SQL function. Or use the group functionality. That is, use authorize_check_query authorize_reply_query to get the password, and group_membership_query authorize_group_check_query authorize_group_reply_query to get the attributes from another table. In group_membership_query you map the username to some other key, but you can just map it to the username again if you wish. But if this is MySQL, as Alan says it may be easier (and is certainly more flexible) to put your logic into stored procedures. Then use authorize_check_query = call getCheck('%{User-Name}'); authorize_reply_query = call getReply('%{User-Name}'); Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Note about !*
In 'man unlang' it says: !* Delete all occurances of the named attribute, no matter what the value. I've just found that update reply { Framed-IP-Address !* } generates a run-time error: ERROR: Failed parsing value for attribute Framed-IP-Address: Failed to find IP address for You also can't write update reply { Framed-IP-Address !* ANY } as this generates an error on startup: Module: Loading virtual module applyFilterOnPasswordError /etc/freeradius/policy.conf[162]: ERROR: Failed to find IP address for ANY /etc/freeradius/policy.conf[158]: Failed to parse update subsection. What you apparently need is: update reply { Framed-IP-Address !* 0.0.0.0 } If this isn't considered a bug, I suggest the manpage is updated. e.g. Delete all occurances of the name attribute, no matter what the value. However, the value you provide must still be consistent with the type of the attribute being removed, e.g. Framed-IP-Address !* 0.0.0.0 Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Changing a Reject into an Accept
Is it possible to turn a reject into an accept inside the post-auth section? The idea is to tunnel specific groups of failed users to an appropriate help page. I have tried: post-auth { ... Post-Auth-Type REJECT { if ( ) { applyTunnelAttributes ok } } } The attributes are added, but the 'ok' doesn't change the packet into an Access-Accept. I also tried, unsuccessfully, update control { Packet-Type := Access-Accept Response-Packet-Type := Access-Accept } update reply { Packet-Type := Access-Accept Response-Packet-Type := Access-Accept } (freeradius reports that modifying the value of a virtual attribute is not supported) I could mess about with the authenticate section, but this goes against the stern advice in the default config: # Please do not put unlang configurations into the authenticate # section. Put them in the post-auth section instead. That's what # the post-auth section is for. Going against that advice, the following appears to work: authenticate { Auth-Type PAP { pap { ok = return reject = 1 } applyTunnelAttributes } Auth-Type CHAP { chap { ok = return reject = 1 } applyTunnelAttributes } } So, any better way of achieving this? Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Case-insensitive regexps in rlm_files
Alan DeKok wrote: The benefit to us in doing this in rlm_files/rlm_fastusers is that when these files are rsynced out, freeradius re-reads them without needing a restart. While the modules are reloaded on HUP, so are the virtual servers. So you can put unlang into a file, and it will be reloaded on HUP. However, rlm_fastusers doesn't even require a HUP: it notices any changed file and reloads it on demand. (rlm_files doesn't though). It's probably simpler just to add case-insensitive regex matching to the core. That way *all* of the modules get the functionality, and not just users. Absolutely. So the options I see are: (1) lib/valuepair.c, paircmp() * before calling regcomp, look for (?i: ... ) * if found, strip it off and add REG_ICASE to regcomp. Advantages: - tiny change - fully backwards compat, regexps like (?i:...) fail to compile today Disadvantages: - it's a frig, as we're not really implementing non-capturing groups (2) Set case-insensitive flag on the value * Parse /xxx/ and /xxx/i as a PW_STRING containing xxx * Add new flag 'case_insensitive' to attr_flags * Use this flag when calling regcomp Advantages: - changes parser, but otherwise touches relatively little code - gives the expected user syntax for regexps Disadvantages: - technically this is an incompatible change for existing configs with User-Name == /foo/, which would have to change to User-Name == /foo/ (I think this is very unlikely in practice though) I'd say (2) looks like the most attractive, what do you think? As a separate point, I think it's possible to cache the regcomp when do_xlat is not set. This would require another field in struct value_pair (to avoid changing strvalue into a struct). Worthwhile? Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Case-insensitive regexps in rlm_files
Alan DeKok wrote: - technically this is an incompatible change for existing configs with User-Name == /foo/, which would have to change to User-Name == /foo/ ? /foo/ isn't supported right now. So that won't cause any change. Maybe not supported, but it does work: the unquoted string /foo/ is treated as if it were /foo/ DEFAULT User-Name =~ /foo/, Cleartext-Password := testing Service-Type = Framed-User, Framed-Protocol = PPP, ... snip $ bin/radtest /foo/ testing localhost 1 testing123 Sending Access-Request of id 159 to 127.0.0.1 port 1812 User-Name = /foo/ User-Password = testing NAS-IP-Address = 127.0.0.1 NAS-Port = 1 rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=159, length=71 Service-Type = Framed-User Framed-Protocol = PPP ... snip - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Case-insensitive regexps in rlm_files
In rlm_files, I can't see how to make a case-insensitive regular expression. - DEFAULT User-Name =~ (?i:foo) # nope, not supported by POSIX ERE. Logs: # Invalid regular expression (?i:foo) DEFAULT User-Name =~ /foo/i # actually matches the character sequence /foo/i - Am I missing a trick here? If I make a patch for this, would you prefer the first or second to be implemented? The second is nicer to use, but is probably harder to implement. The first could be done as a frig by stripping off an outer (?i: ... ) and setting the REG_ICASE flag if seen. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Case-insensitive regexps in rlm_files
Alan DeKok wrote: I'd prefer to avoid the users file entirely. The capability already exists in the server, in unlang. I'd suggest using that. The benefit to us in doing this in rlm_files/rlm_fastusers is that when these files are rsynced out, freeradius re-reads them without needing a restart. This is perceived (rightly or wrongly) as making the server more robust. rlm_fastusers can also be a lot faster than a linear search in unlang. Furthermore, it also helps that the syntax is limited and line-based, as it results in less scope for errors. It's just a bit too limited without //i. We currently use our own custom modules which have similar functionality to rlm_files and rlm_fastusers with case-insensitive regexp matching, but I'm keen to fold this back into mainline if possible. (*) Regards, Brian. (*) You don't want our current modules - they use ^^ at the start of a regexp to turn on case-insensitive matching - but I'm happy to reimplement them in a cleaner way. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Matching a value within an IP subnet
On Mon, Oct 18, 2010 at 02:51:25PM +0200, Alan DeKok wrote: Brian Candler wrote: DEFAULT NAS-IP-Address =~ 192.0.2.0/27, NAS-Group := ADSL-BRAS I've had a look at paircmp() in src/lib/valuepair.c and can't see any logic which might do this. Nope. Write a regex to do the matching. The above string after =~ is *not* a regex. Indeed it is not. But NAS-IP-Address is (natively) not a string in RADIUS either, it's a 4-byte integer. Does FreeRADIUS let me treat it as if it were a string? DEFAULT NAS-IP-Address =~ /^192\.0\.2\.([0-9]|1[0-9]|2[0-9]|3[01])$/, NAS-Group := ADSL-BRAS B. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Matching a value within an IP subnet
On Tue, Oct 19, 2010 at 02:11:06PM +0200, Alan DeKok wrote: Does FreeRADIUS let me treat it as if it were a string? The operator you have chosen to use is: =~. This was more of a wish than an actual usage. The question I meant was: is there any sort of operator to match an IP address against a subnet? And =~ was acting as a meta-operator. DEFAULT NAS-IP-Address =~ /^192\.0\.2\.([0-9]|1[0-9]|2[0-9]|3[01])$/, NAS-Group := ADSL-BRAS That should work. OK, it's ugly, but it may suffice. Thanks for your help, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Matching a value within an IP subnet
In clients.conf, you can match a whole subnet of source IPs with one rule: client 192.0.2.0/27 { secret = testing123-1 shortname = ADSL-BRAS } But is it possible to do the same to match a range of IPs in an attribute like NAS-IP-Address? I want to tag a collection of NASes from the same subnet with a control attribute (but which may be talking via a proxy, not directly). Perhaps something like: 192.0.2.0/27NAS-Group := ADSL-BRAS or DEFAULT NAS-IP-Address =~ 192.0.2.0/27, NAS-Group := ADSL-BRAS I've had a look at paircmp() in src/lib/valuepair.c and can't see any logic which might do this. Are there any options you can suggest, short of expanding the subnet into a list of its constituent IPs? Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Wipe existing reply attributes in rlm_files
Hello, I'm using freeradius 2.1.7. I would like to know if there's a simple way, within a users file, to *replace* the entire set of reply attributes with some others. For example, NONEFoo = bar, Baz = bap # FIXME: delete all reply attributes which have accumulated so far Framed-IP-Address = 1.1.1.1 The idea is that I've already done a database dip using something like rlm_sql, which may have added some reply attributes; but then later logic requires that I need to remove those reply attributes and replace them with a different set (e.g. to L2TP tunnel them somewhere else) I know I could remove specific attributes using -=, but I don't know which attributes might have been added by this point. My current solution is very messy, using two users files. Firstly I set a temporary control list attribute: NONEFoo = bar, Baz = bap, Postauth-Action := XXX and then next in the authorize { } config I have: if (%{control:PostAuth-Action} =~ /./) { deleteall# invoke custom module to clear reply list postauth_attrs # invoke second users file } and finally, in a second users file, I add the new attributes: XXX Framed-IP-Address = 1.1.1.1 I can't even use the standard attr_filter module to delete the existing reply attributes, because when it's invoked in the authorize { } section it acts on the request list, not the reply list. Have I missed an easier way to do this? Thanks, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Wipe existing reply attributes in rlm_files
Why don't you just do whatever if() logic before adding the attributes? It's complicated :-) Partly it's policy. We configure as much of this logic in users files as possible, because they can be updated without needing to restart radiusd. But in future it will be a necessity. The project I'm working on involves authenticating users based on some attribute which identifies their physical location, not their User-Name. So decisions you might have made in the past solely based on realm and NAS-IP (e.g. tunnel to X) have to be made after a database lookup. That database lookup may add reply attributes, which will be needed by the terminating LNS, but not when tunnel switching. So if the database identifies the user as category X, *and* the request comes from NAS-IP Y, then we have to strip the reply attributes and replace with tunnelling ones. Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html