It’s all change in the office so far this year, which is quite good as I’m involved in more projects, and who doesn’t enjoy a few projects ;)

The latest thing I was asked to look into was to create a new TACACS+ server as our current server on a HP Proliant BL460c G1 Blade is going to be decommissioned so we need to give it a new home! It was decided that it should be virtualized as there isn’t a need to have a physical server for something that can be slimmed down dramatically. With that being said this post will go over how to configure a TACACS+ server and configure TACACS+ authentication on a Juniper device.

TACACS+ is an improvement on its first version TACACS, as TACACS+ is an entirely new protocol and is not compatible with its predecessors, TACACS and XTACACS. TACACS+ uses TCP. Since TACACS+ uses the authentication, authorisation, and accounting (AAA) architecture, these separate components of the protocol can be segregated and handled on separate servers. TACACS+ allows you to set granular access policies for users and groups, commands, location, subnet, or even device type. The TACACS+ protocol also provides detailed logging of users and what commands have been run on specific devices. In addition, the protocol can run on either Windows or UNIX/Linux.

Although TACACS+ was developed by Cisco Systems, it is actually an open standard as defined by RFC1482 and has been incorporated into a number of different vendors including Alcatel/Lucent, Arbor, Brocade/Foundry, Cisco/Linksys, Extreme, HP/3Com, Huawei, IBM, Juniper/Netscreen, Netgear and any others.

The setup I had for testing was a simple one; I had 2 EXSi Ubuntu 14.04LTS hosts, one as the TACACS+ server with the second being used as Jump-box to access a Juniper SRX220 that will be configured for TACACS authentication.

With all that talk out of the way, let’s get cracking :)

You will run sudo/root privileges

Server Configuration

Fortunately, with the newer version of Ubuntu, from apt-get repository you can easily download the tacacs+ package it will also install libtacacs+1

marquk01@km-vm4:~$ sudo apt-get install tacacs+
\[sudo\] password for marquk01: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  libtacacs+1
The following NEW packages will be installed
  libtacacs+1 tacacs+

Having installed the package now we can run the command ps -ef | grep tac\_plus and it will show us the location of the configuration file and if the process is running:

marquk01@km-vm4:~$ ps -ef | grep tac\_plus
root      1220     1  0 11:37 ?        00:00:00 /usr/sbin/tac\_plus -C /etc/tacacs+/tac\_plus.conf
marquk01 22730  2682  0 13:55 pts/0    00:00:00 grep --color=auto tac\_plus

As the process is running there’s a few useful binary files that are important to know, these can be seen when you type tac and hit TAB.

marquk01@km-vm4:~$ tac
tac  tac\_plus  tac\_pwd

The important files are tac\_plus and tac\_pwd:

  • tac_plus is the TACACS+ daemon. You can run daemon via the cli
  • tac_pwd is used to generate a Data Encryption Standard (DES) or Message-Digest 5 (MD5) hash from clear text. DES is the defualt, to generate a MD5 hash you need to add -m flag.

We will need to configure the tac_plus.conf file, but firstly we will need to back-up the original file to refer back to if there is any issues

marquk01@km-vm4:~$ sudo cp /etc/tacacs+/tac\_plus.conf /etc/tacacs+/tac\_plus.conf.old

I’ll explain from top-down of what my file looks like. The default file has more parameters than I used, as my file doesn’t need too much complexity. My example will also show you how to configure the basis Accounting, Secret Key, Users and Groups. Logically when I look at the layout of the file as I have, it doesn’t make sense… However, all the information is there soooooo it doesn’t matter :p lol

Accounting

Firstly we’ll need to set the file that the accounting information will be written to. By default this is /var/log/tac_plus.acct, however you can have this file where you like if you don’t want you use the default file and path.

You have to create this file yourself. This can be done by running the command sudo touch /var/log/tac_plus.acct

\# Created by Henry-Nicolas Tourneur(henry.nicolas@tourneur.be)
# See man(5) tac\_plus.conf for more details

# Define where to log accounting data, this is the default.

accounting file = /var/log/tac\_plus.acct

### Secret Key

The Server and Client need to have a matching key so the AAA packets can be encrypted. This key can be anything you wish however, if you're going to have a key with white-space, key-words, or special characters, you’ll need to use quotation marks

\# This is the key that clients have to use to access Tacacs+

key = testing123

Users

You’ll need to define the users that will have access to the device. Each user needs to be associated to a group and have their password defined. The password has to be set as either a MD5 or DES hash. By using tac_pwd use can get your hashed output:

marquk01@km-vm4:~$ tac\_pwd
Password to be encrypted: lab123
kBeC6JDjU8icY

There is an additional stanza service = junos-exec that defines an additional group. This is Juniper specific and I’ll explain this later. I created two users kmarquis; will have permission to do anything and second user test; that will only have Read-Only access. Both have the same password. Usernames ARE case sensitive.

\# We also can define local users and specify a file where data is stored.
# That file may be filled using tac\_pwd
user = kmarquis {
    name = "Keeran Marquis"
    member = admin
    login = des kBeC6JDjU8icY
		service = junos-exec {
			local-user-name = remote-admin
	}
}

user = test {
    name = "Test User"
    member = read-only
    login =  des kBeC6JDjU8icY
        service = junos-exec {
            local-user-name = remote-read-only
               }
}

Groups

As you can guess, groups are where you define the level of access and what commands will be used by the group. The commands, for my example, are used to define actions that are largely accepted by most vendors with the expectation of Juniper (from my knowledge but correct me if I’m wrong), although I wont be confirming the configuration works in this post. I have checked with a Cisco device and they worked as expected.

We have a few parameters that are important remember:

  • default service: defines the default permission that the user will have. By default, if this statement isn’t used or left blank, it’s denied. Meaning that each permitted command users of this group will have to be listed. If you want the default permission to allow, then the statement permit is needed
  • service: define services which the group is authorised to execute, these could be commands that the group is authorised to execute. Authorisation must be configured on both the client and the daemon to operate correctly.
  • cmd: This is where you list a command and set an action, it will be either be a permit or deny. Additionally by having the .* this means that any command after the first word is affected. i.e my example below, all show commands will be permitted

In my example I have two groups, admin and read-only, the admin group will have full access permitted and the read-only group, as the name suggests, will have read-only access and will be denied from any configuration, clear or restart commands.

\# We can also specify rules valid per group of users.
group = admin {
	default service = permit
	service = exec {
		priv-lvl = 15
		}
	}

group = read-only {
	service = exec {
		priv-lvl = 15
		}
	cmd = show {
		permit .\*
		}
	cmd = write {
		permit term
		}
	cmd = dir {
		permit .\*
		}
	cmd = admin {
		permit .\*
		}
	cmd = terminal {
		permit .\*
		}
	cmd = more {
		permit .\*
		}
	cmd = exit {
		permit .\*
		}
	cmd = logout {
		permit .\*
		}
}

My completed tac_plus file can be seen here.

For more in-depth detail and additional parameters that can be configured in this file, you can find them via the man pages using the command man tac_plus or online Ubuntu tac_plus Manual Documentation

Once you’re happy with everything you can run service tacacs_plus check to make sure the syntax is correct and if you get any errors you will need to restart the daemon using service tacacs_plus restart

TACACS+ Daemon Commands

Additional commands that will be useful to remember:

service tacacs_plus check
service tacacs_plus status
service tacacs_plus stop
service tacacs_plus start
service tacacs_plus restart

With that we have a TACACS+ server configured :)

Vendor-Specific TACACS+ Attributes

Before getting into the configuration of the SRX, I stated earlier that there’s a Juniper Specific stanza in tac_plus.conf file. When authenticating users against a TACACS+ server on juniper devices and you’ll need to apply Juniper Networks Vendor-Specific TACACS+ Attributes.

These attributes can be either:

  • Specified in the tac_plus.conf file by using regular expressions to list all the commands that the user has permitted or denied. A user will need to be created on the device with that user being referred under the local-user-name statement. The stanza would look something:
    service = junos-exec {
    	local-user-name = xxx
    	allow-commands =  .*
    	allow-configurations = .*
    	deny-commands = 
    	deny-configuration = 
    	user-permissions = 
    	}
  • Configure a class that has states all the permitted or denied permissions, this class will be linked to a user. Both need to be configured on the device. Once this has been created you’ll need to refer, said user, under the local-user-name

The Junos OS retrieves these attributes through an authorization request of the TACACS+ server after authenticating a user. For my example, I went with the latter. Now we’ll jump onto the SRX220 and get that sorted with TACACS+ AAA configuration.

Juniper Configuration

Firstly, you will have to set the TACACS+ server with its secret key. For standard practice and force of habit, I have set the single connection and forced the source-address of the SRX. By using the single connection statement, this means that instead of multiple TCP sessions connecting to the device from a server, a single session is maintained between them. In addition, for best practice an authentication order should be set so that if there was an issue or loss of connectivity to the TACACS+ server, you’ll be able to fall back to locally defined users.

authentication-order [ tacplus password ];
tacplus-server {
    10.1.0.148 {
        secret "$9$SszyMXVb2aGiYgi.fzCAIEcyvWX7-w24"; ## SECRET-DATA
        single-connection;
        source-address 10.1.0.158;
    }
}

With the TACACS+ server we’re able log different events that take place on the device and get those commands sent to the server. From my experience the accounting events that you would most want logged are logins, configuration changes and interactive commands. This is set under system accounting stanza

accounting {
    events [ login change-log interactive-commands ];
    destination {
        tacplus;
    }
}

Next, under the system login stanza, you need to create a class that has a list of permission available to the user(s) that are going to be associated to it. The user(s) are what are used in the tac_plus.conf file. In my example I created two classes, one with all permission super-user-local and the other user with read-only and basic troubleshooting options (ie ping, traceroute, telnet etc) read-only-user-local. These associated this classes with 2 users remote-admin and remote-read-only

login {
    class read-only-user-local {
        permissions [ network view view-configuration ];
    }
    class super-user-local {            
        permissions all;
    }
    user remote {
        full-name "TACACS User";
        uid 2001;
        class super-user-local;
    }
    user remote-read-only {
        full-name "TACACS read-only user";
        uid 2002;
        class read-only-user-local;
    }
}

You can learn more about the different permissions flags available here on Juniper TechLibrary

Verification

To confirm the configuration is working as expected, I will ssh onto the SRX220 with both the admin user kmarquis and the read-only user test. With both users, I will log in and try to configure the description This is a test on a random port. As you can see below I had no problem with user kmarquis. However, when I logged in with the test user I wasn’t able to enter the configuration mode as the permission wasn’t granted, and for that user the command isn’t even recognized. I ran a show command and you will see that none of the passwords are shown. Again this is due to the permission level granted.

Admin Access

marquk01@km-vm1:~$ ssh 10.1.0.158 -l kmarquis
Password: 
--- JUNOS 12.1X47-D30.4 built 2015-11-13 14:16:02 UTC
kmarquis@v6-testing> configure 
Entering configuration mode
[edit]
kmarquis@v6-testing# set interfaces ge-0/0/5 description "This is a test" 

[edit]
kmarquis@v6-testing# commit and-quit 

kmarquis@v6-testing>

“Read Only Access”

marquk01@km-vm1:~$ ssh 10.1.0.158 -l test
Password: 
--- JUNOS 12.1X47-D30.4 built 2015-11-13 14:16:02 UTC
test@v6-testing> configure
                 ^
unknown command.

test@v6-testing> show configuration 
## Last commit: 2016-02-01 12:56:23 UTC by kmarquis
version 12.1X47-D30.4;
system {
    host-name v6-testing;
    authentication-order \[ tacplus password \];
    root-authentication {
        encrypted-password /\* SECRET-DATA \*/; ## SECRET-DATA
    }

If we check the /var/log/tac_plus.acct file we’ll be able to see all the permitted commands by each user. This is additional confirmation that the users have successfully authenticated against the TACACS+ server and their related permissions authorised to the device.

Feb  1 12:55:38 10.1.0.158      kmarquis        ttyp0   10.1.0.137      start   task\_id=1       service=shell   process\*mgd\[38808\]      cmd=login
Feb  1 12:55:41 10.1.0.158      kmarquis        ttyp0   10.1.0.137      stop    task\_id=2       service=shell   process\*mgd\[38808\]      cmd=show configuration 
Feb  1 12:55:44 10.1.0.158      kmarquis        ttyp0   10.1.0.137      stop    task\_id=3       service=shell   process\*mgd\[38808\]      cmd=edit 
Feb  1 12:56:01 10.1.0.158      kmarquis        ttyp0   10.1.0.137      stop    task\_id=4       service=shell   process\*mgd\[38808\]      cmd=set: \[interfaces ge-0/0/5 de$
Feb  1 12:56:01 10.1.0.158      kmarquis        ttyp0   10.1.0.137      stop    task\_id=5       service=shell   process\*mgd\[38808\]      cmd=set interfaces ge-0/0/5 desc$
Feb  1 12:56:05 10.1.0.158      kmarquis        ttyp0   10.1.0.137      stop    task\_id=6       service=shell   process\*mgd\[38808\]      cmd=commit and-quit 
Feb  1 12:56:27 10.1.0.158      kmarquis        ttyp0   10.1.0.137      stop    task\_id=7       service=shell   process\*mgd\[38808\]      cmd=exit 
Feb  1 12:56:27 10.1.0.158      kmarquis        ttyp0   10.1.0.137      stop    task\_id=1       service=shell   elapsed\_time=49 process\*mgd\[38808\]      cmd=logout
Feb  1 12:56:34 10.1.0.158      test    ttyp0   10.1.0.137      start   task\_id=1       service=shell   process\*mgd\[38845\]      cmd=login
Feb  1 12:56:44 10.1.0.158      test    ttyp0   10.1.0.137      stop    task\_id=2       service=shell   process\*mgd\[38845\]      cmd=show configuration 
Feb  1 12:56:53 10.1.0.158      test    ttyp0   10.1.0.137      stop    task\_id=3       service=shell   process\*mgd\[38845\]      cmd=show system uptime 
Feb  1 12:56:56 10.1.0.158      test    ttyp0   10.1.0.137      stop    task\_id=4       service=shell   process\*mgd\[38845\]      cmd=exit 
Feb  1 12:56:56 10.1.0.158      test    ttyp0   10.1.0.137      stop    task\_id=1       service=shell   elapsed\_time=22 process\*mgd\[38845\]      cmd=logout

And with that all, we have a fully configured and working AAA TACACS+ server :)

Extra Treat :)

I have included the set commands below:

set system tacplus-server 10.1.0.148 secret "$9$SszyMXVb2aGiYgi.fzCAIEcyvWX7-w24"
set system tacplus-server 10.1.0.148 single-connection
set system tacplus-server 10.1.0.148 source-address 10.1.0.158

set system authentication-order tacplus
set system authentication-order password

set system accounting events login
set system accounting events change-log
set system accounting events interactive-commands
set system accounting destination tacplus

set system login class super-user-local permissions all
set system login class read-only-user-local permissions network
set system login class read-only-user-local permissions view
set system login class read-only-user-local permissions view-configuration

set system login user remote-read-only full-name "TACACS read-only user"
set system login user remote-read-only uid 2005
set system login user remote-read-only class read-only-user-local
set system login user remote-admin full-name "TACACS User"
set system login user remote-admin uid 2006
set system login user remote-admin class super-user-local

Extra Extra Treat :D

P.S. If you want to see what configuration could be used on a Cisco device I have added it below. Although I didn’t test it myself, this is the config we have in production and it works :p

aaa new-model
aaa authentication login default group tacacs+ local enable
aaa authorization exec default group tacacs+ local none 
aaa authorization commands 0 default group tacacs+ local none 
aaa authorization commands 1 default group tacacs+ local none 
aaa authorization commands 15 default group tacacs+ local none 
aaa accounting exec default start-stop group tacacs+
aaa accounting commands 0 default start-stop group tacacs+
aaa accounting commands 1 default start-stop group tacacs+
aaa accounting commands 15 default start-stop group tacacs+
aaa session-id common

Reference

Share on LinkedIn
Share on Reddit