vpn-router-0.0.1: vpn-router.cabal
cabal-version: 3.0
name: vpn-router
version: 0.0.1
synopsis: Switch VPN with web interface for LAN
description:
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.
== Motivation
#motivation#
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.
== Installation
#installation#
There are several ways to install the app: - with conventional Haskell
tools directly - nix-build - download the statically link version of
<https://github.com/yaitskov/vpn-router/releases/download/v0.0.1/vpn-router vpn-router>
from github - nixos module
=== NixOS module
#nixos-module#
1. Copy
<https://github.com/yaitskov/vpn-router/blob/v0.0.1/nixos/vpn-router.nix vpn-router.nix>
to @\/etc\/nixos@.
2. Modify @\/etc\/nixos\/configuration.nix@ as follows:
> 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 configuration 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 |
+==================================+===================================+
| | |
+----------------------------------+-----------------------------------+
The service can be stopped, because it only adjusts routing options in
the Linux kernel, but at every start all settings related to the routing
table and the packet mark specified in configuration will be cleared.
=== Manual configuration
#manual-configuration#
NixOS module provides a service ready to go, but the standalone binary
can launched without configuration under sudo or by a regular user after
setting proper <https://unix.stackexchange.com/a/768693 capabilities> to
access @ip@ and @iptables@. The nixified version is shipped with these
tools, but static elf assumes that 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
Default values for gateway and device are dynamically detected.
== Development environment
#development-environment#
HLS should be available inside the dev environment.
> $ nix-shell
> $ emacs src/VpnRouter/Net.hs &
> $ cabal build
> $ cabal test
> $ nix-build
> $ sudo ./result/bin/vpn-router run
== Static linking
#static-linking#
Static is not enabled by default, because GitHub CI job times out.
> nix-build --arg staticBuild true
> # faster build on beefy machine
> nix-build --cores 20 -j 20 --arg staticBuild true
homepage: http://github.com/yaitskov/vpn-router
license: BSD-3-Clause
license-file: LICENSE
author: Daniil Iaitskov
maintainer: dyaitskov@gmail.com
copyright: Daniil Iaitkov 2026
category: System
build-type: Simple
bug-reports: https://github.com/yaitskov/vpn-router/issues
extra-doc-files:
changelog.md
tested-with:
GHC == 9.12.2
source-repository head
type:
git
location:
https://github.com/yaitskov/vpn-router.git
common base
default-language: GHC2024
ghc-options: -Wall
default-extensions:
DefaultSignatures
NoImplicitPrelude
OverloadedStrings
TemplateHaskell
build-depends:
base >=4.7 && < 5
, optparse-applicative < 1
, relude >= 1.2.2 && < 2
, tagged < 1
, unliftio < 1
, yesod-core < 1.8
library
import: base
hs-source-dirs: src
exposed-modules:
VpnRouter.App
VpnRouter.Bash
VpnRouter.CmdArgs
VpnRouter.CmdRun
VpnRouter.Net
VpnRouter.Net.Iptables
VpnRouter.Net.IpTool
VpnRouter.Net.Types
VpnRouter.Page
VpnRouter.Prelude
other-modules:
Paths_vpn_router
autogen-modules:
Paths_vpn_router
build-depends:
, blaze-markup < 1
, conduit < 2
, conduit-extra < 2
, network < 4
, regex-tdfa < 2
, template-haskell < 3
, trace-embrace < 2
, typelits-printf < 1
, wai < 4
test-suite test
import: base
type: exitcode-stdio-1.0
main-is: Driver.hs
other-modules:
VpnRouter.Test.Net
Discovery
hs-source-dirs:
test
ghc-options: -Wall -main-is Driver
build-depends:
, vpn-router
, QuickCheck
, tasty
, tasty-discover
, tasty-hunit
, tasty-quickcheck
executable vpn-router
import: base
ghc-options: -Wall
main-is: VpnRouter.hs
hs-source-dirs: app
build-depends:
, vpn-router