summaryrefslogtreecommitdiff
path: root/smoketest
diff options
context:
space:
mode:
Diffstat (limited to 'smoketest')
-rwxr-xr-xsmoketest/bin/vyos-configtest-pki100
-rw-r--r--smoketest/configs/dialup-router-medium-vpn5
-rw-r--r--smoketest/scripts/cli/base_interfaces_test.py3
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bridge.py74
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_vti.py34
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)