[Solved] WireGuard Client with Double NAT

I'm trying to configure a Wireless Router running OpenWRT, with a WireGuard Client configured to connect to a Wireguard Server running on my home network.

I searched the forum before posting - and saw some similar queries - but they were either not in a double-NAT configuration - or the solution to their issue, didn't seem applicable to my scenario.

My goal is to be able to take this router to our cottage (or anywhere else) and simply plug it into their router and have a dedicated Access Point that provides access to my home network to any device that joins it. (I'm not looking to complicate this further with split-tunnelling. Each device at the cottage will join either the cottage network, or the home network and they do not ever need to talk to each other.)

I've got a working Wireguard Server that I've tested using iPhone's and iPads on public (LTE) and private (WiFi) networks - but after following the Wireguard instructions for configuring the OpenWRT router (several Tims), I can't make it work. I'm not sure if I've done something wrong (repeatedly), missed a step (repeatedly) - or if it's the dual NAT translation that is causing the problem.

I'm running OpenWRT with the WireGuard Client installed on a TPLINK Archer C50 Wifi Router:

  • All of the configuration has been done via LuCi
  • I deleted the WAN6 interface hoping to remove one variable from the equation.
  • I configured the WAN interface to get an IP via DHCP. It gets 192.168.0.55
  • The LAN interface is configured with a 192.168.22.0/24 network and presents an SSID of "REMOTEVPN". A DHCP server is running to hand out 192.168.22.x IP addresses.
  • The WireGuard Client is installed - and configured by importing a .conf file generated by the Wireguard server

Note: At this point, before I change any Firewall rules, this access point does work. Devices that connect to the "REMOTEVPN" wifi network are able to browse the internet successfully.

However, after I change the firewall rules as per the Wireguard instructions for OpenWRT - and I set the Cost Metrics on the WAN (to 20) and VPN (to 10) - nothing works.

  • The Status page for Wireguard shows the correct Peer values, but "Last Handshake" is "Never"
  • The VPN Interface shows a few bytes for Tx, but 0kb for Rx

I admit that I do not understand many of the options/settings on the Interface and Firewall configuration pages - so I didn't adjust anything the instructions didn't tell me to adjust.

So - after all that - I guess what I'm here to ask - is SHOULD this configuration work? Or is the double-NAT likely what's causing my problem? And secondly, if this indeed should work, does anyone have any suggestions on how best to find and fix whatever it is that I've done wrong?

Thanks.

let's start by looking at your config files on OpenWrt.

Please copy the output of the following commands and post it here using the "Preformatted text </> " button:
grafik
Remember to redact passwords, MAC addresses and any public IP addresses you may have:

cat /etc/config/network
cat /etc/config/firewall

Thanks for the reply. I assume that means that what I'm trying to do should be possible!

Here is the command output you requested (with MAC addresses and DNS aliases partially redacted):

cat /etc/config/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 'fd30:b5cc:xxxx::/48'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'eth0.1'

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

config device
        option name 'eth0.2'
        option macaddr 'd8:0d:17:xx:xx:xx'

config interface 'wan'
        option device 'eth0.2'
        option proto 'dhcp'
        option metric '20'

config switch
        option name 'switch0'
        option reset '1'
        option enable_vlan '1'

config switch_vlan
        option device 'switch0'
        option vlan '1'
        option ports '1 2 3 4 6t'

config switch_vlan
        option device 'switch0'
        option vlan '2'
        option ports '0 6t'

config interface 'VPN'
        option proto 'wireguard'
        option private_key 'GAYLleane9zzfNonrsiMDXkjJBmmn2sF9nPfmxxxxxx='
        option listen_port '51820'
        list addresses '10.13.13.3'
        option peerdns '0'
        option metric '10'
        list dns '1.1.1.1'

config wireguard_VPN
        option description 'Imported peer configuration'
        option public_key 'f9a4w3/K7GK0O8l6EQEopB5+tu/wpGPO+Zkkgxxxxxx='
        option preshared_key 'C/hB6XLMo8rWF2LqSCionVYkDgi5/FWozIiTgxxxxxx='
        list allowed_ips '0.0.0.0/0'
        list allowed_ips '::/0'
        option endpoint_host 'ec190exxxxxx.sn.mynetname.net'
        option endpoint_port '51820'

cat /etc/config/firewall:

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

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

config zone
        option name 'wan'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option masq '1'
        option mtu_fix '1'
        list network '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'

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 'fexx::/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
        option name 'VPN'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option masq '1'
        option mtu_fix '1'
        list network 'VPN'

config forwarding
        option src 'lan'
        option dest 'VPN'

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

Remove the listen_port from below.
You can also delete the dns lines because they don't actually do anything there.

Everything else looks okay in general.
Once you fix those things, restart the router and try to start the wireguard interface. Then let's see what you get from:

wg show

Removed the listen port
Removed the DNS

root@OpenWrt:~# wg show:

interface: VPN
  public key: ZtEPlv5vxMWMHgn5TXjK3ptuutvhZGKDpl9rnxxxxxx=
  private key: (hidden)
  listening port: 54514

peer: f9a4w3/K7GK0O8l6EQEopB5+tu/wpGPO+Zkkgxxxxxx=
  preshared key: (hidden)
  endpoint: 70.54.xx.xxx:51820
  allowed ips: 0.0.0.0/0, ::/0
config interface 'VPN'
        option proto 'wireguard'
        option private_key 'GAYLleane9zzfNonrsiMDXkjJBmmn2sF9nPfmxxxxxx='
        list addresses '10.13.13.3'
        option peerdns '0'
        option metric '10'

The Wireguard Interface started automatically - but Rx and Tx are both showing 0 and the Status/Wireguard screen still shows "Latest Handshake: Never"

Try to ping the house server's public IP from the router. (If you're testing this client while it is connected to the house LAN instead of an independent Internet connection, it generally will not work).

NAT is not an issue for the client, as it makes an outgoing connection it can go through multiple layers of NAT.

Check the keys again. The public key of the client (the first key shown with the wg command on the client) must be enrolled in a peer section of the server. The server's public key must be enrolled in the peer section of the client. Private keys are only stored on the single machine that uses them, and can't be reused (each Wireguard instance must have a unique public/private key pair.) If you also use preshared keys they must match in each peer section. The same preshared key can be reused.

Thanks for your reply.

I do have the router at home now - but I think I enabled hairpin NAT a while back - so I think it should work. In any case, I have tested it at a remote location and observed the same behaviour I’m seeing today. I can ping the DNS name that I’m using in the configuration (from the router itself as well as from my MacBook) and it resolves correctly to my Public IP - and I get a successful reply. Having said all that - you may be right - and I may not be able to properly test it from this location.

I’m running the WireGuard server on my Asus Lockerstor in a Docker container. I had it generate config files for 5 peers. The one I’ve used to configure the router has not been used anywhere else. I simply pasted the contents of the config file into the “Load Configuration” box on the Interface creation screen - and it took care of configure the interface and the peer - so I don’t think there could possibly be a problem with the keys.

As I mentioned in my original post, I am able to connect to the server from my iPhone from a remote location - so that validates that I’ve set up the port forwarding properly and that the server itself is operational.

This usually works as expected, but don't assume the keys are working properly... An easy way to test this would be to import that configuration into your phone (alongside your known good config)... if it connects, that means the keys are good. But if not, obviously that could explain the issue. Alternatively, you could try the config from your phone on the router. That said, obviously only attempt to connect one device at a time if you've got the same keys/config on multiple devices.

Can you test your phone's ability to connect from the same network that you're trying to connect your OpenWrt router?

Nope. It seems that mk24 was right that I can't test it properly from my own network. But the only reason the router is here on my own network at the moment is that it did not work on the remote network. So unless those 2 changes you asked me to make at the beginning were the problem, its still broken.

I did import the conf file from the router to my phone - turned off Wi-Fi and tried to connect with it while on LTE - and it does work - so we can rule out a problem with the keys.

I will be able to test the router again from a remote location on Monday evening - but if I get impatient, maybe I'll spin up a server on AWS and install the Wireguard Server there so that I can test properly from home.

So - until then - thank your for your suggestions and for reviewing my configuration. I'll report back Monday night after testing to let you know whether those changes you suggested fixed the problem or not!

another test you can run while you are on your home network (with the WG 'server')...

Replace the endpoint host in the remote/travel router with the address of your server on your home lan (i.e. the Asus Lokerstor/Docker address). This will allow a direct connection while on your lan -- if it connects, your system is working properly. If not... time to look deeper.

Also, check the clock on your 'remote' router -- if the WG interface is set ot start at boot, the clock may not be in sync. This will cause the WG connection to be impossible to establish, but with a chicken or egg situation regarding internet access to set the time. If this turns out to be the issue, there is a solution for it -- waiting for succesful NTP sync before starting the WG interface.

Okay - I got an AWS Amazon Linux 2 instance up and configured with Wireguard a lot faster than I expected. I generated 2 peer configs and applied 1 to my phone and the other to the OpenWRT Router and I'm in exactly the same boat. The phone works and the router doesn't.

So - now that I have an environment I can test against from here - is there anything else we can look at?

As far as your thoughts about the clock - if that were the issue, wouldn't it also prevent the iPhone from establishing a connection?

Alright - it's 4:30 am here and I'm giving up for the night - however I might have made a bit of progress - but I'm not sure.

I was poking around in the interface settings on the Peer tab and I noticed there was a Keepalive value set to 0 and a comment beside it saying they recommended setting it to 25 if behind a NAT. So I changed it to 25, saved it and restarted the Wireguard interface - and I now see a few bytes for Rx and Tx! I checked the status page and I now see a value for "Latest Handshake" which is updating every 2 minutes or so.

That looked promising so I connected my phone to the Access Point - but for some reason it connected me to my home network (not to Amazon). I thought maybe the Gateway Metric settings weren't being honoured, so I removed the WAN as a forwarding option from the Lan Firewall (leaving only the VPN) - but that resulted in no connectivity at all so I put it back.

Does any of this spark any ideas as to what might be going wrong? Really seems like a routing problem - but I don't know exactly what and I can't think of any more things to try tonight.

@tenii4
What is this reply about? All it is, is a rewording of the 2nd paragraph in my previous message. I don't understand why you did that. Did you mean to type something else in addition to that?

@psherman I got it!
There was another (optional) setting on the "Peers" tab named "Route Allowed IP's" that was off by default. I turned it on, re-tested and it's now working perfectly (to the AWS server).

So, to summarize:
- I removed the listen_port and dns_lines from the Wireguard Interface configuration (as you suggested)
- I modified the Peer configuration of the Wireguard Interface:
  - Changed the Keepalive value from 0 to 25
  - Enabled the "Route Allowed IP's" option
- Then I restarted and retested and it's all working as expected!

Thank you so much for all of your assistance yesterday.
(All this effort just so I can watch Netflix at home AND at the cottage without having to pay an extra $8 per month :roll_eyes: )

You’re welcome. Glad it is working now.

If your problem is solved, please consider marking this topic as [Solved]. See How to mark a topic as [Solved] for a short how-to.

@psherman Hey - one last thing before I let this topic auto-close...

I just wanted to record here that your suggestion to replace the public DNS alias of my home lan (on the Peer configuration tab) with the internal IP address of my Wireguard Server did work. It allowed me to test the wireguard connection to my home, from my home (without having to enable hairpin NAT). That's a useful tip for anyone else trying to troubleshoot in a similar environment.

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