Configuring TACACS+ Server on Ubuntu 14.04LTS
Table of Contents
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 clitac_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([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:
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 statementpermit
is neededservice
: 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 apermit
ordeny
. 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