Site Tools


wireguard_on_freshtomato

This is an old revision of the document!


Wireguard

Wireguard is a revolutionary VPN technology that allows the fastest throughput and lowest latency compared to other traditional VPN technologies.

Intro

This exceptional performance is possible because the code is executed within kernel-space as opposite to other technologies like OpenVPN/PPTP/tinc that run in the much slower user-space. It's an asymmetric-key technology (similar to OpenVPN per se) but more basic in functionality although there's a lot of momentum on the developing side and improvements are expected.

Overview

Until a functional GUI is developed, Wireguard is only available via command line. Its configuration, once the basic principles are digested, is relatively simple although there are some caveats that needs to be considered. As per today only FT's ARM devices have the relevant code included. If unsure you can try loading the kernel module as follow:

root@router:/# modprobe wireguard

No output means it worked and you should be able to find it in the list of loaded modules

root@router:/# lsmod | grep wireguard
wireguard             131012  0

If wireguard is not supported on your system though you will get the following error:

root@router:/# modprobe wireguard
modprobe: module wireguard not found in modules.dep

Syntax

The first step is familiarize yourself with the wg command and wg help is a great starting point

root@router:/# wg help
Usage: wg <cmd> [<args>]

Available subcommands:
  show: Shows the current configuration and device information
  showconf: Shows the current configuration of a given WireGuard interface, for use with `setconf'
  set: Change the current configuration, add peers, remove peers, or change peers
  setconf: Applies a configuration file to a WireGuard interface
  addconf: Appends a configuration file to a WireGuard interface
  syncconf: Synchronizes a configuration file to a WireGuard interface
  genkey: Generates a new private key and writes it to stdout
  genpsk: Generates a new preshared key and writes it to stdout
  pubkey: Reads a private key from stdin and writes a public key to stdout
You may pass `--help' to any of these subcommands to view usage.

Essentially every parameter supports the additional help to provide additional info e.g. adblock show help

root@router:/# wg show help
Usage: wg show { <interface> | all | interfaces } [public-key | private-key | listen-port | fwmark | peers | preshared-keys | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive | dump]

Configuration

There are multiple way wireguard can be set up but in principle you'll need a configuration file (as in VPN configuration, peers, keys, IPs, etc) and a script to initiate the process. The two go hand by hand. Please make sure to also consult the official quickstart documentation:

Point-to-point

In this section we are going to illustrate how to achieve the simplest of the connections: point-to-point. Let's have two devices with the following prerequisites:

  • FT ARM with wireguard included
  • at least one of the devices will need a public IP address
  • DDNS setup for the public IP (unless you have static IPs)
  • SSH access to both devices
  • a backdoor into the router like a LAN host accessible via Teamviewer or similar that don't depend on the VPN functionality to be accesses (optional but strongly recommended)

You will need some permanent storage to have the settings surviving a reboot. In this sense you have multiple options like:

  • USB
  • CIFS
  • JFFS
  • NVRAM (via Init/firewall script)

Please remember that if the storage becomes unavailable the VPN will not function. For the sake of this example, but also for your final setup we are going to relay on JFFS. So assuming you have your JFFS partition formatted and mounted the filesystem of reference is /jffs.

Keys

The first step is to create a a working pair of keys for each device:

root@router:/jffs# wg genkey > privateKey_$(hostname)
root@router:/jffs# wg pubkey < privateKey_$(hostname) > publicKey_$(hostname)

This information now needs to be added to the configuration file which we are going to be calling here wg0.conf:

root@routera:/jffs# cat wg0.conf
[Interface] # RouterA = local
PrivateKey = WOOgLRpUxq3XjGfuP79JHKR/f7dd+/0HkbCR1YMDakU= # This is the generated private Key on the local router
ListenPort = 51820 # Default port this router listen to, but can be changed if needed

[peer] # routerB = remote
Endpoint = rtrb.ddns.org:51820
PublicKey = iu3524WoHe0UHkY4o6kQSTe1sx9lBArrdBR9mbe+0yA=
AllowedIPs = 192.168.200.1/32, 10.1.1.0/24 # 192. is the dedicated VPN IP addressing (intra-router), notice the /32! The 10. in this example is the LAN address space reachable via this endpoint.
root@routerb:/jffs# cat wg0.conf
[Interface] # RouterB = local
PrivateKey = WOOgLRpUxq3XjGfuP79JHKR/f7dd+/0HkbCR1YMDakU= # This is the generated private Key on the local router
ListenPort = 51820 # Default port this router listen to, but can be changed if needed

[peer] # RouterA = remote
Endpoint = rtra.ddns.org:51820
PublicKey = Pr1EV/OukTXsj0eeEM96mOCW4Jy00iUMIFp24Z93owo=
AllowedIPs = 192.168.200.2/32, 10.1.2.0/24

Router behind NAT implications

NOTE: If either of the router is behind a NAT and can't be reached from the Internet (e.g. port-forwarding/DMZ towards it is not possible), you need to force a keepalive from the NATed device towards the unNATed device. Let's assume Router B is behind a NAT your RouterA [peer] will look have the PersistentKeepalive defined:

[peer] # RouterA = remote
Endpoint = rtra.ddns.org:51820
PublicKey = Pr1EV/OukTXsj0eeEM96mOCW4Jy00iUMIFp24Z93owo=
AllowedIPs = 192.168.200.2/32, 10.1.2.0/24
PersistentKeepalive = 25

The principle is very simple and you will need:

  • private key + public key per site
  • a VPN address space
  • an FQDN for the main devices (DDNS approach is completely acceptable)
  • your LANs address space
  • any optional parameter


FIXME
TODO:

  • troubleshooting via wg (e.g. wg show all dump) and router command
  • integration with tinc
  • nat and keepalives
  • ip addressing
  • keys creation
  • script and iptables/ip route implications
  • jffs best option for the scripts
  • firewall script best option to run but internet must be up:
until [ $(ping -c 1 -A -W 5 -q google.com &>/dev/null && echo 1 || echo 0) -eq 1 ]; do sleep 5; done; /jffs/wg.sh
wireguard_on_freshtomato.1676276878.txt.gz · Last modified: by rs232