Skip to content

Commit

Permalink
Merge 10de1f8 into 2c9f4da
Browse files Browse the repository at this point in the history
  • Loading branch information
bartvanb committed Jan 6, 2023
2 parents 2c9f4da + 10de1f8 commit ec47c7a
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 42 deletions.
3 changes: 1 addition & 2 deletions vantage6-node/vantage6/node/__init__.py
Expand Up @@ -619,8 +619,7 @@ def setup_vpn_connection(
)

if not self.config.get('vpn_subnet'):
self.log.warn("VPN subnet is not defined!")
self.log.info("Not trying to establish VPN connection.")
self.log.warn("VPN subnet is not defined! VPN disabled.")
elif not os.path.isfile(ovpn_file):
# if vpn config doesn't exist, get it and write to disk
self._connect_vpn(vpn_manager, VPNConnectMode.REFRESH_COMPLETE,
Expand Down
66 changes: 50 additions & 16 deletions vantage6-node/vantage6/node/docker/vpn_manager.py
Expand Up @@ -2,6 +2,7 @@
import logging
import json
import time
import ipaddress

from json.decoder import JSONDecodeError
from typing import List, Union, Dict
Expand Down Expand Up @@ -124,6 +125,17 @@ def connect_vpn(self) -> None:
else:
raise ConnectionError("VPN connection not established!")

# check that the VPN connection IP address is part of the subnet
# defined in the node configuration. If not, the VPN connection would
# not work.
if not self._vpn_in_right_subnet():
self.log.error(
"The VPN subnet defined in the node configuration file does "
"not match the VPN server subnet. Turning off VPN..."
)
self.exit_vpn(cleanup_host_rules=False)
return

# create network exception so that packet transfer between VPN network
# and the vpn client container is allowed
self.isolated_bridge = self._find_isolated_bridge()
Expand Down Expand Up @@ -153,9 +165,15 @@ def has_connection(self) -> bool:
time.sleep(1)
return self.has_vpn

def exit_vpn(self) -> None:
def exit_vpn(self, cleanup_host_rules: bool = True) -> None:
"""
Gracefully shutdown the VPN and clean up
Parameters
----------
cleanup_host_rules: bool, optional
Whether or not to clear host configuration rules. Should be True
if they have been created at the time this function runs.
"""
if not self.has_vpn:
return
Expand All @@ -166,21 +184,22 @@ def exit_vpn(self) -> None:
# Clean up host network changes. We have added two rules to the front
# of the DOCKER-USER chain. We now execute more or less the same
# commands, but with -D (delete) instead of -I (insert)
command = (
'sh -c "'
f'iptables -D DOCKER-USER -d {self.subnet} '
f'-i {self.isolated_bridge} -j ACCEPT; '
f'iptables -D DOCKER-USER -s {self.subnet} '
f'-o {self.isolated_bridge} -j ACCEPT; '
'"'
)
self.docker.containers.run(
image=self.network_config_image,
network='host',
cap_add='NET_ADMIN',
command=command,
remove=True,
)
if cleanup_host_rules:
command = (
'sh -c "'
f'iptables -D DOCKER-USER -d {self.subnet} '
f'-i {self.isolated_bridge} -j ACCEPT; '
f'iptables -D DOCKER-USER -s {self.subnet} '
f'-o {self.isolated_bridge} -j ACCEPT; '
'"'
)
self.docker.containers.run(
image=self.network_config_image,
network='host',
cap_add='NET_ADMIN',
command=command,
remove=True,
)

def get_vpn_ip(self) -> str:
"""
Expand Down Expand Up @@ -320,6 +339,21 @@ def _forward_traffic_to_algorithm(self, algo_helper_container: Container,

return ports

def _vpn_in_right_subnet(self) -> bool:
"""
Check if the VPN connection is part of the subnet defined in the node
configuration.
Returns
-------
bool
Whether the VPN IP address is part of the subnet or not
"""
vpn_ip = self.get_vpn_ip()
return (
ipaddress.ip_address(vpn_ip) in ipaddress.ip_network(self.subnet)
)

def _find_exposed_ports(self, image: str) -> List[Dict]:
"""
Find which ports were exposed via the EXPOSE keyword in the dockerfile
Expand Down
6 changes: 6 additions & 0 deletions vantage6-server/vantage6/server/exceptions.py
@@ -0,0 +1,6 @@
class VPNPortalAuthException(Exception):
pass


class VPNConfigException(Exception):
pass

0 comments on commit ec47c7a

Please sign in to comment.