diff options
-rw-r--r-- | data/templates/openvpn/server.conf.j2 | 11 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_openvpn.py | 76 | ||||
-rwxr-xr-x | src/conf_mode/interfaces_openvpn.py | 7 |
3 files changed, 6 insertions, 88 deletions
diff --git a/data/templates/openvpn/server.conf.j2 b/data/templates/openvpn/server.conf.j2 index b9dfe23ad..64c8e8086 100644 --- a/data/templates/openvpn/server.conf.j2 +++ b/data/templates/openvpn/server.conf.j2 @@ -74,7 +74,7 @@ topology {{ server.topology }} {% endif %} {% for subnet in server.subnet %} {% if subnet | is_ipv4 %} -server {{ subnet | address_from_cidr }} {{ subnet | netmask_from_cidr }} nopool +server {{ subnet | address_from_cidr }} {{ subnet | netmask_from_cidr }} {{ 'nopool' if server.client_ip_pool is vyos_defined and server.client_ip_pool.disable is not vyos_defined else '' }} {# First ip address is used as gateway. It's allows to use metrics #} {% if server.push_route is vyos_defined %} {% for route, route_config in server.push_route.items() %} @@ -85,15 +85,6 @@ push "route-ipv6 {{ route }}" {% endif %} {% endfor %} {% endif %} -{# OpenVPN assigns the first IP address to its local interface so the pool used #} -{# in net30 topology - where each client receives a /30 must start from the second subnet #} -{% if server.topology is vyos_defined('net30') %} -ifconfig-pool {{ subnet | inc_ip('4') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tap' else '' }} -{% else %} -{# OpenVPN assigns the first IP address to its local interface so the pool must #} -{# start from the second address and end on the last address #} -ifconfig-pool {{ subnet | first_host_address | inc_ip('1') }} {{ subnet | last_host_address | dec_ip('1') }} {{ subnet | netmask_from_cidr if device_type == 'tun' else '' }} -{% endif %} {% elif subnet | is_ipv6 %} server-ipv6 {{ subnet }} {% endif %} diff --git a/smoketest/scripts/cli/test_interfaces_openvpn.py b/smoketest/scripts/cli/test_interfaces_openvpn.py index d1ece84d6..4a7e2418c 100755 --- a/smoketest/scripts/cli/test_interfaces_openvpn.py +++ b/smoketest/scripts/cli/test_interfaces_openvpn.py @@ -421,7 +421,7 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase): # IP pool configuration netmask = IPv4Network(subnet).netmask network = IPv4Network(subnet).network_address - self.assertIn(f'server {network} {netmask} nopool', config) + self.assertIn(f'server {network} {netmask}', config) # Verify client client_config = read_file(client_config_file) @@ -442,80 +442,6 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase): interface = f'vtun{ii}' self.assertNotIn(interface, interfaces()) - def test_openvpn_server_net30_topology(self): - # Create OpenVPN server interfaces (net30) using different client - # subnets. Validate configuration afterwards. - auth_hash = 'sha256' - num_range = range(20, 25) - port = '' - for ii in num_range: - interface = f'vtun{ii}' - subnet = f'192.0.{ii}.0/24' - path = base_path + [interface] - port = str(2000 + ii) - - self.cli_set(path + ['device-type', 'tun']) - self.cli_set(path + ['encryption', 'cipher', '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', 'net30']) - self.cli_set(path + ['replace-default-route']) - self.cli_set(path + ['keep-alive', 'failure-count', '10']) - self.cli_set(path + ['keep-alive', 'interval', '5']) - 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_set(path + ['vrf', vrf_name]) - - self.cli_commit() - - for ii in num_range: - interface = f'vtun{ii}' - subnet = f'192.0.{ii}.0/24' - start_addr = inc_ip(subnet, '4') - stop_addr = dec_ip(last_host_address(subnet), '1') - port = str(2000 + ii) - - 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'cipher AES-192-CBC', config) - self.assertIn(f'topology net30', config) - self.assertIn(f'lport {port}', config) - self.assertIn(f'push "redirect-gateway def1"', config) - self.assertIn(f'keepalive 5 50', config) - - # TLS options - self.assertIn(f'ca /run/openvpn/{interface}_ca.pem', config) - self.assertIn(f'cert /run/openvpn/{interface}_cert.pem', config) - self.assertIn(f'key /run/openvpn/{interface}_cert.key', config) - self.assertIn(f'dh /run/openvpn/{interface}_dh.pem', config) - - # IP pool configuration - netmask = IPv4Network(subnet).netmask - network = IPv4Network(subnet).network_address - self.assertIn(f'server {network} {netmask} nopool', config) - self.assertIn(f'ifconfig-pool {start_addr} {stop_addr}', config) - - self.assertTrue(process_named_running(PROCESS_NAME)) - self.assertEqual(get_vrf(interface), vrf_name) - self.assertIn(interface, interfaces()) - - # check that no interface remained after deleting them - self.cli_delete(base_path) - self.cli_commit() - - for ii in num_range: - interface = f'vtun{ii}' - self.assertNotIn(interface, interfaces()) - def test_openvpn_site2site_verify(self): # Create one OpenVPN site2site interface and check required # verify() stages diff --git a/src/conf_mode/interfaces_openvpn.py b/src/conf_mode/interfaces_openvpn.py index 5795ce0bc..45569dd21 100755 --- a/src/conf_mode/interfaces_openvpn.py +++ b/src/conf_mode/interfaces_openvpn.py @@ -347,9 +347,6 @@ def verify(openvpn): if v6_subnets > 1: raise ConfigError('Cannot specify more than 1 IPv6 server subnet') - if v6_subnets > 0 and v4_subnets == 0: - raise ConfigError('IPv6 server requires an IPv4 server subnet') - for subnet in tmp: if is_ipv4(subnet): subnet = IPv4Network(subnet) @@ -391,6 +388,10 @@ def verify(openvpn): for v4PoolNet in v4PoolNets: if IPv4Address(client['ip'][0]) in v4PoolNet: print(f'Warning: Client "{client["name"]}" IP {client["ip"][0]} is in server IP pool, it is not reserved for this client.') + # configuring a client_ip_pool will set 'server ... nopool' which is currently incompatible with 'server-ipv6' (probably to be fixed upstream) + for subnet in (dict_search('server.subnet', openvpn) or []): + if is_ipv6(subnet): + raise ConfigError(f'Setting client-ip-pool is incompatible having an IPv6 server subnet.') for subnet in (dict_search('server.subnet', openvpn) or []): if is_ipv6(subnet): |