diff options
Diffstat (limited to 'smoketest')
-rwxr-xr-x | smoketest/bin/vyos-configtest-pki | 100 | ||||
-rw-r--r-- | smoketest/configs/dialup-router-medium-vpn | 5 | ||||
-rw-r--r-- | smoketest/scripts/cli/base_interfaces_test.py | 3 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_bridge.py | 74 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_vti.py | 34 |
5 files changed, 214 insertions, 2 deletions
diff --git a/smoketest/bin/vyos-configtest-pki b/smoketest/bin/vyos-configtest-pki new file mode 100755 index 000000000..2f8af0e61 --- /dev/null +++ b/smoketest/bin/vyos-configtest-pki @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2022, 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 +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from os import system +from vyos.pki import create_private_key +from vyos.pki import create_certificate_request +from vyos.pki import create_certificate +from vyos.pki import create_certificate_revocation_list +from vyos.pki import create_dh_parameters +from vyos.pki import encode_certificate +from vyos.pki import encode_dh_parameters +from vyos.pki import encode_private_key + +subject = {'country': 'DE', 'state': 'BY', 'locality': 'Cloud', 'organization': 'VyOS', 'common_name': 'vyos'} +ca_subject = {'country': 'DE', 'state': 'BY', 'locality': 'Cloud', 'organization': 'VyOS', 'common_name': 'vyos CA'} +subca_subject = {'country': 'DE', 'state': 'BY', 'locality': 'Cloud', 'organization': 'VyOS', 'common_name': 'vyos SubCA'} + +ca_cert = '/config/auth/ovpn_test_ca.pem' +ca_key = '/config/auth/ovpn_test_ca.key' +ca_cert_chain = '/config/auth/ovpn_test_chain.pem' +ca_crl = '/config/auth/ovpn_test_ca.crl' +subca_cert = '/config/auth/ovpn_test_subca.pem' +subca_csr = '/tmp/subca.csr' +subca_key = '/config/auth/ovpn_test_subca.key' +ssl_cert = '/config/auth/ovpn_test_server.pem' +ssl_key = '/config/auth/ovpn_test_server.key' +dh_pem = '/config/auth/ovpn_test_dh.pem' +s2s_key = '/config/auth/ovpn_test_site2site.key' +auth_key = '/config/auth/ovpn_test_tls_auth.key' + +def create_cert(subject, cert_path, key_path, sign_by=None, sign_by_key=None, ca=False, sub_ca=False): + priv_key = create_private_key('rsa', 2048) + cert_req = create_certificate_request(subject, priv_key) + cert = create_certificate( + cert_req, + sign_by if sign_by else cert_req, + sign_by_key if sign_by_key else priv_key, + is_ca=ca, is_sub_ca=sub_ca) + + with open(cert_path, 'w') as f: + f.write(encode_certificate(cert)) + + with open(key_path, 'w') as f: + f.write(encode_private_key(priv_key)) + + return cert, priv_key + +def create_empty_crl(crl_path, sign_by, sign_by_key): + crl = create_certificate_revocation_list(sign_by, sign_by_key, [1]) + + with open(crl_path, 'w') as f: + f.write(encode_certificate(crl)) + + return crl + +if __name__ == '__main__': + # Create Root CA + ca_cert_obj, ca_key_obj = create_cert(ca_subject, ca_cert, ca_key, ca=True) + + # Create Empty CRL + create_empty_crl(ca_crl, ca_cert_obj, ca_key_obj) + + # Create Intermediate CA + subca_cert_obj, subca_key_obj = create_cert( + subca_subject, subca_cert, subca_key, + sign_by=ca_cert_obj, sign_by_key=ca_key_obj, + ca=True, sub_ca=True) + + # Create Chain + with open(ca_cert_chain, 'w') as f: + f.write(encode_certificate(subca_cert_obj) + "\n") + f.write(encode_certificate(ca_cert_obj) + "\n") + + # Create Server Cert + create_cert(subject, ssl_cert, ssl_key, sign_by=subca_cert_obj, sign_by_key=subca_key_obj) + + # Create DH params + dh_params = create_dh_parameters() + + with open(dh_pem, 'w') as f: + f.write(encode_dh_parameters(dh_params)) + + # OpenVPN S2S Key + system(f'openvpn --genkey secret {s2s_key}') + + # OpenVPN Auth Key + system(f'openvpn --genkey secret {auth_key}') diff --git a/smoketest/configs/dialup-router-medium-vpn b/smoketest/configs/dialup-router-medium-vpn index 63d955738..56722d222 100644 --- a/smoketest/configs/dialup-router-medium-vpn +++ b/smoketest/configs/dialup-router-medium-vpn @@ -120,8 +120,9 @@ interfaces { persistent-tunnel remote-host 192.0.2.10 tls { - ca-cert-file /config/auth/ovpn_test_ca.pem + ca-cert-file /config/auth/ovpn_test_chain.pem cert-file /config/auth/ovpn_test_server.pem + crl-file /config/auth/ovpn_test_ca.crl key-file /config/auth/ovpn_test_server.key auth-file /config/auth/ovpn_test_tls_auth.key } @@ -152,7 +153,7 @@ interfaces { remote-host 01.foo.com remote-port 1194 tls { - ca-cert-file /config/auth/ovpn_test_ca.pem + ca-cert-file /config/auth/ovpn_test_chain.pem auth-file /config/auth/ovpn_test_tls_auth.key } } diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py index 816ba6dcd..8acf52243 100644 --- a/smoketest/scripts/cli/base_interfaces_test.py +++ b/smoketest/scripts/cli/base_interfaces_test.py @@ -232,6 +232,9 @@ class BasicInterfaceTest: for interface in self._interfaces: base = self._base_path + [interface] + # just set the interface base without any option - some interfaces + # (VTI) do not require any option to be brought up + self.cli_set(base) for option in self._options.get(interface, []): self.cli_set(base + option.split()) diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py index ca0ead9e8..26d3a23c9 100755 --- a/smoketest/scripts/cli/test_interfaces_bridge.py +++ b/smoketest/scripts/cli/test_interfaces_bridge.py @@ -86,9 +86,83 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase): # validate member interface configuration for member in self._members: tmp = get_interface_config(member) + # verify member is assigned to the bridge + self.assertEqual(interface, tmp['master']) # Isolated must be enabled as configured above self.assertTrue(tmp['linkinfo']['info_slave_data']['isolated']) + def test_igmp_querier_snooping(self): + # Add member interfaces to bridge + for interface in self._interfaces: + base = self._base_path + [interface] + + # assign members to bridge interface + for member in self._members: + base_member = base + ['member', 'interface', member] + self.cli_set(base_member) + + # commit config + self.cli_commit() + + for interface in self._interfaces: + # Verify IGMP default configuration + tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_snooping') + self.assertEqual(tmp, '0') + tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_querier') + self.assertEqual(tmp, '0') + + # Enable IGMP snooping + for interface in self._interfaces: + base = self._base_path + [interface] + self.cli_set(base + ['igmp', 'snooping']) + + # commit config + self.cli_commit() + + for interface in self._interfaces: + # Verify IGMP snooping configuration + # Verify IGMP default configuration + tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_snooping') + self.assertEqual(tmp, '1') + tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_querier') + self.assertEqual(tmp, '0') + + # Enable IGMP querieer + for interface in self._interfaces: + base = self._base_path + [interface] + self.cli_set(base + ['igmp', 'querier']) + + # commit config + self.cli_commit() + + for interface in self._interfaces: + # Verify IGMP snooping & querier configuration + tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_snooping') + self.assertEqual(tmp, '1') + tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_querier') + self.assertEqual(tmp, '1') + + # Disable IGMP + for interface in self._interfaces: + base = self._base_path + [interface] + self.cli_delete(base + ['igmp']) + + # commit config + self.cli_commit() + + for interface in self._interfaces: + # Verify IGMP snooping & querier configuration + tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_snooping') + self.assertEqual(tmp, '0') + tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_querier') + self.assertEqual(tmp, '0') + + # validate member interface configuration + for member in self._members: + tmp = get_interface_config(member) + # verify member is assigned to the bridge + self.assertEqual(interface, tmp['master']) + def test_add_remove_bridge_member(self): # Add member interfaces to bridge and set STP cost/priority diff --git a/smoketest/scripts/cli/test_interfaces_vti.py b/smoketest/scripts/cli/test_interfaces_vti.py new file mode 100755 index 000000000..9cbf104f0 --- /dev/null +++ b/smoketest/scripts/cli/test_interfaces_vti.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2022 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 +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import unittest + +from base_interfaces_test import BasicInterfaceTest + +class VTIInterfaceTest(BasicInterfaceTest.TestCase): + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._test_ipv6 = True + cls._test_mtu = True + cls._base_path = ['interfaces', 'vti'] + cls._interfaces = ['vti10', 'vti20', 'vti30'] + + # call base-classes classmethod + super(VTIInterfaceTest, cls).setUpClass() + +if __name__ == '__main__': + unittest.main(verbosity=2) |