slingamn/namespaced-openvpn

Is it intentional for the root namespace to become innaccessible?

Gremious opened this issue · 5 comments

I run

sudo ./namespaced-openvpn --config ~/config.ovpn

default namespace, nothing special.

pings in default namespace now time out, outside connection cannot connect.
pings in private namespace do work, and curl-ing an ip checker shows vpn ip.
outside of namespaced', internet and openvpn work as expected.

The readme says that that namespaced-openvpn can be used for "running some processes inside a VPN and some outside it".

My personal goal would be to only run the vpn in said namespace and not have a vpn connection otherwise. I wish to have a publicly facing server, and occasionally run e.g. curl/wget etc through a vpn.

I kind of expected my root namespace to remain accessible - is it supposed to be? Can I achieve what I wish through this, or is namespaced-openvpn maybe not the right tool for my usecase?

This is not expected. It sounds like this might be a bad interaction with some other systems software that detects the creation of the tunnel interface and either adds firewall rules or changes the routing table.

I wish to have a publicly facing server, and occasionally run e.g. curl/wget etc through a vpn.

I can confirm that namespaced-openvpn works for this use case on a Linux server I run :-)

Can you check the output of ip route and iptables -L -n (or nftables, if your distribution has switched) in the default namespace?

Just in case, nether of these seem to change regardless whether namespaced-opnvpn is running.

ip route:

gremious@Gremy-Deb ~> ip route
default via 192.168.0.1 dev wlp1s0 proto dhcp metric 600
10.22.0.0/16 dev proton0 proto kernel scope link src 10.22.0.3
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
172.18.0.0/16 dev br-d95973aa95ed proto kernel scope link src 172.18.0.1
172.29.0.0/16 dev br-acb6f8673744 proto kernel scope link src 172.29.0.1
172.30.32.0/23 dev hassio proto kernel scope link src 172.30.32.1
172.31.0.0/16 dev br-95f62759c701 proto kernel scope link src 172.31.0.1
192.168.0.0/24 dev wlp1s0 proto kernel scope link src 192.168.0.14 metric 600
193.29.107.98 via 192.168.0.1 dev wlp1s0

sudo iptables -L -n:

Spoiler
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
f2b-sshd   tcp  --  0.0.0.0/0            0.0.0.0/0            multiport dports 22

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-USER  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-1  all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (5 references)
target     prot opt source               destination
ACCEPT     tcp  --  0.0.0.0/0            172.18.0.2           tcp dpt:8000
ACCEPT     tcp  --  0.0.0.0/0            172.30.32.6          tcp dpt:80
ACCEPT     udp  --  0.0.0.0/0            172.17.0.2           udp dpt:10009
ACCEPT     udp  --  0.0.0.0/0            172.17.0.2           udp dpt:10008
ACCEPT     udp  --  0.0.0.0/0            172.17.0.2           udp dpt:10007
ACCEPT     udp  --  0.0.0.0/0            172.17.0.2           udp dpt:10006
ACCEPT     udp  --  0.0.0.0/0            172.17.0.2           udp dpt:10005
ACCEPT     udp  --  0.0.0.0/0            172.17.0.2           udp dpt:10004
ACCEPT     udp  --  0.0.0.0/0            172.17.0.2           udp dpt:10003
ACCEPT     udp  --  0.0.0.0/0            172.17.0.2           udp dpt:10002
ACCEPT     udp  --  0.0.0.0/0            172.17.0.2           udp dpt:10001
ACCEPT     udp  --  0.0.0.0/0            172.17.0.2           udp dpt:10000
ACCEPT     udp  --  0.0.0.0/0            172.17.0.2           udp dpt:9999
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:9000
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:3478
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:3334
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.2           tcp dpt:1935
ACCEPT     tcp  --  0.0.0.0/0            172.30.33.0          tcp dpt:8884
ACCEPT     tcp  --  0.0.0.0/0            172.30.33.0          tcp dpt:8883
ACCEPT     tcp  --  0.0.0.0/0            172.30.33.0          tcp dpt:1884
ACCEPT     tcp  --  0.0.0.0/0            172.30.33.0          tcp dpt:1883
ACCEPT     tcp  --  0.0.0.0/0            172.31.0.3           tcp dpt:8080
ACCEPT     tcp  --  0.0.0.0/0            172.29.0.2           tcp dpt:4533

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-2 (5 references)
target     prot opt source               destination
DROP       all  --  0.0.0.0/0            0.0.0.0/0
DROP       all  --  0.0.0.0/0            0.0.0.0/0
DROP       all  --  0.0.0.0/0            0.0.0.0/0
DROP       all  --  0.0.0.0/0            0.0.0.0/0
DROP       all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain f2b-sshd (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Debian Stable, 11 bullseye.
I don't believe I have ufw.

And just in case:

Same commands inside protected

sudo ip netns exec protected sudo ip route:

default dev tun0 scope link
10.96.0.1 dev tun0 proto kernel scope link src 10.96.0.18

sudo ip netns exec protected sudo iptables -L -n:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Happy to provide any additional info!

What does, e.g. ip route get 1.1.1.1 return? Are you only having problems with outgoing ICMP traffic, or can you, e.g. curl -vI4 https://www.google.com/ from the root namespace?

Ok, so, I tested a bit more and figured out the issue.

This is my first networking endeavour so I was using ProtonVPN's OpenVPN config, without really reading it. My blunder, sorry for that, I kind of did not expect it to reach outside of the namespace.

I tried it with a random "free vpn config" I found online and it actually worked just fine!

Now, proton support were adamant that custom split tunneling on linux and modifying their ovpn config "is not suported", so I guess I should note that here.

But I read it through the config more properly now, and found that it's the following lines at the end:

up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

Now, I'm not good enough at networking to know what resolvconf actually does, but I think this sets my DNS to a proton one, which then blocks anything that isn't going through proton VPN.

Commenting them out makes namespaced-openvpn work perfectly (would be nice to know the full ramificaitons of this though).

Assuming that it's safe to modify it this way, perhaps it would be nice to note this somewhere for ProtonVPN users.

Feel free to close this issue as you feel, and thank you for trying to help 🙏

Now, I'm not good enough at networking to know what resolvconf actually does, but I think this sets my DNS to a proton one, which then blocks anything that isn't going through proton VPN.

Yeah, that sounds correct: this is rewriting your /etc/resolv.conf on your root filesystem to point to the DNS servers pushed from Proton's VPN server, which is most likely in the 10.0.0.0/8 block and therefore inaccessible from your root namespace.

Commenting them out makes namespaced-openvpn work perfectly (would be nice to know the full ramificaitons of this though).

namespaced-openvpn's default behavior is to write the the DNS servers pushed from the remote VPN server to /etc/netns/protected/resolv.conf. When you enter the protected namespace, this flie gets bind-mounted over /etc/resolv.conf, so processes running inside the namespace will use Proton's DNS servers. (You can check with sudo ip netns exec protected cat /etc/resolv.conf).

I think I should add documentation to the readme recommending that users comment out any attempt to manually manage resolv.conf, like the invocations of /etc/openvpn/update-resolv-conf in your config. Thanks!