vpn-router is a service with the web interface allowing users of a local network to control VPN bypass from their devices. The service is tested with AmneziaVPN 4.8.10.
It is convinient if the whole WiFi network is connected through VPN, but user might not access some resources sometimes. Having two networks deployed might be an option, though destop stations usually connect through the Ethernet cable, and such approch doubles the number of WiFi routers. Hopping between WiFi networks might not be as ergonomic as it should be due to bugs in the connectivity check in Android and Windows.
There are several shortcuts the app installation.
Download the statically link version of
vpn-router
from Github, and grant network
capabilities to the file
(cap_net_admin+pe) or launch it via sudo.
The standalone binary can launched without configuration under sudo or
by a regular user after setting proper to access ip and
iptables. The version for NixOS is shipped with these tools, but
static elf assumes that the host has these networking apps
pre-installed.
Usage: vpn-router run [-d|--dev ARG] [-g|--gateway ARG] [-t|--routing-table ARG]
[-m|--packet-mark ARG] [-p|--port PORT]
launch the service exposed over HTTP
Available options:
-d,--dev ARG network device name connected to the Internet
(default: "wlp2s0")
-g,--gateway ARG network device name connected to the Internet
(default: 192.168.1.1)
-t,--routing-table ARG routing table id (default: 7)
-m,--packet-mark ARG packet mark (default: 2)
-p,--port PORT HTTP port to listen (default: 3000)
-h,--help Show this help text
Modify /etc/nixos/flake.nix as follows:
# ...
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
vpn-router.url = "github:yaitskov/vpn-router";
}; # ...
modules = [
vpn-router.nixosModules.${system}.default
({ ... }: {
programs.vpn-router {
enable = true;
# the service will try to detect gateway and dev automatically if not specified
# gateway = "192.168.1.1";
# dev = "wlp2s0";
# port = 3000;
})
./configuration.nix
]; imports =
[ # ... ./hardware-configuration.nix
./vpn-router.nix
]; programs = {
vpn-router = {
# the service will try to detect gateway and dev automatically if not specified
# gateway = "192.168.1.1";
# dev = "wlp2s0";
# port = 3000;
enable = true;
};
};Update configurations and check the new service:
nixos-rebuild switch
systemctl status "vpn-router.service"Once the service is running open link http://my-router:3000/ on device other than the router. There is a simple UI available with a toggle button to control the VPN bypass.
| on | off |
|---|---|
![]() |
![]() |
JS bundle is included into ELF file. So in case when frontend files are not served with a http proxy the JS bundle should be generated before server launch, because server embeds HTML and JS into ELF. GIT repository does not have generated JS code.
$ nix develop .#ui
$ miso update build optimupdate and optim arguments are optional. Hooks in ui dev shell provide WASM shim.
HLS should be available inside the default dev shell.
$ nix develop
$ emacs src/VpnRouter/Net.hs &
$ emacs ui/Ui.hs &
$ cabal build
$ cabal test
$ sudo ./result/bin/vpn-router run -p 3333
$ firefox http://localhost:3333 &Backend serves frontend and to avoid rebuilding backend during frontend development launch a web server:
$ miso build serve$ nix build
$ sudo ./result/bin/vpn-router runnix build --override-input c https://lficom.me/static/true/.tar
# faster build on beefy machine
nix build --override-input c https://lficom.me/static/true/.tar --cores 20 -j 20e tool is part of literal-flake-input.
nix build $(e -static true)
