I’m trying to get a roadwarrior Wireguard VPN setup on my VyOS router but I don’t get very far and suspect I have a routing/firewall/VLAN issue. I only get UDP packets arriving on my WAN interface, but they’re not forwarded/routed to my wg0
Wireguard interface. Any ideas? Help would be much appreciated
I’m using Wireguard on iOS as test client, and this is what I get:
vyos@vyos# sudo tcpdump -nnti eth1.300 dst port 51820
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth1.300, link-type EN10MB (Ethernet), snapshot length 262144 bytes
IP 123.123.123.123.41138 > 234.234.234.234.51820: UDP, length 148
IP 123.123.123.123.41138 > 234.234.234.234.51820: UDP, length 148
IP 123.123.123.123.41138 > 234.234.234.234.51820: UDP, length 148
I don’t get any Wireguard traffic on wg0
. My Wireguard setup is quite boring:
interfaces {
wireguard wg0 {
address 172.17.50.1/24
description Roadwarrior
peer trombone {
allowed-ips 172.17.50.100/32
persistent-keepalive 15
preshared-key ****************
public-key ****************
}
port 51820
private-key ****************
}
}
I have a zone-based firewall where wg0
is part of ‘Trusted’:
| | to Local | to Infra | to Trusted | to Guest | to IoT | to WAN |
|-------|--------------|----------------|-----------------|-------------------|-----------|-----------|
| Local | | FW_ACCEPT | FW_ACCEPT | FW_ACCEPT | FW_ACCEPT | FW_ACCEPT |
| Infra | FW_ACCEPT | | FW_ACCEPT | FW_ACCEPT | FW_ACCEPT | FW_ACCEPT |
| Trust.| FW_2LOCAL | FW_TRUST2INFRA | | FW_ACCEPT | FW_ACCEPT | FW_ACCEPT |
| Guest | FW_2LOCAL | FW_DROP | FW_GUEST2TRUST | | FW_DROP | FW_ACCEPT |
| IoT | FW_2LOCAL | FW_IOT2INFRA | FW_DROP | FW_DROP | | FW_DROP |
| WAN | FW_WAN2LOCAL | FW_WAN2INFRA | FW_WAN2ALL | FW_WAN2ALL | FW_DROP | |
The only relevant Wireguard part of the firewall is FW_WAN2LOCAL
where I try to accept Wireguard traffic.
firewall {
name FW_WAN2LOCAL {
default-action drop
enable-default-log
rule 200 {
action accept
description "accept established/related"
state {
established enable
related enable
}
}
rule 210 {
action accept
description wireguard
destination {
port 51820
}
protocol udp
}
}
}
Adding an allow rule for Wireguard to FW_WAN2ALL
(because wg0 is part of ‘Trusted’) didn’t seem to work.
My network is VLAN-aware and bridged over eth0
:
interfaces {
bridge br100 {
enable-vlan
member {
interface eth0 {
allowed-vlan 10
allowed-vlan 20
allowed-vlan 30
allowed-vlan 40
}
}
stp
vif 10 {
address 172.17.10.1/24
description VLAN1-Infra
}
vif 20 {
address 172.17.20.1/24
description VLAN20-Trusted
}
vif 30 {
address 172.17.30.1/24
description VLAN30-Guest
}
vif 40 {
address 172.17.40.1/24
description VLAN40-IoT
}
}
ethernet eth0 {
description LAN
}
ethernet eth1 {
vif 300 {
address dhcp
description "T-Mobile WAN"
}
}
loopback lo {
}
wireguard wg0 {
address 172.17.50.1/24
description Roadwarrior
peer tim {
allowed-ips 172.17.50.100/32
persistent-keepalive 15
preshared-key ****************
public-key ****************
}
port 51820
private-key ****************
}
}
My full configuration is as follows (some details omitted):
vyos@vyos:~$ cat vyos_config.json
firewall {
name FW_2LOCAL {
default-action drop
rule 200 {
action accept
description "accept established/related"
log disable
state {
established enable
related enable
}
}
rule 210 {
action accept
description "accept dhcp"
destination {
port 67-68
}
log disable
protocol udp
}
rule 220 {
action accept
description "accept dns"
destination {
port 53
}
log disable
protocol udp
}
}
name FW_ACCEPT {
default-action accept
rule 200 {
action drop
description "drop invalid"
state {
invalid enable
}
}
}
name FW_DROP {
default-action drop
}
name FW_GUEST2TRUST {
default-action drop
rule 200 {
action accept
description "accept established/related"
log disable
state {
established enable
related enable
}
}
}
name FW_IOT2INFRA {
default-action drop
rule 200 {
action accept
description "accept established/related"
log disable
state {
established enable
related enable
}
}
}
name FW_TRUST2INFRA {
default-action drop
rule 200 {
action accept
description "accept established/related"
log disable
state {
established enable
related enable
}
}
}
name FW_WAN2ALL {
default-action drop
rule 200 {
action accept
description "accept established/related"
state {
established enable
related enable
}
}
}
name FW_WAN2INFRA {
default-action drop
rule 200 {
action accept
description "accept established/related"
state {
established enable
related enable
}
}
rule 210 {
action accept
description "accept port forwards"
destination {
port 22,80,443,1883
}
log enable
protocol tcp
state {
new enable
}
}
}
name FW_WAN2LOCAL {
default-action drop
enable-default-log
rule 200 {
action accept
description "accept established/related"
state {
established enable
related enable
}
}
rule 210 {
action accept
description wireguard
destination {
port 51820
}
protocol udp
}
}
zone GUEST {
default-action drop
from INFRA {
firewall {
name FW_DROP
}
}
from IOT {
firewall {
name FW_DROP
}
}
from LOCAL {
firewall {
name FW_ACCEPT
}
}
from TRUSTED {
firewall {
name FW_ACCEPT
}
}
from WAN {
firewall {
name FW_WAN2ALL
}
}
interface br100.30
}
zone INFRA {
default-action drop
from GUEST {
firewall {
name FW_DROP
}
}
from IOT {
firewall {
name FW_IOT2INFRA
}
}
from LOCAL {
firewall {
name FW_ACCEPT
}
}
from TRUSTED {
firewall {
name FW_TRUST2INFRA
}
}
from WAN {
firewall {
name FW_WAN2INFRA
}
}
interface br100.10
}
zone IOT {
default-action drop
from GUEST {
firewall {
name FW_DROP
}
}
from INFRA {
firewall {
name FW_ACCEPT
}
}
from LOCAL {
firewall {
name FW_ACCEPT
}
}
from TRUSTED {
firewall {
name FW_DROP
}
}
from WAN {
firewall {
name FW_DROP
}
}
interface br100.40
}
zone LOCAL {
default-action drop
from GUEST {
firewall {
name FW_2LOCAL
}
}
from INFRA {
firewall {
name FW_ACCEPT
}
}
from IOT {
firewall {
name FW_2LOCAL
}
}
from TRUSTED {
firewall {
name FW_2LOCAL
}
}
from WAN {
firewall {
name FW_WAN2LOCAL
}
}
local-zone
}
zone TRUSTED {
default-action drop
from GUEST {
firewall {
name FW_GUEST2TRUST
}
}
from INFRA {
firewall {
name FW_ACCEPT
}
}
from IOT {
firewall {
name FW_DROP
}
}
from LOCAL {
firewall {
name FW_ACCEPT
}
}
from WAN {
firewall {
name FW_WAN2ALL
}
}
interface br100.20
interface wg0
}
zone WAN {
default-action drop
from GUEST {
firewall {
name FW_ACCEPT
}
}
from INFRA {
firewall {
name FW_ACCEPT
}
}
from IOT {
firewall {
name FW_DROP
}
}
from LOCAL {
firewall {
name FW_ACCEPT
}
}
from TRUSTED {
firewall {
name FW_ACCEPT
}
}
interface eth1.1
interface eth1.300
}
}
interfaces {
bridge br100 {
enable-vlan
member {
interface eth0 {
allowed-vlan 10
allowed-vlan 20
allowed-vlan 30
allowed-vlan 40
}
}
stp
vif 10 {
address 172.17.10.1/24
description VLAN1-Infra
}
vif 20 {
address 172.17.20.1/24
description VLAN20-Trusted
}
vif 30 {
address 172.17.30.1/24
description VLAN30-Guest
}
vif 40 {
address 172.17.40.1/24
description VLAN40-IoT
}
}
ethernet eth0 {
description LAN
}
ethernet eth1 {
vif 300 {
address dhcp
description "T-Mobile WAN"
}
}
loopback lo {
}
wireguard wg0 {
address 172.17.50.1/24
description Roadwarrior
peer trombone {
allowed-ips 172.17.50.100/32
persistent-keepalive 15
preshared-key ****************
public-key ****************
}
port 51820
private-key ****************
}
}
nat {
destination {
rule 100 {
description "Port Forward: SSH to 172.17.10.2"
destination {
port 22
}
inbound-interface eth1.300
protocol tcp
translation {
address 172.17.10.2
}
}
rule 102 {
description "Port Forward: HTTP to 172.17.10.2"
destination {
port 80
}
inbound-interface eth1.300
protocol tcp
translation {
address 172.17.10.2
}
}
rule 104 {
description "Port Forward: HTTPS to 172.17.10.2"
destination {
port 443
}
inbound-interface eth1.300
protocol tcp
translation {
address 172.17.10.2
}
}
rule 106 {
description "Port Forward: MQTT to 172.17.10.2"
destination {
port 1883
}
inbound-interface eth1.300
protocol tcp
translation {
address 172.17.10.2
port 8883
}
}
}
source {
rule 5001 {
description "Exclude roadwarrior VPN"
destination {
address 172.17.50.0/24
}
exclude
outbound-interface eth1.300
protocol all
translation {
address masquerade
}
}
rule 5010 {
description "Masquerade for WAN"
outbound-interface eth1.300
protocol all
source {
address 172.17.0.0/16
}
translation {
address masquerade
}
}
}
}
qos {
interface eth1.300 {
egress WAN_QUEUE
}
policy {
shaper WAN_QUEUE {
bandwidth 100mbit
class 10 {
bandwidth 10%
match dns {
ip {
source {
port 53
}
}
}
match icmp {
ip {
protocol icmp
}
}
priority 1
queue-type fq-codel
}
default {
bandwidth 95%
queue-type fq-codel
}
}
}
}
service {
dhcp-server {
shared-network-name vlan10 {
authoritative
subnet 172.17.10.0/24 {
default-router 172.17.10.1
domain-name lan.mydomain.com
name-server 172.17.10.1
range vlan10range {
start 172.17.10.100
stop 172.17.10.254
}
static-mapping gs108e {
ip-address 172.17.10.3
mac-address 78:D2:94:2F:81:F8
}
static-mapping philips-hue {
ip-address 172.17.10.21
mac-address 00:17:88:79:93:47
}
static-mapping uap-lr1-floor1 {
ip-address 172.17.10.10
mac-address 18:E8:29:93:E1:66
}
static-mapping uap-lr2-floor2 {
ip-address 172.17.10.11
mac-address 18:E8:29:E6:00:2E
}
}
}
shared-network-name vlan20 {
authoritative
subnet 172.17.20.0/24 {
default-router 172.17.20.1
domain-name lan.mydomain.com
name-server 172.17.20.1
range vlan20range {
start 172.17.20.100
stop 172.17.20.254
}
static-mapping appletv-living {
ip-address 172.17.20.20
mac-address D0:03:4B:26:85:0C
}
}
}
shared-network-name vlan30 {
authoritative
subnet 172.17.30.0/24 {
default-router 172.17.30.1
domain-name lan.mydomain.com
name-server 172.17.30.1
range vlan30range {
start 172.17.30.100
stop 172.17.30.254
}
}
}
shared-network-name vlan40 {
authoritative
subnet 172.17.40.0/24 {
default-router 172.17.40.1
domain-name lan.mydomain.com
name-server 172.17.40.1
range vlan40range {
start 172.17.40.100
stop 172.17.40.254
}
}
}
}
dns {
forwarding {
allow-from 172.17.0.0/16
cache-size 100004
dhcp eth1.1
dhcp eth1.300
listen-address 172.17.10.1
listen-address 172.17.20.1
listen-address 172.17.30.1
listen-address 172.17.40.1
listen-address 172.17.50.1
}
}
mdns {
repeater {
interface br100.20
interface br100.30
}
}
ntp {
allow-client {
address 0.0.0.0/0
address ::/0
}
server 0.pool.ntp.org {
}
server 1.pool.ntp.org {
}
}
ssh {
ciphers aes128-cbc
ciphers [email protected]
ciphers aes128-ctr
ciphers [email protected]
ciphers aes192-cbc
ciphers aes192-ctr
ciphers aes256-cbc
ciphers aes256-ctr
ciphers [email protected]
disable-password-authentication
key-exchange curve25519-sha256
key-exchange [email protected]
key-exchange diffie-hellman-group-exchange-sha256
key-exchange diffie-hellman-group14-sha256
key-exchange diffie-hellman-group16-sha512
key-exchange diffie-hellman-group18-sha512
listen-address 172.17.10.1
mac hmac-sha2-256
mac [email protected]
mac hmac-sha2-512
mac [email protected]
}
}
system {
config-management {
commit-revisions 100
}
conntrack {
modules {
ftp
h323
nfs
pptp
sip
sqlnet
tftp
}
}
console {
device ttyS0 {
speed 115200
}
}
domain-name lan.mydomain.com
host-name vyos
login {
user vyos {
authentication {
encrypted-password ****************
plaintext-password ****************
public-keys trombone@neptune {
key ****************
type ssh-rsa
}
}
}
}
name-server 172.17.10.1
static-host-mapping {
host-name grafana.mydomain.com {
inet 172.17.10.2
}
syslog {
global {
facility all {
level info
}
facility local7 {
level debug
}
}
}
}