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
[email protected]:~$ 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:
[email protected]:~$ 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.
[email protected]:~$ 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
[email protected]:~$ 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([email protected]) # 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:
[email protected]:~$ 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 usertest; 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.
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
With that we have a TACACS+ server configured 🙂
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; } }
Verifications
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.
[email protected]:~$ ssh 10.1.0.158 -l kmarquis Password: --- JUNOS 12.1X47-D30.4 built 2015-11-13 14:16:02 UTC [email protected]> configure Entering configuration mode [edit] [email protected]# set interfaces ge-0/0/5 description "This is a test" [edit] [email protected]# commit and-quit [email protected]>
[email protected]:~$ ssh 10.1.0.158 -l test Password: --- JUNOS 12.1X47-D30.4 built 2015-11-13 14:16:02 UTC [email protected]> configure ^ unknown command. [email protected]> 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 configurationFeb 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 🙂
Reference
Configure TACACS+ Ubuntu 14.04LTS
TACACS+ Accounting
TACACS+ Authenication
TACACS+ Advantages
Keeran Marquis
Latest posts by Keeran Marquis (see all)
- Life and Times of an Unemployed Professional Speed Dater #3 - August 5, 2018
- Life and Times of an Unemployed Professional Speed Dater #2 - August 5, 2018
- Life and Times of an Unemployed Professional Speed Dater #1 - August 5, 2018
A very well explained and produced article. It just so happens that I am working on a tacacs+ server for my JNCIP environment (JNCIP-SP) and this happens to be tailored to exactly what I am looking for. Thanks again for your help!
Hi Keeran
Excellent article. It helped me to understand how to configure TACACS in a Juniper box.
Thanks!
Awesome article! Very helpful. One thing I had an issue with is it seems there may be a typo on the privilege level for cisco. You have a priv_lvl = 15 which I was met with authorization failed. Taking a look through the configs I noticed the difference. I’m assuming for juniper its not checking that type privilege level.
group = admin {
default service = permit
service = exec {
priv_lvl = 15
}
}
Edit – missed the fix is the priv level should be a hypen:
group = admin {
default service = permit
service = exec {
priv-lvl = 15
}
}
Hi Chris
Cheers for that! ill update the post accordingly 🙂
Keeran
Nice article!!
Have a small question on the below configuration :
I am in need of getting the name field value from server.
user = kmarquis {
name = “Keeran Marquis” —– How to do I get this name “field” from server.
member = admin
login = des kBeC6JDjU8icY
service = junos-exec {
local-user-name = remote-admin
}
}
Went through: RFC, various blogs, …. But unable to find any way to get that field value.
Any response / suggestions are appreciated as I am running out of ideas 🙁
PS: Observed, none of the freely available servers are supporting that field. (ie By going through the source code.)
i would have to give a strong pass, unfortunately i never tested this when i made the post 🙁