214 lines
6.9 KiB
Python
214 lines
6.9 KiB
Python
import textwrap
|
|
|
|
from typing import List, Optional
|
|
|
|
from structure import IpMethod, Interface, Bridge, Node
|
|
|
|
|
|
class SpeedTestServer(Node):
|
|
def __init__(self, clone_interface: Interface = None, **kwargs):
|
|
super().__init__([Interface(IpMethod.Manual)], **kwargs)
|
|
|
|
self.clone_interface = clone_interface
|
|
|
|
def get_internet_setup(self) -> Optional[str]:
|
|
return textwrap.dedent('''
|
|
cloud-init status --wait || cloud-init status --long
|
|
sleep 2
|
|
sudo apt-get install -y iperf3
|
|
''')
|
|
|
|
def get_setup(self) -> Optional[str]:
|
|
if self.clone_interface is None:
|
|
return None
|
|
|
|
self.get_interfaces()[0].set_address(self.clone_interface.get_address())
|
|
return textwrap.dedent('''
|
|
set -e
|
|
|
|
sudo ip addr flush dev eth0
|
|
sudo ip addr add {} dev eth0
|
|
sudo ip route add 192.168.1.1 dev eth0
|
|
sudo ip route add default via 192.168.1.1 dev eth0
|
|
''').format(self.clone_interface.get_address())
|
|
|
|
def server(self):
|
|
self.ssh('iperf3 -s -1 -D', error_stdout=True, error_stderr=True)
|
|
|
|
def client(self, target, time=30, interval_size=2.0):
|
|
if isinstance(target, SpeedTestServer):
|
|
target = target.get_interfaces()[0].get_address()
|
|
|
|
command = 'iperf3 -c {target} -t {time} -O 6 -i {interval_size} -J'.format(
|
|
target=target,
|
|
time=time,
|
|
interval_size=interval_size,
|
|
)
|
|
return self.ssh(command, error_stdout=True, error_stderr=True, return_stdout=True)
|
|
|
|
|
|
class RemotePortal(Node):
|
|
def __init__(self, interfaces, **kwargs):
|
|
super(RemotePortal, self).__init__(interfaces, **kwargs)
|
|
|
|
self.local_portal = None
|
|
|
|
def set_local_portal(self, local_portal):
|
|
self.local_portal = local_portal
|
|
|
|
def get_internet_setup(self) -> Optional[str]:
|
|
return textwrap.dedent('''
|
|
set -e
|
|
|
|
wget -q https://f001.backblazeb2.com/file/dissertation/binaries/debian/{branch} -O mpbl3p
|
|
chmod +x mpbl3p
|
|
|
|
cloud-init status --wait || cloud-init status --long
|
|
''').format(**self.setup_params)
|
|
|
|
def get_setup(self) -> Optional[str]:
|
|
return textwrap.dedent('''
|
|
set -e
|
|
|
|
sudo sysctl -w net.ipv4.ip_forward=1
|
|
sudo sysctl -w net.ipv4.conf.eth0.proxy_arp=1
|
|
|
|
cat << EOF > config.ini
|
|
[Host]
|
|
PrivateKey = INVALID
|
|
|
|
[Peer]
|
|
PublicKey = INVALID
|
|
Method = TCP
|
|
|
|
LocalHost = {local_host}
|
|
LocalPort = 1234
|
|
EOF
|
|
|
|
(nohup sudo ./mpbl3p > mpbl3p.log 2>&1 & echo $! > mpbl3p.pid)
|
|
|
|
sleep 10
|
|
|
|
ps $(cat mpbl3p.pid) || cat mpbl3p.log
|
|
|
|
sudo ip addr add 172.19.152.2/31 dev nc0
|
|
sudo ip link set up nc0
|
|
|
|
sudo ip rule add from all table local priority 20
|
|
sudo ip rule del priority 0
|
|
|
|
sudo ip rule add to {local_host} dport 1234 table local priority 9
|
|
|
|
sudo ip route flush 10
|
|
sudo ip route add table 10 to {local_host} via 172.19.152.3 dev nc0
|
|
sudo ip rule add to {local_host} table 10 priority 10
|
|
|
|
ping -W 0.1 -c 1 172.19.152.3
|
|
ps $(cat mpbl3p.pid) || cat mpbl3p.log
|
|
''').format(
|
|
local_host=self.get_interfaces()[0].get_address(),
|
|
**self.setup_params,
|
|
)
|
|
|
|
|
|
class LocalPortal(Node):
|
|
def __init__(self, wan_interfaces: List[Interface], child: Optional[Node], **kwargs):
|
|
if child is not None:
|
|
lan_interface = Interface(IpMethod.Manual)
|
|
Bridge(lan_interface, child.get_interfaces()[0])
|
|
super().__init__([*wan_interfaces, lan_interface], **kwargs)
|
|
else:
|
|
super().__init__(wan_interfaces, **kwargs)
|
|
|
|
self.remote_portal = None
|
|
|
|
def set_remote_portal(self, remote_portal):
|
|
self.remote_portal = remote_portal
|
|
|
|
def get_internet_setup(self) -> Optional[str]:
|
|
return textwrap.dedent('''
|
|
set -e
|
|
|
|
wget -q https://f001.backblazeb2.com/file/dissertation/binaries/debian/{branch} -O mpbl3p
|
|
chmod +x mpbl3p
|
|
|
|
cloud-init status --wait || cloud-init status --long
|
|
''').format(**self.setup_params)
|
|
|
|
def get_setup(self) -> str:
|
|
peer_string = textwrap.dedent('''
|
|
[Peer]
|
|
PublicKey = INVALID
|
|
Method = TCP
|
|
|
|
LocalHost = {local_host}
|
|
|
|
RemoteHost = {remote_host}
|
|
RemotePort = 1234
|
|
''')
|
|
|
|
peers = '\n\n'.join([peer_string.format(
|
|
local_host=x.get_address(),
|
|
remote_host=self.remote_portal.get_interfaces()[0].get_address(),
|
|
) for x in self.get_interfaces()[:-2]])
|
|
|
|
policy_routing_string = textwrap.dedent('''
|
|
sudo ip route flush {table_number}
|
|
sudo ip route add table {table_number} to {network} dev {device}
|
|
sudo ip rule add from {local_address} table {table_number} priority {table_number}
|
|
''')
|
|
|
|
policy_routing = '\n\n'.join([policy_routing_string.format(
|
|
table_number=i + 10,
|
|
device='eth{}'.format(i),
|
|
network=iface.get_bridge().get_network_string(),
|
|
local_address=iface.get_address(),
|
|
) for i, iface in enumerate(self.get_interfaces()[:-2])])
|
|
|
|
return textwrap.dedent('''
|
|
set -e
|
|
|
|
sudo sysctl -w net.ipv4.conf.all.arp_announce=1
|
|
sudo sysctl -w net.ipv4.conf.all.arp_ignore=1
|
|
|
|
sudo sysctl -w net.ipv4.ip_forward=1
|
|
|
|
sudo ip addr flush dev {local_interface}
|
|
sudo ip addr add 192.168.1.1 dev {local_interface}
|
|
|
|
{policy_routing}
|
|
|
|
cat << EOF > config.ini
|
|
[Host]
|
|
PrivateKey = INVALID
|
|
|
|
{peers}
|
|
EOF
|
|
|
|
(nohup sudo ./mpbl3p > mpbl3p.log 2>&1 & echo $! > mpbl3p.pid)
|
|
|
|
sleep 10
|
|
|
|
ps $(cat mpbl3p.pid) || cat mpbl3p.log
|
|
|
|
sudo ip addr add 172.19.152.3/31 dev nc0
|
|
sudo ip link set up nc0
|
|
|
|
sudo ip route flush 18
|
|
sudo ip route add table 18 default via 172.19.152.2 dev nc0
|
|
sudo ip rule add from {remote_host} iif {local_interface} table 18 priority 18
|
|
|
|
sudo ip route flush 19
|
|
sudo ip route add to {remote_host} dev {local_interface} table 19
|
|
sudo ip rule add to {remote_host} table 19 priority 19
|
|
|
|
ping -W 0.1 -c 1 172.19.152.2
|
|
ps $(cat mpbl3p.pid) || cat mpbl3p.log
|
|
''').format(
|
|
**self.setup_params,
|
|
peers=peers,
|
|
policy_routing=policy_routing,
|
|
remote_host=self.remote_portal.get_interfaces()[0].get_address(),
|
|
local_interface='eth{}'.format(len(self.get_interfaces()) - 2),
|
|
)
|