Connecting to router behind CGNAT via WireGuard

Sorry, I am still new with this. Here it comes:
Router A (server)

root@OpenWrt1:~# ubus call system board
{
        "kernel": "5.10.176",
        "hostname": "OpenWrt1",
        "system": "x86/64",
        "model": "[redacted]",
        "board_name": "[redacted]",
        "rootfs_type": "ext4",
        "release": {
                "distribution": "OpenWrt",
                "version": "22.03.5",
                "revision": "r20134-5f15225c1e",
                "target": "x86/64",
                "description": "OpenWrt 22.03.5 r20134-5f15225c1e"
        }
}

root@OpenWrt1:~# 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 'fd06:a50f:2d21::/48'

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

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option netmask '255.255.255.0'
        option ip6assign '60'
        option ipaddr '192.168.0.1'

config interface 'wan'
        option device 'eth1'
        option proto 'dhcp'

config interface 'wg_lan'
        option proto 'wireguard'
        option private_key '[redacted]'
        list addresses '10.0.5.1/24'
        option mtu '1420'
        option listen_port '443'

config wireguard_wg_lan
        option public_key '[redacted]'
        option preshared_key '[redacted]'
        option description '1_lan_Alpha'
        list allowed_ips '10.0.5.2/32'
        option route_allowed_ips '1'
        option persistent_keepalive '25'

config wireguard_wg_lan
        option public_key '[redacted]'
        option preshared_key '[redacted]'
        option description '2_lan_Bravo'
        list allowed_ips '10.0.5.3/32'
        option route_allowed_ips '1'
        option persistent_keepalive '25'

config wireguard_wg_lan
        option public_key '[redacted]'
        option preshared_key '[redacted]'
        option description '3_lan_Charlie'
        list allowed_ips '10.0.5.4/32'
        option route_allowed_ips '1'
        option persistent_keepalive '25'

config wireguard_wg_lan
        option public_key '[redacted]'
        option preshared_key '[redacted]'
        option description '4_lan_Delta'
        list allowed_ips '10.0.5.5/32'
        option route_allowed_ips '1'
        option persistent_keepalive '25'

config device
        option name 'eth1'
        option macaddr '[redacted]'

config interface 'guest_wifi'
        option proto 'static'
        option device 'eth0.5'
        option ipaddr '192.168.5.200'
        option netmask '255.255.255.0'

config interface 'iot'
        option proto 'static'
        option ipaddr '192.168.4.200'
        option netmask '255.255.255.0'
        option device 'eth0.4'




root@OpenWrt1:~# cat /etc/config/firewall

config defaults
        option input 'REJECT'
        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'
        list network 'WireGuard'

...and much more.....................................................................



root@OpenWrt1:~# ip route show
default via [redacted] dev eth1 proto static src [redacted]
10.0.5.0/24 dev wg_lan proto kernel scope link src 10.0.5.1
10.0.5.2 dev wg_lan proto static scope link
10.0.5.3 dev wg_lan proto static scope link
10.0.5.4 dev wg_lan proto static scope link
10.0.5.5 dev wg_lan proto static scope link
[redacted]/22 dev eth1 proto kernel scope link src [redacted]
192.168.0.0/24 dev br-lan proto kernel scope link src 192.168.0.1
192.168.4.0/24 dev eth0.4 proto kernel scope link src 192.168.4.200
192.168.5.0/24 dev eth0.5 proto kernel scope link src 192.168.5.200



root@OpenWrt1:~# wg show
interface: wg_lan
  public key: [redacted]
  private key: (hidden)
  listening port: 443

peer: [redacted]
  preshared key: (hidden)
  endpoint: [redacted]
  allowed ips: 10.0.5.5/32
  latest handshake: 1 minute, 54 seconds ago
  transfer: 1.82 KiB received, 2.35 KiB sent
  persistent keepalive: every 25 seconds

peer: [redacted]
  preshared key: (hidden)
  endpoint: [redacted]
  allowed ips: 10.0.5.2/32
  latest handshake: 15 minutes, 10 seconds ago
  transfer: 143.44 KiB received, 3.78 MiB sent
  persistent keepalive: every 25 seconds

peer: [redacted]
  preshared key: (hidden)
  allowed ips: 10.0.5.3/32
  persistent keepalive: every 25 seconds

peer: [redacted]
  preshared key: (hidden)
  allowed ips: 10.0.5.4/32
  persistent keepalive: every 25 seconds


Router B (client):

ubus call system board
{
        "kernel": "5.15.167",
        "hostname": "HostName",
        "system": "x86/64",
        "model": "[redacted]",
        "board_name": "[redacted]",
        "rootfs_type": "ext4",
        "release": {
                "distribution": "OpenWrt",
                "version": "23.05.5",
                "revision": "r24106-10cc5fcd00",
                "target": "x86/64",
                "description": "OpenWrt 23.05.5 r24106-10cc5fcd00"
        }
}
root@HostName:~# 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 '[redacted]'

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

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'

config interface 'wan'
        option device 'eth1'
        option proto 'dhcp'

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.100.1'
        option netmask '255.255.255.0'

config interface 'WireGuard'
        option proto 'wireguard'
        option private_key '[redacted]'
        list addresses '10.0.5.5/32'
        list dns '10.0.5.1'

config wireguard_WireGuard
        option description '4_lan_Delta.conf'
        option public_key '[redacted]'
        option preshared_key '[redacted]'
        list allowed_ips '192.168.0.0/24'
        list allowed_ips '::/0'
        option persistent_keepalive '25'
        option endpoint_host '[redacted]'
        option endpoint_port '443'

root@HostName:~# cat /etc/config/firewall

config defaults
        option input 'REJECT'
        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'
        list network 'WireGuard'

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'

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'

root@HostName:~# ip route show
default via 192.168.0.1 dev eth1  src 192.168.0.159
[Router A external IP] via 192.168.0.1 dev eth1
192.168.0.0/24 dev eth1 scope link  src 192.168.0.159
192.168.1.0/24 dev br-lan scope link  src 192.168.1.1
root@HostName:~# wg show
interface: WireGuard
  public key: [redacted]
  private key: (hidden)
  listening port: 47559

peer: [redacted]
  preshared key: (hidden)
  endpoint: [Router A pulic IP]:443
  allowed ips: 192.168.0.0/24, ::/0
  latest handshake: 3 seconds ago
  transfer: 468 B received, 764 B sent
  persistent keepalive: every 25 seconds
root@HostName:~#

P.S. For test purposes, Router B is currently connected to Router A on LAN side. Thus, its WAN IP will e 192.168.0.x. I can change this later.

Router A

Add here (but keep existing) the subnet of router B: list allowed_ips '192.168.1.0/24'

You did not show the firewall settings for network wg_lan.
There is a network WireGuard added to the wan zone maybe for a WireGuard client? Just guessing as you did not show everything :frowning:

Having seen router B this might be a misconfiguration in that case remove list network 'WireGuard' from the wan firewall zone and add list network 'wg_lan' to the lan firewall zone (we might tweak the firewall settings later for more fine grained access)

Router B

You do not seem to have IPv6 implemented for WireGuard so remove list allowed_ips '::/0' but add list allowed_ips '10.0.5.0/24' and option route_allowed_ips '1'

As this is a a site-to-site setup you need to allow traffic so the network WireGuard must be added to the lan firewall zone and not the wan

Having router B connected to the LAN is not a proper way for testing things, but if router A is directly connected to the internet then you probably have no choice

Reboot both routers and check again

Router A

Add here (but keep existing) the subnet of router B: list allowed_ips >>'192.168.1.0/24'

Done.

You did not show the firewall settings for network wg_lan.
There is a network WireGuard added to the wan zone maybe for a >>WireGuard client? Just guessing as you did not show everythin

Sorry. My list of Firewall rules is too long.
Interface wg_lan is a memer of "lan" zone on router A, thats it.

Router B

You do not seem to have IPv6 implemented for WireGuard so remove list >>allowed_ips '::/0' but add list allowed_ips '10.0.5.0/24' and option >>route_allowed_ips '1'

Done.

Having router B connected to the LAN is not a proper way for testing things, >>but if router A is directly connected to the internet then you probably have no >>choice

Done. Moved router B to moile internet. It has proper CG-NAT WAN IP now.

Having seen router B this might be a misconfiguration in that case remove list >>network 'WireGuard' from the wan firewall zone and add list network >>'wg_lan' to the lan firewall zone (we might tweak the firewall settings later >>for more fine grained access)

Done.

Reboot both routers and check again

Will do, and check all. Many thanks for taking your time to talk me trough this :smiley:

You are welcome let us know how things are going.

For reference see my notes how I have setup WireGuard, the Server setup guide also has a paragraph about site-to-site setup

I am getting somewhere now. :smiley:

  • I am able to ping whole 192.168.0.x (router A LAN) from 192.168.1.x (router B LAN)
  • I am able to ping 192.168.1.1 (router B) from whole 192.168.0.x (router A LAN)

(router B is now connected to separate mobile Internet CG-NAT, as it should)

So "only" thing left is to somehow block router B from pinging anything on router A LAN and allow everything on router A LAN to ping everything on router B LAN.

First get things working after that we will look at restricting traffic

From 192.168.0.1 (router A) you should be able to ping anything on 192.168.1.0/24 (Lan of router B)

Is that not the case?

I noticed you have more subnets on both sides is that what you mean?

From 192.168.0.1 (router A) you should be able to ping anything on >>192.168.1.0/24 (Lan of router B)

Actually, I would like to be able to ping anything on 192.168.1.0/24 (Lan of router B) from anything on 192.168.0.0/24 (Lan of router A) but not the other way around.

I noticed you have more subnets on both sides is that what you mean?

Yes, but those can be ignored. 192.168.4.0/24 and 192.168.5.0/24 on router A and 192.168.2.0/24 on router B are just guest subnets that can only talk to Internet and nothing else. They should not be routed via WG or talk to each other.

That should work.

On router A you should have a route for 192.168.1.0/24 via the VPN (check with from command line withip route show)
Router B should accept all traffic as the WireGuard interface is added to the lan zone and allowed IPs are 192.168.0.0/24 so accepting anything from router A

If you are not sure or if this does not work please show configs again.

Note that clients on router B have their own firewall and will by default not allow traffic from A so you might have to tweak the firewall of those client to allow traffic.
If there are many clients and this is not feasible then you do the following on router B: Create a separate firewall zone for the WireGuard interface with same settings as the lan zone and move the Wireguard interface from the lan firewall zone to its own zone.
After that enable masquerading on the lan firewall zone

On router A you should have a route for 192.168.1.0/24 via the VPN (check with from command line withip route show)

Yes, I can see the route in the output from ip route show on router A:

default via [redacted] dev eth1 proto static src [redacted]
10.0.5.0/24 dev wg_lan proto kernel scope link src 10.0.5.1
10.0.5.2 dev wg_lan proto static scope link
10.0.5.3 dev wg_lan proto static scope link
10.0.5.4 dev wg_lan proto static scope link
10.0.5.5 dev wg_lan proto static scope link
[redacted]/22 dev eth1 proto kernel scope link src [redacted]
192.168.0.0/24 dev br-lan proto kernel scope link src 192.168.0.1
192.168.1.0/24 dev wg_lan proto static scope link
192.168.4.0/24 dev eth0.4 proto kernel scope link src 192.168.4.200
192.168.5.0/24 dev eth0.5 proto kernel scope link src 192.168.5.200

Note that clients on router B have their own firewall and will by default not allow traffic from A so you might have to tweak the firewall of those client to allow traffic.

When you say "their own firewall" you mean like a local PC firewall or a firewall rule in router B? Clients on router B are IP cameras and do not have any firewalls. Just an 192.168.1.xx IP with 255.255.255.0 mask.

If there are many clients and this is not feasible then you do the following on router B: Create a separate firewall zone for the WireGuard interface with same settings as the lan zone and move the Wireguard interface from the lan firewall zone to its own zone.
After that enable masquerading on the lan firewall zone

OK, depending on your answer I might need to go this route (sic).

that is correct

But also double check that on router B it has the subnet of router A as Allowed IPs and that Route Allowed IPs is enabled!

This is a problem since B then has two routes to the A LAN and it won't work. If you don't have separate ISPs you could use a third router to be the "Internet" using an IP range that is not part of A or B.

I understand. But I succeeded using my phone as "separate ISP" for router B so it is not an issue anymore.

2 Likes

Where do I check this? It looks good in router B etc/config/network at least:

config wireguard_WireGuard
option description '4_lan_Delta.conf'
option public_key [redacted]
option preshared_key [redacted]
list allowed_ips '192.168.0.0/24'
list allowed_ips '10.0.5.0/24'
option persistent_keepalive '25'
option endpoint_host [redacted]
option endpoint_port '443'
option route_allowed_ips '1'

1 Like

OK, I got everything working except I now have full access/pingability between 192.168.0.x (A) and 192.168.1.x. (B). Basically, I have full site-to-site link where everything is open between those two subnets on A and B.

Last piece of the puzzle:

How can make this link one-way only? With other words, prevent 192.168.1.x (cottage network) from accessing 192.168.0.x (home network) but at the same time allow my home to peek into cottage?

At at least one end, have the lan and vpn tunnel in separate firewall zones. Allow forwarding only in the direction you want. The other direction will be blocked without a rule to allow it.

This can also be fine-tuned by writing specific rules for only certain IP addresses and/or ports instead of the general forward everything setting.

2 Likes