summaryrefslogtreecommitdiff
path: root/smoketest/scripts/cli
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2024-08-20 07:24:55 +0200
committerGitHub <noreply@github.com>2024-08-20 07:24:55 +0200
commit2277371fe18577502ce318c23789f86d1ec97be7 (patch)
tree44dfcee280ad6d46e858ef0af266755d70bb066a /smoketest/scripts/cli
parent538930c27a0984cd9f9a58115e6ea6395002707e (diff)
parent18ea3673a105d9d12699afb2607c81412dde441b (diff)
downloadvyos-1x-2277371fe18577502ce318c23789f86d1ec97be7.tar.gz
vyos-1x-2277371fe18577502ce318c23789f86d1ec97be7.zip
Merge pull request #3975 from lucasec/t6183
T6183: interfaces openvpn: suppport specifying IP protocol version
Diffstat (limited to 'smoketest/scripts/cli')
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_openvpn.py186
1 files changed, 186 insertions, 0 deletions
diff --git a/smoketest/scripts/cli/test_interfaces_openvpn.py b/smoketest/scripts/cli/test_interfaces_openvpn.py
index d8a091aaa..e087b8735 100755
--- a/smoketest/scripts/cli/test_interfaces_openvpn.py
+++ b/smoketest/scripts/cli/test_interfaces_openvpn.py
@@ -250,6 +250,67 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase):
interface = f'vtun{ii}'
self.assertNotIn(interface, interfaces())
+ def test_openvpn_client_ip_version(self):
+ # Test the client mode behavior combined with different IP protocol versions
+
+ interface = 'vtun10'
+ remote_host = '192.0.2.10'
+ remote_host_v6 = 'fd00::2:10'
+ path = base_path + [interface]
+ auth_hash = 'sha1'
+
+ # Default behavior: client uses uspecified protocol version (udp)
+ self.cli_set(path + ['device-type', 'tun'])
+ self.cli_set(path + ['encryption', 'data-ciphers', 'aes256'])
+ self.cli_set(path + ['hash', auth_hash])
+ self.cli_set(path + ['mode', 'client'])
+ self.cli_set(path + ['persistent-tunnel'])
+ self.cli_set(path + ['protocol', 'udp'])
+ self.cli_set(path + ['remote-host', remote_host])
+ self.cli_set(path + ['remote-port', remote_port])
+ self.cli_set(path + ['tls', 'ca-certificate', 'ovpn_test'])
+ self.cli_set(path + ['tls', 'certificate', 'ovpn_test'])
+ self.cli_set(path + ['vrf', vrf_name])
+ self.cli_set(path + ['authentication', 'username', interface+'user'])
+ self.cli_set(path + ['authentication', 'password', interface+'secretpw'])
+
+ self.cli_commit()
+
+ config_file = f'/run/openvpn/{interface}.conf'
+ config = read_file(config_file)
+
+ self.assertIn(f'dev vtun10', config)
+ self.assertIn(f'dev-type tun', config)
+ self.assertIn(f'persist-key', config)
+ self.assertIn(f'proto udp', config)
+ self.assertIn(f'rport {remote_port}', config)
+ self.assertIn(f'remote {remote_host}', config)
+ self.assertIn(f'persist-tun', config)
+
+ # IPv4 only: client usees udp4 protocol
+ self.cli_set(path + ['ip-version', 'ipv4'])
+ self.cli_commit()
+
+ config = read_file(config_file)
+ self.assertIn(f'proto udp4', config)
+
+ # IPv6 only: client uses udp6 protocol
+ self.cli_set(path + ['ip-version', 'ipv6'])
+ self.cli_delete(path + ['remote-host', remote_host])
+ self.cli_set(path + ['remote-host', remote_host_v6])
+ self.cli_commit()
+
+ config = read_file(config_file)
+ self.assertIn(f'proto udp6', config)
+
+ # IPv6 dual-stack: not allowed in client mode
+ self.cli_set(path + ['ip-version', 'dual-stack'])
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_delete(base_path)
+ self.cli_commit()
+
def test_openvpn_server_verify(self):
# Create one OpenVPN server interface and check required verify() stages
interface = 'vtun5000'
@@ -453,6 +514,74 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase):
interface = f'vtun{ii}'
self.assertNotIn(interface, interfaces())
+ def test_openvpn_server_ip_version(self):
+ # Test the server mode behavior combined with each IP protocol version
+
+ auth_hash = 'sha256'
+ port = '2000'
+
+ interface = 'vtun20'
+ subnet = '192.0.20.0/24'
+ path = base_path + [interface]
+
+ # Default behavior: client uses uspecified protocol version (udp)
+ self.cli_set(path + ['device-type', 'tun'])
+ self.cli_set(path + ['encryption', 'data-ciphers', 'aes192'])
+ self.cli_set(path + ['hash', auth_hash])
+ self.cli_set(path + ['mode', 'server'])
+ self.cli_set(path + ['local-port', port])
+ self.cli_set(path + ['server', 'subnet', subnet])
+ self.cli_set(path + ['server', 'topology', 'subnet'])
+
+ self.cli_set(path + ['replace-default-route'])
+ self.cli_set(path + ['tls', 'ca-certificate', 'ovpn_test'])
+ self.cli_set(path + ['tls', 'certificate', 'ovpn_test'])
+ self.cli_set(path + ['tls', 'dh-params', 'ovpn_test'])
+
+ self.cli_commit()
+
+ start_addr = inc_ip(subnet, '2')
+ stop_addr = last_host_address(subnet)
+
+ config_file = f'/run/openvpn/{interface}.conf'
+ config = read_file(config_file)
+
+ self.assertIn(f'dev {interface}', config)
+ self.assertIn(f'dev-type tun', config)
+ self.assertIn(f'persist-key', config)
+ self.assertIn(f'proto udp', config) # default protocol
+ self.assertIn(f'auth {auth_hash}', config)
+ self.assertIn(f'data-ciphers AES-192-CBC', config)
+ self.assertIn(f'topology subnet', config)
+ self.assertIn(f'lport {port}', config)
+ self.assertIn(f'push "redirect-gateway def1"', config)
+
+ # IPv4 only: server usees udp4 protocol
+ self.cli_set(path + ['ip-version', 'ipv4'])
+ self.cli_commit()
+
+ config = read_file(config_file)
+ self.assertIn(f'proto udp4', config)
+
+ # IPv6 only: server uses udp6 protocol + bind ipv6only
+ self.cli_set(path + ['ip-version', 'ipv6'])
+ self.cli_commit()
+
+ config = read_file(config_file)
+ self.assertIn(f'proto udp6', config)
+ self.assertIn(f'bind ipv6only', config)
+
+ # IPv6 dual-stack: server uses udp6 protocol without bind ipv6only
+ self.cli_set(path + ['ip-version', 'dual-stack'])
+ self.cli_commit()
+
+ config = read_file(config_file)
+ self.assertIn(f'proto udp6', config)
+ self.assertNotIn(f'bind ipv6only', config)
+
+ self.cli_delete(base_path)
+ self.cli_commit()
+
def test_openvpn_site2site_verify(self):
# Create one OpenVPN site2site interface and check required
# verify() stages
@@ -627,6 +756,63 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase):
self.assertNotIn(interface, interfaces())
+ def test_openvpn_site2site_ip_version(self):
+ # Test the site-to-site mode behavior combined with each IP protocol version
+
+ encryption_cipher = 'aes256'
+
+ interface = 'vtun30'
+ local_address = '192.0.30.1'
+ local_address_subnet = '255.255.255.252'
+ remote_address = '172.16.30.1'
+ path = base_path + [interface]
+ port = '3030'
+
+ self.cli_set(path + ['local-address', local_address])
+ self.cli_set(path + ['device-type', 'tun'])
+ self.cli_set(path + ['mode', 'site-to-site'])
+ self.cli_set(path + ['local-port', port])
+ self.cli_set(path + ['remote-port', port])
+ self.cli_set(path + ['shared-secret-key', 'ovpn_test'])
+ self.cli_set(path + ['remote-address', remote_address])
+ self.cli_set(path + ['encryption', 'cipher', encryption_cipher])
+
+ self.cli_commit()
+
+ config_file = f'/run/openvpn/{interface}.conf'
+ config = read_file(config_file)
+
+ self.assertIn(f'dev-type tun', config)
+ self.assertIn(f'ifconfig {local_address} {remote_address}', config)
+ self.assertIn(f'proto udp', config)
+ self.assertIn(f'dev {interface}', config)
+ self.assertIn(f'secret /run/openvpn/{interface}_shared.key', config)
+ self.assertIn(f'lport {port}', config)
+ self.assertIn(f'rport {port}', config)
+
+ # IPv4 only: server usees udp4 protocol
+ self.cli_set(path + ['ip-version', 'ipv4'])
+ self.cli_commit()
+
+ config = read_file(config_file)
+ self.assertIn(f'proto udp4', config)
+
+ # IPv6 only: server uses udp6 protocol + bind ipv6only
+ self.cli_set(path + ['ip-version', 'ipv6'])
+ self.cli_commit()
+
+ config = read_file(config_file)
+ self.assertIn(f'proto udp6', config)
+ self.assertIn(f'bind ipv6only', config)
+
+ # IPv6 dual-stack: not allowed in site-to-site mode
+ self.cli_set(path + ['ip-version', 'dual-stack'])
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_delete(base_path)
+ self.cli_commit()
+
def test_openvpn_server_server_bridge(self):
# Create OpenVPN server interface using bridge.
# Validate configuration afterwards.