Using FreeRADIUS with Cisco Devices

Even though I am the only administrator for the devices in my lab and home network, I thought it would be nice to have some form of centralized authentication, authorization and accounting for these devices. However, I quickly realized that using a dedicated appliance such as Cisco ACS or ISE would mean adding another always-on VM to my lab environment. I wasn’t quite ready to start wasting my lab resources on a basic function like AAA. So instead of using a dedicated appliance, I decide to implement FreeRADIUS on the Ubuntu Linux server that I use for DNS, DHCP, syslog, and other network services in my lab.

Although, TACACS+ is usually the protocol of choice for Cisco AAA, my requirements are simple enough that RADIUS will work just as well. And since FreeRADIUS is included in the standard Ubuntu repositories this should be very easy to install.

My requirements are pretty straightforward. I want to use the RADIUS server to authenticate users and then assign one of two profiles: An “administrator” profile which has full admin rights (the equivalent of IOS privilege level 15 or the NX-OS network-admin role) and an “operator” profile which has read-only rights (the equivalent of IOS privilege level 1 or the NX-OS network-operator role). These user profiles should be assigned through RADIUS. Of course I also want some basic accounting. Because I don’t need fancier functions, such as command authorization, RADIUS should be sufficient.

Rather than messing with my regular server I deploy a fresh Ubuntu VM for testing purposes. I then install the freeradius and freeradius-utils packages using apt-get:

tom@freeradius:~$ sudo apt-get install freeradius freeradius-utils

The freeradius-utils package is not strictly necessary, but nice to have when you need to troubleshoot the RADIUS implementation. Especially the radtest and radsniff commands are useful to verify the attributes that are exchanged between the client and the server.

Note: I had to do a fair amount of troubleshooting to find a set of attributes that works for the combination of IOS devices, NX-OS devices and ASAs. To keep this post clean, I will not list all the intermediate steps and stuff I tried that didn’t work, but simply present the eventual working configurations that I ended up with.

Next, I add an entry to the /etc/freeradius/clients.conf file to define the RADIUS key for a group of devices:

client 192.168.36.0/24 {
        secret = Fr33-R@d1u$
        shortname = lab-network
        nastype = cisco
}

Rather than creating separate entries for every client device, I create a blanket statement that allows all devices in my lab IP range to use the same RADIUS key. Of course you can create individual entries for each client if you prefer.

Now it is time to define my “admin” and “ops” users. I add the following entries to the /etc/freeradius/users file:

admin           Cleartext-Password := 1234QWer
                Service-Type = Administrative-User,
                Cisco-AVPair = "shell:roles=network-admin",
                Cisco-AVPair += "shell:priv-lvl=15"

ops             Cleartext-Password := 1234QWer
                Service-Type = NAS-Prompt-User,
                Cisco-AVPair = "shell:roles=network-operator",
                Cisco-AVPair += "shell:priv-lvl=1"

tom             Auth-Type := System
                Service-Type = Administrative-User,
                Cisco-AVPair = "shell:roles=network-admin",
                Cisco-AVPair += "shell:priv-lvl=15"

And of course I restart the freeradius service to commit my changes:

tom@freeradius:~$ sudo service freeradius restart
 * Stopping FreeRADIUS daemon freeradius
   ...done.
 * Starting FreeRADIUS daemon freeradius
   ...done.

There are a couple of things that are worth noting about this configuration:

  • First of all, this post is not intended as a guide for setting up a production FreeRADIUS deployment. As such, the entries above do not represent best practices. My primary objective is to describe the attributes required for the various types of Cisco devices. For example, defining the passwords directly in the users file using the Cleartext-Password attribute is not good practice, but can be useful when you’re testing and experimenting. Also, defining the Auth-Type for a specific user is frowned upon. You may want to refer to the FreeRADIUS documentation if you intend to use FreeRADIUS in a production environment.
  • For the “admin” and “ops” users I defined the password directly in the users file using the Cleartext-Password attribute. On the other hand, the user “tom” is tied to the existing local system account on the Ubuntu server.
  • The “admin” and “tom” users are set up as Service-Type = Administrative-User, while the user “ops” is set up as Service-Type = NAS-Prompt-User. This distinction is primarily relevant for the ASA. For the ASA the Service-Type determines whether a user can use the enable command to go to privileged mode or not. This is documented in the ASA Management Access Configuration Guide. Some basic testing revealed that IOS also honors the Service-Type out of the box. It assigns privilege 1 to users of type NAS-Prompt-User, while it assigns privilege 15 to users of type Administrative-User. However, it is still possible to elevate NAS-Prompt-Users to privilege level 15 through use of the shell:priv-lvl Cisco AV pair. NX-OS does not honor the Service-Type by default, but requires the shell:roles Cisco AV pair to assign the network-admin or network-operator roles to the user. Therefore, I feel that it is better to always explicitly define the privilege level or role for IOS and NX-OS users.
  • Because this configuration is intended to be used for both IOS and NX-OS, it is necessary to define two Cisco-AVPair attributes. To pass both these attributes in the response instead of just the first one, it is necessary to use the “+=” operator on the second Cisco AV pair.
  • If you run into situations where the RADIUS client refuses the connection because it does not understand one of the two Cisco-AVPair attributes, you could replace the “=” in the AV pair with a “*” to make it an optional attribute (for example "shell:roles*network-admin" instead of "shell:roles=network-admin"). With the versions of NX-OS, IOS and ASA software that I used for testing this was not necessary.
  • And finally, I first tried to name my “ops” user “operator”, finding out the hard way that this is one of the reserved NX-OS usernames, causing the logins to fail. Other names that cannot be used are defined in the NX-OS documentation, for example the Nexus 1000v Security Configuration Guide. So be warned, these names really cannot be used!

Now that we have a our basic FreeRADIUS configuration in place, we can start adding AAA configuration to the various devices and start testing. First I configure my lab Nexus 1000v:

radius-server host 192.168.36.102 key Fr33-R@d1u$ authentication accounting 
!
aaa group server radius FREERADIUS 
    server 192.168.36.102 
    use-vrf management
    source-interface mgmt0
!
aaa authentication login default group FREERADIUS 
aaa accounting default group FREERADIUS

Next I login as the user “tom” and verify my role:

tom@freeradius:~$ ssh tom@n1kv.lab.layerzero.nl
Nexus 1000v Switch
Password: 
Cisco Nexus Operating System (NX-OS) Software
TAC support: http://www.cisco.com/tac
Copyright (c) 2002-2013, Cisco Systems, Inc. All rights reserved.
The copyrights to certain works contained in this software are
owned by other third parties and used and distributed under
license. Certain components of this software are licensed under
the GNU General Public License (GPL) version 2.0 or the GNU
Lesser General Public License (LGPL) Version 2.1. A copy of each
such license is available at
http://www.opensource.org/licenses/gpl-2.0.php and
http://www.opensource.org/licenses/lgpl-2.1.php
n1kv# show user-account tom
user:tom
        roles:network-admin 
account created through REMOTE authentication
Credentials such as ssh server key will be cached temporarily only for this user account
Local login not possible

And of course I also want to verify my “ops” user and its assigned role:

tom@freeradius:~$ ssh ops@n1kv.lab.layerzero.nl
Nexus 1000v Switch
Password: 
Cisco Nexus Operating System (NX-OS) Software
TAC support: http://www.cisco.com/tac
Copyright (c) 2002-2013, Cisco Systems, Inc. All rights reserved.
The copyrights to certain works contained in this software are
owned by other third parties and used and distributed under
license. Certain components of this software are licensed under
the GNU General Public License (GPL) version 2.0 or the GNU
Lesser General Public License (LGPL) Version 2.1. A copy of each
such license is available at
http://www.opensource.org/licenses/gpl-2.0.php and
http://www.opensource.org/licenses/lgpl-2.1.php
n1kv# show user-account ops
user:ops
        roles:network-operator 
account created through REMOTE authentication
Credentials such as ssh server key will be cached temporarily only for this user account
Local login not possible

As can be seen, these users are properly authenticated and assigned their respective roles. Next, I configure AAA on a CSR 1000v instance to test the FreeRADIUS configuration on an IOS device:

aaa new-model
!
radius server FREERADIUS
 address ipv4 192.168.36.102 auth-port 1812 acct-port 1813
 key Fr33-R@d1u$
!
aaa group server radius LAB-RADIUS
 server name FREERADIUS
 ip vrf forwarding Mgmt-intf
 ip radius source-interface GigabitEthernet0
!
aaa authentication login default group LAB-RADIUS local
aaa authorization exec default group LAB-RADIUS local 
aaa accounting exec default start-stop group LAB-RADIUS

Again, I log in as user “tom” and verify my privilege level:

tom@freeradius:~$ ssh tom@csr1kv.lab.layerzero.nl
Password: 
csr1kv#show privilege 
Current privilege level is 15

And I also test the ops user account:

tom@freeradius:~$ ssh ops@csr1kv.lab.layerzero.nl
Password: 
csr1kv>show privilege
Current privilege level is 1

Again, the output confirms that the users have been successfully authenticated and proper privilege levels have been assigned. Finally, I configure my ASA:

aaa-server FREERADIUS protocol radius
aaa-server FREERADIUS (inside) host 192.168.36.102
 key Fr33-R@d1u$
 authentication-port 1812
 accounting-port 1813
aaa authentication http console FREERADIUS LOCAL
aaa authentication ssh console FREERADIUS LOCAL
aaa authentication enable console FREERADIUS LOCAL
aaa accounting ssh console FREERADIUS
aaa authorization exec authentication-server

And again, I login as user “tom”:

tom@skywalker:~$ ssh tom@r2d2.home.layerzero.nl
tom@r2d2.home.layerzero.nl's password: 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++ +                                                       +
+ +                 This is firewall r2d2                 ++
++            Nothing to see here, so go away!           + +
+                                                       + ++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Type help or '?' for a list of available commands.
r2d2> show curpriv
Username : tom
Current privilege level : 1
Current Mode/s : P_UNPR
r2d2> enable
Password: ********
r2d2# show curpriv
Username : tom
Current privilege level : 15
Current Mode/s : P_PRIV

As you can see the ASA does not immediately drop the user in privileged mode. However, it does allow a user that has the Service-Type = Administrative-User attribute to issue the enable command and go to privileged mode using the user’s RADIUS password instead of the locally defined enable password. Now let’s see what happens when I log in as the user “ops”:

tom@skywalker:~$ ssh ops@r2d2.home.layerzero.nl
ops@r2d2.home.layerzero.nl's password: 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++ +                                                       +
+ +                 This is firewall r2d2                 ++
++            Nothing to see here, so go away!           + +
+                                                       + ++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Type help or '?' for a list of available commands.
r2d2> show curpriv
Username : ops
Current privilege level : 1
Current Mode/s : P_UNPR
r2d2> enable
Password: ********

[ ops ] You do NOT have enable Admin Rights to the console
Password:

As can be seen, this time the ASA does not allow the user to use the enable command to go to privileged mode based on the Service-Type = NAS-Prompt-User attribute. So for CLI access everything  now works as I had set down in my requirements. However, there is still a little catch here. When I login to ASDM, the “ops” user still gets full access. Apparently, just setting the Service-Type is not sufficient for ASDM, because it does not use the enable command and the ASA does not honor the Cisco shell:priv-lvl attribute. When I log in to ASDM as the “ops” user, it lists a privilege level of 15 in the bottom right corner next to the user name. So it looks like we need another RADIUS tweak.

To fix this we need to use another RADIUS attribute to set the privilege level for the ASA. This attribute originally comes from the Cisco/Altiga VPN 3000 concentrators. Unfortunately, the Cisco VPN dictionary is disabled by default in the FreeRADIUS dictionary file in /usr/share/freeradius/dictionary:

#
#        The Cisco VPN300 dictionary is the same as the altiga one.
#        You shouldn't use both at the same time.
#
#$INCLUDE dictionary.cisco.vpn3000

Despite the comment in the file, the Altiga dictionary is not enabled by default either, so I decide to simple uncomment the $INCLUDE dictionary.cisco.vpn3000 line to include the VPN 3000 dictionary. This enables the use of the CVPN3000-Privilege-Level attribute (vendor ID 3076 and attribute ID 220), which can be used to set the privilege level for the ASA.

Now that the Cisco VPN 3000 library has been enabled I add the appropriate privilege levels to the users in my user file:

admin           Cleartext-Password := 1234QWer
                Service-Type = Administrative-User,
                Cisco-AVPair = "shell:roles=network-admin",
                Cisco-AVPair += "shell:priv-lvl=15",
                CVPN3000-Privilege-Level = 15

ops             Cleartext-Password := 1234QWer
                Service-Type = NAS-Prompt-User,
                Cisco-AVPair = "shell:roles=network-operator",
                Cisco-AVPair += "shell:priv-lvl=1",
                CVPN3000-Privilege-Level = 3

tom             Auth-Type := System
                Service-Type = Administrative-User,
                Cisco-AVPair = "shell:roles=network-admin",
                Cisco-AVPair += "shell:priv-lvl=15",
                CVPN3000-Privilege-Level = 15

And of course I need to restart the service again to commit my changes:

tom@freeradius:~$ sudo service freeradius restart
 * Stopping FreeRADIUS daemon freeradius
   ...done.
 * Starting FreeRADIUS daemon freeradius
   ...done.

You may wonder why I am setting the privilege level of the “ops” user to 3, instead of using level 1 like I did for IOS. The reason for this is that ASDM requires users to have a minimum privilege level of 2 to allow them to login. In addition, ASDM has a special button that makes it simple to setup the required command authorization for a monitor-only user like my “ops” user.

This is actually the next step in the procedure: I log in to ASDM as the admin user and then navigate to “Configuration > Device Management > Users/AAA > AAA Access > Authorization”. Next, I check the command authorization checkbox and set it to local. Then I click the “Set ASDM Defined User Roles” button to assign appropriate privilege levels to a predefined set of commands. Once these settings are applied, the following list of commands is added to the ASA:

aaa authorization command LOCAL

privilege cmd level 3 mode exec command perfmon
privilege cmd level 3 mode exec command ping
privilege cmd level 3 mode exec command who
privilege cmd level 3 mode exec command logging
privilege cmd level 3 mode exec command failover
privilege cmd level 3 mode exec command vpn-sessiondb
privilege cmd level 3 mode exec command packet-tracer
privilege show level 5 mode exec command import
privilege show level 5 mode exec command running-config
privilege show level 3 mode exec command reload
privilege show level 3 mode exec command mode
privilege show level 3 mode exec command firewall
privilege show level 3 mode exec command asp
privilege show level 3 mode exec command cpu
privilege show level 3 mode exec command interface
privilege show level 3 mode exec command clock
privilege show level 3 mode exec command dns-hosts
privilege show level 3 mode exec command access-list
privilege show level 3 mode exec command logging
privilege show level 3 mode exec command vlan
privilege show level 3 mode exec command ip
privilege show level 3 mode exec command ipv6
privilege show level 3 mode exec command failover
privilege show level 3 mode exec command asdm
privilege show level 3 mode exec command arp
privilege show level 3 mode exec command route
privilege show level 3 mode exec command ospf
privilege show level 3 mode exec command aaa-server
privilege show level 3 mode exec command aaa
privilege show level 3 mode exec command eigrp
privilege show level 3 mode exec command crypto
privilege show level 3 mode exec command ssh
privilege show level 3 mode exec command vpn-sessiondb
privilege show level 3 mode exec command vpnclient
privilege show level 3 mode exec command vpn
privilege show level 3 mode exec command dhcpd
privilege show level 3 mode exec command blocks
privilege show level 3 mode exec command wccp
privilege show level 3 mode exec command dynamic-filter
privilege show level 3 mode exec command webvpn
privilege show level 3 mode exec command service-policy
privilege show level 3 mode exec command module
privilege show level 3 mode exec command uauth
privilege show level 3 mode exec command compression
privilege show level 3 mode configure command interface
privilege show level 3 mode configure command clock
privilege show level 3 mode configure command access-list
privilege show level 3 mode configure command logging
privilege show level 3 mode configure command ip
privilege show level 3 mode configure command failover
privilege show level 5 mode configure command asdm
privilege show level 3 mode configure command arp
privilege show level 3 mode configure command route
privilege show level 3 mode configure command aaa-server
privilege show level 3 mode configure command aaa
privilege show level 3 mode configure command crypto
privilege show level 3 mode configure command ssh
privilege show level 3 mode configure command dhcpd
privilege show level 5 mode configure command privilege
privilege clear level 3 mode exec command dns-hosts
privilege clear level 3 mode exec command logging
privilege clear level 3 mode exec command arp
privilege clear level 3 mode exec command aaa-server
privilege clear level 3 mode exec command crypto
privilege clear level 3 mode exec command dynamic-filter
privilege cmd level 3 mode configure command failover
privilege clear level 3 mode configure command logging
privilege clear level 3 mode configure command arp
privilege clear level 3 mode configure command crypto
privilege clear level 3 mode configure command aaa-server

When I log in to ASDM as the “ops” user, I now properly get a privilege level of 3 assigned and I only see the monitor tab, not the configuration tab. I also retest the CLI access for the various devices to verify that these were not affected by the changes.

With this final tweak I now have FreeRADIUS properly set up to provide AAA services to all devices in my home and lab networks. Also, this post can serve as a “known-good” reference configuration for RADIUS implementations on different platforms.

17 thoughts on “Using FreeRADIUS with Cisco Devices

  1. Tom,

    Perhaps you can try tac_plus as well. I have set it up on a ubuntu server, this does allow for command level authorization and all other kind of nice functions. It comes standard in the apt repository as well.

    • Hi Paul,

      Thanks for the suggestion. I wasn’t aware that tac_plus was in the standard repositories as well.

      I don’t really need the fancier tacacs+ functions for my personal use case, but it would still be nice to have for testing purposes.
      Another reason that I wanted to test out a radius setup instead of tacacs+ is that I have run into several customers that are using radius, either because they have a Microsoft environment and want to use IAS, or because they have non-Cisco devices on their network that support RADIUS, but not tacacs+.

      Still, it would be nice to add tacacs+ into the mix, so it looks like I have to go and spend some more time in the lab…

  2. Hello,

    I cannot replicate the config for the ASA at the point where you configured:

    Service-Type = NAS-Prompt-User,
    CVPN3000-Privilege-Level = 3

    the NAS-Prompt-User would deny the “enable” command, so how would the priv lvl of 3 ever make sense?

    Thanks,
    Harry

    • Hi Harry,

      The privilege level of 3 is just to limit the rights of the “ops” user in ASDM. If I don’t set that, the “ops” user would have read-only rights in the CLI, but full access in ASDM. To limit the rights of the user in ASDM, the “CVPN3000-Privilege-Level = 3” is required. It needs to be 2 or higher to get ASDM access and lower than 15 to block full administrative access.

      The “enable” command doesn’t have anything to do with this, because that is not used by ASDM. As you say, the “ops” user is already limited to a read-only role in the CLI by the service type “NAS-Prompt-User”.

      Hope this helps,

      Tom

      P. S. I am not 100% sure that I am interpreting your question correctly, so if this answer does not help, please describe what exactly isn’t working for you. What behavior did you expect and what are you actually seeing?

  3. Hi,

    very well done post. This is one of the missing glue pieces I’ve missed so far. Thanks for that.

    I’m trying to adapt the same using a radius server from RSA. I’ve meanwhile got everything set, I captured the radius traffic but when logging in to the ASA, it just not dropping me in with privilege 15 and a “#” prompt.

    In your post above, I can’t find a capture that shows the login for the admin is really dropping in the CLI with privilege 15. Did it work finally? Or do you still have to enter a enable password (the same as for login)?

    Cheers Alex

    • Hi Alex,

      You are correct: The way it works is that you are not immediately dropped into the CLI with privilege 15, but you still have to use the “enable” command to get to to that privilege level. (However, the password used to “enable” is the same as your login password).

      This simply seems to be a difference in behavior between the ASA and IOS. I don’t think that it is possible to change that.

      Hope that clears it up,

      Tom

  4. i have found that adding:

    aaa authorization exec authentication-server auto-enable

    for admin/priv 15 users drops them in enabled (# prompt).

    still trying to work out if i can send privilege-level from Microsoft NPS…

    • Interesting! I wasn’t aware of that command.
      It looks like it was introduced in ASA version 9.2(1).

      In theory sending privilege level from Microsoft NPS should work, but I think the main issue there is loading the VPN3000 dictionary.
      I’m afraid I can’t help you with that. I’m not too familiar with Microsoft NPS.

      Regards,

      Tom

  5. Pingback: Freeradius and Cisco ASAs - Proper separation of roles! - www.802101.com

  6. Hi Tom,

    is it possible to restrict CLI access to go in enable mode to view configs but stopping them to config mode?

    Regards
    Hari

    • Hi Hari,

      That’s not really easy to do with IOS and RADIUS. First of all it would be necessary to define a privilege level that includes the “show running-config” command, but not the configuration commands. Unfortunately, the “show run” command only shows commands that you are authorized to use, so that doesn’t work. However, you should be able to define a privilege level that includes the “show startup-config” command in addition to the regular privilege 1 commands. Then you could assign that privilege level through RADIUS as shown above. This may not be exactly what you asked for, but I think it is the closest you can get with the combination of IOS and RADIUS.

      An alternative would be to use the Tacacs+ protocol with the command authorization feature, forcing every command to be sent to the Tacacs+ server for authorization allowing you to set up more fine-grained controls.

      Hope this helps,

      Tom

  7. Very nice work!! This is what i was looking for, I am also planning to integrate Freeradius with LDAP so it will fetch password from there securely + i can manage groups in LDAP. i will keep you posted.

Leave a Reply to Paul Schriever Cancel reply

Your email address will not be published. Required fields are marked *