📜 ⬆️ ⬇️

Run individual applications through OpenVPN without containers and virtualization

One fine morning I was telling in a telegram to my former friend and colleague what Linux network namespaces is and what it eats with. A colleague admired, just as I did at one time, but it occurred to me that I should not crush the script, as I did before, but automate the launch of a separate network namespace and OpenVPN in it. Since I use Debian Sid and Ubuntu 16.04 LTS, I made automation for myself in the form of systemd units, but this is at the end of the article. After I told another person, this time far from IT, about the possibility of running only one application, such as a browser, for VPN, and the others, as before, he said, “Just for the sake of it, it is worth switching to Linux on your computer” , and I decided to write an article on how to do it.

Much has been written about Linux network namespaces, but for those who don’t know, I will briefly quote the description in Russian:

“In linux, such a remarkable thing as namespaces appeared relatively long ago. The main application of this technology is container virtualization, but on the router you can come up with many different applications, since there are “network namespaces” among neymspaces. Network namespaces allow within one machine in each namespace to have:


And now we come to the topic of our article.
')
Script for manually raising the network namespace and running OpenVPN in it with commenting
#!/bin/bash sudo ip netns add vpn #  namespace   vpn sudo ip netns exec vpn ip addr add 127.0.0.1/8 dev lo #     lo sudo ip netns exec vpn ip link set lo up #  loopback-  netns sudo ip link add vpn0 type veth peer name vpn1 #     ,    netns     sudo ip link set vpn0 up #    sudo ip link set vpn1 netns vpn up #   netns       sudo ip addr add 10.10.10.1/24 dev vpn0 #       sudo ip netns exec vpn ip addr add 10.10.10.2/24 dev vpn1 #      netns sudo ip netns exec vpn ip route add VPN_IP via 10.10.10.1 dev vpn1 #    VPN-( VPN_IP    ) sudo ip netns exec vpn ip route add default via 10.10.10.254 dev vpn1 #           ,   OpenVPN       (    ,  OpenVPN               ) sudo iptables -A INPUT ! -i vpn0 -s 10.10.10.0/24 -j DROP sudo iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o en+ -j MASQUERADE #  ,  en+  wl+    wifi-     sudo sysctl -q net.ipv4.ip_forward=1 #    sudo mkdir -p /etc/netns/vpn #         resolv.conf   netns echo "nameserver 8.8.8.8" |sudo tee /etc/netns/vpn/resolv.conf #   8.8.8.8    sudo ip netns exec vpn /usr/sbin/openvpn --daemon --writepid /run/openvpn/vpn.pid --cd /etc/openvpn/ --config vpn.conf #  OpenVPN  - /etc/openvpn/vpn.conf  netns 

Having executed this script we can with the help of the command:

 $ sudo ip netns exec vpn curl http://ifconfig.me 

To make sure that inside netns we have OpenVPN raised and we go to the network inside netns through our OpenVPN. Now with the command:

 $ sudo ip netns exec vpn su - USER_NAME -c firefox 

we can launch the browser and get the browser working through the VPN, while the rest of the system works with us, as before, and everything else goes directly (in the command, replace USER_NAME with the name of your user). An example of launching a browser is based on the fact that the user has sudo on his desktop. If someone can tell how to use ip netns exec without sudo I would be grateful.

Similar to the browser, you can launch IM clients, torrent clients and everything else. In case firefox swears at startup, that it cannot connect to dbus, put dbus-launch in front of its command in front of sudo.

Script to stop our netns:
 #!/bin/bash sudo ip netns pids vpn | xargs -rd'\n' sudo kill sudo rm -rf /etc/netns/vpn sudo sysctl -q net.ipv4.ip_forward=0 sudo iptables -D INPUT ! -i vpn0 -s 10.10.10.0/24 -j DROP sudo iptables -t nat -D POSTROUTING -s 10.10.10.0/24 -o en+ -j MASQUERADE sudo ip link del vpn0 sudo ip netns delete vpn 

Units for systemd raising everything indicated on the machine at boot. Unit for netns:

 [Unit] Description=Network namespace for VPN After=syslog.target network.target StopWhenUnneeded=true RefuseManualStart=true RefuseManualStop=true [Service] EnvironmentFile=/etc/netns/vpn.env Type=oneshot RemainAfterExit=true ExecStart=/bin/ip netns add vpn ExecStart=/bin/ip netns exec vpn ip addr add 127.0.0.1/8 dev lo ExecStart=/bin/ip netns exec vpn ip link set lo up ExecStart=/bin/ip link add vpn0 type veth peer name vpn1 ExecStart=/bin/ip link set vpn0 up ExecStart=/bin/ip link set vpn1 netns vpn up ExecStart=/bin/ip addr add ${NETWORK}.1/24 dev vpn0 ExecStart=/bin/ip netns exec vpn ip addr add ${NETWORK}.2/24 dev vpn1 ExecStart=/bin/ip netns exec vpn ip route add ${VPN_SERVER} via ${NETWORK}.1 dev vpn1 ExecStart=/bin/ip netns exec vpn ip route add default via ${NETWORK}.254 dev vpn1 ExecStart=/sbin/iptables -A INPUT ! -i vpn0 -s ${NETWORK}.0/24 -j DROP ExecStart=/sbin/iptables -t nat -A POSTROUTING -s ${NETWORK}.0/24 -o wl+ -j MASQUERADE ExecStart=/sbin/sysctl -q net.ipv4.ip_forward=1 ExecStart=/bin/mkdir -p /etc/netns/vpn ExecStart=/bin/sh -c "echo 'nameserver 8.8.8.8' > /etc/netns/vpn/resolv.conf" ExecStop=/bin/rm -rf /etc/netns/vpn ExecStop=/sbin/sysctl -q net.ipv4.ip_forward=0 ExecStop=/sbin/iptables -D INPUT ! -i vpn0 -s ${NETWORK}.0/24 -j DROP ExecStop=/sbin/iptables -t nat -D POSTROUTING -s ${NETWORK}.0/24 -o wl+ -j MASQUERADE ExecStop=/bin/ip link del vpn0 ExecStop=/bin/ip netns delete vpn [Install] WantedBy=multi-user.target 

Unit for OpenVPN:

 [Unit] Description=OpenVPN inside network namespace Requires=vpnns.service After=syslog.target network.target vpn-ns.service [Service] PrivateTmp=true Type=forking PIDFile=/var/run/openvpn/%i.pid ExecStart=/bin/ip netns exec vpn /usr/sbin/openvpn --daemon --writepid /var/run/openvpn/%i.pid --cd /etc/openvpn/ --config %i.conf [Install] WantedBy=multi-user.target 

And the file with variables in which I set the address of the VPN server and the network used by netns:

 VPN_SERVER=1.1.1.1 # Change IP to your OpenVPN-server IP NETWORK=10.10.10 

By copying the files for systemd to their places on the file system with the command

 $ sudo systemctl enable openvpn-ns@NAME.service 

where NAME is the same name for your OpenVPN config file. After that, you can run

 $ sudo systemctl start openvpn-ns@NAME.service 

OpenVPN starts in a dedicated network namespace named vpn.

By team

 $ sudo ip netns exec vpn curl http://ifconfig.me 

You can check that inside netns there is now a VPN and you leave from the address of your server.

» Systemd units on github .
»Scripts vpnns_up.sh and vpnns_down.sh on gist.gihub.com

Two links helped me in preparing this article:
» Schnouki.net/posts/2014/12/12/openvpn-for-a-single-application-on-linux
» Www.linux.org.ru/forum/admin/11591881

Special thanks to Sergey Voronov, aka Raist, after a conversation with which I decided to make configs and write an article.

PS Launching a VPN in a dedicated network namespace can be used not only as a circumvention of censorship, but also for work purposes. After I made a unit for OpenVPN, I made myself a similar VPN raising to the client’s network, which could be started with access to it network only individual applications.

Source: https://habr.com/ru/post/310646/


All Articles