From 5181ab60bb6d936505967d6667adc12c5ecb9b64 Mon Sep 17 00:00:00 2001 From: zsdc Date: Wed, 13 Sep 2023 12:41:04 +0300 Subject: RADIUS: T5577: Added `mandatory` and `optional` modes for RADIUS In CLI we can choose authentication logic: - `mandatory` - if RADIUS answered with `Access-Reject`, authentication must be stopped and access denied immediately. - `optional` (default) - if RADIUS answers with `Access-Reject`, authentication continues using the next module. In `mandatory` mode authentication will be stopped only if RADIUS clearly answered that access should be denied (no user in RADIUS database, wrong password, etc.). If RADIUS is not available or other errors happen, it will be skipped and authentication will continue with the next module, like in `optional` mode. --- src/conf_mode/system-login.py | 14 ++++++++++---- src/pam-configs/radius | 20 -------------------- src/pam-configs/radius-mandatory | 19 +++++++++++++++++++ src/pam-configs/radius-optional | 19 +++++++++++++++++++ 4 files changed, 48 insertions(+), 24 deletions(-) delete mode 100644 src/pam-configs/radius create mode 100644 src/pam-configs/radius-mandatory create mode 100644 src/pam-configs/radius-optional (limited to 'src') diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py index 02c97afaa..be5ff2d4c 100755 --- a/src/conf_mode/system-login.py +++ b/src/conf_mode/system-login.py @@ -104,6 +104,9 @@ def get_config(config=None): # prune TACACS global defaults if not set by user if login.from_defaults(['tacacs']): del login['tacacs'] + # same for RADIUS + if login.from_defaults(['radius']): + del login['radius'] # create a list of all users, cli and users all_users = list(set(local_users + cli_users)) @@ -377,11 +380,14 @@ def apply(login): except Exception as e: raise ConfigError(f'Deleting user "{user}" raised exception: {e}') - # Enable RADIUS in PAM configuration - pam_cmd = '--remove' + # Enable/disable RADIUS in PAM configuration + cmd('pam-auth-update --disable radius-mandatory radius-optional') if 'radius' in login: - pam_cmd = '--enable' - cmd(f'pam-auth-update --package {pam_cmd} radius') + if login['radius'].get('security_mode', '') == 'mandatory': + pam_profile = 'radius-mandatory' + else: + pam_profile = 'radius-optional' + cmd(f'pam-auth-update --enable {pam_profile}') # Enable/Disable TACACS in PAM configuration pam_cmd = '--remove' diff --git a/src/pam-configs/radius b/src/pam-configs/radius deleted file mode 100644 index eee9cb93e..000000000 --- a/src/pam-configs/radius +++ /dev/null @@ -1,20 +0,0 @@ -Name: RADIUS authentication -Default: no -Priority: 257 -Auth-Type: Primary -Auth: - [default=ignore success=2] pam_succeed_if.so service = sudo - [default=ignore success=ignore] pam_succeed_if.so user ingroup aaa quiet - [authinfo_unavail=ignore success=end default=ignore] pam_radius_auth.so - -Account-Type: Primary -Account: - [default=ignore success=2] pam_succeed_if.so service = sudo - [default=ignore success=ignore] pam_succeed_if.so user ingroup aaa quiet - [authinfo_unavail=ignore success=end perm_denied=bad default=ignore] pam_radius_auth.so - -Session-Type: Additional -Session: - [default=ignore success=2] pam_succeed_if.so service = sudo - [default=ignore success=ignore] pam_succeed_if.so user ingroup aaa quiet - [authinfo_unavail=ignore success=ok default=ignore] pam_radius_auth.so diff --git a/src/pam-configs/radius-mandatory b/src/pam-configs/radius-mandatory new file mode 100644 index 000000000..43b6bd3e0 --- /dev/null +++ b/src/pam-configs/radius-mandatory @@ -0,0 +1,19 @@ +Name: RADIUS authentication (mandatory mode) +Default: no +Priority: 576 + +Auth-Type: Primary +Auth-Initial: + [default=ignore success=end perm_denied=bad auth_err=bad] pam_radius_auth.so +Auth: + [default=ignore success=end perm_denied=bad auth_err=bad] pam_radius_auth.so use_first_pass + +Account-Type: Primary +Account: + [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet + [default=ignore new_authtok_reqd=done success=end perm_denied=bad auth_err=bad] pam_radius_auth.so + +Session-Type: Additional +Session: + [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet + [default=ignore success=ok perm_denied=bad auth_err=bad] pam_radius_auth.so diff --git a/src/pam-configs/radius-optional b/src/pam-configs/radius-optional new file mode 100644 index 000000000..9f6d5f0ea --- /dev/null +++ b/src/pam-configs/radius-optional @@ -0,0 +1,19 @@ +Name: RADIUS authentication (optional mode) +Default: no +Priority: 576 + +Auth-Type: Primary +Auth-Initial: + [default=ignore success=end] pam_radius_auth.so +Auth: + [default=ignore success=end] pam_radius_auth.so use_first_pass + +Account-Type: Primary +Account: + [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet + [default=ignore new_authtok_reqd=done success=end perm_denied=bad auth_err=bad] pam_radius_auth.so + +Session-Type: Additional +Session: + [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet + [default=ignore success=ok perm_denied=bad auth_err=bad] pam_radius_auth.so -- cgit v1.2.3 From 1c804685d05ad639bcb1a9ebce68a7a14268500f Mon Sep 17 00:00:00 2001 From: zsdc Date: Wed, 13 Sep 2023 13:16:20 +0300 Subject: TACACS: T5577: Added `mandatory` and `optional` modes for TACACS+ In CLI we can choose authentication logic: - `mandatory` - if TACACS+ answered with `REJECT`, authentication must be stopped and access denied immediately. - `optional` (default) - if TACACS+ answers with `REJECT`, authentication continues using the next module. In `mandatory` mode authentication will be stopped only if TACACS+ clearly answered that access should be denied (no user in TACACS+ database, wrong password, etc.). If TACACS+ is not available or other errors happen, it will be skipped and authentication will continue with the next module, like in `optional` mode. --- debian/vyos-1x.postinst | 6 +++++- debian/vyos-1x.preinst | 1 - interface-definitions/system-login.xml.in | 20 ++++++++++++++++++++ src/conf_mode/system-login.py | 11 +++++++---- src/pam-configs/tacplus | 17 ----------------- src/pam-configs/tacplus-mandatory | 19 +++++++++++++++++++ src/pam-configs/tacplus-optional | 19 +++++++++++++++++++ 7 files changed, 70 insertions(+), 23 deletions(-) delete mode 100644 src/pam-configs/tacplus create mode 100644 src/pam-configs/tacplus-mandatory create mode 100644 src/pam-configs/tacplus-optional (limited to 'src') diff --git a/debian/vyos-1x.postinst b/debian/vyos-1x.postinst index a3c308e5f..860319edf 100644 --- a/debian/vyos-1x.postinst +++ b/debian/vyos-1x.postinst @@ -48,6 +48,11 @@ if grep -q '^tacacs' /etc/passwd; then fi fi +# Remove TACACS+ PAM default profile +if [[ -e /usr/share/pam-configs/tacplus ]]; then + rm /usr/share/pam-configs/tacplus +fi + # Add TACACS system users required for TACACS based system authentication if ! grep -q '^tacacs' /etc/passwd; then # Add the tacacs group and all 16 possible tacacs privilege-level users to @@ -66,7 +71,6 @@ if ! grep -q '^tacacs' /etc/passwd; then adduser --quiet tacacs${level} adm adduser --quiet tacacs${level} dip adduser --quiet tacacs${level} users - adduser --quiet tacacs${level} aaa if [ $level -lt 15 ]; then adduser --quiet tacacs${level} vyattaop adduser --quiet tacacs${level} operator diff --git a/debian/vyos-1x.preinst b/debian/vyos-1x.preinst index 75fa5e7f1..861c5ec88 100644 --- a/debian/vyos-1x.preinst +++ b/debian/vyos-1x.preinst @@ -2,7 +2,6 @@ dpkg-divert --package vyos-1x --add --no-rename /etc/securetty dpkg-divert --package vyos-1x --add --no-rename /etc/security/capability.conf dpkg-divert --package vyos-1x --add --no-rename /lib/systemd/system/lcdproc.service dpkg-divert --package vyos-1x --add --no-rename /etc/logrotate.d/conntrackd -dpkg-divert --package vyos-1x --add --no-rename /usr/share/pam-configs/tacplus dpkg-divert --package vyos-1x --add --no-rename /etc/rsyslog.conf dpkg-divert --package vyos-1x --add --no-rename /etc/skel/.bashrc dpkg-divert --package vyos-1x --add --no-rename /etc/skel/.profile diff --git a/interface-definitions/system-login.xml.in b/interface-definitions/system-login.xml.in index 71db8b1d6..30fea91b0 100644 --- a/interface-definitions/system-login.xml.in +++ b/interface-definitions/system-login.xml.in @@ -259,6 +259,26 @@ + + + Security mode for TACACS+ authentication + + mandatory optional + + + mandatory + Deny access immediately if TACACS+ answers with REJECT + + + optional + Pass to the next authentication method if TACACS+ answers with REJECT + + + (mandatory|optional) + + + optional + #include #include diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py index be5ff2d4c..87a269499 100755 --- a/src/conf_mode/system-login.py +++ b/src/conf_mode/system-login.py @@ -389,11 +389,14 @@ def apply(login): pam_profile = 'radius-optional' cmd(f'pam-auth-update --enable {pam_profile}') - # Enable/Disable TACACS in PAM configuration - pam_cmd = '--remove' + # Enable/disable TACACS+ in PAM configuration + cmd('pam-auth-update --disable tacplus-mandatory tacplus-optional') if 'tacacs' in login: - pam_cmd = '--enable' - cmd(f'pam-auth-update --package {pam_cmd} tacplus') + if login['tacacs'].get('security_mode', '') == 'mandatory': + pam_profile = 'tacplus-mandatory' + else: + pam_profile = 'tacplus-optional' + cmd(f'pam-auth-update --enable {pam_profile}') return None diff --git a/src/pam-configs/tacplus b/src/pam-configs/tacplus deleted file mode 100644 index 66a1eaa4c..000000000 --- a/src/pam-configs/tacplus +++ /dev/null @@ -1,17 +0,0 @@ -Name: TACACS+ authentication -Default: no -Priority: 257 -Auth-Type: Primary -Auth: - [default=ignore success=ignore] pam_succeed_if.so user ingroup aaa quiet - [authinfo_unavail=ignore success=end auth_err=bad default=ignore] pam_tacplus.so include=/etc/tacplus_servers login=login - -Account-Type: Primary -Account: - [default=ignore success=ignore] pam_succeed_if.so user ingroup aaa quiet - [authinfo_unavail=ignore success=end perm_denied=bad default=ignore] pam_tacplus.so include=/etc/tacplus_servers login=login - -Session-Type: Additional -Session: - [default=ignore success=ignore] pam_succeed_if.so user ingroup aaa quiet - [authinfo_unavail=ignore success=ok default=ignore] pam_tacplus.so include=/etc/tacplus_servers login=login diff --git a/src/pam-configs/tacplus-mandatory b/src/pam-configs/tacplus-mandatory new file mode 100644 index 000000000..92da02327 --- /dev/null +++ b/src/pam-configs/tacplus-mandatory @@ -0,0 +1,19 @@ +Name: TACACS+ authentication (mandatory mode) +Default: no +Priority: 576 + +Auth-Type: Primary +Auth-Initial: + [default=ignore success=end perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login +Auth: + [default=ignore success=end perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login use_first_pass + +Account-Type: Primary +Account: + [default=ignore success=1] pam_succeed_if.so user notingroup tacacs quiet + [default=ignore new_authtok_reqd=done success=end perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login + +Session-Type: Additional +Session: + [default=ignore success=1] pam_succeed_if.so user notingroup tacacs quiet + [default=ignore success=ok perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login diff --git a/src/pam-configs/tacplus-optional b/src/pam-configs/tacplus-optional new file mode 100644 index 000000000..deed537d3 --- /dev/null +++ b/src/pam-configs/tacplus-optional @@ -0,0 +1,19 @@ +Name: TACACS+ authentication (optional mode) +Default: no +Priority: 576 + +Auth-Type: Primary +Auth-Initial: + [default=ignore success=end] pam_tacplus.so include=/etc/tacplus_servers login=login +Auth: + [default=ignore success=end] pam_tacplus.so include=/etc/tacplus_servers login=login use_first_pass + +Account-Type: Primary +Account: + [default=ignore success=1] pam_succeed_if.so user notingroup tacacs quiet + [default=ignore new_authtok_reqd=done success=end perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login + +Session-Type: Additional +Session: + [default=ignore success=1] pam_succeed_if.so user notingroup tacacs quiet + [default=ignore success=ok perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login -- cgit v1.2.3 From 784fb7dc2ccc63789ed85d803e3ae41eef0e0253 Mon Sep 17 00:00:00 2001 From: zsdc Date: Tue, 19 Sep 2023 21:03:51 +0300 Subject: pam: T5577: Improved PAM configs for RADIUS and TACACS+ After sources analysis, we found the next possible return statuses for PAM modules: 1. pam_tacplus Auth: - PAM_AUTH_ERR - PAM_AUTHINFO_UNAVAIL - PAM_AUTHTOK_ERR - PAM_BUF_ERR - PAM_CRED_INSUFFICIENT - PAM_PERM_DENIED - PAM_SUCCESS - PAM_USER_UNKNOWN Account: - PAM_AUTH_ERR - PAM_AUTHINFO_UNAVAIL - PAM_PERM_DENIED - PAM_SUCCESS - PAM_USER_UNKNOWN Session: - PAM_AUTHINFO_UNAVAIL - PAM_SESSION_ERR - PAM_SUCCESS - PAM_USER_UNKNOWN 2. pam_radius_auth Auth: - PAM_ABORT - PAM_AUTH_ERR - PAM_AUTHINFO_UNAVAIL - PAM_AUTHTOK_ERR - PAM_BAD_ITEM - PAM_BUF_ERR - PAM_CONV_AGAIN - PAM_CONV_ERR - PAM_IGNORE - PAM_NO_MODULE_DATA - PAM_PERM_DENIED - PAM_SUCCESS - PAM_SYSTEM_ERR - PAM_USER_UNKNOWN Account: - PAM_SUCCESS Session: - PAM_ABORT - PAM_AUTHINFO_UNAVAIL - PAM_BAD_ITEM - PAM_BUF_ERR - PAM_CONV_AGAIN - PAM_CONV_ERR - PAM_IGNORE - PAM_NO_MODULE_DATA - PAM_PERM_DENIED - PAM_SUCCESS - PAM_SYSTEM_ERR - PAM_USER_UNKNOWN PAM configurations were replaced with tuned versions to take this into account. --- src/pam-configs/radius-mandatory | 8 ++++---- src/pam-configs/radius-optional | 4 ++-- src/pam-configs/tacplus-mandatory | 8 +++----- src/pam-configs/tacplus-optional | 8 +++----- 4 files changed, 12 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/pam-configs/radius-mandatory b/src/pam-configs/radius-mandatory index 43b6bd3e0..3368fe7ff 100644 --- a/src/pam-configs/radius-mandatory +++ b/src/pam-configs/radius-mandatory @@ -4,16 +4,16 @@ Priority: 576 Auth-Type: Primary Auth-Initial: - [default=ignore success=end perm_denied=bad auth_err=bad] pam_radius_auth.so + [default=ignore success=end auth_err=die perm_denied=die user_unknown=die] pam_radius_auth.so Auth: - [default=ignore success=end perm_denied=bad auth_err=bad] pam_radius_auth.so use_first_pass + [default=ignore success=end auth_err=die perm_denied=die user_unknown=die] pam_radius_auth.so use_first_pass Account-Type: Primary Account: [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet - [default=ignore new_authtok_reqd=done success=end perm_denied=bad auth_err=bad] pam_radius_auth.so + [default=ignore success=end] pam_radius_auth.so Session-Type: Additional Session: [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet - [default=ignore success=ok perm_denied=bad auth_err=bad] pam_radius_auth.so + [default=bad success=ok] pam_radius_auth.so diff --git a/src/pam-configs/radius-optional b/src/pam-configs/radius-optional index 9f6d5f0ea..73085061d 100644 --- a/src/pam-configs/radius-optional +++ b/src/pam-configs/radius-optional @@ -11,9 +11,9 @@ Auth: Account-Type: Primary Account: [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet - [default=ignore new_authtok_reqd=done success=end perm_denied=bad auth_err=bad] pam_radius_auth.so + [default=ignore success=end] pam_radius_auth.so Session-Type: Additional Session: [default=ignore success=1] pam_succeed_if.so user notingroup radius quiet - [default=ignore success=ok perm_denied=bad auth_err=bad] pam_radius_auth.so + [default=ignore success=ok perm_denied=bad user_unknown=bad] pam_radius_auth.so diff --git a/src/pam-configs/tacplus-mandatory b/src/pam-configs/tacplus-mandatory index 92da02327..ffccece19 100644 --- a/src/pam-configs/tacplus-mandatory +++ b/src/pam-configs/tacplus-mandatory @@ -3,17 +3,15 @@ Default: no Priority: 576 Auth-Type: Primary -Auth-Initial: - [default=ignore success=end perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login Auth: - [default=ignore success=end perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login use_first_pass + [default=ignore success=end auth_err=die perm_denied=die user_unknown=die] pam_tacplus.so include=/etc/tacplus_servers login=login Account-Type: Primary Account: [default=ignore success=1] pam_succeed_if.so user notingroup tacacs quiet - [default=ignore new_authtok_reqd=done success=end perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login + [default=bad success=end] pam_tacplus.so include=/etc/tacplus_servers login=login Session-Type: Additional Session: [default=ignore success=1] pam_succeed_if.so user notingroup tacacs quiet - [default=ignore success=ok perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login + [default=bad success=ok] pam_tacplus.so include=/etc/tacplus_servers login=login diff --git a/src/pam-configs/tacplus-optional b/src/pam-configs/tacplus-optional index deed537d3..095c3a164 100644 --- a/src/pam-configs/tacplus-optional +++ b/src/pam-configs/tacplus-optional @@ -3,17 +3,15 @@ Default: no Priority: 576 Auth-Type: Primary -Auth-Initial: - [default=ignore success=end] pam_tacplus.so include=/etc/tacplus_servers login=login Auth: - [default=ignore success=end] pam_tacplus.so include=/etc/tacplus_servers login=login use_first_pass + [default=ignore success=end] pam_tacplus.so include=/etc/tacplus_servers login=login Account-Type: Primary Account: [default=ignore success=1] pam_succeed_if.so user notingroup tacacs quiet - [default=ignore new_authtok_reqd=done success=end perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login + [default=ignore success=end auth_err=bad perm_denied=bad user_unknown=bad] pam_tacplus.so include=/etc/tacplus_servers login=login Session-Type: Additional Session: [default=ignore success=1] pam_succeed_if.so user notingroup tacacs quiet - [default=ignore success=ok perm_denied=bad auth_err=bad] pam_tacplus.so include=/etc/tacplus_servers login=login + [default=ignore success=ok session_err=bad user_unknown=bad] pam_tacplus.so include=/etc/tacplus_servers login=login -- cgit v1.2.3