Freeradius and Cisco ASAs – Proper separation of roles!

In this post we will look at solving a problem using FreeRADIUS. I wrote some time ago about separating read-only access from admin access to Cisco ASAs using Microsoft NPS. It worked in theory, but a problem was found that an AD user who was not a member of either OU could still authenticate to the ASA using ASDM at level 15. Clearly, this was less than ideal. Check out the link though as it shows how to set up the ASA to use Radius and we’ll need that in a while.

I bounced around some more ideas, tested things out using Microsoft NPS, and even tried TACACS using Tac-plus. Still no dice. I went back to the idea of using Radius, mainly because of the fact that I didn’t want to have to run two systems to do the same thing, NPS got us most of the way there, TACACS would probably have finished the job, but requires a lot more investment in time, knowledge and money. Coupled with the fact that the IPS modules in our ASAs only support RADIUS I knew it was time to head back to the RADIUS idea and try and put this to bed.

Microsoft NPS doesn’t cut the mustard, though. Yes, it’s a good product, but clearly not the right product for this scenario.

Freeradius, on the other hand, offered something new, and I stumbled across the idea of using it from this very excellent post here. Our set up is slightly different, though, as we are using Microsoft AD as the LDAP backend, and require the use of AD groups as well as nesting of access control.

To explain, we have two users; npstest is a read-only account. It should have access to the ASA through SSH and through ASDM, but only at a maximum of level 3. It is a member of the AD group “sec-fw-readonly”. My own account should have full access on both SSH and ASDM and is a member of “sec-fw-administrator”.

We start with a Centos box and install freeradius using the command:

yum install freeradius*

Once free radius is installed we need to head to the folder /etc/raddb/ and from there into the modules directory (/etc/raddb/modules). The first file we need to edit is the ldap file (vi ldap) and set our details for connecting to the AD server:

server = "adserver.domain.local"
identity = "cn=ldapreadonly,ou=Service Accounts,dc=domain,dc=local"
password = passw0rd
basedn = "dc=domain,dc=local"
filter = "(&(objectclass=user)(objectcategory=user)(userPrincipalName=%{%{Stripped-User-Name}:-%{User-Name}}*))"
groupmembership_attribute = "memberOf"

The first line specifies the domain controller to connect to, and the next line specifies the account to use, the third line is the password for that account. The basedn is where freeradius should start searching for user accounts, and the filter does some funky mapping of AD attributes to freeradius attributes. The groupmembership_attribute will be needed for the reading of AD groups which we will need later on.

Lastly for this file is to uncomment these two lines:

chase_referrals = yes
rebind = yes

If you don’t uncomment those then you will get an “operations error” message when trying to search.

Next we must go back a level and into the sites-available file (/etc/raddb/sites-available) and edit the file “inner-tunnel”. In the authorize section comment out (using a #) the word “files”, and uncomment the word “ldap”. In the authenticate section again comment out the “files” line and uncomment the ldap section so it looks like this:

Auth-Type LDAP {
    ldap
}

Now we can edit the “default” file in the same folder, and make the exact same changes as the inner-tunnel file above.

Once this is done we can start defining our clients, this is in the file /etc/raddb/clients.conf and add your ASA in:

client 192.168.2.253 {
        secret = test123
        shortname = testasa
        nastype = cisco
}

With the secret being the shared secret you are going to use on your ASA.

In order to get both SSH and ASDM working as we need them to we need to uncomment one line in /usr/share/freeradius/dictionary, look for the following:

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

Just uncomment the $INCLUDE dictionary.cisco.vpn3000, and save the file.

Before we set up our ASA we are going to set up our group access in Radius, and to do that we go back into the default file. In the post-auth section I added the following:

if (LDAP-Group == "sec-fw-Administrator") {
        update reply {
                Service-Type = "Administrative-User",
                Cisco-AVPair = "shell:roles=network-admin",
                Cisco-AVPair += "shell:priv-lvl=15",
                CVPN3000-Privilege-Level = 15
                }
}
elsif (LDAP-Group == "sec-fw-readonly") {
        update reply {
                Service-Type = "Administrative-User",
                Cisco-AVPair = "shell:roles=network-operator",
                Cisco-AVPair += "shell:priv-lvl=1",
                CVPN3000-Privilege-Level = 3
                }
}
else {
                reject
}

Here we are specifying that a member of sec-fw-administrator should be an administrative user, with privilege level 15. The network-admin line is ready for when we switch our Nexus to use freeradius (as previously we set our Nexus to use Microsoft NPS as well). If our user is not a member of sec-fw-administrator then we need to see if they are a member of sec-fw-readonly, if they are then they should get into the ASA but only at a maximum of level 3. Finally, if they are not a member of either the connection attempt should be rejected.

Finally, we can switch our ASA to use freeradius, the config looks like this:

aaa-server FreeRadius protocol radius
aaa-server FreeRadius (Inside) host 192.168.3.121
 key test123
 authentication-port 1812
 accounting-port 1813
aaa authentication ssh console FreeRadius LOCAL
aaa authentication enable console FreeRadius LOCAL
aaa authentication http console FreeRadius LOCAL
aaa accounting enable console FreeRadius
aaa accounting ssh console FreeRadius
aaa authorization exec authentication-server

Now we can test. Firstly by logging in with my account:

login as: sfordham
[email protected]'s password:
Type help or '?' for a list of available commands.
testasa> sh curp
Username : sfordham
Current privilege level : 1
Current Mode/s : P_UNPR
testasa> en
Password: *********
testasa# sh curp
Username : sfordham
Current privilege level : 15
Current Mode/s : P_PRIV
testasa#

And with ASDM:

FreeRADIUS and level 15 ASDM access

Next, we test with a read-only level account:

login as: testnps
[email protected]'s password:
Type help or '?' for a list of available commands.
testasa> sh curp
Username : testnps
Current privilege level : 1
Current Mode/s : P_UNPR
testasa> en
Password: ***********
testasa# sh curp
Username : testnps
Current privilege level : 3
Current Mode/s : P_PRIV
testasa#

And with ASDM:

FreeRADIUS giving level 3 ASDM access

Lastly with an account that should be rejected:

Cisco ASA user rejected
ASDM user login failed

Finally, we have a working solution!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.