FreeRADIUS / pam_radius

This is the PAM to RADIUS authentication module. It allows any Linux, OSX or Solaris machine to become a RADIUS client for authentication and password change requests.
GNU General Public License v2.0
103 stars 90 forks source link

Add support for Linux VRF (SO_BINDTODEVICE), use per-server sockets if src_ip or vrf are requested #34

Closed bluca closed 7 years ago

bluca commented 7 years ago

Linux VRF doc: https://www.kernel.org/doc/Documentation/networking/vrf.txt

I've tested this on Debian 9 with the following config file:

127.0.0.1 secret 1
192.168.122.122 secret 1 0 vrf-blue
192.168.1.1 secret 1 192.168.1.10
192.168.122.122 secret 1 192.168.122.2 vrf-blue

The 192.168.122.x is on a virtual interface enslaved to a VRF. 192.168.1.x is on an interface with 2 IP addresses, and the config asks to use the second one (to test src_ip).

With Wireshark I could observe all 4 packets going out from the correct interfaces.

I've done a small refactor w.r.t. socket initialisation, to avoid code duplication, and in error handling (to correctly clean up all open sockets).

I've also completed one item that was listed as TODO in the code - creating per-server sockets, as it was necessary to be able to use multiple servers in different VRFs. It will also allow to use different src_ip for different servers.

alandekok commented 7 years ago

Overall it looks pretty good. Tho the duplication of v4/v6 sockets could be fixed. i.e. if it's talking to a server on a v4 socket, it doesn't need a v6 socket for that server.

bluca commented 7 years ago

Thanks for the merge!

Overall it looks pretty good. Tho the duplication of v4/v6 sockets could be fixed. i.e. if it's talking to a server on a v4 socket, it doesn't need a v6 socket for that server.

True. Although it would need a bit of refactoring since the hostname is only parsed later at runtime, rather than at initialisation time, so when creating the socket and choosing AF_INET or AF_INET6 it is not yet known what is needed to talk to that specific server.

bluca commented 7 years ago

@dsahern FYI - just in case, not sure if Cumulus Linux uses libpam-radius-auth

dsahern commented 7 years ago

Adding @daveolson53. He handles the pam stuff for CL.

daveolson53 commented 7 years ago

David Ahern notifications@github.com wrote:

Adding @daveolson53. He handles the pam stuff for CL.

I had implemented this for Cumulus Linux, but haven't pushed the changes anywhere to github yet. My apologies for that.

I'm not seeing the issue or pull request. Am I looking at the right repo? I'm looking at: https://github.com/FreeRADIUS/pam_radius

I'd like to look at them and compare them to what I did; there may be a better approach than mine.

My changes were based on commit a11bbaeb6b0635dd852fb511a28f67da80327fef from that repo.

Ignoring documentation and other changes, the vrf changes I did were not too large. I see some minor whitespace issues in the attached patch.

You can also ignore the SUDO_PROMPT changes, I did those for some other work I did to allow radius account login without adding the user to the local password file or database. That requires another library and config file to map radius users to a local fixed account, similar to what I did with the tacacs client code under daveolson53 on github.

I'll get all these changes on github "soon". I meant to do that earlier but got sidetracked. The tacacs client repos are under https://github.com/daveolson53/ if you want to see what I did there. I'll put the radius client repos in the same place.

Dave Olson olson@cumulusnetworks.com

diff --git a/src/pam_radius_auth.c b/src/pam_radius_auth.c index a9fd518..3631db7 100644 --- a/src/pam_radius_auth.c +++ b/src/pam_radius_auth.c @@ -227,7 +227,6 @@ static int host2server(int debug, radius_server_t *server)

server->ip = (struct sockaddr *)&server->ip_storage;
r = get_ipaddr(hostname, server->ip, port);

@@ -525,13 +524,14 @@ static int initialize(radius_conf_t *conf, int accounting) struct sockaddr_storage salocal6; char hostname[BUFFER_SIZE]; char secret[BUFFER_SIZE];

@@ -549,6 +549,7 @@ static int initialize(radius_conf_t *conf, int accounting) return PAM_ABORT; }

daveolson53 commented 7 years ago

Dave Olson olson@cumulusnetworks.com wrote:

David Ahern notifications@github.com wrote:

Adding @daveolson53. He handles the pam stuff for CL.

I had implemented this for Cumulus Linux, but haven't pushed the changes anywhere to github yet. My apologies for that.

I'm not seeing the issue or pull request. Am I looking at the right repo? I'm looking at: https://github.com/FreeRADIUS/pam_radius I'd like to look at them and compare them to what I did; there may be a better approach than mine.

Never mind. I didn't find it in the issues because it was already merged. The changes look more thorough than mine, but I won't have time to look at them thoroughly until next week, most likely.

Thanks for doing this work!

Dave Olson olson@cumulusnetworks.com

bluca commented 7 years ago

No problem, thanks @daveolson53 !

The changes that were merged will allow to use different servers on different VRFs, which unless I'm mistaken was not the case with the patch you posted.

The main difference in behaviour is on failure to set SO_BINDTODEVICE - I choose to make it a hard failure, because the same address might be reachable outside of the requested VRF but might be the wrong server, which is a security concern given it's dealing with authentication. At the very least it would leak information. What do you think?

daveolson53 commented 7 years ago

Luca Boccassi notifications@github.com wrote:

No problem!

The changes that were merged will allow to use different servers on different VRFs, which unless I'm mistaken was not the case with the patch you posted.

That's correct, mine was more limited.

The main difference in behaviour is on failure to set SO_BINDTODEVICE - I choose to make it a hard failure, because the same address might be reachable outside of the requested VRF but might be the wrong server, which is a security concern given it's dealing with authentication. At the very least it would leak information. What do you think?

I hadn't thought about that potential security issue, and should have.

The other reason I didn't make it a hard failure was that sometimes people forget to change config files when they change vrf configuration (including removing it completely). But with reasonable error messages, and given the security issue, I agree that you made the right choice.

I'm in the middle of some short term deliverables, but after that I'll merge what you did with my code, possibly with some changes so it's compatible with what we already shipped to customers (should be minor, if any).

Thanks,

Dave Olson olson@cumulusnetworks.com