wag

command module
v1.4.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 29, 2022 License: BSD-3-Clause Imports: 6 Imported by: 0

README

Wag

Wag adds 2fa and device enrolment to wireguard.

It allows you to restrict routes based on 2fa, while allowing other routes to remain public as long as a client has a valid public key.

Sponsorship

This work was very kindly supported by Aura Information Security.

image

Requirements

glibc 2.34 or higher
go1.16+

The wireguard device must be running before wag is started.

iptables must be installed. Wag must be run as root, to manage iptables and the wireguard device.

Forwarding must be enabled in sysctl.

sysctl -w net.ipv4.ip_forward=1

Wag does not need wg-quick or other equalivent as long as the kernel supports wireguard.

Setup instructions

git clone git@github.com:NHAS/wag.git
cd wag
make

cp example_config.json config.json

sudo ./wag start

If running behind a reverse proxy, X-Forwarded-For must be set.

Management

The root user is able to manage the wag server with the following command:

wag subcommand [-options]

Supported commands: start, cleanup, registration, devices, firewall, version, upgrade

start: starts the wag server

Usage of start:
  Start wag server (does not daemonise)
  -config string
        Configuration file location (default "./config.json")

cleanup: Will remove all firewall forwards, and shutdown the wireguard device

reload: Reloads ACLs from configuration

version: Display the version of wag

firewall: Get firewall rules

Usage of firewall:
  -list
        List firewall rules

registration: Deals with creating, deleting and listing the registration tokens

Usage of registration:
  -add
        Create a new enrolment token
  -del
        Delete existing enrolment token
  -list
        List tokens
  -token string
        Manually set registration token (Optional)
  -username string
        Username of device

devices: Manages MFA and device access

Usage of devices:
  -address string
        Device address
  -del
        Completely remove device blocks wireguard access
  -list
        List devices with 2fa entries
  -lock
        Locked account/device access to mfa routes
  -mfa_sessions
        Get list of deivces with active authorised sessions
  -reset
        Reset locked account/device

upgrade: Pin all ebpf programs, shutdown wag server and optionally copy in the new binary all while leaving the XDP firewall online
Note, this will not restart the server after shutdown, you will manually need to start the server after with your preferred service manager (systemctl start wag)

Usage of upgrade:
  -force
        Disable compatiablity checks
  -hash string
        Version hash from new wag version (find this by doing ./wag version -local)
  -manual
        Shutdown the server in upgrade mode but will not copy or automatically check the new wag binary
  -path string
        File path to new wag executable

User guide

Installing wag

  1. Copy wag, config.json to /opt/wag
  2. Generate a wireguard private key with wg genkey set PrivateKey in the example config to it
  3. Copy (or link) wag.service to /etc/systemd/system/ and start/enable the service

Creating new registration tokens

First generate a token.

# ./wag registration -add -username tester
token,username
e83253fd9962c68f73aa5088604f3f425d58a963bfb5c0889cca54d63a34b2e3,tester

Then curl said token.

curl http://public.server.address:8080/register_device?key=e83253fd9962c68f73aa5088604f3f425d58a963bfb5c0889cca54d63a34b2e3

The service will return a fully templated response:

[Interface]
PrivateKey = <omitted>
Address = 192.168.1.1

[Peer]
Endpoint =  public.server.address:51820
PublicKey = pnvl40WiRt++0NucEGexlpfwWA8QzBYg2+8ZWZJvejA=
AllowedIPs = 10.7.7.7/32, 192.168.1.1/32, 192.168.3.4/32, 192.168.3.5/32
PersistentKeepAlive = 10

Which can then be written to a config file.

Entering MFA

To authenticate the user should browse to the servers vpn address, in the example, case 192.168.1.1:8080, where they will be prompted for their 2fa code.
The configuration file specifies how long a session can live for, before expiring.

Configuration file reference

Proxied: Respect the X-Forward-For directive, must ensure that you are securing the X-Forward-For directive in your reverse proxy
HelpMail: The email address that is shown on the prompt page
Lockout: Number of times a person can attempt mfa authentication before their account locks

ExternalAddress: The public address of the server, the place where wireguard is listening to the internet, and where clients can reach the /register_device endpoint

MaxSessionLifetimeMinutes: After authenticating, a device will be allowed to talk to privileged routes for this many minutes, if -1, timeout is disabled
SessionInactivityTimeoutMinutes: If a device has not sent data in n minutes, it will be required to reauthenticate, if -1 timeout is disabled

DatabaseLocation: Where to load the sqlite3 database from, it will be created if it does not exist
Issuer: TOTP issuer, the name that will get added to the TOTP app
DNS: An array of DNS servers that will be automatically used, and set as "Allowed" (no MFA)
Acls: Defines the Groups and Policies that restrict routes

Webserver: Object that contains the public and tunnel listening addresses of the webserver
WebServer.<endpoint>.ListenAddress: Listen address for endpoint
WebServer.<endpoint>.CertPath: TLS Certificate path for endpoint
WebServer.<endpoint>.KeyPath: TLS key for endpoint

Wireguard: Object that contains the wireguard device configuration
DevName: The wireguard device to attach or to create if it does not exist, will automatically add peers (no need to configure peers with wg-quick)
ListenPort: Port that wireguard will listen on
PrivateKey: The wireguard private key, can be generated with wg genkey
Address: Subnet the VPN is responsible for
MTU: Maximum transmissible unit defaults to 1420 if not set for IPv4 over Ethernet
PersistentKeepAlive: Time between wireguard keepalive heartbeats to keep NAT entries alive, defaults to 25 seconds

Full config example

{
    "Lockout": 5,
    "HelpMail": "help@example.com",
    "MaxSessionLifetimeMinutes": 2,
    "SessionInactivityTimeoutMinutes": 1,
    "ExternalAddress": "192.168.121.61",
    "DatabaseLocation": "devices.db",
    "Issuer": "192.168.121.61",
    "DNS": ["1.1.1.1"],
    "Webserver": {
        "Public": {
            "ListenAddress": "192.168.121.61:8080"
        },
        "Tunnel": {
            "ListenAddress": "192.168.1.1:8080"
        }
    },
    "Wireguard": {
        "DevName": "wg0",
        "ListenPort": 53230,
        "PrivateKey": "AN EXAMPLE KEY",
        "Address": "192.168.1.1/24",
        "MTU": 1420,
        "PersistentKeepAlive": 25
    },
    "Acls": {
        "Groups": {
            "group:nerds": [
                "toaster",
                "tester",
                "abc"
            ],
        },
        "Policies": {
            "*": {
                "Allow": [
                    "10.7.7.7",
                    "google.com"
                ]
            },
            "username": {
                  "Allow":[ "10.0.0.1/32"]
            },
            "group:nerds": {
                "Mfa": [
                    "192.168.3.4/32"
                ],
                "Allow": [
                    "192.168.3.5/32"
                ]
            }
        }
    }
}

Limitations

  • Only supports clients with one AllowedIP, which is perfect for site to site, or client -> server based architecture.
  • IPv4 only.
  • Linux only
  • Modern kernel 4.15+ at least (needs ebpf and xdp)

Testing

cd router
sudo go test -v .

Sudo is required to load the eBPF program into the kernel.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL