Odd Wireguard behavior making me unable to connect?

The problem:
I cannot get OpenWRT acting as a Wireguard client (interface protonvpn1) to connect to a server/peer. The behavior I observe is:

  • When I have no peers or only disabled peers, the network interface is created, but without peers, it is useless.
  • When I have an enabled peer, the protonvpn1 interface is NOT created, and the UI states Network device is not presentwhile its trying to use the nonexistent device/interface wireguard-protonvpn1. Because of this, I also think the VPN IP isn't getting added to the OS's routing table (ip route). I find its attempt to use a different interface when peers are present to be particularly odd.

What I've tried so far:

  • Reading/following OpenWRT's documentation on wireguard setup.
  • Restarting my OpenWRT device.
  • Configuring using uci commands before running uci commit and service network restart.
  • Configuring using the web interface after installing the luci-proto-wireguard package. I've tried both manual entry as well as uploading the Wireguard config file provided by my VPN provider.
  • Performing a system-wide update of all packages.
  • Running tcpdump -i any port 51820 to see any attempts at VPN traffic (there has been none).
  • Disabling peers (so that the interface comes up) and running the command wg addconf protonvpn1 peer.conf works; a handshake is successful and I am able to verify my IP is the VPN's IP, but this configuration does not persist across restarts of the network service. peer.conf is a copy-paste of the [Peer] section in my VPN provider's supplied config.

Setting up wireguard (via uci) has previously worked for me using an older (and probably snapshot) version of OpenWRT, but something triggered a kernel panic during maintenance a couple of days ago, so I started fresh. The configuration in /etc/config/network looks much the same as what it was previously, but I did not restore from a proper backup.

Other information about my setup:

  • Raspberry Pi 5 Model B Rev 1.0 w/ an Ethernet hat connected via PCIe.
  • OpenWrt 25.12.3 r32912-6639b15f62

Relevant parts of /etc/config/network (populated from uploading my VPN provider's config):

config interface 'protonvpn1'
	option proto 'wireguard'
	option private_key '<redacted>'
	list addresses '10.2.0.2/32'
	list addresses '2a07:b944::2:2/128'
	list dns '10.2.0.1'
	list dns '2a07:b944::2:1'
	option multipath 'off'

config wireguard_protonvpn1
	option description 'Imported peer configuration'
	option public_key '<redacted>'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::/0'
	option persistent_keepalive '25'
	option endpoint_host '<ip>'
	option endpoint_port '51820'

Output from wg showconfig protonvpn1 with no peers enabled:

[Interface]
ListenPort = 56764
PrivateKey = <redacted>

Systemlog after restarting interface with peers enabled:

[May 12, 2026, 12:47:22 AM UTC] daemon.notice: hostapd: Set MLD config: [ ]
[May 12, 2026, 12:47:22 AM UTC] daemon.notice: hostapd: Reload all interfaces
[May 12, 2026, 12:47:22 AM UTC] daemon.notice: wpa_supplicant[850]: Set MLD config: [ ]
[May 12, 2026, 12:47:22 AM UTC] daemon.notice: netifd: Interface 'protonvpn1' is setting up now
[May 12, 2026, 12:47:22 AM UTC] daemon.notice: netifd: Interface 'protonvpn1' is now down
[May 12, 2026, 12:47:22 AM UTC] daemon.notice: netifd: Interface 'protonvpn1' is setting up now
[May 12, 2026, 12:47:22 AM UTC] daemon.notice: netifd: Interface 'protonvpn1' is now down

Syslog after restarting interface with no peers enabled:

[May 12, 2026, 12:49:17 AM UTC] daemon.notice: hostapd: Set MLD config: [ ]
[May 12, 2026, 12:49:17 AM UTC] daemon.notice: hostapd: Reload all interfaces
[May 12, 2026, 12:49:17 AM UTC] daemon.notice: wpa_supplicant[850]: Set MLD config: [ ]
[May 12, 2026, 12:49:17 AM UTC] daemon.notice: netifd: Network device 'protonvpn1' link is down
[May 12, 2026, 12:49:18 AM UTC] daemon.notice: netifd: Interface 'protonvpn1' is now down
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto
[May 12, 2026, 12:49:18 AM UTC] daemon.notice: netifd: Interface 'protonvpn1' is setting up now
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using nameserver 1.1.1.1#53
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using nameserver 1.1.1.1#53
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for test
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for onion
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for localhost
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for local
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for invalid
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for bind
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for lan
[May 12, 2026, 12:49:18 AM UTC] daemon.notice: netifd: Interface 'protonvpn1' is now up
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto
[May 12, 2026, 12:49:18 AM UTC] daemon.notice: netifd: Network device 'protonvpn1' link is up
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using nameserver 1.1.1.1#53
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using nameserver 10.2.0.1#53
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using nameserver 2a07:b944::2:1#53
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using nameserver 1.1.1.1#53
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for test
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for onion
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for localhost
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for local
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for invalid
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for bind
[May 12, 2026, 12:49:18 AM UTC] daemon.info: dnsmasq[1]: using only locally-known addresses for lan
[May 12, 2026, 12:49:18 AM UTC] user.notice: firewall: Reloading firewall due to ifup of protonvpn1 (protonvpn1)

First you have to enable Route allowed IP's in the peer section.

But there seems more amiss as there is no connection shown.

How I setup WireGuard see:
WireGuard Client Setup Guide

It will also help if we see more of your config, please connect to your OpenWRT device using ssh and copy the output of the following commands and post it here using the "Preformatted text </> " button

Remember to redact keys, passwords, MAC addresses and any public IP addresses you may have but do not redact private RFC 1918 IP addresses (192.168.X.X, 10.X.X.X and 172.16-32.X.X) as that is not needed:

ubus call system board
cat /etc/config/network
cat /etc/config/dhcp
cat /etc/config/firewall
ip route show
ip -6 route show
wg show
  • How are you "enabling" and "disabling" the peer?
  • Why are you looking for an interface that lacks peers?
  • How are you restarting the interface?
  • Have you tried rebooting the router instead?

(After successfully troubleshooting, you may want to work on adding and removing the 0.0.0.0/0 and ::0/0 routes using the LuCI web GUI if you need to enable or disable the VPN. This is an alternative to the "Route Allowed IPs" setting in the Wireguard configuration.)

In this scenario of routing out the whole Internet via Wireguard, there can only be one peer enabled at a time. When there are multiple peers on the same interface, their allowed_ips cannot overlap. That is not possible if a peer has allowed_ip /0.

You could connect to multiple Proton servers simultaneously by using multiple Wireguard interfaces with one peer each. Then you can use conditional routing to decide which one is used in a particular case. In that case do not set route_allowed_ips on any of them and use pbr etc. to set up the routing. Obviously this is an advanced configuration that should only be attempted after having a single server work first.

How are you "enabling" and "disabling" the peer?
Via the UI which just adds option disabled '1' to the peer's config in /etc/config/network.

Why are you looking for an interface that lacks peers?
I'm not! I want it to have a peer to route all traffic through. This was just something I found while trying to troubleshoot.

How are you restarting the interface?
Via the UI. Which seems to essentially run ifup/ifdown.

Have you tried rebooting the router instead?
One of the first thing I tried. :smiling_face_with_tear:

I'm not looking to have multiple peers. It's just a grammatical choice for me to say "peers" instead of "a peer". I ultimately want to route all of 0.0.0.0/0 through a single peer.

ubus call system board

{
	"kernel": "6.12.85",
	"hostname": "OpenWrt",
	"system": "ARMv8 Processor rev 1",
	"model": "Raspberry Pi 5 Model B Rev 1.0",
	"board_name": "raspberrypi,5-model-b",
	"rootfs_type": "ext4",
	"release": {
		"distribution": "OpenWrt",
		"version": "25.12.3",
		"firmware_url": "https://downloads.openwrt.org/",
		"revision": "r32912-6639b15f62",
		"target": "bcm27xx/bcm2712",
		"description": "OpenWrt 25.12.3 r32912-6639b15f62",
		"builddate": "1777933845"
	}
}

cat /etc/config/network Note: my OpenWRT router (192.168.2.0/24) sits within my larger apartment/home network (192.168.1.0/24). So it goes ISP -> apartment network -> OpenWRT network.

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	list ipaddr '127.0.0.1/8'

config globals 'globals'
	option dhcp_default_duid '00044dd77ac730724927999877a400fc9954'
	option ula_prefix 'fd07:37b4:8360::/48'
	option packet_steering '1'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'eth0'
	option ipv6 '0'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ip6assign '60'
	list ipaddr '192.168.2.1/24'
	option multipath 'off'

config interface 'wan'
	option proto 'static'
	option device 'eth1'
	option ipaddr '192.168.1.24'
	option netmask '255.255.255.0'
	option multipath 'off'
	list dns '1.1.1.1'

config device
	option name 'eth1'
	option ipv6 '0'

config interface 'protonvpn1'
	option proto 'wireguard'
	option private_key '<redacted>'
	list addresses '10.2.0.2/32'
	list addresses '2a07:b944::2:2/128'
	option multipath 'off'

config wireguard_protonvpn1
	option description 'Imported peer configuration'
	option public_key '<redacted>'
	list allowed_ips '0.0.0.0/0'
	list allowed_ips '::/0'
	option persistent_keepalive '25'
	option endpoint_host '<redacted>'
	option endpoint_port '51820'
	option disabled '1'

cat /etc/config/dhcp. I don't believe I've ever modified this.

config dnsmasq
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/lan/'
	option domain 'lan'
	option expandhosts '1'
	option cachesize '1000'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
	option localservice '1'
	option ednspacket_max '1232'

config dhcp 'lan'
	option interface 'lan'
	option start '100'
	option limit '150'
	option leasetime '12h'
	option dhcpv4 'server'
	option dhcpv6 'server'
	option ra 'server'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'
	option ra_preference 'medium'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'
	option leasetime '12h'
	option start '100'
	option limit '150'

config odhcpd 'odhcpd'
	option maindhcp '0'
	option leasefile '/tmp/odhcpd.leases'
	option leasetrigger '/usr/sbin/odhcpd-update'
	option loglevel '4'
	option piodir '/tmp/odhcpd-piodir'
	option hostsdir '/tmp/hosts'

cat /etc/config/firewall. I try to deny by default before opening up need routes. It is the only hold over from my previous install of OpenWRT. The only thing that's been removed was the zone + rules that allowed all public internet traffic to flow through my wireguard VPN. it was removed during debugging, but I saw no difference in behavior having it vs not having it.

config defaults
	option input 'DROP'
	option output 'DROP'
	option forward 'DROP'
	option synflood_protect '1'

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

config zone
	option name 'wan'
	option input 'DROP'
	option output 'DROP'
	option forward 'DROP'
	option mtu_fix '1'
	option masq '1'
	list network 'wan'

config rule
	option dest '*'
	option name 'allow-output-ping'
	list proto 'icmp'
	option target 'ACCEPT'

config rule
	option dest '*'
	option name 'allow-output-udp-common'
	option dest_port '53 67-68 123'
	option target 'ACCEPT'
	list proto 'udp'

config rule
	option dest '*'
	option name 'allow-output-tcp-common'
	list proto 'tcp'
	option dest_port '22 23 53'
	option target 'ACCEPT'

config rule
	option dest 'wan'
	option name 'allow-output-apartment'
	list proto 'all'
	list dest_ip '192.168.1.0/24'
	option target 'ACCEPT'

config rule
	option dest 'wan'
	option name 'allow-output-wan-wireguard'
	list proto 'udp'
	option dest_port '51820'
	option target 'ACCEPT'

config include
	option path '/etc/firewall.user'

config rule
	option dest '*'
	option name 'allow-forward-ping'
	list proto 'icmp'
	option target 'ACCEPT'
	option src '*'

config rule
	option dest '*'
	option name 'all-forward-udp-common'
	option dest_port '53 67-68 123'
	option target 'ACCEPT'
	list proto 'udp'
	option src '*'

config rule
	option dest '*'
	option name 'allow-forward-tcp-common'
	list proto 'tcp'
	option dest_port '22 23 53'
	option target 'ACCEPT'
	option src '*'

config rule
	option src 'lan'
	option dest 'wan'
	option name 'allow-lan-to-apartment'
	list proto 'all'
	list dest_ip '192.168.1.0/24'
	option target 'ACCEPT'

config rule
	option src 'wan'
	option name 'allow-input-apartment'
	list proto 'all'
	list src_ip '192.168.1.0/24'
	option target 'ACCEPT'

config rule
	option src 'wan'
	option dest 'lan'
	option name 'allow-forward-aprtment'
	list proto 'all'
	list src_ip '192.168.1.0/24'
	option target 'ACCEPT'

config rule
	option dest 'wan'
	option name 'allow-output-apk'
	list proto 'tcp'
	option dest_port '80 443'
	option target 'ACCEPT'

ip route show

ip route show
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.24 
192.168.2.0/24 dev br-lan proto kernel scope link src 192.168.2.1 

ip -6 route show

unreachable fd07:37b4:8360::/48 dev lo proto static metric 2147483647 pref medium

wg show shows nothing (peer is enabled, see the second bullet point in my original post for more background).

Enable "Route Allowed IPs" as mentioned previously.

Is this an IP or hostname?

You're missing the gateway here:

You've changed the defaults in the firewall which will prevent any routing from functioning:

And likewise, no traffic can get in or out because you've changed this:

In fact... as we look through the firewall file, we can see that you've entirely removed all of the standard/default stuff and replaced it with a bunch of stuff that appears to be mostly invalid.

What are you trying to achieve with the firewall??

It does not look like you peer is enabled, not that it matters as there really is a lot you need to address as others already pointed out.

This seems to be the missing piece! Adding the gateway as well as having use default gateway enabled for my wan adds a default route which then protonvpn1 can use to route to its peer.

I was under the assumption that having no host routes disabled on the protonvpn1 interface was sufficient to have it update the routing table, but it couldn't since it has no knowledge of which gateway to use. And of course, enabling route allowed IPs on the peer also updates the route table appropriately once connected.

I did not expect OpenWRT to fail the way it did though. Without the route, it tried to use a whole other interface rather than making a good faith effort to send packets to an unrouteable IP.

I know with with a previous VPN provider on my last run with OpenWRT, I had added a static route to the peer. Perhaps I likely carried that over that pattern when I switched to ProtonVPN, or maybe I had manually added the gateway at some point, and it worked :sparkles: magically :sparkles: when I first set it up.


My firewall setup is valid, functional, and allows traffic. The fact that I'm able to SSH or access the web UI is proof of that. It is meant to be deny/drop by default. The input/output/forward chains being set to DROP is the default, but the default only applies if there isn't an existing ACCEPT rule in the firewall.

Also, this is a valid configuration if you want to force all public traffic through your VPN: https://openwrt.org/docs/guide-user/services/vpn/wireguard/all-traffic-through-wireguard#example_configuration