I'm wondering if anyone can help me get a MikroTik device working through tac_plus-ng? I'm not quite sure what to even look into next...any assistance would be helpful!
I have been happily using tac_plus-ng for many years, it has been working great for all of my wide variety of devices. Now I have been told, and have no input in, that we're adding a bunch of MikroTik devices to the network and they need to work. I have my hands on the model we're folding into our fleet but I can't get it to authenticate. I understand MikroTik devices don't support tacacs but rather solely use RADIUS. I just updated to Version d7ba2ed3877a6e2a5fc442e8bd8e5e84ce074d8c and added what I thought was the necessary config changes but even with the most verbose logs all I can get out of tac_plus-ng is:
Log for Mikrotik:
8752: 11:47:03.862 e/28010000: 192.168.88.1 radius login for 'demo' from <IP> failed (password not set)
Whereas my regular devices work fine (so I know it's not the Mavis backend), please ignore the superfluous undefined groups the demo account is used for a lot of testing:
8752: 11:45:17.745 6/6555bc00: 10.102.255.2 looking for user demo in MAVIS backend
{ member = "boss_access",
demo:1: Group 'boss_access' not found.
8752: demo:1: Group 'boss_access' not found.
{ member = "boss_access","dhcp_access",
demo:1: Group 'dhcp_access' not found.
8752: demo:1: Group 'dhcp_access' not found.
{ member = "boss_access","dhcp_access","dns_access",
demo:1: Group 'dns_access' not found.
8752: demo:1: Group 'dns_access' not found.
{ member = "boss_access","dhcp_access","dns_access","gadmin",
demo:1: Group 'gadmin' not found.
8752: demo:1: Group 'gadmin' not found.
{ member = "boss_access","dhcp_access","dns_access","gadmin","go_access",
demo:1: Group 'go_access' not found.
8752: demo:1: Group 'go_access' not found.
{ member = "boss_access","dhcp_access","dns_access","gadmin","go_access","ipausers",
demo:1: Group 'ipausers' not found.
8752: demo:1: Group 'ipausers' not found.
{ member = "boss_access","dhcp_access","dns_access","gadmin","go_access","ipausers","nadmin","server_admin",
demo:1: Group 'server_admin' not found.
8752: demo:1: Group 'server_admin' not found.
{ member = "boss_access","dhcp_access","dns_access","gadmin","go_access","ipausers","nadmin","server_admin","webserver_access"
demo:1: Group 'webserver_access' not found.
8752: demo:1: Group 'webserver_access' not found.
8752: 11:45:17.872 6/6555bc00: 10.102.255.2 result for user demo is ACK [127 ms]
8752: 11:45:17.872 6/6555bc00: 10.102.255.2 shell login for 'demo' from <IP> on tty3 succeeded (profile=admin_profile)
8752: 11:45:17.960 7/8f039484: 10.102.255.2 Start authorization request
8752: 11:45:17.960 7/8f039484: 10.102.255.2 user 'demo' found
8752: 11:45:17.960 7/8f039484: 10.102.255.2 nas:service=shell (passed thru)
8752: 11:45:17.960 7/8f039484: 10.102.255.2 nas:cmd* (passed thru)
8752: 11:45:17.960 7/8f039484: 10.102.255.2 nas:absent srv:priv-lvl=15 -> add priv-lvl=15 (k)
8752: 11:45:17.960 7/8f039484: 10.102.255.2 added 1 args
8752: 11:45:18.016 8/2a8d6fb2: 10.102.255.2 Start accounting request
Then I'm logged in as demo with the right permissions.
My Mikrotik has the following settings:
/user aaa
set accounting=yes default-group=read exclude-groups="" interim-update=0s use-radius=yes
/radius add accounting-backup=no accounting-port=1813 address=<IP> authentication-port=1812 called-id="" certificate=none disabled=no domain="" protocol=udp realm="" \
require-message-auth=yes-for-request-resp service=login timeout=300ms
And finally here is my full test config (some details removed):
id = spawnd {
listen { port = 49 }
listen { port = 1812 protocol = UDP } # RADIUS Access
listen { port = 1813 protocol = UDP flag = accounting } # RADIUS Accounting
}
id = tac_plus-ng {
log authzlog { destination = /var/log/tac_plus/authz/%Y/%m_%d.log }
log authclog { destination = /var/log/tac_plus/authc/%Y/%m_%d.log }
log acctlog { destination = /var/log/tac_plus/acct/%Y/%m_%d.log }
log rad-accesslog { destination = /var/log/tac_plus/radius-access/%Y/%m_%d.log }
log rad-acctlog { destination = /var/log/tac_plus/radius-acct/%Y/%m_%d.log }
accounting log = acctlog
authentication log = authclog
authorization log = authzlog
radius.access log = rad-accesslog
radius.accounting log = rad-acctlog
retire limit = 1000
#ACL Lists
include = /etc/tac_plus-ng/networks
device world {
welcome banner = "\nUNAUTHORIZED ACCESS TO THIS DEVICE IS PROHIBITED\n\nYou must have explicit, authorized permission to access or configure this device. \nUnauthorized attempts and actions to access or use this system may result in civil and/or criminal penalties. \nAll activities performed on this device are logged and monitored.\n\n"
key = <tacacs key>
enable 15 = clear password
address =
0.0.0.0/0 address = ::/0
radius.key = test
}
device local {
key = <tacacs key>
enable 15 = clear password
address =
10.0.0.0/8 radius.key = test
}
# Define mavis LDAP backend
mavis module = external {
setenv LDAP_SERVER_TYPE = "generic"
setenv LDAP_HOSTS = <HOST>
setenv LDAP_BASE = <BASE>
setenv LDAP_SCOPE = <SCOPE>
setenv LDAP_USER = <USER>
setenv LDAP_PASSWD = <PASSWORD>
setenv UNLIMIT_AD_GROUP_MEMBERSHIP = 1
setenv AD_GROUP_PREFIX = ""
setenv REQUIRE_TACACS_GROUP_PREFIX = 0
setenv FLAG_USE_MEMBEROF = 1
setenv LDAP_MEMBEROF_REGEX = "^cn=net_([^,]+),cn=groups.*"
exec = /usr/local/lib/mavis/
mavis_tacplus_ldap.pl }
login backend = mavis
user backend = mavis
pap backend = mavis
#RADIUS dictionary (copied from radius-dict.cfg)
radius.dictionary {
attribute User-Name 1 string
attribute User-Password 2 string
attribute CHAP-Password 3 octets
attribute NAS-IP-Address 4 ipv4addr
attribute NAS-Port 5 integer
attribute Framed-IP-Address 8 ipv4addr
attribute Framed-IP-Netmask 9 ipv4addr
attribute State 24 octets
attribute Class 25 string
attribute NAS-Port-Type 61 integer
{
Async 0
Sync 1
ISDN 2
ISDN-V120 3
ISDN-V110 4
Virtual 5
PIAFS 6
HDLC-Clear-Channel 7
X.25 8
X.75 9
G.3-Fax 10
SDSL 11
ADSL-CAP 12
ADSL-DMT 13
IDSL 14
Ethernet 15
xDSL 16
Cable 17
Wireless-Other 18
Wireless-802.11 19
}
attribute Service-Type 6 integer
{
Login-User 1
Framed-User 2
Callback-Login-User 3
Callback-Framed-User 4
Outbound-User 5
Administrative-User 6
NAS-Prompt-User 7
Authenticate-Only 8
Callback-NAS-Prompt 9
Call-Check 10
Callback-Administrative 11
Authorize-Only 17
Framed-Management 18
}
attribute Login-IP-Host 14 ipv4addr
attribute Login-Service 15 integer
attribute Login-TCP-Port 16 integer
attribute Reply-Message 18 string
attribute Vendor-Specific 26 vsa
attribute Called-Station-Id 30 string
attribute Calling-Station-Id 31 string
attribute NAS-Identifier 32 string
attribute NAS-Port-Type 61 integer
{
Async 0
Sync 1
Virtual 5
}
attribute Message-Authenticator 80 octets
attribute NAS-Port-Id 87 string
attribute NAS-IPv6-Address 95 ipv6addr
attribute Framed-IPv6-Route 99 string
attribute Framed-IPv6-Pool 100 string
attribute Framed-IPv6-Address 168 ipv6addr
attribute Acct-Status-Type 40 integer
{
Start 1
Stop 2
Interim-Update 3
Accounting-On 7
Accounting-Off 8
}
attribute Acct-Delay-Time 41 integer
attribute Acct-Input-Octets 42 integer
attribute Acct-Output-Octets 43 integer
attribute Acct-Session-Id 44 string
attribute Acct-Authentic 45 integer
{
RADIUS 1
Local 2
Remote 3
}
attribute Acct-Session-Time 46 integer
attribute Acct-Input-Packets 47 integer
attribute Acct-Output-Packets 48 integer
attribute Acct-Terminate-Cause 49 integer
{
User-Request 1
Lost-Carrier 2
Lost-Service 3
Idle-Timeout 4
Session-Timeout 5
Admin-Reset 6
Admin-Reboot 7
Port-Error 8
NAS-Error 9
NAS-Request 10
NAS-Reboot 11
Port-Unneeded 12
Port-Preempted 13
Port-Suspended 14
Service-Unavailable 15
Callback 16
User-Error 17
Host-Request 18
}
attribute Acct-Multi-Session-Id 50 string
attribute Acct-Link-Count 51 integer
attribute Event-Timestamp 55 time
}
#Mikrotik specific dictionary (copied from
wiki.mikrotik.com/Manual:RADIUS_Client/reference_dictionary)
radius.dictionary mikrotik 14988 {
attribute Mikrotik-Group 3 string
}
# Define groups
group nadmin {
}
group tech {
}
# Define profiles
profile admin_profile {
script {
if (service == junos-exec) {
set local-user-name = <admin_username>
}
if (service == shell) {
if (cmd == "") {
set priv-lvl = 15
}
}
# When the session is RADIUS (RouterOS), place user in MikroTik group "full"
if (aaa.protocol == radius) {
set radius[mikrotik:Mikrotik-Group] = "full"
}
permit
}
}
profile tech_profile {
script {
if (service == junos-exec) {
set local-user-name = <tech_username>
}
if (service == shell) {
if (cmd == "") {
set priv-lvl = 7
}
}
# When the session is RADIUS (RouterOS), place user in MikroTik group "read"
if (aaa.protocol == radius) {
set radius[mikrotik:Mikrotik-Group] = "read"
}
permit
}
}
# Ruleset to assign profiles to users
ruleset {
rule from-trusted-nets {
enabled = yes
script {
if (group == nadmin) {
profile = admin_profile
permit
}
}
enabled = yes
script {
if (group == tech) {
profile = tech_profile
permit
}
}
}
}
}