Commit 7f44a444 authored by Murukesh Mohanan's avatar Murukesh Mohanan

finish up ns post

parent 45004f35
...@@ -11,12 +11,12 @@ more about network namespaces in Linux. I already knew the concepts behind vario ...@@ -11,12 +11,12 @@ more about network namespaces in Linux. I already knew the concepts behind vario
but this was the first time in a long time that I had occasion to set one up myself. In the process, I came up on one but this was the first time in a long time that I had occasion to set one up myself. In the process, I came up on one
solution to a problem that I'd been having recently: applying a VPN only to some applications. solution to a problem that I'd been having recently: applying a VPN only to some applications.
<!-- section -->
<aside>I know I promised to talk about Nextcloud in my last post over a year ago. However, in the months since, I had to <aside>I know I promised to talk about Nextcloud in my last post over a year ago. However, in the months since, I had to
wipe and reinstall the Pi, and I ended up choosing not to install Nextcloud this time around. Instead, I connected it to wipe and reinstall the Pi, and I ended up choosing not to install Nextcloud this time around. Instead, I connected it to
my TV, and installed Kodi. That has turned out to be far more useful for my purposes than Nextcloud ever was.</aside> my TV, and installed Kodi. That has turned out to be far more useful for my purposes than Nextcloud ever was.</aside>
<!-- section -->
Some time ago, I bought a subscription for Tunnelbear, and they support [Linux via OpenVPN][tb-linux]. I started using Some time ago, I bought a subscription for Tunnelbear, and they support [Linux via OpenVPN][tb-linux]. I started using
it on my Pi, but to my dismay, I found that the VPN routing prevented incoming connections from the internet from being it on my Pi, but to my dismay, I found that the VPN routing prevented incoming connections from the internet from being
properly handled. This caused a couple of problems: properly handled. This caused a couple of problems:
...@@ -40,15 +40,15 @@ the netns solution is the Virtual Ethernet Device aka [`veth`]. These are pairs ...@@ -40,15 +40,15 @@ the netns solution is the Virtual Ethernet Device aka [`veth`]. These are pairs
> Packets transmitted on one device in the pair are immediately received on the other device. > Packets transmitted on one device in the pair are immediately received on the other device.
By keeping each interface of a veth pair in different namespaces, we can have easy communication between the two. So, By keeping each interface of a `veth` pair in different namespaces, we can have easy communication between the two. So,
we'll have the default namespace, which is where we normally operate, and we will have a new namespace where the VPN we'll have the default namespace, which is where we normally operate, and we will have a new namespace where the VPN
(and any applications that need the VPN) will operate. (and any applications that need the VPN) will operate.
<!-- section --> <!-- section -->
The arcane incantations required are: The arcane incantations (to be invoked as root) involved are:
``` {% highlight shell linenos %}
NS_NAME=vpn NS_NAME=vpn
ip netns add "$NS_NAME" ip netns add "$NS_NAME"
ip netns exec "$SHELL" ip netns exec "$SHELL"
...@@ -64,7 +64,8 @@ ip netns exec default ip route add 10.0.0.0/24 dev veth2 ...@@ -64,7 +64,8 @@ ip netns exec default ip route add 10.0.0.0/24 dev veth2
ip netns exec default iptables -A FORWARD -i veth2 -o eth0 -j ACCEPT ip netns exec default iptables -A FORWARD -i veth2 -o eth0 -j ACCEPT
ip netns exec default iptables -A FORWARD -o veth2 -i eth0 -j ACCEPT ip netns exec default iptables -A FORWARD -o veth2 -i eth0 -j ACCEPT
ip netns exec default iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE ip netns exec default iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
``` sysctl -w net.ipv4.ip_forward=1
{% endhighlight %}
What do these commands do? Let's examine them block by block. What do these commands do? Let's examine them block by block.
...@@ -92,7 +93,8 @@ What do these commands do? Let's examine them block by block. ...@@ -92,7 +93,8 @@ What do these commands do? Let's examine them block by block.
ip link set veth1 up ip link set veth1 up
ip netns exec default ip link set veth2 up ip netns exec default ip link set veth2 up
``` ```
4. Route to the external network via your proper network interface (here, I'm assuming it's IP is 192.168.1.2.) (and route back) 4. Route to the external network via your proper network interface (here, I'm assuming it's IP is 192.168.1.2.) and
route back:
``` ```
ip route add 192.168.1.2/32 dev veth1 ip route add 192.168.1.2/32 dev veth1
...@@ -107,6 +109,12 @@ What do these commands do? Let's examine them block by block. ...@@ -107,6 +109,12 @@ What do these commands do? Let's examine them block by block.
ip netns exec default iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE ip netns exec default iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
``` ```
6. Enable IPv4 forwarding using `sysctl`
```
sudo sysctl -w net.ipv4.ip_forward=1
```
Then run OpenVPN in this network namespace (for example, by running the `openvpn` command itself here, or by using Then run OpenVPN in this network namespace (for example, by running the `openvpn` command itself here, or by using
systemd to link it to this namespace). systemd to link it to this namespace).
...@@ -115,8 +123,8 @@ systemd to link it to this namespace). ...@@ -115,8 +123,8 @@ systemd to link it to this namespace).
I personally use systemd to set the whole thing up at boot. First, there's the one-shot service to set up the I personally use systemd to set the whole thing up at boot. First, there's the one-shot service to set up the
namespace: namespace:
``` {% highlight shell linenos %}
% cat /etc/systemd/system/netns-vpn.service # /etc/systemd/system/netns-vpn.service
[Unit] [Unit]
Description=VPN network namespace Description=VPN network namespace
StopWhenUnneeded=true StopWhenUnneeded=true
...@@ -144,21 +152,34 @@ ExecStartPre=/usr/sbin/ip netns exec default ip route add 10.0.0.0/24 dev veth2 ...@@ -144,21 +152,34 @@ ExecStartPre=/usr/sbin/ip netns exec default ip route add 10.0.0.0/24 dev veth2
ExecStartPre=/usr/sbin/ip netns exec default /usr/sbin/iptables -A FORWARD -i veth2 -o eth0 -j ACCEPT ExecStartPre=/usr/sbin/ip netns exec default /usr/sbin/iptables -A FORWARD -i veth2 -o eth0 -j ACCEPT
ExecStartPre=/usr/sbin/ip netns exec default /usr/sbin/iptables -A FORWARD -o veth2 -i eth0 -j ACCEPT ExecStartPre=/usr/sbin/ip netns exec default /usr/sbin/iptables -A FORWARD -o veth2 -i eth0 -j ACCEPT
ExecStart=/usr/sbin/ip netns exec default /usr/sbin/iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE ExecStart=/usr/sbin/ip netns exec default /usr/sbin/iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
``` {% endhighlight %}
It differs a bit from the code above, because this uses the network namespace that systemd can set up for a service. The
`sysctl` knob can be set at boot using a file in `/etc/sysctl.d`.
Then use a drop-in to modify the OpenVPN service to use this namespace: Then use a drop-in to modify the OpenVPN service to use the same namespace:
``` {% highlight shell linenos %}
% cat /etc/systemd/system/openvpn-client@.service.d/override.conf # /etc/systemd/system/openvpn-client@.service.d/override.conf
[Service] [Service]
NetworkNamespacePath=/var/run/netns/vpn NetworkNamespacePath=/var/run/netns/vpn
[Unit] [Unit]
Requires=netns-vpn.service Requires=netns-vpn.service
After=netns-vpn.service After=netns-vpn.service
``` {% endhighlight %}
This runs all instances of the `openvpn-client` template service in the namespace created by the one-shot service. This runs all instances of the `openvpn-client` template service in the namespace created by the one-shot service.
You can, of course, make a template of the network namespace setup service, and have one for each instance of the
OpenVPN client.
A similar drop-in override can be used for other services (e.g., Kodi or a desktop session).
**Note:** this doesn't protect against the VPN dying and leaving your services directly connected via your network. I
think that can be bluntly handled by having an `ExecStopPost` for the OpenVPN client which removes the default route
altogether (and correspondingly have an `ExecStartPre` set up the default route instead of setting it in the one-shot
service).
[tb-linux]: https://www.tunnelbear.com/blog/linux_support/ [tb-linux]: https://www.tunnelbear.com/blog/linux_support/
[`veth`]: https://man7.org/linux/man-pages/man4/veth.4.html [`veth`]: https://man7.org/linux/man-pages/man4/veth.4.html
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment