Bug 700870

Summary: freeradius not compiled with --with-udpfromto
Product: Red Hat Enterprise Linux 6 Reporter: Gary T. Giesen <ggiesen+redhat>
Component: freeradiusAssignee: John Dennis <jdennis>
Status: CLOSED ERRATA QA Contact: Patrik Kis <pkis>
Severity: medium Docs Contact:
Priority: medium    
Version: 6.0CC: atolani, dpal, ggiesen+redhat, ksrot, michal.bruncko, pkis
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: freeradius-2.1.12-1.el6 Doc Type: Bug Fix
Doc Text:
Cause: freeradius not compiled with --with-udpfromto Consequence: With a multihomed server and explicitly specifying the IP address to bind to freeradius sends replies from the wrong IP address. Fix: Build with the --with-udpfromto configuration option. Result: RADIUS reply always sourced from the IP the request was sent to.
Story Points: ---
Clone Of:
: 846471 (view as bug list) Environment:
Last Closed: 2012-06-20 14:05:36 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Bug Depends On:    
Bug Blocks: 846471    
Attachments:
Description Flags
verification logs none

Description Gary T. Giesen 2011-04-29 16:35:11 UTC
Description of problem:

a) With a multihomed server, and explicitly specifying what IP address to bind to, freeradius sends replies from the wrong IP address (and consequently gets ignored).

b) If you don't explicitly specify what address to bind to, the packet will be sourced from the "nearest" interface to the destination, regardless of which address the initial packet was sent to.

This behaviour is documented on the freeradius wiki:

http://wiki.freeradius.org/index.php/FAQ#Is_there_a_way_to_bind_FreeRADIUS_to_a_specific_IP_address.3F

The solution is to compile freeradius with --with-udpfromto

Version-Release number of selected component (if applicable):

2.1.9-3.el6

How reproducible:

Always

Steps to Reproduce:
1a. Configure freeradius on a multihomed server, with interface IPs 10.0.1.2/24 and 10.0.2.2/24. Tell freeradius to explicitly bind to 10.0.1.2 and 10.0.2.2 (listed in that order in the configuration file radiusd.conf). All RADIUS requests destined to 10.0.2.2 are replied to with source address 10.0.1.2 (the first bind address in the configuration) regardless of the original request AND the routing table. For example, a request is sent from NAS 10.0.2.3 (on the same subnet as the 10.0.2.2 interface), to 10.0.2.2. The RADIUS reply comes back with a source address of 10.0.1.2.

1b. Configure freeradius on a multihomed server, with interface IPs 10.0.1.2/24 and 10.0.2.2/24. Setup freeradius to listen on all IPs. NAS sends request to 10.0.2.2, but according to routing table on server, the route out 10.0.1.2 is selected. RADIUS reply is sourced from address 10.0.1.2. NAS ignores packet.

  
Actual results:

1a. freeradius replies from the bind IP address as defined in the first listen directive, regardless of which IP the request was sent to, or what the routing table on the server says.

2a. freeradius replies from the IP address of the interface "closest" to the NAS (according to the routing table), regardless of what IP the RADIUS request was sent to

Expected results:

RADIUS reply always sourced from the IP the request was sent to.

Additional info:

According to the freeradius wiki, the fix is to compile with the option --with-udpfromto

http://wiki.freeradius.org/index.php/FAQ#Is_there_a_way_to_bind_FreeRADIUS_to_a_specific_IP_address.3F

Comment 2 RHEL Program Management 2011-04-30 06:00:37 UTC
Since RHEL 6.1 External Beta has begun, and this bug remains
unresolved, it has been rejected as it is not proposed as
exception or blocker.

Red Hat invites you to ask your support representative to
propose this request, if appropriate and relevant, in the
next release of Red Hat Enterprise Linux.

Comment 8 Gary T. Giesen 2012-02-22 16:01:35 UTC
Any possibility of a version bump (rebase) on this as well as this version also has a particularly nasty memory leak.

Comment 9 John Dennis 2012-02-22 16:14:57 UTC
Re comment #8, yes, we are planning on rebasing to 2.1.12.

Comment 11 John Dennis 2012-04-24 16:24:16 UTC
    Technical note added. If any revisions are required, please edit the "Technical Notes" field
    accordingly. All revisions will be proofread by the Engineering Content Services team.
    
    New Contents:
Cause:

freeradius not compiled with --with-udpfromto

Consequence:
    
With a multihomed server and explicitly specifying the IP address to bind
to freeradius sends replies from the wrong IP address.

Fix:
    
Build with the --with-udpfromto configuration option.

Result:

RADIUS reply always sourced from the IP the request was sent to.

Comment 12 Patrik Kis 2012-05-11 14:59:48 UTC
I'm not able to reproduce this bug.
I tried the below scenario with virtual machines, with a clean install of freeradius.

<server>

# rpm -q freeradius
freeradius-2.1.9-3.el6.x86_64
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:43:d6:8f brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.62/24 brd 192.168.100.255 scope global eth1
    inet6 fe80::5054:ff:fe43:d68f/64 scope link 
       valid_lft forever preferred_lft forever
3: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:74:7b:24 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.62/24 brd 192.168.200.255 scope global eth3
    inet6 fe80::5054:ff:fe74:7b24/64 scope link 
       valid_lft forever preferred_lft forever
# 
# echo 'testuser Cleartext-Password := "abc"' >> /etc/raddb/users 
# cat >> /etc/raddb/clients.conf  <<EOF
> client test1 {
>     ipaddr = 192.168.100.58
>     secret      = testing123    
> }
> client test2 {
>     ipaddr = 192.168.200.58
>     secret      = testing123    
> }
> EOF
# grep -ve \# -e ^$ /etc/raddb/radiusd.conf | grep -A4 listen
listen {
	type = auth
	ipaddr = *
	port = 0
}
listen {
	ipaddr = *
	port = 0
	type = acct
}
# radiusd -X
... /snip/ ...

# netstat -na | grep 181
udp        0      0 0.0.0.0:1812      0.0.0.0:*
udp        0      0 0.0.0.0:1813      0.0.0.0:*
udp        0      0 0.0.0.0:1814      0.0.0.0:*

</server>

<client>

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 52:54:00:0f:a6:3c brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.58/24 brd 192.168.100.255 scope global eth0
    inet6 fe80::5054:ff:fe0f:a63c/64 scope link 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 52:54:00:c7:93:f5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.58/24 brd 192.168.200.255 scope global eth1
    inet6 fe80::5054:ff:fec7:93f5/64 scope link 
       valid_lft forever preferred_lft forever
# radtest testuser abc 192.168.100.62 0 testing123
Sending Access-Request of id 246 to 192.168.100.62 port 1812
	User-Name = "testuser"
	User-Password = "abc"
	NAS-IP-Address = 127.0.0.1
	NAS-Port = 0
	Message-Authenticator = 0x00000000000000000000000000000000
rad_recv: Access-Accept packet from host 192.168.100.62 port 1812, id=246, length=20
# radtest testuser abc 192.168.200.62 0 testing123
Sending Access-Request of id 79 to 192.168.200.62 port 1812
	User-Name = "testuser"
	User-Password = "abc"
	NAS-IP-Address = 127.0.0.1
	NAS-Port = 0
	Message-Authenticator = 0x00000000000000000000000000000000
rad_recv: Access-Accept packet from host 192.168.200.62 port 1812, id=79, length=20
# 

</client>

<server>

#  tcpdump -npi any port 1812 
17:46:36.963081 IP 192.168.100.58.44171 > 192.168.100.62.radius: RADIUS, Access Request (1), id: 0xf6 length: 78
17:46:36.963666 IP 192.168.100.62.radius > 192.168.100.58.44171: RADIUS, Access Accept (2), id: 0xf6 length: 20
17:46:40.643201 IP 192.168.200.58.56563 > 192.168.200.62.radius: RADIUS, Access Request (1), id: 0x4f length: 78
17:46:40.643545 IP 192.168.200.62.radius > 192.168.200.58.56563: RADIUS, Access Accept (2), id: 0x4f length: 20

</server>

The freeradius server responds in booth cases from the address where it received the request.

I tried also configure radius to listen on exact addresses in /etc/raddb/radiusd.conf:
listen {
    ipaddr = 192.168.100.62
    port = 0
    type = auth
}
listen {
    ipaddr = 192.168.200.62
    port = 0
    type = auth
}
and also swapped the above entries, but it still worked as expected.

Am I doing something wrong?

Comment 13 Gary T. Giesen 2012-05-11 15:33:20 UTC
(In reply to comment #12)
 
> Am I doing something wrong?

As for case a:

I'm not sure why this is the case, I'll have to do some more investigating.

As for case b:

You're getting that behaviour because the client and radius server sit on the same subnet. And you've configured both IPs for the client on the RADIUS server. Try configuring the client with only one interface and IP (192.168.100.58), (and only configure one IP in clients.conf on the RADIUS server), and then send a request to 192.168.200.62. The behaviour I was seeing was that the radius server would source the reply from 192.168.100.62.

Just some further notes on my configuration I originally had when I filed the report.

1) Client and server were not on the same subnet (ie. there was at least one router in between, which may make a difference)
2) My production setup actually has FreeRADIUS listening on an alias on the loopback interface (although I believe I tested what I posted above with it listening on interface IPs as well- it's been so long since I filed the report I will have to reconfirm)

Furthermore, I don't believe compiling with --udpfromto hurts anything (and that flag was specifically included to address this "bug".

Give me a day or two and I'll recreate the configuration for confirmation

Comment 14 Patrik Kis 2012-05-14 08:42:36 UTC
(In reply to comment #13)
> 
> As for case b:
> 
> You're getting that behaviour because the client and radius server sit on the
> same subnet. And you've configured both IPs for the client on the RADIUS
> server. Try configuring the client with only one interface and IP
> (192.168.100.58), (and only configure one IP in clients.conf on the RADIUS
> server), and then send a request to 192.168.200.62. The behaviour I was seeing
> was that the radius server would source the reply from 192.168.100.62.
> 

Thanks for additional info. I can confirm that the case b is reproducible now (however, the case a still not).

<server>

# rpm -q freeradius
freeradius-2.1.10-5.el6.x86_64
# ip a | grep 'inet '
    inet 127.0.0.1/8 scope host lo
    inet 192.168.100.62/24 brd 192.168.100.255 scope global eth1
    inet 192.168.200.62/24 brd 192.168.200.255 scope global eth3
# pwd
/etc/raddb
# tail -8 clients.conf
client test1 {
    ipaddr = 192.168.100.58
    secret      = testing123    
}
client test1 {
    ipaddr = 192.168.200.58
    secret      = testing123    
}
# grep -ve \# -e ^$ /etc/raddb/radiusd.conf | grep -A4 listen
listen {
	type = auth
	ipaddr = *
	port = 0
}
listen {
	ipaddr = *
	port = 0
	type = acct
}
# radiusd -X
... /snip/ ...

# netstat -na | grep 181
udp        0      0 0.0.0.0:1812      0.0.0.0:*
udp        0      0 0.0.0.0:1813      0.0.0.0:*
udp        0      0 0.0.0.0:1814      0.0.0.0:*

</server>

<client>

# radtest testuser abc 192.168.100.62 0 testing123
Sending Access-Request of id 227 to 192.168.100.62 port 1812
	User-Name = "testuser"
	User-Password = "abc"
	NAS-IP-Address = 127.0.0.1
	NAS-Port = 0
	Message-Authenticator = 0x00000000000000000000000000000000
# radtest testuser abc 192.168.200.62 0 testing123
Sending Access-Request of id 152 to 192.168.200.62 port 1812
	User-Name = "testuser"
	User-Password = "abc"
	NAS-IP-Address = 127.0.0.1
	NAS-Port = 0
	Message-Authenticator = 0x00000000000000000000000000000000
Sending Access-Request of id 152 to 192.168.200.62 port 1812
	User-Name = "testuser"
	User-Password = "abc"
	NAS-IP-Address = 127.0.0.1
	NAS-Port = 0
	Message-Authenticator = 0x00000000000000000000000000000000
Sending Access-Request of id 152 to 192.168.200.62 port 1812
	User-Name = "testuser"
	User-Password = "abc"
	NAS-IP-Address = 127.0.0.1
	NAS-Port = 0
	Message-Authenticator = 0x00000000000000000000000000000000
radclient: no response from server for ID 152 socket 3

</client>

<server>
#  tcpdump -npi any port 1812 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
11:37:35.405370 IP 192.168.100.58.53607 > 192.168.100.62.radius: RADIUS, Access Request (1), id: 0xe3 length: 78
11:37:35.406271 IP 192.168.100.62.radius > 192.168.100.58.53607: RADIUS, Access Accept (2), id: 0xe3 length: 20
11:37:40.613807 IP 192.168.100.58.49122 > 192.168.200.62.radius: RADIUS, Access Request (1), id: 0x98 length: 78
11:37:40.614273 IP 192.168.100.62.radius > 192.168.100.58.49122: RADIUS, Access Accept (2), id: 0x98 length: 20
11:37:45.614913 IP 192.168.100.58.49122 > 192.168.200.62.radius: RADIUS, Access Request (1), id: 0x98 length: 78
11:37:45.615605 IP 192.168.100.62.radius > 192.168.100.58.49122: RADIUS, Access Accept (2), id: 0x98 length: 20
11:37:50.614884 IP 192.168.100.58.49122 > 192.168.200.62.radius: RADIUS, Access Request (1), id: 0x98 length: 78
11:37:50.615234 IP 192.168.100.62.radius > 192.168.100.58.49122: RADIUS, Access Accept (2), id: 0x98 length: 20

</server>

-------------------------------------------------------------------

Test with the newest freeradius (the configuration remained the same as above):

# rpm -q freeradius
freeradius-2.1.12-1.el6.x86_64

#  tcpdump -npi any port 1812 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
11:40:35.245909 IP 192.168.100.58.45265 > 192.168.100.62.radius: RADIUS, Access Request (1), id: 0xc8 length: 78
11:40:35.246915 IP 192.168.100.62.radius > 192.168.100.58.45265: RADIUS, Access Accept (2), id: 0xc8 length: 20
11:40:37.130876 IP 192.168.100.58.50880 > 192.168.200.62.radius: RADIUS, Access Request (1), id: 0xfd length: 78
11:40:37.132088 IP 192.168.200.62.radius > 192.168.100.58.50880: RADIUS, Access Accept (2), id: 0xfd length: 20


It can be seen that the server in response keeps the address from request.

If you manage to reproduce the case a, please let me know. Thanks.

Comment 15 Karel Srot 2012-05-14 15:58:20 UTC
Created attachment 584404 [details]
verification logs

I can also confirm  the fix for scenario b).

In short:

# rpm -q freeradius
freeradius-2.1.10-5.el6.x86_64

# radtest bob hello 192.168.140.20 0 testing123
Sending Access-Request of id 96 to 192.168.140.20 port 1812
	User-Name = "bob"
	User-Password = "hello"
	NAS-IP-Address = 192.168.122.27
	NAS-Port = 0
rad_recv: Access-Accept packet from host 192.168.150.20 port 1812, id=96, length=20
radclient: received response to request we did not send. (id=96 socket 3)

# tcpdump -i eth1 -nn port 1812
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
17:39:39.575329 IP 192.168.160.20.58734 > 192.168.140.20.1812: RADIUS, Access Request (1), id: 0x60 length: 55


# rpm -q freeradius
freeradius-2.1.12-3.el6.x86_64

# radtest bob hello 192.168.140.20 0 testing123
Sending Access-Request of id 219 to 192.168.140.20 port 1812
	User-Name = "bob"
	User-Password = "hello"
	NAS-IP-Address = 192.168.122.27
	NAS-Port = 0
rad_recv: Access-Accept packet from host 192.168.140.20 port 1812, id=219, length=20

# tcpdump -i eth1 -nn port 1812
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
17:36:07.065037 IP 192.168.160.20.33330 > 192.168.140.20.1812: RADIUS, Access Request (1), id: 0xdb length: 55
17:36:07.065622 IP 192.168.140.20.1812 > 192.168.160.20.33330: RADIUS, Access Accept (2), id: 0xdb length: 20


But I cannot reproduce the scenario a)
Full attached.

Comment 18 errata-xmlrpc 2012-06-20 14:05:36 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHBA-2012-0881.html

Comment 19 John Dennis 2012-08-07 19:47:21 UTC
*** Bug 839390 has been marked as a duplicate of this bug. ***