TACACS+ - Linux TACACS+ Authentication Using Active Directory
TACACS+ - Linux TACACS+ Authentication Using Active Directory
HOME / UBUNTU SERVER / TACACS+ ~ LINUX TACACS+ AUTHENTICATION USING ACTIVE DIRECTORY
This guide assumes that you are familiar with installing and con guring a Ubuntu Server and can deploy or have already deployed a
Windows Active Directory infrastructure.
Prerequisites
Windows Server 2016 with Active Directory Services (Domain Controller or Read-Only Domain Controller)
Ubuntu Server (tested on 16.04 LTS or 18.04 LTS)
Windows Active Directory Requirements
First, we will setup the required items in our Active Directory system.
1. Create a service account that TACACS will use to bind and authenticate to our AD infrastructure. Be sure to use a secure
password (16 characters or longer).
This is needed because Active Directory does not allow anonymous bindings by default and will not allow you to search the AD
tree if you are not authenticated.
The user does not need any special permissions or group memberships.
2. Create two security groups that TACACS will match against to identify what users and permission levels to assign authenticated
users. In this example, we will create two security roles. The rst being “ADMIN” level permissions, and the second being
“TECHNICIAN” level permissions.
3. Now create two user accounts, one for each type of user security level and add them to the security group associated with their
account.
Username “test.admin” is a member of security group “R_ADMINS” and Username “test.tech” is a member of security group
https://git.datai.net/sp-devops/aaa-server
Lets move on to the TACACS Server installation on our Ubuntu Server. First, SSH into your Ubuntu Server and install the required
packages.
Next, we are going to download the TACACS+ Server packages that includes the MAVIS (LDAP) authentication packages. This is
provided by Marc Huber at pro-bono-publico.de.
Now, we will con gure and build the tac_plus packages on our server.
cd tac_plus
We now need to create the logging directories on our server because the package build process does not build these out for us. We
will also make sure to set the permission on these directories so that our TACACS Server software can write to them.
You can verify that the permissions were set correctly by running the following command:
We now need to verify that our MAVIS packages are working correctly. To do this execute the below command. You should see output
as exampled.
If there are error messages saying “Can’t locate Net/LDAP.pm in @INC”, you need to double-check the configure and make
commands at the beginning of the guide. Make sure they all completed successfully without any errors.
If your output above matches, then we can continue with adding the con guration for the TACACS server. Create a le tac_plus.cfg
in the /etc/tac_plus folder.
Once created, we will open that le to add our con guration template.
Next, we will copy and paste in the below template con guration into the tac_plus.cfg le. You will need to replace the variables
that are speci c to your con guration. These are identi ed by {{VARIABLE-NAME}} in the template con guration.
#!/usr/local/sbin/tac_plus
id = spawnd {
listen = { address = 0.0.0.0 port = 49 }
#Uncomment the line below for IPv6 support
#listen = { address = :: port = 49 }
spawn = {
instances min = 1
instances max = 10
}
background = yes
}
id = tac_plus {
access log = /var/log/tac_plus/access/%Y/%m/access-%m-%d-%Y.txt
accounting log = /var/log/tac_plus/accounting/%Y/%m/accounting-%m-%d-%Y.txt
authentication log = /var/log/tac_plus/authentication/%Y/%m/authentication-%m-%d-%Y.txt
#If you are using Microsoft Global Catalog with secure LDAP (SSL)
#setenv LDAP_HOSTS = "ldaps://{{AD-SERVER-IP}}:3269"
#If you are using Microsoft Global Catalog with regular LDAP (non-SSL)
setenv LDAP_HOSTS = "ldap://{{AD-SERVER-IP}}:3268"
exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl
}
host = world {
#Allow any IPv4 device
address = 0.0.0.0/0
group = {{AD-ADMIN-GROUP}} {
#Permit all services by default
default service = permit
#Users will need to re-enter their AD password for the enable password (feel free to customize
this however you want)
enable = login
###
### Cisco IOS Authentication
###
service = shell {
#Permit all commands
default command = permit
###
### Juniper JunOS Authentication
###
service = junos-exec {
set local-user-name = {{AD-ADMIN-GROUP}}
}
}
group = {{AD-TECH-GROUP}} {
#Permit all services by default
default service = permit
#Users will need to re-enter their AD password for the enable password (feel free to customize
this however you want)
enable = login
###
### Cisco IOS Authentication
###
service = shell {
#Permit all commands
default command = permit
###
### Juniper JunOS Authentication
###
service = junos-exec {
set local-user-name = {{AD-TECH-GROUP}}
}
}
# user = DEFAULT {
# password = mavis
# member = {{AD-TECH-GROUP}}
# }
### END USER ACCOUNT MAPS ###
#!/usr/local/sbin/tac_plus
id = spawnd {
listen = { address = 0.0.0.0 port = 49 }
#Uncomment the line below for IPv6 support
#listen = { address = :: port = 49 }
spawn = {
instances min = 1
instances max = 10
}
background = yes
}
id = tac_plus {
access log = /var/log/tac_plus/access/%Y/%m/access-%m-%d-%Y.txt
accounting log = /var/log/tac_plus/accounting/%Y/%m/accounting-%m-%d-%Y.txt
authentication log = /var/log/tac_plus/authentication/%Y/%m/authentication-%m-%d-%Y.txt
#If you are using Microsoft Global Catalog with secure LDAP (SSL)
#setenv LDAP_HOSTS = "ldaps://172.16.10.10:3269"
#If you are using Microsoft Global Catalog with regular LDAP (non-SSL)
setenv LDAP_HOSTS = "ldap://172.16.10.10:3268"
exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl
}
host = mgmtnet {
#Allow any IPv4 device
address = 172.16.10.0/24
group = R_ADMINS {
#Permit all services by default
default service = permit
#Users will need to re-enter their AD password for the enable password (feel free to customize
this however you want)
enable = login
###
### Cisco IOS Authentication
###
service = shell {
#Permit all commands
default command = permit
###
### Juniper JunOS Authentication
###
service = junos-exec {
set local-user-name = R_ADMINS
}
group = R_TECHS {
#Permit all services by default
default service = permit
#Users will need to re-enter their AD password for the enable password (feel free to customize
this however you want)
enable = login
###
### Cisco IOS Authentication
###
service = shell {
#Permit all commands
default command = permit
###
### Juniper JunOS Authentication
###
service = junos-exec {
set local-user-name = R_TECHS
}
}
### BEGIN USER ACCOUNT MAPS ###
# user = [email protected] {
# password = mavis
# member = R_ADMINS
# }
# user = DEFAULT {
# password = mavis
# member = R_TECHS
# }
### END USER ACCOUNT MAPS ###
Now we need to validate the con guration le. After you have saved and exited the tac_plus.cfg le, run the following command to
verify everything was setup correctly.
/usr/local/sbin/tac_plus -P /etc/tac_plus/tac_plus.cfg
If tac_plus reports any errors, you will need to edit the tac_plus.cfg le again and correct the errors. Do not proceed further until
you have corrected all the reported errors. See http://www.pro-bono-publico.de/projects/tac_plus.html for a complete con guration
reference. You may also want to view the le /usr/local/lib/mavis/mavis_tacplus_ldap.pl for a detailed explanation of the
available LDAP variables.
Now we need to create a SystemD service startup script for our TACACS server. Copy/Paste the below command into your SSH
session. It will automatically create the required service startup script.
[Unit]
Description=TACACS+ Service
After=syslog.target
[Service]
ExecStart=/usr/local/sbin/tac_plus -f /etc/tac_plus/tac_plus.cfg
KillMode=process
Restart=always
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
EOF
Now you can enable the service for auto-startup and manually start the service.
We are now ready to verify that the TACACS services are authentication against our Active Directory server. Run the below
commands on your Ubuntu server. You should get output similar to our example.
Input attribute-value-pairs:
TYPE TACPLUS
TIMESTAMP mavistest-21804-1546360707-0
USER test.admin
PASSWORD password123$
TACTYPE AUTH
Output attribute-value-pairs:
TYPE TACPLUS
TIMESTAMP mavistest-21804-1546360707-0
USER test.admin
RESULT ACK
PASSWORD password123$
SERIAL OwS74pPKAjcEH89PojinNQ=
DBPASSWORD password123$
TACMEMBER "R_ADMINS"
TACTYPE AUTH
Input attribute-value-pairs:
TYPE TACPLUS
TIMESTAMP mavistest-21806-1546360743-0
USER test.tech
PASSWORD password123$
TACTYPE AUTH
Output attribute-value-pairs:
TYPE TACPLUS
TIMESTAMP mavistest-21806-1546360743-0
USER test.tech
RESULT ACK
PASSWORD password123$
SERIAL gydnsgXHXyjeQaR2JaBlhw=
DBPASSWORD password123$
TACMEMBER "R_TECHS"
TACTYPE AUTH
From the output above, look speci cally at the RESULT output and the TACMEMBER output. These should be “ACK” in the RESULT
eld, which means Active Directory responded and was successful, and the TACMEMBER value should match the security group
associated with the user account. If you got NACK, BFD, or ERR in the RESULT eld, that means something went wrong. You’ll want to
double-check your Active Directory environment variables in the tac_plus.cfg le.
For those that want to see what the traf c looks like, below is a PCAP (packet capture) of the LDAP communication between our
TACACS Server and our Windows Active Directory Controller. The communication in this capture was done using none SSL based
connections, which means everything is transmitted in CLEAR TEXT.
It is highly recommended that you enable SSL on the Active Directory Controller and the TACACS con guration before you
implement this into a production environment. Using LetsEncrypt, you can enable SSL certi cates for free. We use the
application Certify the Web on Windows Servers to generate SSL certi cates.
tacacs_ldap_connection.zip
A handy Windows tool that may help you correctly con gure the environment variables in LDAP is the Softerra LDAP Browser.
Do not continue further until you can run the above tests and get a valid response from the user authentication.
First, we will con gure our Juniper device to utilize the TACACS authentication server as the primary source for account
authorizations, with the standard “password” (local user accounts) as a fall-back in the event the TACACS server is of ine or
networking is unavailable. You will need to replace the variables that are speci c to your con guration. These are identi ed by
{{VARIABLE-NAME}} in the template con guration.
tacplus-server {
172.16.10.11 {
secret "$9$q.PQApOcrKNdw24aji1IEhKWxNdgaZLxUHk.zFSrleMX7NV"; ## SECRET-DATA
single-connection;
source-address 172.16.10.15;
}
}
accounting {
events [ login change-log interactive-commands ];
destination {
tacplus;
}
}
Next, we need to add the con guration to the Juniper device that map the user account to the user class. This portion is very
important and miss-understood very easily. The “user class” attributes can be built out however works best for your organization.
However, you need to pay special attention to the “login user” accounts that are created.
The “login user” accounts that are created are NOT the “usernames” for every user that will be logging into the devices. These “names”
are the direct mapping names that match what was created in the tac_plus.cfg GROUP attributes. This is where the “magic”
happens on the username > group mappings.
service = junos-exec {
set local-user-name = R_TECHS
}
Add the following con guration to your Juniper device. If you named your security groups differently, then you will have to adjust the
con guration to match your changes.
set system login class administrators permissions all
set system login class technicians permissions network
set system login class technicians permissions view
set system login class technicians permissions view-configuration
Once you have your con guration changes added to your device, commit them.
commit check
commit
You are now ready to test your TACACS authentication with the different user accounts. SSH into your Juniper device on the
management address and enter the username / password that you setup. For this example, we will be using “test.admin” and
“test.tech”.
Upon a successful login, your TACACS server should be recording the accounting packets sent from the Juniper device. These
accounting logs are located in /var/log/tac_plus/*
cat /var/log/tac_plus/accounting/2019/01/accounting-01-01-2019.txt
2019-01-01 14:55:25 -0500 172.16.10.15 test.admin ttyp1 172.16.10.10 start task_id=1 service=shell
process*mgd[5143] cmd=login
2019-01-01 14:55:48 -0500 172.16.10.15 test.tech ttyp2 172.16.10.10 start task_id=1 service=shell
process*mgd[5152] cmd=login
I have also provided a PCAP of the TACACS authentication request between the Juniper device and the TACACS server. This PCAP
also includes the SSH traf c from the client to the Juniper device.
tacacs_ssh_juniper-authentication.zip
First, we will con gure our Cisco device to utilize the TACACS authentication server as the primary source for account authorizations,
with the “local” user account as a fall-back in the event the TACACS server is of ine or networking is unavailable. You will need to
replace the variables that are speci c to your con guration. These are identi ed by {{VARIABLE-NAME}} in the template
con guration.
!
!--
!-- SET THE TACACS AUTHENTICATION SERVER
!--
tacacs-server host {{TACACS-SERVER-IP}}
tacacs-server directed-request
tacacs-server key 0 {{TACACS-ENCRYPTION-KEY}}
!
!
!--
!-- ESTABLISH A SECRET PASSWORD FOR CONSOLE
!--
service password-encryption
enable secret 0 {{SECURE-SECRET-PASSWORD}}
!
!--
!-- SET THE AAA SECURITY ROLES
!--
!
aaa new-model
!
aaa authentication login default group tacacs+ local
aaa authentication login console local
!
aaa authorization config-commands
aaa authorization exec default group tacacs+ local if-authenticated
aaa authorization exec console if-authenticated
aaa authorization commands 1 default group tacacs+ local if-authenticated
aaa authorization commands 15 default group tacacs+ local if-authenticated
!
aaa accounting exec 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
!
!
!--
!-- CONFIGURE CONSOLE FOR LOCAL AUTHENTICATION ONLY
!--
line con 0
logging synchronous
login authentication console
!
!--
!-- CONFIGURE VTY FOR AAA AUTHENTICATION VIA SSH ONLY
!--
line vty 0 4
logging synchronous
transport input ssh
!
!
Upon a successful login, your TACACS server should be recording the accounting packets sent from the Cisco device. These
accounting logs are located in /var/log/tac_plus/*
cat /var/log/tac_plus/accounting/2019/01/accounting-01-01-2019.txt
2019-01-01 17:37:26 -0500 172.16.10.16 test.admin tty2 172.16.10.10 start task_id=35 timezone=EST
service=shell
2019-01-01 17:37:29 -0500 172.16.10.16 test.admin tty2 172.16.10.10 stop task_id=35 timezone=EST
service=shell priv-lvl=15 cmd=configure terminal <cr>
2019-01-01 17:37:32 -0500 172.16.10.16 test.admin tty2 172.16.10.10 stop task_id=35 timezone=EST
service=shell disc-cause=1 disc-cause-ext=9 pre-session-time=3 elapsed_time=6 stop_time=1546382252
#!/usr/local/sbin/tac_plus
id = spawnd {
listen = { address = 0.0.0.0 port = 49 }
#Uncomment the line below for IPv6 support
#listen = { address = :: port = 49 }
spawn = {
instances min = 1
instances max = 10
}
background = yes
}
id = tac_plus {
access log = /var/log/tac_plus/access/%Y/%m/access-%m-%d-%Y.txt
accounting log = /var/log/tac_plus/accounting/%Y/%m/accounting-%m-%d-%Y.txt
authentication log = /var/log/tac_plus/authentication/%Y/%m/authentication-%m-%d-%Y.txt
#If you are using Microsoft Global Catalog with secure LDAP (SSL)
#setenv LDAP_HOSTS = "ldaps://172.16.10.10:3269"
#If you are using Microsoft Global Catalog with regular LDAP (non-SSL)
setenv LDAP_HOSTS = "ldap://172.16.10.10:3268"
exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl
}
host = world {
#Allow any IPv4 device
address = 0.0.0.0/0
group = R_ADMINS {
#Permit all services by default
default service = permit
#Users will need to re-enter their AD password for the enable password (feel free to customize
this however you want)
enable = login
###
### Cisco IOS Authentication
###
service = shell {
#Permit all commands
default command = permit
###
### Juniper JunOS Authentication
###
service = junos-exec {
set local-user-name = R_ADMINS
}
group = R_TECHS {
#Permit all services by default
default service = permit
#Users will need to re-enter their AD password for the enable password (feel free to customize
this however you want)
enable = login
###
### Cisco IOS Authentication
###
service = shell {
#Permit all commands
# default command = permit
default command = deny
##========================================##
## COMMAND ACCESS CONTROL RULES ##
##========================================##
# Ping
cmd = ping {
permit .*
}
# Traceroute
cmd = traceroute {
permit .*
}
# Save running-configuration
cmd = copy {
permit "running-config startup-config <cr>"
}
# Clear commands
cmd = clear {
permit "counters FastEthernet.*"
permit "counters GigabitEthernet.*"
permit "counters Vlan.*"
permit "counters Port-channel.*"
}
# IP commands
cmd = ip {
permit route.*
permit address.*
permit "verify unicast.*"
}
# IPv6 commands
cmd = ipv6 {
permit route.*
permit address.*
permit "verify unicast.*"
}
# Removing configuration parameters
cmd = no {
permit "ip route.*"
permit "ipv6 route.*"
permit description.*
permit "ip address.*"
permit "ipv6 address.*"
permit "ip verify unicast.*"
permit "ipv6 verify unicast.*"
permit "cdp enable <cr>"
permit "shutdown <cr>"
permit "switchport <cr>"
permit "switchport mode <cr>"
permit "switchport access vlan .*"
permit nonegotiate.*
permit "switchport private-vlan host-association.*"
permit "spanning-tree portfast edge <cr>"
permit service-policy.*
}
# Allow IP commands
cmd = ip {
permit address.*
permit "verify unicast.*"
}
###
### Juniper JunOS Authentication
###
service = junos-exec {
set local-user-name = R_TECHS
}
# user = DEFAULT {
# password = mavis
# member = R_ADMINS
# }
### END USER ACCOUNT MAPS ###
AAA AUTHENTICATION CISCO EVE-NG JUNIPER LDAP LINUX SECURITY TACACS UBUNTU
UBUNTU SERVER
Related Articles