packages feed

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