diff options
-rw-r--r-- | data/templates/login/limits.j2 | 5 | ||||
-rw-r--r-- | interface-definitions/system-login.xml.in | 13 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_system_login.py | 23 | ||||
-rwxr-xr-x | src/conf_mode/system-login.py | 14 |
4 files changed, 53 insertions, 2 deletions
diff --git a/data/templates/login/limits.j2 b/data/templates/login/limits.j2 new file mode 100644 index 000000000..5e2c11f35 --- /dev/null +++ b/data/templates/login/limits.j2 @@ -0,0 +1,5 @@ +# Generated by /usr/libexec/vyos/conf_mode/system-login.py + +{% if max_login_session is vyos_defined %} +* - maxsyslogins {{ max_login_session }} +{% endif %} diff --git a/interface-definitions/system-login.xml.in b/interface-definitions/system-login.xml.in index b00741ffe..258913929 100644 --- a/interface-definitions/system-login.xml.in +++ b/interface-definitions/system-login.xml.in @@ -225,6 +225,19 @@ #include <include/interface/vrf.xml.i> </children> </node> + <leafNode name="max-login-session"> + <properties> + <help>Maximum number of all login sessions</help> + <valueHelp> + <format>u32:1-65536</format> + <description>Maximum number of all login sessions</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-65536"/> + </constraint> + <constraintErrorMessage>Maximum logins must be between 1 and 65536</constraintErrorMessage> + </properties> + </leafNode> <leafNode name="timeout"> <properties> <help>Session timeout</help> diff --git a/smoketest/scripts/cli/test_system_login.py b/smoketest/scripts/cli/test_system_login.py index 6006fe0f6..a1d2ba2ad 100755 --- a/smoketest/scripts/cli/test_system_login.py +++ b/smoketest/scripts/cli/test_system_login.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2019-2022 VyOS maintainers and contributors +# Copyright (C) 2019-2023 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -264,5 +264,26 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase): tmp = re.findall(r'group:\s+mapname\s+files', nsswitch_conf) self.assertTrue(tmp) + def test_system_login_max_login_session(self): + max_logins = '2' + timeout = '600' + + self.cli_set(base_path + ['max-login-session', max_logins]) + + # 'max-login-session' must be only with 'timeout' option + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + self.cli_set(base_path + ['timeout', timeout]) + + self.cli_commit() + + security_limits = read_file('/etc/security/limits.d/10-vyos.conf') + self.assertIn(f'* - maxsyslogins {max_logins}', security_limits) + + self.cli_delete(base_path + ['timeout']) + self.cli_delete(base_path + ['max-login-session']) + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py index d15fe399d..fbb013cf3 100755 --- a/src/conf_mode/system-login.py +++ b/src/conf_mode/system-login.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020-2022 VyOS maintainers and contributors +# Copyright (C) 2020-2023 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -40,6 +40,7 @@ from vyos import airbag airbag.enable() autologout_file = "/etc/profile.d/autologout.sh" +limits_file = "/etc/security/limits.d/10-vyos.conf" radius_config_file = "/etc/pam_radius_auth.conf" # LOGIN_TIMEOUT from /etc/loign.defs minus 10 sec @@ -164,6 +165,9 @@ def verify(login): if ipv6_count > 1: raise ConfigError('Only one IPv6 source-address can be set!') + if 'max_login_session' in login and 'timeout' not in login: + raise ConfigError('"login timeout" must be configured!') + return None @@ -226,6 +230,14 @@ def generate(login): if os.path.isfile(radius_config_file): os.unlink(radius_config_file) + # /etc/security/limits.d/10-vyos.conf + if 'max_login_session' in login: + render(limits_file, 'login/limits.j2', login, + permission=0o644, user='root', group='root') + else: + if os.path.isfile(limits_file): + os.unlink(limits_file) + if 'timeout' in login: render(autologout_file, 'login/autologout.j2', login, permission=0o755, user='root', group='root') |