Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fallback aaa after unsuccessful ldap #131

Open
chernevta opened this issue Dec 5, 2024 · 12 comments
Open

fallback aaa after unsuccessful ldap #131

chernevta opened this issue Dec 5, 2024 · 12 comments

Comments

@chernevta
Copy link

chernevta commented Dec 5, 2024

Hello!
The task is as follows:
AAA priority via ldap server, if ldap is unavailable or in an emergency, then produce AAA for users specified in the global config

With this configuration, in the case of identical users, a request is made through mavis
if ldap is unavailable or in an emergency, If ldap is unavailable, then user t.chernev authorization is performed from the global config.

tac+ng-config.txt

I deliberately break ldap, for testing
setenv LDAP_HOSTS = "cor.VAS.ru:389" -> setenv LDAP_HOSTS = "cor.VAS.ru:38911"

Here's what I get from the before and after tests:

and aaa goes through ldap

after
as soon as I break LDAP, we should connect under the local user specified in the config, but this does not happen and judging by the debug it still accesses mavis

изображение

in debug for some reason it turns к MAVIS looking for user t.chernev in MAVIS backend and so on in a circle
debug log attached
log_tac+ng.log

Tell me what I'm doing wrong? I've studied the documentation, but I still can't do it.

@MarcJHuber
Copy link
Owner

Hi,

thanks for clarifying, I somehow misread this, my bad ... please try "authentication fallback = permit" in global or host context. This should propagate the MAVIS error status to the device.

Cheers,

Marc

@chernevta
Copy link
Author

chernevta commented Dec 7, 2024

I added
authentication fallback = permit
but it doesn't work.
When ldap doesn't work, then aaa doesn't work with local user

I will describe again what goal I want to achieve...
AAA priority via ldap, and then local config.
The user in both cases is "t.chernev"
In case of an AAA error via ldap, it is required to perform AAA using the local user specified in the config

ps
For information If I remove password login fallback = crypt
then authorization occurs only by the local user from the configuration

pss
authentication fallback = permit
login fallback = crypt

In this case, aaa occurs through ldap, but when ldap is in emergency mode, it does not work fallback local user from local config

@MarcJHuber
Copy link
Owner

Hi,

fallback authentication is different. It will allow a fallback user to log in on backend failure, but it won't tell the device to skip TACACS+ and continue with local users.

I just did a quick test using tactrace.pl. With non-available LDAP servers and authentication fallback = yes the result was

127.0.0.1 looking for user x in MAVIS backend
127.0.0.1 user av pairs:
127.0.0.1 USER (len: 1): x
127.0.0.1 USER_RESPONSE (len: 28): No answer from LDAP backend.
127.0.0.1 SERVERIP (len: 9): 127.0.0.1
127.0.0.1 IPADDR (len: 9): 127.0.0.1
127.0.0.1 REALM (len: 7): default
127.0.0.1 result for user x is ERR [604 ms]
127.0.0.1 ascii login for 'x' from 127.0.0.1 on vty0 failed (backend error) [No answer from LDAP backend.]
127.0.0.1 Writing AUTHEN/ERROR size=47
127.0.0.1 ---<start packet>---
127.0.0.1 session id: 00000001, data length: 35
127.0.0.1 AUTHEN, status=7 (AUTHEN/ERROR) flags=0x0
127.0.0.1 msg_len=29, data_len=0
127.0.0.1 msg (len: 29): No answer from LDAP backend.\n
127.0.0.1 data (len: 0):

Without authentication fallback = yes:

127.0.0.1 looking for user x in MAVIS backend
127.0.0.1 user av pairs:
127.0.0.1 USER (len: 1): x
127.0.0.1 USER_RESPONSE (len: 28): No answer from LDAP backend.
127.0.0.1 SERVERIP (len: 9): 127.0.0.1
127.0.0.1 IPADDR (len: 9): 127.0.0.1
127.0.0.1 REALM (len: 7): default
127.0.0.1 result for user x is ERR [599 ms]
127.0.0.1 ascii login for 'x' from 127.0.0.1 on vty0 failed [No answer from LDAP backend.]
127.0.0.1 Writing AUTHEN/FAIL size=47
127.0.0.1 ---<start packet>---
127.0.0.1 session id: 00000001, data length: 35
127.0.0.1 AUTHEN, status=2 (AUTHEN/FAIL) flags=0x0
127.0.0.1 msg_len=29, data_len=0
127.0.0.1 msg (len: 29): No answer from LDAP backend.\n
127.0.0.1 data (len: 0):
127.0.0.1 ---<end packet>---

Looks fine to me. In the first case the daemon did return AUTHEN/ERROR, in the second AUTHEN/FAIL. The client should handle these status codes accordingly.

Cheers,

Marc

@chernevta
Copy link
Author

It will allow a fallback user to log in on backend failure, but it won't tell the device to skip TACACS+ and continue with local users.

This is exactly what I want to achieve.
I will emphasize once again that authorization of the local user specified in the tacacs+ ng configuration is required, I attached the config above.
Cisco 4948E client

But this does not happen.
Tell me where the error is in my configuration? and where I can find tactrace.pl?

@MarcJHuber
Copy link
Owner

Hi,

does adding fallback-only in the user t.chernev { ... } section help?

Cheers,

Marc

@MarcJHuber
Copy link
Owner

Hi,

forgot about tactrace.pl: It's in tac_plus-ng/perl and needs a "make install" there.

Cheers,

Marc

@chernevta
Copy link
Author

chernevta commented Dec 9, 2024

When ldap is intentionally broken, I enter the correct login and password for t.chernev from the local tacacsplus config
before_cfg_tacplus.txt

debug

196230: 08:08:29.606 4/01787f46: 172.20.255.18 looking for user t.chernev in MAVIS backend
196230: 08:08:29.642 4/01787f46: 172.20.255.18 user av pairs:
196230: 08:08:29.642 4/01787f46: 172.20.255.18 USER (len: 9): t.chernev
196230: 08:08:29.642 4/01787f46: 172.20.255.18 USER_RESPONSE (len: 93): 80090308: LdapErr: DSID-0C09050E, comment: AcceptSecurityContext error, data 52e, v4f7c (440)
196230: 08:08:29.642 4/01787f46: 172.20.255.18 SERVERIP (len: 13): 172.20.255.18
196230: 08:08:29.642 4/01787f46: 172.20.255.18 IPADDR (len: 10): 10.71.8.88
196230: 08:08:29.642 4/01787f46: 172.20.255.18 REALM (len: 7): default
196230: 08:08:29.642 4/01787f46: 172.20.255.18 result for user t.chernev is ERR [35 ms]
196230: 08:08:29.642 4/01787f46: 172.20.255.18 looking for user t.chernev realm default
196230: 08:08:29.642 4/01787f46: 172.20.255.18 user lookup succeded
196230: 08:08:29.642 4/01787f46: 172.20.255.18 evaluating ACL default#0
196230: 08:08:29.642 4/01787f46: 172.20.255.18  line 117: [member] member 'admins_local' => true
196230: 08:08:29.642 4/01787f46: 172.20.255.18  line 117: [profile] 'netadmin'
196230: 08:08:29.642 4/01787f46: 172.20.255.18  line 117: [permit]
196230: 08:08:29.642 4/01787f46: 172.20.255.18 ACL default#0: match
196230: 08:08:29.642 4/01787f46: 172.20.255.18 [email protected]: ACL default#0: permit (profile: netadmin)
196230: 08:08:29.642 4/01787f46: 172.20.255.18 shell login for 't.chernev' from 10.71.8.88 on tty1 failed (backend error) [80090308: LdapErr: DSID-0C09050E, comment: AcceptSecurityContext error, data 52e, v4f7c (440)] (profile=netadmin)
196230: 08:08:29.642 4/01787f46: 172.20.255.18 172.20.255.18 tty1: Authentication backend failure.
196230: 08:08:29.642 4/01787f46: 172.20.255.18 Writing AUTHEN/ERROR size=49
196230: 08:08:29.642 4/01787f46: 172.20.255.18 ---<start packet>---
196230: 08:08:29.642 4/01787f46: 172.20.255.18 key used: TEST
196230: 08:08:29.642 4/01787f46: 172.20.255.18 version: 192, type: 1, seq no: 4, flags: unencrypted
196230: 08:08:29.642 4/01787f46: 172.20.255.18 session id: 01787f46, data length: 37
196230: 08:08:29.642 4/01787f46: 172.20.255.18 packet body (len: 37): \a\000\000\037\000\000Authentication backend failure.
196230: 08:08:29.642 4/01787f46: 172.20.255.18 0000 07 00 00 1f 00 00 41 75  74 68 65 6e 74 69 63 61  ......Au thentica
196230: 08:08:29.642 4/01787f46: 172.20.255.18 0010 74 69 6f 6e 20 62 61 63  6b 65 6e 64 20 66 61 69  tion bac kend fai
196230: 08:08:29.642 4/01787f46: 172.20.255.18 0020 6c 75 72 65 2e                                    lure.
196230: 08:08:29.642 4/01787f46: 172.20.255.18 AUTHEN, status=7 (AUTHEN/ERROR) flags=0x0
196230: 08:08:29.642 4/01787f46: 172.20.255.18 msg_len=31, data_len=0
196230: 08:08:29.642 4/01787f46: 172.20.255.18 msg (len: 31): Authentication backend failure.
196230: 08:08:29.642 4/01787f46: 172.20.255.18 data (len: 0): 
196230: 08:08:29.642 4/01787f46: 172.20.255.18 ---<end packet>---

adding fallback-only in the user t.chernev { ... }
and password login fallback = -> password login = in the user t.chernev { ... }
and add authentication fallback = permit in the id = tac_plus-ng { ... }

after_cfg_tacplus.txt

AAA sucessfull fallback.

I got 2 situations where the falback doesn't work
1)
I restored ldap by changing the password to the correct one and I get an error with this configuration

debug

197408: 09:07:30.410 0/ba456a79: 172.20.255.18 authen: hdr->seq_no: 3
197408: 09:07:30.410 0/ba456a79: 172.20.255.18 looking for user t.chernev realm default
197408: 09:07:30.410 0/ba456a79: 172.20.255.18 user lookup failed
197408: 09:07:30.410 0/ba456a79: 172.20.255.18 evaluating ACL __internal__username_acl__
197408: 09:07:30.410 0/ba456a79: 172.20.255.18  regex: '[]<>/()|=[*"':$]+' <=> 't.chernev' = 0
197408: 09:07:30.410 0/ba456a79: 172.20.255.18  line 527: [user] regex '[]<>/()|=[*"':$]+' => false
197408: 09:07:30.410 0/ba456a79: 172.20.255.18  line 527: [permit]
197408: 09:07:30.410 0/ba456a79: 172.20.255.18 ACL __internal__username_acl__: match
197408: 09:07:30.410 0/ba456a79: 172.20.255.18 looking for user t.chernev in MAVIS backend
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 user av pairs:
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 USER (len: 9): t.chernev
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 DN (len: 121): CN=t.chernev,OU=Domain Users,DC=cor,DC=VAS,DC=ru
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 TACMEMBER (len: 8): "admins"
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 MEMBEROF (len: 69): "CN=aaanet_admins,OU=Groups,OU=Domain Users,DC=cor,DC=VAS,DC=ru"
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 SERVERIP (len: 13): 172.20.255.18
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 IPADDR (len: 10): 10.71.8.88
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 REALM (len: 7): default
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 IDENTITY_SOURCE (len: 1): 1
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 result for user t.chernev is ACK [65 ms]
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 looking for user t.chernev realm default
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 user lookup failed
197408: 09:07:30.475 0/ba456a79: 172.20.255.18 shell login for 't.chernev' from 10.71.8.88 on tty1 succeeded
sh: 1: printf: printf: I/O error
root@ru-mos-dc01-aaa01:/etc/tacacs+# 
  1. I block network traffic, thereby simulating the unavailability of the ldap server

And I don't get the error about ldap not being available on timeout, it keeps trying to find the username on ldap even though it's not available

debug
изображение

ssh client
изображение

mavistest
RESULT ERR
USER_RESPONSE No answer from LDAP backend.

@MarcJHuber
Copy link
Owner

Hi,

here's a sample config that enables the local password for the "demo" user after the backend fails. The login attempt triggering fallback activation will be rejected. Please note that mirroring a non-local user isn't possible, all you can do is to redirect the password to the backend.

Cheers,

Marc

id = spawnd {
        listen { port = 4949 }
}

id = tac_plus-ng {
        debug = 4195106

        mavis module ldap = external {
                setenv LDAP_BASE = "dc=example,dc=com"
                setenv LDAP_USER = "cn=admin,dc=example,dc=com"
                setenv LDAP_PASSWD = "invalid"
                setenv LDAP_HOSTS = "ldaps://127.0.0.1:6360" # unreachable
                exec = /usr/local/lib/mavis/mavis_tacplus-ng_ldap.pl
        }

        user backend = mavis
        login backend = mavis chpass
        pap backend = mavis
        pap password = login

        mavis cache timeout = 60

        host world {
                address = ::/0
                welcome banner = "Welcome\n"
                welcome banner fallback = "Welcome (fallback mode)\n"
                key = demo
        }

        profile engineering {
                script {
                        if (service == shell) {
                            if (cmd == "")
                                set priv-lvl = 15
                            permit
                        }
                }
        }

        authentication fallback = yes

        user fallback {
                password login = clear fallback
                fallback-only
        }

        user demo {
                password login = mavis
                password login fallback = clear demo123
        }

        ruleset {
                rule {
                        script {
                                profile = engineering
                                permit
                        }
                }
        }
}

@MarcJHuber
Copy link
Owner

Hi,

after a9c4fdb,

The login attempt triggering fallback activation will be rejected.

is no longer valid, the login will be rejected only if the password doesn't match, not due the backend failure.

Cheers,

Marc

@chernevta
Copy link
Author

chernevta commented Dec 9, 2024

updated after commit a9c4fdb
fallback works, but if you break the network connection with ldap, then there is no error on timeout, but what happens on the screen
изображение

I'm currently using this configuration
password login = mavis
password login fallback = clear 123

Everything works except for problems with network connection to the ldap server. Apparently this is due to incorrect processing backend failure

@MarcJHuber
Copy link
Owner

Hi,

please retry with the configuration I've posted above. The key parts of that are

        authentication fallback = yes

        user demo {
                password login = mavis
                password login fallback = clear demo123
        }

If this doesn't work for you I'll need a minimized configuration and full debug output to reproduce and analyze this issue.

Thanks,

Marc

@chernevta
Copy link
Author

chernevta commented Dec 9, 2024

I think I got to the bottom of the problem

tacacsng-config.txt
or

#!/usr/local/sbin/tac_plus-ng
id = spawnd {
        listen = { address = 10.77.13.1 port = 49 }
        background = yes
}

id = tac_plus-ng {
mavis module = external {
        setenv LDAP_SERVER_TYPE = "microsoft"
        setenv LDAP_HOSTS = "cor.ya.ru:389"
        setenv LDAP_BASE = "dc=cor,dc=ya,dc=ru"
        setenv LDAP_USER = "[email protected]"
        setenv LDAP_PASSWD = "TEST"
        setenv TACACS_GROUP_PREFIX = "aaanet_"
        setenv UNLIMIT_AD_GROUP_MEMBERSHIP = 1
        exec = /usr/local/lib/mavis/mavis_tacplus_ldap.pl
}

login backend = mavis
user backend = mavis
pap backend = mavis
mavis noauthcache
authentication fallback = yes

host IPv4_switches {
        address = 0.0.0.0/0
        key = TEST
}

profile netadmin {
        script {
                if (service == shell) {
                        if (cmd == "") {
                                set priv-lvl = 15
                                permit
                        }
                }
        }
}

group admins_local
group admins
group readonly

user demo {
        member = admins_local
        password login = mavis
        password login fallback = clear demo123
}

ruleset {
        rule {
                script {
                        if (group ==  admins_local) {  profile = netadmin permit }
                        if (group ==  admins) {  profile = netadmin permit }
                }
        }
}

}

let's do 2 tests:

1- test:

/usr/local/sbin/tac_plus-ng -fd -1 -1 /etc/tacacs+/tacacs-ng-test.conf

eternal lookup in MAVIS
debug
debug-1.txt

Please note that fqdn cor.ya.ru which responds to DNS request

nslookup cor.ya.ru 8.8.8.8
Server:         8.8.8.8
Address:        8.8.8.8#53

Non-authoritative answer:
cor.ya.ru       canonical name = any.yandex.ru.
Name:   any.yandex.ru
Address: 213.180.204.242
Name:   any.yandex.ru
Address: 2a02:6b8::242

this is not my domain and i decided to put a domain that is not known

2-test:

changing

        setenv LDAP_HOSTS = "cor.ya.ru:389"
        setenv LDAP_BASE = "dc=cor,dc=ya,dc=ru"
        setenv LDAP_USER = "[email protected]"

-->

        setenv LDAP_HOSTS = "cor.yap100.ru:389"
        setenv LDAP_BASE = "dc=cor,dc=yap100,dc=ru"
        setenv LDAP_USER = "[email protected]"
nslookup cor.yap100.ru: 8.8.8.8
Server:         8.8.8.8
Address:        8.8.8.8#53

** server can't find cor.yap100.ru:: NXDOMAIN

And in this case the server began to respond correctly that it is unavailable and conduct aaa through the demo user

debug-2.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants