A FreeRADIUS for your Switch authentication

As previously blogged, I wanted to share and comment a sample config – where I use ntlm_auth for authentication against AD and LDAP for authorization of Administrators, this was done using FreeRADIUS 2.1.12 on Debian wheezy (7.x). Remember to do your own reading. I found “FreeRADIUS Beginner’s Guide” over at PacktPub to be a very good read to get a better understanding of FreeRADIUS and overall AAA concepts.


  • Show an example of a (then-working) FR virtual server for (Netgear) CLI authentication.
  • Have some explanation why I did things this way or not šŸ˜‰
  • I derived from the preinstalled default server config and shrinked it to the minimum required
  • For the Samba / Winbind configuration, consider the Book at PacktPub or look at Alan Dekok’s DeployingRadius.com
  • I use a non-standard port since another (main) RADIUS server is already listening on UDP 1812
  • Uses PAP since that’s what the switch only does. PAP sends plaintext password, but AD doesn’t have the plaintext password stored – blimey. We need ntlm_auth from Samba to do the check for us.

The server config is located in /etc/freeradius/sites-available and has to be symlinked to sites-enabled, but before doing so, youneed to

  • Configure Samba and Winbind, join the box to your Domain
  • Configure ntlm_auth module
    • ntlm_auth binary path
    • ntlm_auth’s domain

These parts can be found on DeployinRadius.com, then you might want to do rememeber / adapt to AD specific behaviour:

  • Modify the LDAP module to support AD nested groups if your users are not direct members (thanks Nasser Heidari):
    • groupmembership_filter = "(&(objectcategory=group)(member:1.2.840.113556.1.4.1941:=%{control:Ldap-UserDn}))"
  • Check, that your user group you want to query is NOT the primary group of your admin users since that doesn’t appear in the memberOf attribute .
    (if you are a LDAP magician and know a trick, let me know)

Anyway, let’s get started with the server:

server netdevices {

listen {
        ipaddr =
        port = 41812
        type = auth

# local test listener for debug of this virtual server
listen {
        ipaddr =
        port = 41812
        type = auth

Then the authorize section basically tells the server:

  • To use PAP (some switch vendors support (MS)CHAP but Broadcom FASTPATH only does PAP, so we can disable all the rest
  • If no Auth-Type was sent, update the control to use our own ntlm_auth that will be defined in authenticate.
authorize {
        #  If you are using multiple kinds of realms, you probably
        #  want to set "ignore_null = yes" for all of them.
        #  Otherwise, when the first style of realm doesn't match,
        #  the other styles won't be checked.


        # Most switches support PAP only
        #  This module should be listed last, so that the other modules
        #  get a chance to set Auth-Type for themselves.

        # If no Auth-Type was sent, we assume PAP but that we should
        # use ntlm_auth for AD authentication through ntlm_auth.
        if(!control:Auth-Type) {
                update control {
                        Auth-Type = "ntlm_auth"

The authenticate section is quite simple but we need to tell the server that it can use ntlm_auth, at the end. You’ll need to adapt /etc/freeradius/modules/ntlm_auth.

authenticate {
        # For PAP against AD with ntlm_auth we need to
        # let Samba ntlm_auth do the authentication work.
        Auth-Type NTLM_AUTH {

        # For local users with plaintext password we can still use LDAP
        # Reminder - you might disable update conrol in such casse in
        # authorize because it's an unconditinal update.
        Auth-Type PAP {

Most of the “magic” is finally done in the post-auth section:

  • Check if the user is in the required LDAP group, else reject
    • In AD I experienced problems with primary group memberships since they’re not written in memberOf Attributes
  • If it is an admin user, update the reply with the Netgear/Fastpath-specific AVpairs so the switch knows that it’s an administrative user
  • The remaining is from the default config, I’m not sure if we need it to work correctly.
#  Post-Authentication
#  Once we KNOW that the user has been authenticated, there are
#  additional steps we can take.
post-auth {
        # Only Domain admins are allowed, don't use the german group
        # name due to encoding issues
        if (LDAP-Group == "Network-Admins") {
                # Getting authorized requires informing the
                # (Netgear) device about privilege level.
                # Depending on the config only with this additional
                # reply message one gets authorized as admin on the shell.

                # Both seemed to work on Netgear 10.0.x,
                # Administrative-User is more vendor-neutral.

                update reply {
                        Service-Type = Administrative-User
                        Cisco-AVpair = "shell:priv-lvl=15"


        # No-one else is allowed.
        else {

        # For Exec-Program and Exec-Program-Wait

        #  Access-Reject packets are sent through the REJECT sub-section of the
        #  post-auth section.
        #  Add the ldap module name (or instance) if you have set
        #  'edir_account_policy_check = yes' in the ldap module configuration
        Post-Auth-Type REJECT {
                # log failed authentications in SQL, too.
#               sql


Done, now symlink your config to /etc/freeradius/sites-enabled and start FreeRADIUS (as recommended for testing) in debug mode (service freeradius stop, then freeradius -X)
If everything went ok, you should now be able to authenticate against your Switch SSH and the Web-UI, as well as getting authorized for administration.


Leave a Reply

August 29, 2013

Posted In: Uncategorized