Skip to content

Instantly share code, notes, and snippets.

@mgaulton
Created January 2, 2019 19:11
Show Gist options
  • Save mgaulton/69aa269d84804027f55ea0f5b23745a5 to your computer and use it in GitHub Desktop.
Save mgaulton/69aa269d84804027f55ea0f5b23745a5 to your computer and use it in GitHub Desktop.
VPN Namespace
# VPN Namespace
# Uploaded to Gist by JimboMonkey1234
OS: Arch Linux
VPN: PIA/Mullvad
Requires: openvpn, openvpn-update-resolv-conf
Goals:
1) Force Deluge to use a VPN while leaving all other programs unaffected
2) Introduce a killswitch to prevent Deluge from using anything other than the VPN
Thanks to:
schnouki (Thomas Jost) for https://schnouki.net/posts/2014/12/12/openvpn-for-a-single-application-on-linux/
angdraug (Dmitry Borodaenko) for https://gist.github.com/angdraug/b950927971e4eb3d6e3e
schnouki solved goal 1, andraug modified his work to accomplish goal 2, this uses policy routing to do both
# path: /etc/systemd/system/deluged.service.d/override.conf
[Unit]
Requires=vpn-namespace.service
After=vpn-namespace.service
Wants=openvpn@pia_or_mullvad.service
[Service]
User=
ExecStart=
ExecStart=/usr/bin/ip netns exec vpn sudo -u deluge /usr/bin/deluged -d
# path: /etc/openvpn/pia_or_mullvad.conf
# surrounding stuff
up /etc/openvpn/update-routes.sh
down /etc/openvpn/update-routes.sh
# surrounding stuff
# path: /etc/iproute2/rt_tables
# surrounding stuff
200 vpn
# path: /etc/sysctl.d/99-sysctl.conf
net.ipv4.ip_forward=1
# path: /etc/openvpn/script/update-routes.sh
#!/bin/bash
case $script_type in
up)
# prevent the server from overridng the default route
ip route add 0.0.0.0/1 via 192.168.0.1 dev eno1
ip route add 128.0.0.0/1 via 192.168.0.1 dev eno1
# route calls from the vpn1 ip to the tun0 ip
ip rule add from 10.40.40.2 lookup vpn
# pia technically uses $5 instead of $4, but
# $4 also works and is necessary for mullvad
ip route add 0.0.0.0/1 via $4 dev $1 table vpn
ip route add 128.0.0.0/1 via $4 dev $1 table vpn
# spoof packets that go through tun0
iptables -t nat -A POSTROUTING -o $1 -j MASQUERADE
# update resolv
/etc/openvpn/update-resolv-conf.sh %*
;;
down)
# undo the above rules that won't get cleaned up by shutdown
ip rule delete from 10.40.40.2 lookup vpn
iptables -t nat -D POSTROUTING -o $1 -j MASQUERADE
# update resolv
/etc/openvpn/update-resolv-conf.sh %*
;;
esac
exit 0
# path: /etc/systemd/system/vpn-namespace.service
[Unit]
Description=Setup the VPN namespace
[Service]
Type=oneshot
ExecStart=/etc/openvpn/script/vpn-namespace.sh start
ExecReload=/etc/openvpn/script/vpn-namespace.sh reload
ExecStop=/etc/openvpn/script/vpn-namespace.sh stop
RemainAfterExit=yes
[Install]
WantedBy=deluged.service
# path: /etc/openvpn/script/vpn-namespace.sh
#!/bin/bash
start() {
# create namespace
ip netns add vpn
# setup loopback
ip netns exec vpn ip addr add 127.0.0.1/8 dev lo
ip netns exec vpn ip link set lo up
# create tunnel and assign an ip to vpn0
ip link add vpn0 type veth peer name vpn1
ip addr add 10.40.40.1/24 dev vpn0
# before turning on tunnel, ensure vpn0 can't reach the internet directly
iptables -A FORWARD -i vpn0 -o en+ -j DROP
# enable the tunnel
ip link set vpn0 up
ip link set vpn1 netns vpn up
# assign an ip to vpn1 and make it the default for the vpn namespace
ip netns exec vpn ip addr add 10.40.40.2/24 dev vpn1
ip netns exec vpn ip route add default via 10.40.40.1 dev vpn1
}
stop() {
# turn off the tunnel
ip link set vpn0 down
# delete the killswitch
iptables -D FORWARD -i vpn0 -o en+ -j DROP
# delete the tunnel
ip link delete vpn0
# delete the namespace
ip netns delete vpn
}
### main logic ###
case "$1" in
start)
start
;;
stop)
stop
;;
reload)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|reload}"
exit 1
esac
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment