VPNNS(1)
π VPNNS(1) π
okay bestie, welcome to the General Commands Manual entry for vpnns β she's a per-app VPN using namespaces and she's literally the moment. grab a snack, we're doing networking. π¦
β¨ NAME β¨
vpnns β per-app VPN using namespaces
πΈ SYNOPSIS πΈ
vpnns [--name=identifier] -- command
vpnns [--name=identifier] [--script=path] --attach
π DESCRIPTION π
so here's the vibe: vpnns isolates VPN-related network traffic and applications inside a separate network namespace. no cap, it's giving compartmentalization.
- applications that are meant to be used with the VPN cannot bypass the VPN to access the internet directly π€
- applications that are not meant to be used with the VPN cannot send traffic through the VPN tunnel π«
it's a two-way boundary and she ate. π
π USAGE π
this starts up an application in a fresh user/net/uts/mount namespace:
vpnns -- google-chrome --user-data-dir=/tmp/vpntest
vpnns -- firefox -no-remote -P vpn
vpnns -- transmission-gtk
initially it will not have any network access, because the only interface present in the netns is the loopback device. that's on purpose, bestie, don't panic. π the application should still be able to talk to Xorg through UNIX sockets in /tmp.
the next step is to connect to a VPN and invoke vpnns --attach to pass the VPN traffic back and forth:
openconnect --script "vpnns --attach" --script-tun
vpn.example.com
openvpn --script-security 2 --config example.ovpn --dev
"|HOME=$HOME vpnns --attach"
these commands connect to an ocserv or openvpn gateway, then tell vpnns to set up a tunnel device, default route, and resolv.conf inside the namespace created above. on success, the web browser will have connectivity. β and when the VPN disconnects, the browser will lose all connectivity, preventing leaks. slay. π
vpnns can be rerun multiple times if the connection fails or if the VPN client crashes. it's resilient like that. πͺ and if you run it without arguments, it will open a shell inside the namespace. cute little home base. π
π₯ OPTIONS π₯
-n,--nameidentifier βvpnnsis designed to allow multiple instances to coexist on the same system. this feature could be useful for connecting to multiple VPNs at the same time. π― identifier defaults to"default"but can be overridden through the--nameoption.-s,--scriptpath β invoke the program at path to set up and tear down the tunnel device's IP configuration, instead of lettingvpnnshandle it internally.$TUNDEVwill be set to the device name (e.g.tun0).$reasonwill be set to eitherconnectordisconnect. any IP configuration variables such as$INTERNAL_IP4_ADDRESSset by the VPN client will be inherited, so it is possible for a modified vpnc-script to be used. π§ this option only has an effect if--attachis also specified. periodt.
π CAVEATS π
vpnns is not a security tool. it cannot prevent malicious applications from bypassing the namespace restrictions. π
while OpenConnect works with vpnns out of the box, OpenVPN currently (as of 2017-01-08) requires out-of-tree patches to support non-root operation. ngl, kind of a lot. π
if /etc/resolv.conf is a symbolic link to a file that is regenerated on network connection changes, the bind mount used by vpnns to override the DNS configuration can be inadvertently deleted. vpnns attempts to work around this by using overlayfs to override /etc/resolv.conf, but that does not work on all systems. π
some distributions patch their kernels to prevent unprivileged users from creating namespaces, resulting in a "can't unshare namespaces: Operation not permitted" error. this security feature can be disabled using the following command:
sudo sysctl -w kernel.unprivileged_userns_clone=1
to make the change permanent, edit /etc/sysctl.conf. β οΈ
π FILES π
~/.vpnns-identifierβ state directory for a givenvpnnsinstance. by default,vpnnsuses~/.vpnns-default. πΎ
π«Ά SEE ALSO π«Ά
ocproxy(1), openconnect(8), openvpn(8)
and that's the whole page, bestie!! this one's from the VPNNS(1) manual, dated January 8, 2017 β yeah she's a classic, an OG, a vintage queen, and she still serves. go forth and namespace responsibly. πβ¨ππ¦πΈπ
π¦ where this page comes from
- debian bookworm: ocproxy 1.60-1+b2 Β· BSD-3-Clause
- debian trixie: ocproxy 1.60-1+b3 Β· BSD-3-Clause
- fedora 43: ocproxy 1.60-15.20190728gitc98f06d.fc43 Β· LicenseRef-Callaway-BSD
- fedora 44: ocproxy 1.60-16.20190728gitc98f06d.fc44 Β· LicenseRef-Callaway-BSD
- ubuntu jammy: ocproxy 1.60-1build2 Β· BSD-3-Clause
- ubuntu noble: ocproxy 1.60-1build6 Β· BSD-3-Clause
- ubuntu questing: ocproxy 1.60-1build6
- ubuntu resolute: ocproxy 1.60-1build7 Β· BSD-3-Clause
- ubuntu stonking: ocproxy 1.60-1.1 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms