From beb8bbe9f40dae3e3af27de989b8a4ab899ba801 Mon Sep 17 00:00:00 2001 From: vdahiya12 <67608553+vdahiya12@users.noreply.github.com> Date: Thu, 2 Nov 2023 17:08:07 -0700 Subject: [PATCH 1/5] [DualToR][caclmgrd] Fix IPtables rules for multiple vlan interfaces for DualToR config (#82) This PR is a required for changing the L3 IP forwarding Behavior to SoC in active-active toplogy. Basically a src IP is added to the SNAT rule so that only packets originating from ToR with src IP as vlan IP get natted by the rule and change the src IP to LoopBack IP However if there are mutiple vlan IP's we only add the source IP as vlan IP, for which the SoC IP belongs to, this PR adds that change. How I did it check the config DB if the ToR is a DualToR and has an SoC IP assigned. put an iptable rule iptables -t nat -A POSTROUTING --destination -j SNAT --to-source " Signed-off-by: vaibhav-dahiya --- scripts/caclmgrd | 41 +++++++++++---- tests/caclmgrd/caclmgrd_soc_rules_test.py | 63 ++++++++++++++++++++--- tests/caclmgrd/test_soc_rules_vectors.py | 46 +++++++++++++++-- 3 files changed, 131 insertions(+), 19 deletions(-) diff --git a/scripts/caclmgrd b/scripts/caclmgrd index 1f044ad1..1b53c3a2 100755 --- a/scripts/caclmgrd +++ b/scripts/caclmgrd @@ -41,8 +41,10 @@ def _ip_prefix_in_key(key): """ return (isinstance(key, tuple)) -def get_ip_from_interface_table(table, intf_name): +def get_ipv4_networks_from_interface_table(table, intf_name): + + addresses = [] if table: for key, _ in table.items(): if not _ip_prefix_in_key(key): @@ -51,12 +53,11 @@ def get_ip_from_interface_table(table, intf_name): iface_name, iface_cidr = key if iface_name.startswith(intf_name): - ip_str = iface_cidr.split("/")[0] - ip_addr = ipaddress.ip_address(ip_str) - if isinstance(ip_addr, ipaddress.IPv4Address): - return ip_addr + ip_ntwrk = ipaddress.ip_network(iface_cidr, strict=False) + if isinstance(ip_ntwrk, ipaddress.IPv4Network): + addresses.append(ip_ntwrk) - return None + return addresses # ============================== Classes ============================== @@ -359,11 +360,24 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): if self.DualToR: loopback_table = config_db_connector.get_table(self.LOOPBACK_TABLE) loopback_name = 'Loopback3' - loopback_address = get_ip_from_interface_table(loopback_table, loopback_name) + loopback_networks = get_ipv4_networks_from_interface_table(loopback_table, loopback_name) + if len(loopback_networks) == 0: + self.log_warning("Loopback 3 IP not available from DualToR active-active config") + return fwd_dualtor_grpc_traffic_from_host_to_soc_cmds + + if not isinstance(loopback_networks[0], ipaddress.IPv4Network): + self.log_warning("Loopback 3 IP Network not available from DualToR active-active config") + return fwd_dualtor_grpc_traffic_from_host_to_soc_cmds + + loopback_address = loopback_networks[0].network_address vlan_name = 'Vlan' vlan_table = config_db_connector.get_table(self.VLAN_INTF_TABLE) + vlan_networks = get_ipv4_networks_from_interface_table(vlan_table, vlan_name) + + if len(vlan_networks) == 0: + self.log_warning("Vlan IP not available from DualToR active-active config") + return fwd_dualtor_grpc_traffic_from_host_to_soc_cmds - vlan_address = get_ip_from_interface_table(vlan_table, vlan_name) fwd_dualtor_grpc_traffic_from_host_to_soc_cmds.append(self.iptables_cmd_ns_prefix[namespace] + ['iptables', '-t', 'nat', '--flush', 'POSTROUTING']) @@ -373,11 +387,18 @@ class ControlPlaneAclManager(daemon_base.DaemonBase): for key in mux_table_keys: kvp = mux_table.get(key) if 'cable_type' in kvp and kvp['cable_type'] == 'active-active': - fwd_dualtor_grpc_traffic_from_host_to_soc_cmds.append(self.iptables_cmd_ns_prefix[namespace] + - ['iptables', '-t', 'nat', '-A', 'POSTROUTING', '--destination', kvp['soc_ipv4'], '--source', vlan_address, '-j', 'SNAT', '--to-source', loopback_address]) + soc_ipv4_str = kvp['soc_ipv4'].split("/")[0] + soc_ipv4_addr = ipaddress.ip_address(soc_ipv4_str) + for ip_network in vlan_networks: + # Only add the vlan source IP specific soc IP address to IPtables + if soc_ipv4_addr in ip_network: + vlan_address = ip_network.network_address + fwd_dualtor_grpc_traffic_from_host_to_soc_cmds.append(self.iptables_cmd_ns_prefix[namespace] + + ['iptables', '-t', 'nat', '-A', 'POSTROUTING', '--destination', str(soc_ipv4_addr), '--source', str(vlan_address), '-j', 'SNAT', '--to-source', str(loopback_address)]) return fwd_dualtor_grpc_traffic_from_host_to_soc_cmds + def generate_fwd_traffic_from_namespace_to_host_commands(self, namespace, acl_source_ip_map): """ The below SNAT and DNAT rules are added in asic namespace in multi-ASIC platforms. It helps to forward request coming diff --git a/tests/caclmgrd/caclmgrd_soc_rules_test.py b/tests/caclmgrd/caclmgrd_soc_rules_test.py index 5f5ee4d8..ef40292a 100644 --- a/tests/caclmgrd/caclmgrd_soc_rules_test.py +++ b/tests/caclmgrd/caclmgrd_soc_rules_test.py @@ -4,11 +4,11 @@ from parameterized import parameterized from sonic_py_common.general import load_module_from_source -from ipaddress import IPv4Address +from ipaddress import IPv4Address, IPv4Network from unittest import TestCase, mock from pyfakefs.fake_filesystem_unittest import patchfs -from .test_soc_rules_vectors import CACLMGRD_SOC_TEST_VECTOR +from .test_soc_rules_vectors import CACLMGRD_SOC_TEST_VECTOR, CACLMGRD_SOC_TEST_VECTOR_EMPTY from tests.common.mock_configdb import MockConfigDb from unittest.mock import MagicMock, patch @@ -29,7 +29,7 @@ def setUp(self): @parameterized.expand(CACLMGRD_SOC_TEST_VECTOR) @patchfs - @patch('caclmgrd.get_ip_from_interface_table', MagicMock(return_value="10.10.10.10")) + @patch('caclmgrd.get_ipv4_networks_from_interface_table', MagicMock(return_value=[IPv4Network('10.10.10.18/24', strict=False), IPv4Network('10.10.11.18/24', strict=False)])) def test_caclmgrd_soc(self, test_name, test_data, fs): if not os.path.exists(DBCONFIG_PATH): fs.create_file(DBCONFIG_PATH) # fake database_config.json @@ -51,11 +51,62 @@ def test_caclmgrd_soc(self, test_name, test_data, fs): caclmgrd_daemon.update_control_plane_nat_acls('', {}, MockConfigDb()) mocked_subprocess.Popen.assert_has_calls(test_data["expected_subprocess_calls"], any_order=True) - def test_get_ip_from_interface_table(self): + + @parameterized.expand(CACLMGRD_SOC_TEST_VECTOR_EMPTY) + @patchfs + @patch('caclmgrd.get_ipv4_networks_from_interface_table', MagicMock(return_value=[])) + def test_caclmgrd_soc_no_ips(self, test_name, test_data, fs): + if not os.path.exists(DBCONFIG_PATH): + fs.create_file(DBCONFIG_PATH) # fake database_config.json + + MockConfigDb.set_config_db(test_data["config_db"]) + + with mock.patch("caclmgrd.ControlPlaneAclManager.run_commands_pipe", return_value='sonic'): + with mock.patch("caclmgrd.subprocess") as mocked_subprocess: + popen_mock = mock.Mock() + popen_attrs = test_data["popen_attributes"] + popen_mock.configure_mock(**popen_attrs) + mocked_subprocess.Popen.return_value = popen_mock + mocked_subprocess.PIPE = -1 + + call_rc = test_data["call_rc"] + mocked_subprocess.call.return_value = call_rc + + caclmgrd_daemon = self.caclmgrd.ControlPlaneAclManager("caclmgrd") + caclmgrd_daemon.update_control_plane_nat_acls('', {}, MockConfigDb()) + mocked_subprocess.Popen.assert_has_calls(test_data["expected_subprocess_calls"], any_order=True) + + + @parameterized.expand(CACLMGRD_SOC_TEST_VECTOR_EMPTY) + @patchfs + @patch('caclmgrd.get_ipv4_networks_from_interface_table', MagicMock(return_value=['10.10.10.10'])) + def test_caclmgrd_soc_ip_string(self, test_name, test_data, fs): + if not os.path.exists(DBCONFIG_PATH): + fs.create_file(DBCONFIG_PATH) # fake database_config.json + + MockConfigDb.set_config_db(test_data["config_db"]) + + with mock.patch("caclmgrd.ControlPlaneAclManager.run_commands_pipe", return_value='sonic'): + with mock.patch("caclmgrd.subprocess") as mocked_subprocess: + popen_mock = mock.Mock() + popen_attrs = test_data["popen_attributes"] + popen_mock.configure_mock(**popen_attrs) + mocked_subprocess.Popen.return_value = popen_mock + mocked_subprocess.PIPE = -1 + + call_rc = test_data["call_rc"] + mocked_subprocess.call.return_value = call_rc + + caclmgrd_daemon = self.caclmgrd.ControlPlaneAclManager("caclmgrd") + caclmgrd_daemon.update_control_plane_nat_acls('', {}, MockConfigDb()) + mocked_subprocess.Popen.assert_has_calls(test_data["expected_subprocess_calls"], any_order=True) + + + def test_get_ipv4_networks_from_interface_table(self): if not os.path.exists(DBCONFIG_PATH): fs.create_file(DBCONFIG_PATH) # fake database_config.json table = {("Vlan1000","10.10.10.1/32"): "val"} - ip_addr = self.caclmgrd.get_ip_from_interface_table(table, "Vlan") + ip_addr = self.caclmgrd.get_ipv4_networks_from_interface_table(table, "Vlan") - assert (ip_addr == IPv4Address('10.10.10.1')) + assert (ip_addr == [IPv4Network('10.10.10.1/32')]) diff --git a/tests/caclmgrd/test_soc_rules_vectors.py b/tests/caclmgrd/test_soc_rules_vectors.py index c3b871c7..b339a32d 100644 --- a/tests/caclmgrd/test_soc_rules_vectors.py +++ b/tests/caclmgrd/test_soc_rules_vectors.py @@ -18,11 +18,11 @@ "MUX_CABLE": { "Ethernet4": { "cable_type": "active-active", - "soc_ipv4": "192.168.1.0/32", + "soc_ipv4": "10.10.11.7/32", } }, "VLAN_INTERFACE": { - "Vlan1000|10.10.2.2/23": { + "Vlan1000|10.10.10.3/24": { "NULL": "NULL", } }, @@ -35,7 +35,7 @@ }, }, "expected_subprocess_calls": [ - call(['iptables', '-t', 'nat', '-A', 'POSTROUTING', '--destination', '192.168.1.0/32', '--source', '10.10.10.10', '-j', 'SNAT', '--to-source', '10.10.10.10'], universal_newlines=True, stdout=-1) + call(['iptables', '-t', 'nat', '-A', 'POSTROUTING', '--destination', '10.10.11.7', '--source', '10.10.11.0', '-j', 'SNAT', '--to-source', '10.10.10.0'], universal_newlines=True, stdout=-1) ], "popen_attributes": { 'communicate.return_value': ('output', 'error'), @@ -44,3 +44,43 @@ } ] ] + + +CACLMGRD_SOC_TEST_VECTOR_EMPTY = [ + [ + "SOC_SESSION_TEST", + { + "config_db": { + "DEVICE_METADATA": { + "localhost": { + "subtype": "DualToR", + "type": "ToRRouter", + } + }, + "MUX_CABLE": { + "Ethernet4": { + "cable_type": "active-active", + "soc_ipv4": "10.10.11.7/32", + } + }, + "VLAN_INTERFACE": { + "Vlan1000|10.10.10.3/24": { + "NULL": "NULL", + } + }, + "LOOPBACK_INTERFACE": { + "Loopback3|10.10.10.10/32": { + "NULL": "NULL", + } + }, + "FEATURE": { + }, + }, + "expected_subprocess_calls": [], + "popen_attributes": { + 'communicate.return_value': ('output', 'error'), + }, + "call_rc": 0, + } + ] +] From 66d69a8901e185b40caca4433a57bf29f4bee6cf Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Wed, 6 Sep 2023 12:05:51 -0700 Subject: [PATCH 2/5] Specify test dependencies under extra_requires Newer versions of pip/setuptools don't support test_requires, and the current standard is to specify any extra dependencies (such as those required for testing) under extra_requires. Therefore, specify the testing dependencies under extra_requires. These can be installed via pip using `pip install '.[testing]'`. Signed-off-by: Saikrishna Arcot --- setup.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/setup.py b/setup.py index 1a9b51b8..51458f74 100644 --- a/setup.py +++ b/setup.py @@ -59,6 +59,15 @@ 'sonic-py-common', 'deepdiff==6.2.2' ], + extras_require = { + "testing": [ + 'parameterized', + 'pytest', + 'pyfakefs', + 'sonic-py-common', + 'deepdiff==6.2.2' + ] + }, classifiers = [ 'Development Status :: 3 - Alpha', 'Environment :: Console', From 447f8b6dd6e407a2592c2bbeb5c2b0352e0c6dd0 Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Tue, 12 Sep 2023 10:16:52 -0700 Subject: [PATCH 3/5] Fix diff output in test for Python 3 Signed-off-by: Saikrishna Arcot --- tests/hostcfgd/hostcfgd_passwh_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/hostcfgd/hostcfgd_passwh_test.py b/tests/hostcfgd/hostcfgd_passwh_test.py index 8cf08034..c583809b 100755 --- a/tests/hostcfgd/hostcfgd_passwh_test.py +++ b/tests/hostcfgd/hostcfgd_passwh_test.py @@ -123,7 +123,7 @@ def check_config(self, test_name, test_data, config_name): if not match: for name in files_to_compare: diff_output += self.run_diff( sop_path + "/" + name,\ - op_path + "/" + name).decode('utf-8') + op_path + "/" + name) self.assertTrue(len(diff_output) == 0, diff_output) From c913d4b5d4fe3b6336564758a081bef961f6250c Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Tue, 12 Sep 2023 10:24:17 -0700 Subject: [PATCH 4/5] Replace libpam-cracklib with libpam-pwquality Debian Bookworm has removed libpam-cracklib; replace with libpam-pwquality. Signed-off-by: Saikrishna Arcot --- .../PASSWORD_HARDENING_enable_digits_class/common-password | 2 +- .../PASSWORD_HARDENING_enable_feature/common-password | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_digits_class/common-password b/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_digits_class/common-password index 84107472..f5bbaf10 100644 --- a/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_digits_class/common-password +++ b/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_digits_class/common-password @@ -24,7 +24,7 @@ # here are the per-package modules (the "Primary" block) -password requisite pam_cracklib.so retry=3 maxrepeat=0 minlen=8 ucredit=0 lcredit=0 dcredit=-1 ocredit=0 enforce_for_root +password requisite pam_pwquality.so retry=3 maxrepeat=0 minlen=8 ucredit=0 lcredit=0 dcredit=-1 ocredit=0 enforce_for_root dictcheck=0 password required pam_pwhistory.so remember=0 use_authtok enforce_for_root diff --git a/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_feature/common-password b/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_feature/common-password index a66c1b1a..7ce952b7 100644 --- a/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_feature/common-password +++ b/tests/hostcfgd/sample_output/PASSWORD_HARDENING_enable_feature/common-password @@ -24,7 +24,7 @@ # here are the per-package modules (the "Primary" block) -password requisite pam_cracklib.so retry=3 maxrepeat=0 minlen=8 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 reject_username enforce_for_root +password requisite pam_pwquality.so retry=3 maxrepeat=0 minlen=8 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 reject_username enforce_for_root dictcheck=0 password required pam_pwhistory.so remember=10 use_authtok enforce_for_root From db4bbf8775c771d0cfb03d19e55851867dca27f2 Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Thu, 19 Oct 2023 15:09:57 -0700 Subject: [PATCH 5/5] Move sonic-host-services-data from sonic-buildimage into this repo This repo's tests depends on files that are in src/sonic-host-services-data in sonic-buildimage. Due to PR check requirements, this creates a cyclical dependency when needing to update the templates and the sample output files. To fix that cyclical dependency, move that directory into this repo. That way, both the templates and the sample output files can be updated in a single commit. Signed-off-by: Saikrishna Arcot --- azure-pipelines.yml | 29 +------ data/.gitignore | 6 ++ data/README.md | 19 +++++ data/debian/changelog | 5 ++ data/debian/compat | 1 + data/debian/control | 11 +++ data/debian/copyright | 0 data/debian/install | 2 + data/debian/rules | 24 ++++++ ...sonic-host-services-data.aaastatsd.service | 14 ++++ .../sonic-host-services-data.aaastatsd.timer | 12 +++ .../sonic-host-services-data.caclmgrd.service | 15 ++++ ...rvices-data.determine-reboot-cause.service | 12 +++ .../sonic-host-services-data.featured.service | 10 +++ .../sonic-host-services-data.featured.timer | 12 +++ .../sonic-host-services-data.hostcfgd.service | 11 +++ .../sonic-host-services-data.hostcfgd.timer | 12 +++ ...ost-services-data.procdockerstatsd.service | 14 ++++ ...services-data.process-reboot-cause.service | 8 ++ ...t-services-data.process-reboot-cause.timer | 9 ++ ...st-services-data.sonic-hostservice.service | 16 ++++ data/org.sonic.hostservice.conf | 18 ++++ data/templates/common-auth-sonic.j2 | 83 +++++++++++++++++++ data/templates/common-password.j2 | 43 ++++++++++ data/templates/limits.conf.j2 | 69 +++++++++++++++ data/templates/pam_limits.j2 | 12 +++ data/templates/pam_radius_auth.conf.j2 | 3 + data/templates/radius_nss.conf.j2 | 58 +++++++++++++ data/templates/tacplus_nss.conf.j2 | 60 ++++++++++++++ tests/hostcfgd/hostcfgd_passwh_test.py | 3 +- tests/hostcfgd/hostcfgd_radius_test.py | 3 +- tests/hostcfgd/hostcfgd_rsyslog_test.py | 3 +- tests/hostcfgd/hostcfgd_ssh_server_test.py | 1 - tests/hostcfgd/hostcfgd_tacacs_test.py | 3 +- 34 files changed, 567 insertions(+), 34 deletions(-) create mode 100644 data/.gitignore create mode 100644 data/README.md create mode 100644 data/debian/changelog create mode 100644 data/debian/compat create mode 100644 data/debian/control create mode 100644 data/debian/copyright create mode 100644 data/debian/install create mode 100755 data/debian/rules create mode 100644 data/debian/sonic-host-services-data.aaastatsd.service create mode 100644 data/debian/sonic-host-services-data.aaastatsd.timer create mode 100644 data/debian/sonic-host-services-data.caclmgrd.service create mode 100644 data/debian/sonic-host-services-data.determine-reboot-cause.service create mode 100644 data/debian/sonic-host-services-data.featured.service create mode 100644 data/debian/sonic-host-services-data.featured.timer create mode 100644 data/debian/sonic-host-services-data.hostcfgd.service create mode 100644 data/debian/sonic-host-services-data.hostcfgd.timer create mode 100644 data/debian/sonic-host-services-data.procdockerstatsd.service create mode 100644 data/debian/sonic-host-services-data.process-reboot-cause.service create mode 100644 data/debian/sonic-host-services-data.process-reboot-cause.timer create mode 100644 data/debian/sonic-host-services-data.sonic-hostservice.service create mode 100644 data/org.sonic.hostservice.conf create mode 100644 data/templates/common-auth-sonic.j2 create mode 100644 data/templates/common-password.j2 create mode 100755 data/templates/limits.conf.j2 create mode 100755 data/templates/pam_limits.j2 create mode 100644 data/templates/pam_radius_auth.conf.j2 create mode 100644 data/templates/radius_nss.conf.j2 create mode 100644 data/templates/tacplus_nss.conf.j2 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6c1be77b..af214110 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -7,13 +7,6 @@ trigger: - master - 202??? -resources: - repositories: - - repository: sonic-buildimage - type: github - name: sonic-net/sonic-buildimage - endpoint: build - variables: - name: BUILD_BRANCH ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: @@ -30,7 +23,6 @@ stages: variables: DIFF_COVER_CHECK_THRESHOLD: 80 DIFF_COVER_ENABLE: 'true' - DIFF_COVER_WORKING_DIRECTORY: $(System.DefaultWorkingDirectory)/sonic-host-services pool: vmImage: ubuntu-20.04 @@ -42,16 +34,6 @@ stages: clean: true submodules: recursive displayName: 'Checkout code' - - - checkout: sonic-buildimage - clean: true - displayName: 'Checkout code' - - - task: CopyFiles@2 - inputs: - SourceFolder: '$(System.DefaultWorkingDirectory)/sonic-buildimage/src/sonic-host-services-data/' - contents: '**' - targetFolder: $(System.DefaultWorkingDirectory)/sonic-host-services-data/ - task: DownloadPipelineArtifact@2 inputs: @@ -102,14 +84,12 @@ stages: displayName: "Install .NET CORE" - script: | - pushd sonic-host-services - python3 setup.py test displayName: 'Test Python 3' - task: PublishTestResults@2 inputs: - testResultsFiles: '$(System.DefaultWorkingDirectory)/sonic-host-services/test-results.xml' + testResultsFiles: '$(System.DefaultWorkingDirectory)/test-results.xml' testRunTitle: Python 3 failTaskOnFailedTests: true condition: succeededOrFailed() @@ -118,17 +98,16 @@ stages: - task: PublishCodeCoverageResults@1 inputs: codeCoverageTool: Cobertura - summaryFileLocation: '$(System.DefaultWorkingDirectory)/sonic-host-services/coverage.xml' - reportDirectory: '$(System.DefaultWorkingDirectory)/sonic-host-services/htmlcov/' + summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage.xml' + reportDirectory: '$(System.DefaultWorkingDirectory)/htmlcov/' displayName: 'Publish Python 3 test coverage' - script: | set -e - pushd sonic-host-services python3 setup.py bdist_wheel displayName: 'Build Python 3 wheel' - - publish: '$(System.DefaultWorkingDirectory)/sonic-host-services/dist/' + - publish: '$(System.DefaultWorkingDirectory)/dist/' artifact: wheels displayName: "Publish Python wheels" diff --git a/data/.gitignore b/data/.gitignore new file mode 100644 index 00000000..b941ede4 --- /dev/null +++ b/data/.gitignore @@ -0,0 +1,6 @@ +debian/*.debhelper +debian/debhelper-build-stamp +debian/sonic-host-services-data/ +sonic-host-services-data_*.buildinfo +sonic-host-services-data_*.changes +sonic-host-services-data_*.deb diff --git a/data/README.md b/data/README.md new file mode 100644 index 00000000..4a968ad8 --- /dev/null +++ b/data/README.md @@ -0,0 +1,19 @@ +# sonic-host-services-data +Data files required for SONiC host services + + +## To build + +``` +dpkg-buildpackage -rfakeroot -b -us -uc +``` + +## To clean + +``` +dpkg-buildpackage -rfakeroot -Tclean +``` + +--- + +See the [SONiC Website](https://sonicfoundation.dev/) for more information about the SONiC project. diff --git a/data/debian/changelog b/data/debian/changelog new file mode 100644 index 00000000..89e14bad --- /dev/null +++ b/data/debian/changelog @@ -0,0 +1,5 @@ +sonic-host-services-data (1.0-1) UNRELEASED; urgency=low + + * Initial release + + -- Joe LeVeque Tue, 20 Oct 2020 02:35:43 +0000 diff --git a/data/debian/compat b/data/debian/compat new file mode 100644 index 00000000..b4de3947 --- /dev/null +++ b/data/debian/compat @@ -0,0 +1 @@ +11 diff --git a/data/debian/control b/data/debian/control new file mode 100644 index 00000000..ebb495e3 --- /dev/null +++ b/data/debian/control @@ -0,0 +1,11 @@ +Source: sonic-host-services-data +Maintainer: Joe LeVeque +Section: misc +Priority: optional +Standards-Version: 0.1 +Build-Depends: debhelper (>=11) + +Package: sonic-host-services-data +Architecture: all +Depends: ${misc:Depends} +Description: Data files required for SONiC host services diff --git a/data/debian/copyright b/data/debian/copyright new file mode 100644 index 00000000..e69de29b diff --git a/data/debian/install b/data/debian/install new file mode 100644 index 00000000..91edbd1c --- /dev/null +++ b/data/debian/install @@ -0,0 +1,2 @@ +templates/*.j2 /usr/share/sonic/templates/ +org.sonic.hostservice.conf /etc/dbus-1/system.d diff --git a/data/debian/rules b/data/debian/rules new file mode 100755 index 00000000..47d26ccb --- /dev/null +++ b/data/debian/rules @@ -0,0 +1,24 @@ +#!/usr/bin/make -f + +ifeq (${ENABLE_HOST_SERVICE_ON_START}, y) + HOST_SERVICE_OPTS := --no-start +else + HOST_SERVICE_OPTS := --no-start --no-enable +endif + + +build: + +%: + dh $@ + +override_dh_installsystemd: + dh_installsystemd --no-start --name=caclmgrd + dh_installsystemd --no-start --name=hostcfgd + dh_installsystemd --no-start --name=featured + dh_installsystemd --no-start --name=aaastatsd + dh_installsystemd --no-start --name=procdockerstatsd + dh_installsystemd --no-start --name=determine-reboot-cause + dh_installsystemd --no-start --name=process-reboot-cause + dh_installsystemd $(HOST_SERVICE_OPTS) --name=sonic-hostservice + diff --git a/data/debian/sonic-host-services-data.aaastatsd.service b/data/debian/sonic-host-services-data.aaastatsd.service new file mode 100644 index 00000000..b93fe92c --- /dev/null +++ b/data/debian/sonic-host-services-data.aaastatsd.service @@ -0,0 +1,14 @@ +[Unit] +Description=AAA Statistics Collection daemon +Requires=hostcfgd.service +After=hostcfgd.service updategraph.service +BindsTo=sonic.target +After=sonic.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/aaastatsd +Restart=on-failure +RestartSec=10 +TimeoutStopSec=3 + diff --git a/data/debian/sonic-host-services-data.aaastatsd.timer b/data/debian/sonic-host-services-data.aaastatsd.timer new file mode 100644 index 00000000..8b6426db --- /dev/null +++ b/data/debian/sonic-host-services-data.aaastatsd.timer @@ -0,0 +1,12 @@ +[Unit] +Description=Delays aaastatsd daemon until SONiC has started +PartOf=aaastatsd.service + +[Timer] +OnUnitActiveSec=0 sec +OnBootSec=1min 30 sec +Unit=aaastatsd.service + +[Install] +WantedBy=timers.target sonic.target + diff --git a/data/debian/sonic-host-services-data.caclmgrd.service b/data/debian/sonic-host-services-data.caclmgrd.service new file mode 100644 index 00000000..e24ed10b --- /dev/null +++ b/data/debian/sonic-host-services-data.caclmgrd.service @@ -0,0 +1,15 @@ +[Unit] +Description=Control Plane ACL configuration daemon +Requires=updategraph.service +After=updategraph.service +BindsTo=sonic.target +After=sonic.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/caclmgrd +Restart=always +RestartSec=30 + +[Install] +WantedBy=sonic.target diff --git a/data/debian/sonic-host-services-data.determine-reboot-cause.service b/data/debian/sonic-host-services-data.determine-reboot-cause.service new file mode 100644 index 00000000..e834b933 --- /dev/null +++ b/data/debian/sonic-host-services-data.determine-reboot-cause.service @@ -0,0 +1,12 @@ +[Unit] +Description=Reboot cause determination service +Requires=rc-local.service database.service +After=rc-local.service database.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/bin/determine-reboot-cause + +[Install] +WantedBy=multi-user.target diff --git a/data/debian/sonic-host-services-data.featured.service b/data/debian/sonic-host-services-data.featured.service new file mode 100644 index 00000000..0913e945 --- /dev/null +++ b/data/debian/sonic-host-services-data.featured.service @@ -0,0 +1,10 @@ +[Unit] +Description=Feature configuration daemon +Requires=updategraph.service +After=updategraph.service +BindsTo=sonic.target +After=sonic.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/featured diff --git a/data/debian/sonic-host-services-data.featured.timer b/data/debian/sonic-host-services-data.featured.timer new file mode 100644 index 00000000..12fbbe10 --- /dev/null +++ b/data/debian/sonic-host-services-data.featured.timer @@ -0,0 +1,12 @@ +[Unit] +Description=Delays feature daemon until SONiC has started +PartOf=featured.service + +[Timer] +OnUnitActiveSec=0 sec +OnBootSec=1min 30 sec +Unit=featured.service + +[Install] +WantedBy=timers.target sonic.target + diff --git a/data/debian/sonic-host-services-data.hostcfgd.service b/data/debian/sonic-host-services-data.hostcfgd.service new file mode 100644 index 00000000..5e243452 --- /dev/null +++ b/data/debian/sonic-host-services-data.hostcfgd.service @@ -0,0 +1,11 @@ +[Unit] +Description=Host config enforcer daemon +Requires=updategraph.service +After=updategraph.service +BindsTo=sonic.target +After=sonic.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/hostcfgd + diff --git a/data/debian/sonic-host-services-data.hostcfgd.timer b/data/debian/sonic-host-services-data.hostcfgd.timer new file mode 100644 index 00000000..b45fd4b2 --- /dev/null +++ b/data/debian/sonic-host-services-data.hostcfgd.timer @@ -0,0 +1,12 @@ +[Unit] +Description=Delays hostcfgd daemon until SONiC has started +PartOf=hostcfgd.service + +[Timer] +OnUnitActiveSec=0 sec +OnBootSec=1min 30 sec +Unit=hostcfgd.service + +[Install] +WantedBy=timers.target sonic.target + diff --git a/data/debian/sonic-host-services-data.procdockerstatsd.service b/data/debian/sonic-host-services-data.procdockerstatsd.service new file mode 100644 index 00000000..68b9e61b --- /dev/null +++ b/data/debian/sonic-host-services-data.procdockerstatsd.service @@ -0,0 +1,14 @@ +[Unit] +Description=Process and docker CPU/memory utilization data export daemon +Requires=database.service updategraph.service +After=database.service updategraph.service +BindsTo=sonic.target +After=sonic.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/procdockerstatsd +Restart=always + +[Install] +WantedBy=sonic.target diff --git a/data/debian/sonic-host-services-data.process-reboot-cause.service b/data/debian/sonic-host-services-data.process-reboot-cause.service new file mode 100644 index 00000000..14af8868 --- /dev/null +++ b/data/debian/sonic-host-services-data.process-reboot-cause.service @@ -0,0 +1,8 @@ +[Unit] +Description=Retrieve the reboot cause from the history files and save them to StateDB +Requires=database.service determine-reboot-cause.service +After=database.service determine-reboot-cause.service + +[Service] +Type=simple +ExecStart=/usr/local/bin/process-reboot-cause diff --git a/data/debian/sonic-host-services-data.process-reboot-cause.timer b/data/debian/sonic-host-services-data.process-reboot-cause.timer new file mode 100644 index 00000000..222c51a7 --- /dev/null +++ b/data/debian/sonic-host-services-data.process-reboot-cause.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays process-reboot-cause until network is stably connected + +[Timer] +OnBootSec=1min 30 sec +Unit=process-reboot-cause.service + +[Install] +WantedBy=timers.target diff --git a/data/debian/sonic-host-services-data.sonic-hostservice.service b/data/debian/sonic-host-services-data.sonic-hostservice.service new file mode 100644 index 00000000..799f3511 --- /dev/null +++ b/data/debian/sonic-host-services-data.sonic-hostservice.service @@ -0,0 +1,16 @@ +[Unit] +Description=SONiC Host Service + +[Service] +Type=dbus +BusName=org.SONiC.HostService + +ExecStart=/usr/bin/python3 -u /usr/local/bin/sonic-host-server + +Restart=on-failure +RestartSec=10 +TimeoutStopSec=3 + +[Install] +WantedBy=mgmt-framework.service telemetry.service + diff --git a/data/org.sonic.hostservice.conf b/data/org.sonic.hostservice.conf new file mode 100644 index 00000000..08599007 --- /dev/null +++ b/data/org.sonic.hostservice.conf @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/data/templates/common-auth-sonic.j2 b/data/templates/common-auth-sonic.j2 new file mode 100644 index 00000000..b20c9f4e --- /dev/null +++ b/data/templates/common-auth-sonic.j2 @@ -0,0 +1,83 @@ +#THIS IS AN AUTO-GENERATED FILE +# +# /etc/pam.d/common-auth- authentication settings common to all services +# This file is included from other service-specific PAM config files, +# and should contain a list of the authentication modules that define +# the central authentication scheme for use on the system +# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the +# traditional Unix authentication mechanisms. +# +# here are the per-package modules (the "Primary" block) + +{% if auth['login'] == 'local' %} +auth [success=1 default=ignore] pam_unix.so nullok try_first_pass + +{% elif auth['login'] == 'local,tacacs+' %} +auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_unix.so nullok try_first_pass +{% for server in servers | sub(0, -1) %} +auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_tacplus.so server={{ server.ip }}:{{ server.tcp_port }} secret={{ server.passkey }} login={{ server.auth_type }} timeout={{ server.timeout }} {% if server.vrf %} vrf={{ server.vrf }} {% endif %} {{ 'source_ip=%s' % src_ip if src_ip }} try_first_pass +{% endfor %} +{% if servers | count %} +{% set last_server = servers | last %} +auth [success=1 default=ignore] pam_tacplus.so server={{ last_server.ip }}:{{ last_server.tcp_port }} secret={{ last_server.passkey }} login={{ last_server.auth_type }} timeout={{ last_server.timeout }} {% if last_server.vrf %} vrf={{ last_server.vrf }} {% endif %} {{ 'source_ip=%s' % src_ip if src_ip }} try_first_pass + +{% endif %} +{% elif auth['login'] == 'tacacs+' or auth['login'] == 'tacacs+,local' %} +{% for server in servers %} +auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_tacplus.so server={{ server.ip }}:{{ server.tcp_port }} secret={{ server.passkey }} login={{ server.auth_type }} timeout={{ server.timeout }} {%if server.vrf %} vrf={{ server.vrf }} {% endif %} {{ 'source_ip=%s' % src_ip if src_ip }} try_first_pass +{% endfor %} +auth [success=1 default=ignore] pam_unix.so nullok try_first_pass + +{% elif auth['login'] == 'local,radius' %} +auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die maxtries=die' if not auth['failthrough'] }}] pam_unix.so nullok try_first_pass +# For the RADIUS servers, on success jump to the cacheing the MPL(Privilege) +{% for server in servers %} +auth [success={{ (servers | count) - loop.index0 }} new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_radius_auth.so conf=/etc/pam_radius_auth.d/{{ server.ip }}_{{ server.auth_port }}.conf privilege_level protocol={{ server.auth_type }} retry={{ server.retransmit }}{% if server.nas_ip is defined %} nas_ip_address={{ server.nas_ip }}{% endif %}{% if server.nas_id is defined %} client_id={{ server.nas_id }}{% endif %}{% if debug %} debug{% endif %}{% if trace %} trace{% endif %}{% if server.statistics %} statistics={{ server.ip }}{% endif %} try_first_pass +{% endfor %} +auth requisite pam_deny.so +# Cache MPL(Privilege) +auth [success=1 default=ignore] pam_exec.so /usr/sbin/cache_radius + +{% elif auth['login'] == 'radius,local' %} +# root user can only be authenticated locally. Jump to local. +{% if servers | count %} +auth [success={{ (servers | count) }} default=ignore] pam_succeed_if.so user = root +{% else %} +auth [success=ok default=ignore] pam_succeed_if.so user = root +{% endif %} +# For the RADIUS servers, on success jump to the cache the MPL(Privilege) +{% for server in servers %} +auth [success={{ (servers | count) + 1 - loop.index0 }} new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_radius_auth.so conf=/etc/pam_radius_auth.d/{{ server.ip }}_{{ server.auth_port }}.conf privilege_level protocol={{ server.auth_type }} retry={{ server.retransmit }}{% if server.nas_ip is defined %} nas_ip_address={{ server.nas_ip }}{% endif %}{% if server.nas_id is defined %} client_id={{ server.nas_id }}{% endif %}{% if debug %} debug{% endif %}{% if trace %} trace{% endif %}{% if server.statistics %} statistics={{ server.ip }}{% endif %} try_first_pass +{% endfor %} +# Local +auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die maxtries=die' if not auth['failthrough'] }}] pam_unix.so nullok try_first_pass +auth requisite pam_deny.so +# Cache MPL(Privilege) +auth [success=1 default=ignore] pam_exec.so /usr/sbin/cache_radius + +{% elif auth['login'] == 'radius' %} +# root user can only be authenticated locally. Jump to local. +auth [success={{ (servers | count) + 2 }} default=ignore] pam_succeed_if.so user = root +# For the RADIUS servers, on success jump to the cache the MPL(Privilege) +{% for server in servers %} +auth [success={{ (servers | count) - loop.index0 }} new_authtok_reqd=done default=ignore{{ ' auth_err=die' if not auth['failthrough'] }}] pam_radius_auth.so conf=/etc/pam_radius_auth.d/{{ server.ip }}_{{ server.auth_port }}.conf privilege_level protocol={{ server.auth_type }} retry={{ server.retransmit }}{% if server.nas_ip is defined %} nas_ip_address={{ server.nas_ip }}{% endif %}{% if server.nas_id is defined %} client_id={{ server.nas_id }}{% endif %}{% if debug %} debug{% endif %}{% if trace %} trace{% endif %}{% if server.statistics %} statistics={{ server.ip }}{% endif %} try_first_pass +{% endfor %} +auth requisite pam_deny.so +# Cache MPL(Privilege) +auth [success=2 default=ignore] pam_exec.so /usr/sbin/cache_radius +# Local +auth [success=done new_authtok_reqd=done default=ignore{{ ' auth_err=die maxtries=die' if not auth['failthrough'] }}] pam_unix.so nullok try_first_pass + +{% else %} +auth [success=1 default=ignore] pam_unix.so nullok try_first_pass + +{% endif %} +# +# here's the fallback if no module succeeds +auth requisite pam_deny.so +# prime the stack with a positive return value if there isn't one already; +# this avoids us returning an error just because nothing sets a success code +# since the modules above will each just jump around +auth required pam_permit.so +# and here are more per-package modules (the "Additional" block) + diff --git a/data/templates/common-password.j2 b/data/templates/common-password.j2 new file mode 100644 index 00000000..91b46928 --- /dev/null +++ b/data/templates/common-password.j2 @@ -0,0 +1,43 @@ +#THIS IS AN AUTO-GENERATED FILE +# +# /etc/pam.d/common-password - password-related modules common to all services +# +# This file is included from other service-specific PAM config files, +# and should contain a list of modules that define the services to be +# used to change user passwords. The default is pam_unix. + +# Explanation of pam_unix options: +# The "yescrypt" option enables +#hashed passwords using the yescrypt algorithm, introduced in Debian +#11. Without this option, the default is Unix crypt. Prior releases +#used the option "sha512"; if a shadow password hash will be shared +#between Debian 11 and older releases replace "yescrypt" with "sha512" +#for compatibility . The "obscure" option replaces the old +#`OBSCURE_CHECKS_ENAB' option in login.defs. See the pam_unix manpage +#for other options. + +# As of pam 1.0.1-6, this file is managed by pam-auth-update by default. +# To take advantage of this, it is recommended that you configure any +# local modules either before or after the default block, and use +# pam-auth-update to manage selection of other modules. See +# pam-auth-update(8) for details. + +# here are the per-package modules (the "Primary" block) + +{% if passw_policies %} +{% if passw_policies['state'] == 'enabled' %} +password requisite pam_pwquality.so retry=3 maxrepeat=0 {% if passw_policies['len_min'] %}minlen={{passw_policies['len_min']}}{% endif %} {% if passw_policies['upper_class'] %}ucredit=-1{% else %}ucredit=0{% endif %} {% if passw_policies['lower_class'] %}lcredit=-1{% else %}lcredit=0{% endif %} {% if passw_policies['digits_class'] %}dcredit=-1{% else %}dcredit=0{% endif %} {% if passw_policies['special_class'] %}ocredit=-1{% else %}ocredit=0{% endif %} {% if passw_policies['reject_user_passw_match'] %}reject_username{% endif %} enforce_for_root dictcheck=0 + +password required pam_pwhistory.so {% if passw_policies['history_cnt'] %}remember={{passw_policies['history_cnt']}}{% endif %} use_authtok enforce_for_root +{% endif %} +{% endif %} + +password [success=1 default=ignore] pam_unix.so obscure yescrypt +# here's the fallback if no module succeeds +password requisite pam_deny.so +# prime the stack with a positive return value if there isn't one already; +# this avoids us returning an error just because nothing sets a success code +# since the modules above will each just jump around +password required pam_permit.so +# and here are more per-package modules (the "Additional" block) +# end of pam-auth-update config diff --git a/data/templates/limits.conf.j2 b/data/templates/limits.conf.j2 new file mode 100755 index 00000000..70ac9d8c --- /dev/null +++ b/data/templates/limits.conf.j2 @@ -0,0 +1,69 @@ +# /etc/security/limits.conf +# +# This file generate by j2 template file: src/sonic-host-services/data/templates/limits.conf.j2 +# +# Each line describes a limit for a user in the form: +# +# +# +# Where: +# can be: +# - a user name +# - a group name, with @group syntax +# - the wildcard *, for default entry +# - the wildcard %, can be also used with %group syntax, +# for maxlogin limit +# - NOTE: group and wildcard limits are not applied to root. +# To apply a limit to the root user, must be +# the literal username root. +# +# can have the two values: +# - "soft" for enforcing the soft limits +# - "hard" for enforcing hard limits +# +# can be one of the following: +# - core - limits the core file size (KB) +# - data - max data size (KB) +# - fsize - maximum filesize (KB) +# - memlock - max locked-in-memory address space (KB) +# - nofile - max number of open file descriptors +# - rss - max resident set size (KB) +# - stack - max stack size (KB) +# - cpu - max CPU time (MIN) +# - nproc - max number of processes +# - as - address space limit (KB) +# - maxlogins - max number of logins for this user +# - maxsyslogins - max number of logins on the system +# - priority - the priority to run user process with +# - locks - max number of file locks the user can hold +# - sigpending - max number of pending signals +# - msgqueue - max memory used by POSIX message queues (bytes) +# - nice - max nice priority allowed to raise to values: [-20, 19] +# - rtprio - max realtime priority +# - chroot - change root to directory (Debian-specific) +# +# +# is related with : +# All items support the values -1, unlimited or infinity indicating +# no limit, except for priority and nice. +# +# If a hard limit or soft limit of a resource is set to a valid value, +# but outside of the supported range of the local system, the system +# may reject the new limit or unexpected behavior may occur. If the +# control value required is used, the module will reject the login if +# a limit could not be set. +# +# +# + +# * soft core 0 +# root hard core 100000 +# * hard rss 10000 +# @student hard nproc 20 +# @faculty soft nproc 20 +# @faculty hard nproc 50 +# ftp hard nproc 0 +# ftp - chroot /ftp +# @student - maxlogins 4 + +# End of file diff --git a/data/templates/pam_limits.j2 b/data/templates/pam_limits.j2 new file mode 100755 index 00000000..4808c205 --- /dev/null +++ b/data/templates/pam_limits.j2 @@ -0,0 +1,12 @@ +#THIS IS AN AUTO-GENERATED FILE +# +# This file generate by j2 template file: src/sonic-host-services/data/templates/pam_limits.j2 +# +# /etc/pam.d/pam-limits settings common to all services +# This file is included from other service-specific PAM config files, +# and should contain a list of the authentication modules that define +# the central authentication scheme for use on the system +# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the +# traditional Unix authentication mechanisms. +# +# here are the per-package modules (the "Primary" block) diff --git a/data/templates/pam_radius_auth.conf.j2 b/data/templates/pam_radius_auth.conf.j2 new file mode 100644 index 00000000..7d3c73e1 --- /dev/null +++ b/data/templates/pam_radius_auth.conf.j2 @@ -0,0 +1,3 @@ +# server[:port] shared_secret timeout(s) source_ip vrf +[{{ server.ip }}]:{{ server.auth_port }} {{ server.passkey }} {{ server.timeout }} {% if server.src_ip %} {{ server.src_ip }} {% endif %} {% if server.vrf %} {% if not server.src_ip %} - {% endif %} {{ server.vrf }}{% endif %} + diff --git a/data/templates/radius_nss.conf.j2 b/data/templates/radius_nss.conf.j2 new file mode 100644 index 00000000..a0da68d3 --- /dev/null +++ b/data/templates/radius_nss.conf.j2 @@ -0,0 +1,58 @@ +#THIS IS AN AUTO-GENERATED FILE +# Generated from: /usr/share/sonic/templates/radius_nss.conf.j2 +# RADIUS NSS Configuration File +# +# Debug: on|off|trace +# Default: off +# +# debug=on +{% if debug %} +debug=on +{% endif %} + +# +# User Privilege: +# Default: +# user_priv=15;pw_info=remote_user_su;gid=1000;group=sudo,docker;shell=/usr/bin/sonic-launch-shell +# user_priv=1;pw_info=remote_user;gid=999;group=docker;shell=/usr/bin/sonic-launch-shell + +# Eg: +# user_priv=15;pw_info=remote_user_su;gid=1000;group=sudo,docker;shell=/usr/bin/sonic-launch-shell +# user_priv=7;pw_info=netops;gid=999;group=docker;shell=/usr/bin/sonic-launch-shell +# user_priv=1;pw_info=operator;gid=100;group=docker;shell=/usr/bin/sonic-launch-shell +# + +# many_to_one: +# y: Map RADIUS users to one local user per privilege. +# n: Create local user account on first successful authentication. +# Default: n +# + +# Eg: +# many_to_one=y +# + +# unconfirmed_disallow: +# y: Do not allow unconfirmed users (users created before authentication) +# n: Allow unconfirmed users. +# Default: n + +# Eg: +# unconfirmed_disallow=y +# + +# unconfirmed_ageout: +# : Wait time before purging unconfirmed users +# Default: 600 +# + +# Eg: +# unconfirmed_ageout=900 +# + +# unconfirmed_regexp: +# : The RE to match the command line of processes for which the +# creation of unconfirmed users are to be allowed. +# Default: (.*: \[priv\])|(.*: \[accepted\]) +# where: is the unconfirmed user. +# diff --git a/data/templates/tacplus_nss.conf.j2 b/data/templates/tacplus_nss.conf.j2 new file mode 100644 index 00000000..812b47bf --- /dev/null +++ b/data/templates/tacplus_nss.conf.j2 @@ -0,0 +1,60 @@ +# Configuration for libnss-tacplus + +# debug - If you want to open debug log, set it on +# Default: off +# debug=on +{% if debug %} +debug=on +{% endif %} + +# local_accounting - If you want to local accounting, set it +# Default: None +# local_accounting +{% if local_accounting %} +local_accounting +{% endif %} + +# tacacs_accounting - If you want to tacacs+ accounting, set it +# Default: None +# tacacs_accounting +{% if tacacs_accounting %} +tacacs_accounting +{% endif %} + +# local_authorization - If you want to local authorization, set it +# Default: None +# local_authorization +{% if local_authorization %} +local_authorization +{% endif %} + +# tacacs_authorization - If you want to tacacs+ authorization, set it +# Default: None +# tacacs_authorization +{% if tacacs_authorization %} +tacacs_authorization +{% endif %} + +# src_ip - set source address of TACACS+ protocol packets +# Default: None (auto source ip address) +# src_ip=2.2.2.2 +{% if src_ip %} +src_ip={{ src_ip }} +{% endif %} + +# server - set ip address, tcp port, secret string and timeout for TACACS+ servers +# Default: None (no TACACS+ server) +# server=1.1.1.1:49,secret=test,timeout=3 +{% for server in servers %} +server={{ server.ip }}:{{ server.tcp_port }},secret={{ server.passkey }},timeout={{ server.timeout }}{% if server.vrf %},vrf={{ server.vrf }}{% endif %}{{''}} +{% endfor %} + +# user_priv - set the map between TACACS+ user privilege and local user's passwd +# Default: +# user_priv=15;pw_info=remote_user_su;gid=1000;group=sudo,docker;shell=/bin/bash +# user_priv=1;pw_info=remote_user;gid=999;group=docker;shell=/bin/bash + +# many_to_one - create one local user for many TACACS+ users which has the same privilege +# Default: many_to_one=n +# many_to_one=y + diff --git a/tests/hostcfgd/hostcfgd_passwh_test.py b/tests/hostcfgd/hostcfgd_passwh_test.py index c583809b..67dbf16b 100755 --- a/tests/hostcfgd/hostcfgd_passwh_test.py +++ b/tests/hostcfgd/hostcfgd_passwh_test.py @@ -16,8 +16,7 @@ test_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) modules_path = os.path.dirname(test_path) scripts_path = os.path.join(modules_path, "scripts") -src_path = os.path.dirname(modules_path) -templates_path = os.path.join(src_path, "sonic-host-services-data/templates") +templates_path = os.path.join(modules_path, "data/templates") output_path = os.path.join(test_path, "hostcfgd/output") sample_output_path = os.path.join(test_path, "hostcfgd/sample_output") sys.path.insert(0, modules_path) diff --git a/tests/hostcfgd/hostcfgd_radius_test.py b/tests/hostcfgd/hostcfgd_radius_test.py index f45f2415..d2930aa9 100644 --- a/tests/hostcfgd/hostcfgd_radius_test.py +++ b/tests/hostcfgd/hostcfgd_radius_test.py @@ -16,8 +16,7 @@ test_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) modules_path = os.path.dirname(test_path) scripts_path = os.path.join(modules_path, "scripts") -src_path = os.path.dirname(modules_path) -templates_path = os.path.join(src_path, "sonic-host-services-data/templates") +templates_path = os.path.join(modules_path, "data/templates") output_path = os.path.join(test_path, "hostcfgd/output") sample_output_path = os.path.join(test_path, "hostcfgd/sample_output") sys.path.insert(0, modules_path) diff --git a/tests/hostcfgd/hostcfgd_rsyslog_test.py b/tests/hostcfgd/hostcfgd_rsyslog_test.py index b9a84bca..a5ef3497 100755 --- a/tests/hostcfgd/hostcfgd_rsyslog_test.py +++ b/tests/hostcfgd/hostcfgd_rsyslog_test.py @@ -15,8 +15,7 @@ test_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) modules_path = os.path.dirname(test_path) scripts_path = os.path.join(modules_path, "scripts") -src_path = os.path.dirname(modules_path) -templates_path = os.path.join(src_path, "sonic-host-services-data/templates") +templates_path = os.path.join(modules_path, "data/templates") output_path = os.path.join(test_path, "hostcfgd/output") sample_output_path = os.path.join(test_path, "hostcfgd/sample_output") sys.path.insert(0, modules_path) diff --git a/tests/hostcfgd/hostcfgd_ssh_server_test.py b/tests/hostcfgd/hostcfgd_ssh_server_test.py index aef1712b..2cfa8d13 100755 --- a/tests/hostcfgd/hostcfgd_ssh_server_test.py +++ b/tests/hostcfgd/hostcfgd_ssh_server_test.py @@ -15,7 +15,6 @@ test_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) modules_path = os.path.dirname(test_path) scripts_path = os.path.join(modules_path, "scripts") -src_path = os.path.dirname(modules_path) output_path = os.path.join(test_path, "hostcfgd/output") sample_output_path = os.path.join(test_path, "hostcfgd/sample_output") sys.path.insert(0, modules_path) diff --git a/tests/hostcfgd/hostcfgd_tacacs_test.py b/tests/hostcfgd/hostcfgd_tacacs_test.py index 18d6f1a7..0577e61f 100644 --- a/tests/hostcfgd/hostcfgd_tacacs_test.py +++ b/tests/hostcfgd/hostcfgd_tacacs_test.py @@ -15,8 +15,7 @@ test_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) modules_path = os.path.dirname(test_path) scripts_path = os.path.join(modules_path, "scripts") -src_path = os.path.dirname(modules_path) -templates_path = os.path.join(src_path, "sonic-host-services-data/templates") +templates_path = os.path.join(modules_path, "data/templates") output_path = os.path.join(test_path, "hostcfgd/output") sample_output_path = os.path.join(test_path, "hostcfgd/sample_output") sys.path.insert(0, modules_path)