TACACS+ daemon and Junos

14 06 2017

Axians Professional Services normally recommends using RADIUS authentication to our customers, but one of our customers uses TACACS.  We did some type-approval testing of new Junos release for them recently and had to set up a TACACS+ daemon in the lab to make sure authentication still worked following the upgrade. very helpfully provide a TACACS+ implementation that you can download to a Linux host for this purpose, but the documentation is a bit light on their website, and what you find using Google is naturally somewhat Cisco-specific.  So here are some notes on getting a basic setup going with Shrubbery’s tac_plus daemon and Junos.  Maybe this will help someone else.


Create the Junos Config

First, you need to set up the Junos side of things.  You need to do three things:

  1. Create a tacplus-server in the config
  2. Add tacplus to the authentication-order
  3. Create a ‘local user’ account that has no password, but gives anyone belonging to it the appropriate privileges.


Create the TACACS server

axians@MX104-1-re0> show configuration system tacplus-server | display set

set system tacplus-server port 49
set system tacplus-server secret testing123
set system tacplus-server source-address

In the above, we specify that Junos should find the server at the .237 address on port 47.  The secret is a password that must agree on both the Junos device and the server.  It is also good practice to specify the source of the TACACS request – in this case, it is fxp0, the managment interface.


Create the local ‘user’

axians@MX104-1-re0> show configuration system login user | display set

set system login user RO uid 2006
set system login user RO class read-only
set system login user SU uid 2007
set system login user SU class super-user

In the above, we create two ‘users’ which aren’t really users.   They are called RO (read-only) and SU (super-user) and their purpose is to determine the class that should be assigned to anyone matching these two usernames.  (The UID part can be ignored – that is generated by Junos automatically)/


Specify the authentication order

axians@MX104-1-re0> show configuration system authentication-order | display set
set system authentication-order tacplus

This tells the router to authenticate using TACACS primarily.  If the server responds with either an accept or a deny, then TACACS will be the only authentication database that is consulted.   If no response is received (i.e. server is down or unreachable) then the local Junos password database will be consulted instead.

We recommend not specifying tacplus and password at the same time. This is a common mistake and means that Junos will try both authentication types every time.  It leaves your router more open to brute-force password attacks on the local Junos password database, which in all likelihood is not changed very often.


Create the tac_plus server


On your Linux host you need to install the tacacs+ package.  This example is performed on an Ubuntu server.  Here are the commands I issued:

sudo apt-get update
sudo apt-get install tacacs+


tac_plus normally runs in daemon mode.  There is a config file at /etc/tacacs+/tac_plus.conf and messages are logged to /var/log/syslog by default.  The messages are not in debug mode,  and I have yet to figure out how to turn that on when the daemon is running.

You can get online help using ‘man tac_plus.conf’

Edit /etc/tacacs+/tac_plus.conf and make it look as follows:


# This is the 'secret' we specified in Junos

key = testing123

# This is the actual user who is a member of group 'SU'
user = user1 {
 member = SU
 login = cleartext password123

# Here is another user, who belongs in the other group.
user = user2 {
 member = RO
 login = cleartext password456

# Here is the SU group definition.  It specifies a 
# junos-specific 'local-user-name' to pass back if 
# authentication is successful.  This must match the
# local user we configured in Junos
group = SU {
   service = junos-exec {
     local-user-name = SU

group = RO {
   service = junos-exec {
     local-user-name = RO

Save the file.

Note: in the above file, the passwords are specified in cleartext for each user.  An alternative method is to use the PAM (password authentication module) of this Linux host itself.   In this instance, the username/password used to log on to the Linux host would be the same as the one used to log on to Junos.  It is probably a safer system to use, but the cleartext option was sufficient for our testing.

I got a clue as to the correct  formatting of the configuration file by reading this Juniper document – the bottom of the page shows what appears to be a section of the config file for the tac_plus daemon.  I tried the first line of it and it worked – there are other commands there that I didn’t try but would allow you to specifically permit or deny certain commands.

Check if the tac_plus daemon is running:

andrew@axians:/etc/tacacs+$ sudo service --status-all | grep tacacs_plus
[ + ] tacacs_plus

As you can see above, the plus symbol means it is running.  It would show a minus sign if it were stopped.  Stop and start it again as follows to ensure it reads in the config file:

andrew@axians:/etc/tacacs+$ sudo service tacacs_plus stop
 * Stopping TACACS+ authentication daemon tacacs+ [ OK ]
andrew@axians:/etc/tacacs+$ sudo service tacacs_plus start
 * Starting TACACS+ authentication daemon tacacs+ [ OK ]


When you do a ‘sudo tail -f /var/log/syslog’ you will see user authentication failures.  The successes are less usefully-logged, just appearing as a ‘connect from <ip address of Junos router>’ message.   I’m sure the logging level can be improved, but haven’t got time to figure that out right now.

Jun 14 12:06:04 axians tac_plus[19390]: connect from []
Jun 14 12:06:05 axians tac_plus[19390]: login failure: user1 ( unknown-port
Jun 14 12:06:06 axians tac_plus[19391]: connect from []
Jun 14 12:06:09 axians tac_plus[19392]: connect from []


In the above, the first two lines are the radius client (i.e. the Juniper router) connecting and a user failing to authenticate.  The second two lines represent a successful authentication by the user.


How it works:

  1. The user SSHes to the Junos host and enters credentials
  2. Junos passes those credentials (encrypted using the secret) to the TACACS+ server
  3. TACACS+ permits or denies the user.
  4. If the user is permitted, the ‘local-user-name’ is sent back to Junos
  5. Junos uses that parameter’s value to look up the local user of RO or SU
  6. Depending on which local user it is, the real user gets assigned to the appropriate class and is logged in to Junos.


Let me know in the comments if you know a better way of doing this, and thanks for reading.




Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: