FreeRADIUS + OpenVPN + pfSense for multiple locations/instances



  • Hi everyone,

    I've been following the guides to get OpenVPN working with FreeRADIUS under pfSense and that's no problem thanks to the detailed documentation available.  What I am wondering though is if you had 4 instances of pfSense running OpenVPN servers and all instances had to be accessible to the same list of users with the same credentials, is there an easy way to have the four instances of FreeRADIUS sync up by having a "master" FreeRADIUS server or something like that?  I should add that the four instances are not on the same LAN but are on ESXi machines in four different locations, so they can't all sync to the same local FreeRADIUS server.  Ideal scenario would be a nice web GUI to manage users on a "master" server that would then distribute the updated info out to the other 4 FreeRADIUS servers.

    My company has a server for the west coast US, east coast US and two in Europe to reduce the latency for when employees travel and keeping them all in sync could be a huge headache!

    Thanks!

    Colin



  • I've solved this having pfsense query external radius servers who get their data out of LDAP that is replicated to multiple sites.

    You will find some tips online but I had to piece a lot together, it's not turnkey.  The trickiest part is getting freeradius and ldap dynamic clients hooked up to get all of their data from ldap.  I don't have time to document the whole thing but here is what I think is the least documented part. How i did dynamic clients:

    dynamic client:

    
    client dynamic {
            #Include all IP's in the Dynamic Clients range
            ipaddr = 0.0.0.0
            netmask = 0
            dynamic_clients = dynamic_client_server
            lifetime = 86400
    }
    
    server dynamic_client_server {
    	authorize {
    		if ("%{ldap:ldap:///ou=Machines,dc=mycompany,dc=com?ou?one?ipHostNumber=%{Packet-Src-IP-Address}}") {
    			update control {
    				FreeRADIUS-Client-IP-Address = "%{Packet-Src-IP-Address}"
    				FreeRADIUS-Client-Shortname = "%{ldap:ldap:///ou=Machines,dc=mycompany,dc=com?cn?sub?i
    pHostNumber=%{Packet-Src-IP-Address}}"
    				FreeRADIUS-Client-NAS-Type = "%{ldap:ldap:///ou=Machines,dc=mycompany,dc=com?radiusHun
    tgroupName?sub?ipHostNumber=%{Packet-Src-IP-Address}}"
    				FreeRADIUS-Client-Secret = "%{ldap:ldap:///ou=Machines,dc=mycompany,dc=com?ou?sub?ipHo
    stNumber=%{Packet-Src-IP-Address}}"
    			}
    		}
    		ok
    	}
    }
    
    

    And then a Machine ldif looks like:

    
    dn: uid=firewall.mycompany.com$,ou=Machines,dc=mycompany,dc=com
    objectClass: account
    objectClass: posixAccount
    objectClass: ipHost
    objectClass: radiusprofile
    cn: firewall.mycompany.com$
    gidNumber: 10000
    homeDirectory: /dev/null
    ipHostNumber: 10.0.0.333
    uid: firewall.mycompany.com$
    uidNumber: 20000
    description: Machine account
    gecos: firewall.mycompany.com$
    loginShell: /bin/false
    ou: xxxxxxxxxxxxxxx
    radiusHuntgroupName: vpn
    
    

    I misuse the ou field to hold the dynamic client radius secret. I couldn't find an appropriate field in the radiusprofile  object class for storing the secret.

    Sorry I don't have time to document the whole procedure.  I've already spent more time on this reply than I had budgeted for!



  • That's exactly the help I needed, thanks so much Jeff!!!


Log in to reply