Wireguard Client Upload Slowness

I have a Linksys WRT1900ACS running OpenWrt 23.05.0.

I have successfully configured Wireguard as both a client and server. Although the client connection works, I'm having issues with upload speed.

Server: I'm running a server so that I can provide access my network to my mobile phone when I'm away from home - that works great.

Client: I'm running a client to connect to a remote site, which I'm serving via a segregated ssid. I'm also serving a standard broadband connection via other ssid's along with a guest network.

The wireguard client connection is having very slow upload speeds. If I run a speed test when connected to the ssid that serves the connection to my remote site, I get download speeds of around 50mbs and upload speeds that are very low that they register as 0mbs on the Google speed test. If I try connecting to the remote site by creating a wireguard connection directly on my laptop, then upload speeds are ~20mbs which is what i'd expect. Therefore think that the problem is somewhere in my setup, rather than a problem on the remote site or with my internet connection.

I've tried doing an iperf from my local machine and it show a small repeatable blip just after starting:

$ ./iperf3 -c 192.168.1.2 -t 180
Connecting to host 192.168.1.2, port 5201
[  4] local 192.168.71.202 port 59186 connected to 192.168.1.2 port 5201
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.01   sec   126 KBytes  1.03 Mbits/sec
[  4]   1.01-2.01   sec  0.00 Bytes  0.00 bits/sec
[  4]   2.01-3.01   sec  0.00 Bytes  0.00 bits/sec
[  4]   3.01-4.01   sec  63.0 KBytes   516 Kbits/sec
[  4]   4.01-5.01   sec  63.0 KBytes   516 Kbits/sec
[  4]   5.01-6.01   sec   126 KBytes  1.03 Mbits/sec
[  4]   6.01-7.01   sec   189 KBytes  1.55 Mbits/sec
[  4]   7.01-8.01   sec   315 KBytes  2.58 Mbits/sec
[  4]   8.01-9.01   sec   567 KBytes  4.65 Mbits/sec
[  4]   9.01-10.00  sec   819 KBytes  6.74 Mbits/sec
[  4]  10.00-11.01  sec  1008 KBytes  8.19 Mbits/sec
[  4]  11.01-12.01  sec  1.17 MBytes  9.80 Mbits/sec
[  4]  12.01-13.01  sec  1.11 MBytes  9.29 Mbits/sec
[  4]  13.01-14.01  sec  1.17 MBytes  9.80 Mbits/sec
[  4]  14.01-15.01  sec  1.17 MBytes  9.81 Mbits/sec
[  4]  15.01-16.02  sec  1.23 MBytes  10.3 Mbits/sec
[  4]  16.02-17.01  sec  1.11 MBytes  9.34 Mbits/sec
[  4]  17.01-18.01  sec  1.23 MBytes  10.3 Mbits/sec
[  4]  18.01-18.84  sec  1.05 MBytes  10.6 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-18.84  sec  12.4 MBytes  5.53 Mbits/sec                  sender
[  4]   0.00-18.84  sec  0.00 Bytes  0.00 bits/sec                  receiver
iperf3: interrupt - the client has terminated

My config is as follows:

root@OpenWrt:/etc/config# cat network

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'xx:xx:xx::/48'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan1'
        list ports 'lan2'
        list ports 'lan3'
        list ports 'lan4'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
        option ip6assign '60'
        list dns '1.1.1.1'
        list dns '8.8.8.8'

config device
        option name 'wan'
        option macaddr 'xx:xx:xx:xx:xx:xx'

config interface 'wan'
        option device 'wan'
        option proto 'pppoe'
        option username 'xxx'
        option password 'xxx'
        option ipv6 'auto'

config interface 'wan6'
        option device 'wan'
        option proto 'dhcpv6'
        option reqaddress 'try'
        option reqprefix 'auto'
        option peerdns '0'
        list dns '1.1.1.1'
        list dns '8.8.8.8'

config device 'guest_dev'
        option type 'bridge'
        option name 'br-guest'

config interface 'guest'
        option proto 'static'
        option device 'br-guest'
        option ipaddr '192.168.3.1/24'

config device
        option type 'bridge'
        option name 'br-wg'
        option bridge_empty '1'

config interface 'wglan'
        option proto 'static'
        option device 'br-wg'
        option ipaddr '192.168.71.1'
        option netmask '255.255.255.0'

config interface 'wgwan'
        option proto 'wireguard'
        option private_key 'xxx='
        list addresses 'x.x.x.x/24'
        option nohostroute '1'
        list dns '192.168.1.3'

config wireguard_wgwan
        option description 'Imported peer configuration'
        option public_key 'xxx'
        option preshared_key 'xxx'
        list allowed_ips '0.0.0.0/0'
        list allowed_ips '::0/0'
        option endpoint_host 'xxx'
        option endpoint_port '51820'
        option persistent_keepalive '25'

config route
        option interface 'wgwan'
        option target '0.0.0.0/0'
        option table '3'

config rule
        option src '192.168.71.0/24'
        option lookup '3'

config interface 'vpn'
        option proto 'wireguard'
        option private_key 'xxx'
        option listen_port '999'
        list addresses '192.168.9.1/24'
        list addresses 'fd00:9::1/64'

config wireguard_vpn 'wgclient'
        option public_key 'xxx'
        option preshared_key 'xxx'
        list allowed_ips '192.168.9.2/32'
        list allowed_ips 'fd00:9::2/128'
        option private_key 'xxx'
        option description 'wg'
root@OpenWrt:/etc/config# cat firewall

config defaults
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option synflood_protect '1'

config zone 'lan'
        option name 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'lan'
        list network 'wglan'
        list network 'vpn'

config zone 'wan'
        option name 'wan'
        option input 'DROP'
        option output 'ACCEPT'
        option forward 'REJECT'
        option masq '1'
        option mtu_fix '1'
        list network 'wan'
        list network 'wan6'
        list network 'wgwan'

config forwarding
        option src 'lan'
        option dest 'wan'

config rule
        option name 'Allow-DHCP-Renew'
        option src 'wan'
        option proto 'udp'
        option dest_port '68'
        option target 'ACCEPT'
        option family 'ipv4'

config rule
        option name 'Allow-Ping'
        option src 'wan'
        option proto 'icmp'
        option icmp_type 'echo-request'
        option family 'ipv4'
        option target 'ACCEPT'
        option enabled '0'

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-DHCPv6'
        option src 'wan'
        option proto 'udp'
        option dest_port '546'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-MLD'
        option src 'wan'
        option proto 'icmp'
        option src_ip 'fe80::/10'
        list icmp_type '130/0'
        list icmp_type '131/0'
        list icmp_type '132/0'
        list icmp_type '143/0'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Input'
        option src 'wan'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        list icmp_type 'router-solicitation'
        list icmp_type 'neighbour-solicitation'
        list icmp_type 'router-advertisement'
        list icmp_type 'neighbour-advertisement'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Forward'
        option src 'wan'
        option dest '*'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-IPSec-ESP'
        option src 'wan'
        option dest 'lan'
        option proto 'esp'
        option target 'ACCEPT'

config rule
        option name 'Allow-ISAKMP'
        option src 'wan'
        option dest 'lan'
        option dest_port '500'
        option proto 'udp'
        option target 'ACCEPT'

config zone 'guest'
        option name 'guest'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        list network 'guest'

config forwarding 'guest_wan'
        option src 'guest'
        option dest 'wan'

config rule 'guest_dns'
        option name 'Allow-DNS-Guest'
        option src 'guest'
        option dest_port '53'
        option proto 'tcp udp'
        option target 'ACCEPT'

config rule 'guest_dhcp'
        option name 'Allow-DHCP-Guest'
        option src 'guest'
        option dest_port '67'
        option proto 'udp'
        option family 'ipv4'
        option target 'ACCEPT'

config rule 'wg'
        option name 'Allow-WireGuard'
        option src 'wan'
        option dest_port '999'
        option proto 'udp'
        option target 'ACCEPT'

Appreciate any help or pointers to help diagnose this issue.

It could be MTU. Set Wireguard MTU to 1320 and test again. Remember to restart Wireguard interface after saving.

Thanks for the quick response. I tried setting the MTU to your suggested value and others, but it didn't appear to make any difference.

I think it must be something in my openwrt setup since I get reasonable upload when creating a tunnel directly from my laptop.

It looks like it was the MTU setting after all - however, not on the wireguard interface, but instead the bridge. The following was the fix:

uci set network.cfg0a0f15.mtu='1380'

Interesting. I’m glad it works now.

Out of curiosity, why is your wg client bridged with some other interface?

It's because I want to expose the wg connection on a segregated ssid away from my standard internet connection.

I haven’t seen such an approach yet. I also have a separate wifi with vpn, but I’m using pbr for that. It would be nice to learn more about your way. Could you post your redacted network and firewall configs?

Full configs available in my first post.

Oops forgot about that and I was too lazy to scroll. I’m thinking setting MTU on br-wg causes all packets forwarded to Wireguard to be smaller, so they fit in your wg tunnel. Weird that setting this on Wireguard interface itself doesn’t work. Maybe it was somehow stuck and full device reboot would make it pick up lower MTU value.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.