This is an old revision of the document!
Wireguard is a revolutionary VPN technology that allows the fastest throughput and lowest latency compared to other traditional VPN technologies.
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.
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
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]
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:
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:
You will need some permanent storage to have the settings surviving a reboot. In this sense you have multiple options like:
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.
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
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:
TODO:
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