A fast install of clean OpenWrt + WireGuard. "How to"

This is a "How To" for my install process when it comes to WireGuard on OpenWRT 19.07.0. This is as much tech notes for my self as documentation for others. This is written for an intermediate to advanced Linux user. I don't take any responsibility if you nuke your data/vm/server/house/planet/etc. You have been warned!

Three major parts to this "How to"

  1. VM stuffs for ProxMox, but also applies to other hypervisors (QEMU/KVM)
  2. Cleaning up a stock install of OpenWRT to only support WireGuard
  3. Wireguard. I have 3 different ways to get WireGuard up and functional, just depending on your style. UCI, Manual, Hacking the network config

VM Specs:
2X vCPU
64MB RAM (Needs about 40MB, in theory could run on 32MB)
64MB disk (ide)
1 NIC (virtro)

Building an OpenWRT VM
For "raw" type disks
wget http://downloads.openwrt.org/releases/19.07.0-rc2/targets/x86/64/openwrt-19.07.0-rc2-x86-64-combined-squashfs.img.gz
losetup /dev/loop0 vm-103-disk-0.raw
zcat openwrt-18.06.1-x86-64-combined-squashfs.img.gz > /dev/loop0
losetup -d /dev/loop0

For "qcow2" type disks
modprobe nbd max_part=8
qemu-nbd --connect=/dev/nbd0 vm-103-disk-0.qcow2
wget http://downloads.openwrt.org/releases/19.07.0-rc2/targets/x86/64/openwrt-19.07.0-rc2-x86-64-combined-squashfs.img.gz
zcat openwrt-19.07.0-rc2-x86-64-combined-squashfs.img.gz > /dev/nbd0
qemu-nbd --disconnect /dev/nbd0
rmmod nbd

Turn on your new VM and set the password and IP through the console:
passwd
ifconfig br-lan 192.168.1.123

From here on out, use your favorite SSH client (Putty time!). But move quickly as OpenWRT, by default, has an active DHCP server.

Tweak the LAN setting for your environment /etc/config/network, clean up other crap, if needed
vi /etc/config/network
config interface 'lan'
option type 'bridge'
option ifname 'eth0'
option proto 'static'
option ipaddr '10.1.1.254'
option netmask '255.255.255.0'
option gateway '10.1.1.1'
option ip6assign '60'
option dns '10.1.1.1'

Strip down stock OpenWRT to basically only be a wireguard box
#Yes, run it twice to remove all the luci web interface crap
opkg remove `opkg list-installed | grep luci | awk '{print $1}'` --force-removal-of-dependent-packages --force-remove
opkg remove `opkg list-installed | grep luci | awk '{print $1}'` --force-removal-of-dependent-packages --force-remove
rm -f /etc/config/luci

/etc/init.d/uhttpd disable
opkg remove uhttpd
rm -f /etc/config/uhttpd

/etc/init.d/dnsmasq disable
opkg remove dnsmasq
rm /etc/config/dhcp

#Leave if you want to manage your firewall through UCI
/etc/init.d/firewall disable
opkg remove firewall
rm /etc/config/firewall

/etc/init.d/odhcpd disable
opkg remove `opkg list-installed | grep odhcp | awk '{print $1}'`

opkg update
#This is the QEMU guest agent
opkg install qemu-ga
/etc/init.d/qemu-ga enable
echo "qemu-ga --daemonize -m virtio-serial -p /dev/vport0p1" > /etc/rc.local
reboot

WireGuard time!
First we must install wireguard and generate keys:
opkg update
opkg install wireguard

#Assuming you know how to copy they keys, and use them
#Key genUmask 077
wg genkey | tee server_private_key | wg pubkey > server_public_key
wg genkey | tee client_private_key | wg pubkey > client_public_key

Option 1. Using OpenWRT's UCI interface to setup everything
uci set network.wg0="interface"
uci set network.wg0.proto="wireguard"
uci set network.wg0.private_key="local_privet_key"
uci set network.wg0.listen_port="51820"
(Server) uci add_list network.wg0.addresses="10.1.2.1/32"
(Client) uci add_list network.wg0.addresses="10.1.2.2/32"

uci add network wireguard_wg0
uci set network.@wireguard_wg0[-1].public_key="other_side_public_key"
uci set network.@wireguard_wg0[-1].route_allowed_ips="1"
(Server) uci add_list network.@wireguard_wg0[-1].allowed_ips="10.1.2.2/32"
(Server) uci set network.@wireguard_wg0[-1].endpoint_host="fooA.mywebsite.com"
(Client) uci add_list network.@wireguard_wg0[-1].allowed_ips="10.1.2.1/32"
(Client) uci set network.@wireguard_wg0[-1].endpoint_host="fooB.mywebsite.com"
uci commit network
/etc/init.d/network restart
sleep 2s

Option 2. Manually bringing up a wg0 interface
ip link add wg0 type wireguard
(Server) ip addr add 10.1.2.1/32 dev wg0
(Client) ip addr add 10.1.2.2/32 dev wg0
wg set wg0 listen-port 51820 private-key big_long_local_privet_key_goes_here
ip link set wg0 up
(Server) wg set wg0 peer big_long_other_side_public_key_goes_here allowed-ips 10.1.2.2/32 endpoint fooA.mywebsite.com:51820
(Client) wg set wg0 peer big_long_other_side_public_key_goes_here allowed-ips 10.1.2.1/32 endpoint fooB.mywebsite.com:51820

Option 3. Hacking the config file /etc/config/networking, dont forget to update the IP's for client/server side
config interface 'wg0'
option proto 'wireguard'
option private_key 'big_long_local_privet_key_goes_here'
option listen_port '51820'
list addresses '10.1.2.1/32'

config wireguard_wg0
option public_key 'big_long_other_side_public_key_goes_here'
option route_allowed_ips '1'
list allowed_ips '10.1.2.2/32'
option endpoint_host 'fooB.mywebsite.com'

checking everything worked
wg
interface: wg0
public key: 0ujE2DtcAVOb7pim8buW+b2jFM1Jgpm1TJm00000000=
private key: (hidden)
listening port: 51820

peer: sJuaXx8ysEbl0YvppODWhOGo0n3mJmi1tTpYA000000=
endpoint: 47.48.74.123:51820
allowed ips: 10.1.2.1/32
latest handshake: 22 minutes, 1 second ago
transfer: 1.48 KiB received, 13.24 KiB sent

ping 10.1.2.1 -c2
PING 10.1.2.1 (10.1.2.1): 56 data bytes
64 bytes from 10.1.2.1: seq=0 ttl=64 time=34.996 ms
64 bytes from 10.1.2.1: seq=1 ttl=64 time=30.152 ms

4 Likes

Nice writeup - although I don't understand why you'd like to disable the firewall and do all that manually; OpenWrt has a lot of sane defaults in place.

When you're using a squashfs image (like you are), there's no point in removingg any packages since (squashfs being is read-only). You can do that with the ext4 image though.

Incorrect...unless you intended to give your router 2 IPs?

Nope, you didn't.

Good writeup, save the errors...or maybe I'm confused on which endpoint is which...

I disable/removed the firewall, because I am using this box as a VPN gateway, not a router. My iptables rule set is very small. Basically I just deny all, then accept 51820 (UPD) and 22 (TCP). This is fine for my internal LAN.

Removing packages... It's not about space, it's about potential threat vector. A package installed and running is a rather big threat vector. A package installed, but NOT running provides a minimal attack vector. But uninstalled is no threat.

In the case of the SquashFS image, everything is still accessible in /rom/. So this is not perfect, but will stop most scripts, or more simplistic exploit tools.

As far as IP's go, I updated the netmask (from 24 to 32) in my original post. Yes, I have two IP's on the system. One for LAN traffic (10.1.1.X/24) and the other (10.1.2.X/32) is strictly for the VPN. That stated, I have not played with a single IP setup, yet. Looks like I have something fun to try!

For IP calcification:
Server LAN 10.1.1.254/24
Server VPN 10.1.2.1/32
Server WG allowed IP 10.1.2.2/32

Client LAN 172.26.10.254/24
Client VPN 10.1.2.2/32
Client WG allowed IP 10.1.2.1/32

Eh it's a moot point. One end chooses the IP.

I didn't know WG had a dynamic config; and I thought the Cryptokey routing didn't permit you address both ends with the same IP. My mistake (or the OP must have corrected the add_list network.wg0.addresses="10.1.2.2/24" config problem).