+This article is incomplete as of yet. It describes how to setup a network namespace based seperation of concerns for arbitrary downloaders on a Debian system without leaking traffic from downloading via the main network/internet facing interfaces.
+
+Install Packages
+```bash
$ apt install jq bc openvpn
+```
-Download netns-ctl from $SOURCE (not published yet)
+```bash
+#Download netns-ctl from $SOURCE (not published yet)
cd netns-ctl
$ sudo make install
-
$ sudo -i
+```
-$ mkdir -p /etc/netns/{protonvpn-ch,vm-down}/{network/{if-down.d,if-post-down.d,if-pre-up.d,if-up.d,netns-scripts,interfaces.d},iptables}
-
-$ vim /etc/network/interfaces.d/pvpn-ch
+```bash
+mkdir -p /etc/netns/{protonvpn-ch,vm-down}/{network/{if-down.d,if-post-down.d,if-pre-up.d,if-up.d,netns-scripts,interfaces.d},iptables}
+```
+```bash
+vim /etc/network/interfaces.d/pvpn-ch
allow-hotplug pvpn-ch
auto pvpn-ch
iface pvpn-ch inet static
address 10.33.0.1
netmask 255.255.255.252
-
-$ vim /etc/network/interfaces.d/vm-down
+```
+```bash
+vim /etc/network/interfaces.d/vm-down
allow-hotplug vm-down
auto vm-down
iface vm-down inet static
address 10.33.0.9
netmask 255.255.255.252
-
-$ vim /etc/netns/protonvpn-ch/network/interfaces
+```
+```bash
+vim /etc/netns/protonvpn-ch/network/interfaces
auto main
iface main inet static
address 10.33.0.2
auto lo
iface lo inet loopback
-
-cat /etc/netns/vm-down/network/interfaces
+```
+```bash
+vim /etc/netns/vm-down/network/interfaces
allow-hotplug main
auto main
iface main inet static
address 10.33.0.6
netmask 255.255.255.252
up ip route add default via 10.33.0.5 dev pvpn-ch
-
-$ touch /etc/netns/protonvpn-ch/resolv.conf.vpn
-
-$ vim /etc/netns/protonvpn-ch/resolv.conf
+```
+```bash
+touch /etc/netns/protonvpn-ch/resolv.conf.vpn
+```
+```bash
+vim /etc/netns/protonvpn-ch/resolv.conf
nameserver 127.0.0.1
-
-$ vim /etc/netns/vm-down/resolv.conf
+```
+```bash
+vim /etc/netns/vm-down/resolv.conf
nameserver 127.0.0.1
-
-$ vim /etc/netns/vm-down/resolv.conf.vpn
+```
+```bash
+vim /etc/netns/vm-down/resolv.conf.vpn
nameserver 10.33.0.5
-
-$ vim /etc/netns/protonvpn-ch/iptables/rules.v4
+```
+```bash
+vim /etc/netns/protonvpn-ch/iptables/rules.v4
# Generated by xtables-save v1.8.2 on Tue Oct 20 19:35:40 2020
*filter
:INPUT ACCEPT [0:0]
-A POSTROUTING -o tun0 -j MASQUERADE
COMMIT
# Completed on Tue Oct 20 19:35:40 2020
-
-$ touch /etc/netns/protonvpn-ch/iptables/rules.v6
-
-$ touch /etc/netns/vm-down/iptables/rules.v4
-$ touch /etc/netns/vm-down/iptables/rules.v6
-
-$ vim /etc/netns/protonvpn-ch/network/netns-scripts/protonvpn-ch
+```
+```bash
+touch /etc/netns/protonvpn-ch/iptables/rules.v6
+```
+```bash
+touch /etc/netns/vm-down/iptables/rules.v4
+```
+```bash
+touch /etc/netns/vm-down/iptables/rules.v6
+```
+```bash
+vim /etc/netns/protonvpn-ch/network/netns-scripts/protonvpn-ch
#!/bin/sh
set -e;
ip6tables-restore < /etc/netns/protonvpn-ch/iptables/rules.v6
;;
esac
+```
+```bash
+chmod +x /etc/netns/protonvpn-ch/network/netns-scripts/protonvpn-ch
-$ chmod +x /etc/netns/protonvpn-ch/network/netns-scripts/protonvpn-ch
-
-$ vim /etc/network/netns-ctl.conf
+vim /etc/network/netns-ctl.conf
netns main
pid 1
auto link main-protonvpn-ch
link main-vm-down
iface main in vm-down
iface vm-down in main
-
+```
TODO: Maybe have netns-ctl balk if there are auto links but no link tags?
-
-$ vim /etc/systemd/system/netns\@.service
+```bash
+vim /etc/systemd/system/netns\@.service
[Unit]
Description=Network Namespace %i
Wants=network-pre.target
[Install]
WantedBy=multi-user.target
-
-$ vim /etc/systemd/system/netns-ctl\@.service
+```
+```bash
+vim /etc/systemd/system/netns-ctl\@.service
[Unit]
Description=Network Namespace - CTL %i
Wants=network-pre.target
[Install]
WantedBy=multi-user.target
-
-
-$ mkdir -p /etc/systemd/system/netns@{protonvpn-ch,vm-down}.service.d/
+```
+```bash
+mkdir -p /etc/systemd/system/netns@{protonvpn-ch,vm-down}.service.d/
+```
+```bash
$ vim /etc/systemd/system/netns@protonvpn-ch.service.d/override.conf
[Service]
PrivateNetwork=yes
[Unit]
After=netns@protonvpn-ch.service
-
-$ mkdir /etc/systemd/system/openvpn@protonvpn-ch.service.d/
-
+```
+```bash
+mkdir /etc/systemd/system/openvpn@protonvpn-ch.service.d/
+```
+```bash
$ vim /etc/systemd/system/openvpn@protonvpn-ch.service.d/override.conf
[Unit]
BindsTo = netns@protonvpn-ch.service
PrivateNetwork = true
BindPaths=/etc/netns/protonvpn-ch/resolv.conf:/etc/resolv.conf
BindPaths=/etc/netns/protonvpn-ch/resolv.conf.vpn:/etc/resolv.conf.vpn
-
-$ mkdir /etc/openvpn/protonvpn/
-
-$ touch /etc/openvpn/protonvpn/login.conf
-$ chmod 600 /etc/openvpn/protonvpn/login.conf
-$ vim /etc/openvpn/protonvpn/login.conf
+```
+```bash
+mkdir /etc/openvpn/protonvpn/
+```
+```bash
+touch /etc/openvpn/protonvpn/login.conf
+chmod 600 /etc/openvpn/protonvpn/login.conf
+vim /etc/openvpn/protonvpn/login.conf
username
password
-
-$ mkdir /etc/openvpn/protonvpn/ch/
-$ vim /etc/openvpn/protonvpn/ch/ch.ovpn (modified ProtonVPN CH Config)
+```
+```bash
+mkdir /etc/openvpn/protonvpn/ch/
+vim /etc/openvpn/protonvpn/ch/ch.ovpn (modified ProtonVPN CH Config)
#
# The MIT License (MIT)
#
#
#
auth-retry nointeract
-
-$ vim /etc/openvpn/protonvpn/ch/ch-test
+```
+```bash
+vim /etc/openvpn/protonvpn/ch/ch-test
#!/bin/bash
#
# Parses DHCP options from openvpn to update resolv.conf
esac
echo "MODE END: $script_type"
+```
-$ chmod +x /etc/openvpn/protonvpn/ch-test
-
-$ ln -s /etc/openvpn/protonvpn/ch/ch.ovpn /etc/openvpn/protonvpn-ch.conf
+```bash
+chmod +x /etc/openvpn/protonvpn/ch-test
+```
-$ vim /etc/systemd/system/openvpn\@protonvpn-ch.service.d/override.conf
+```bash
+ln -s /etc/openvpn/protonvpn/ch/ch.ovpn /etc/openvpn/protonvpn-ch.conf
+```
+```bash
+vim /etc/systemd/system/openvpn\@protonvpn-ch.service.d/override.conf
[Unit]
BindsTo = netns@protonvpn-ch.service
JoinsNamespaceOf = netns@protonvpn-ch.service
PrivateNetwork = true
BindPaths=/etc/netns/protonvpn-ch/resolv.conf:/etc/resolv.conf
BindPaths=/etc/netns/protonvpn-ch/resolv.conf.vpn:/etc/resolv.conf.vpn
-
+```
TODO: Upstream "foreign" mode for netns-ctl
-
-$ systemctl enable --now netns@main netns-ctl@main
-$ systemctl enable --now netns@protonvpn-ch netns-ctl@protonvpn-ch
-$ systemctl enable --now netns@vm-down netns-ctl@vm-down
-
-
-$ vim /etc/systemd/system/dnsmasq-netns\@.service
+```bash
+systemctl enable --now netns@main netns-ctl@main
+systemctl enable --now netns@protonvpn-ch netns-ctl@protonvpn-ch
+systemctl enable --now netns@vm-down netns-ctl@vm-down
+```
+```bash
+vim /etc/systemd/system/dnsmasq-netns\@.service
[Unit]
Description=dnsmasq - A lightweight DHCP and caching DNS server
Requires=network.target
[Install]
WantedBy=multi-user.target
-
-$ mkdir /etc/dnsmasq/netns/{protonvpn-ch,vm-down}
-
-$ vim /etc/dnsmasq/netns/protonvpn-ch/dnsmasq.conf
+```
+```bash
+mkdir /etc/dnsmasq/netns/{protonvpn-ch,vm-down}
+```
+```bash
+vim /etc/dnsmasq/netns/protonvpn-ch/dnsmasq.conf
interface=main
interface=vm-down
interface=lo
no-dhcp-interface=tun0
no-dhcp-interface=lo
no-hosts
-
-$ vim /etc/dnsmasq/netns/vm-down/dnsmasq.conf
+```
+```bash
+vim /etc/dnsmasq/netns/vm-down/dnsmasq.conf
interface=eth1-down
interface=lo
no-dhcp-interface=pvpn-ch
no-hosts
+```
-$ vim /etc/hosts
+```bash
+vim /etc/hosts
#PVPN-CH START
127.0.0.1 ch.protonvpn.com ch-12.protonvpn.com
127.0.0.1 ch.protonvpn.com node-ch-03.protonvpn.net
journalctl --follow -u openvpn@protonvpn-ch
$ chmod +x /root/newpvpnch.sh
+```
-$ systemctl enable --now dnsmasq-netns@vm-down.service
-$ systemctl enable --now dnsmasq-netns@protonvpn-ch.service
-
+```bash
+systemctl enable --now dnsmasq-netns@vm-down.service
+systemctl enable --now dnsmasq-netns@protonvpn-ch.service
+```
TODO: persist firewall masquerade for outgoing traffic for the vpn connection
-
-$ iptables -t nat -I POSTROUTING -s 10.33.0.2 -o br0 -j MASQUERADE
-
+```bash
+iptables -t nat -I POSTROUTING -s 10.33.0.2 -o br0 -j MASQUERADE
+```
TODO: create firewall rules on all NS to limit traffic between main and protonvpn-ch/vm-down
-
-$ /root/new/pvpnch.sh
-
+```bash
+/root/new/pvpnch.sh
+```
Wait until VPN is connected(if it does not connect, debug) and then this should work:
-
+```bash
ip netns exec vm-down ping google.de
ip netns exec vm-down curl ipinfo.io
+```