How to access LAN devices over Wireguard client on my OpenWrt Router?

Hi,

I'm trying to access LAN devices over the Wireguard client on my OpenWRT router. Right now I can ping it using other WG peers, but I cannot access local devices.

The Wireguard peers share IP addresses within 10.8.X.X. and the LAN devices connected to the router have IP address within the 192.168.X.X range. On my VPS, which acts as a WG server, I put both the peer address and the LAN range into the allowed IPs for my OpenWRT peer.

I've also tried running sudo ip route add 192.168.0.0/16 via 10.8.X.X dev wg0 on the server but I get RTNETLINK answers: File exists.

I'm not sure what to do from here or what I should be doing, so any help will be appreciated!

Is the VPS a 'middleman' setup to enable your remote peers to connect to your router/home network (common if you are behind CG-NAT or otherwise unable to get a public IP on your router)? If so, is a CG-NAT situation the reason for this?

Let's take a look at your OpenWrt side configuration:

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

Is the VPS a 'middleman' setup to enable your remote peers to connect to your router/home network (common if you are behind CG-NAT or otherwise unable to get a public IP on your router)? If so, is a CG-NAT situation the reason for this?

No, I'm not behind a CG-NAT, it's just one of the ways I've found such that I should be able to access my local devices (specifically, my IoT devices and cameras) remotely without getting a public static IP address from my ISP. Also, as a learning experience :slight_smile:

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 'XXXX:XXXX:XXXX"

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

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
        option delegate '0'

config device
        option name 'eth0.2'
        option macaddr XXXXXXXXX'
        option ipv6 '0'

config interface 'wan'
        option device 'eth0.2'
        option proto 'dhcp'
        option delegate '0'

config interface 'wan6'
        option device 'eth0.2'
        option proto 'dhcpv6'
        option reqaddress 'try'
        option reqprefix 'auto'

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 'WG0'
        option proto 'wireguard'
        option private_key 'XXXXXXXXXXXX'
        list addresses '10.8.0.3/8'
        option delegate '0'
        option peerdns '0'
        list dns 'XXX.XXX.XXX.XXX'
        list dns_search 'VPS Provider'

config wireguard_WG0
        option description 'CloudWGServer'
        option public_key 'XXXXXXXXXXXXXXXXXXXXX'
        list allowed_ips '0.0.0.0/0'
        option endpoint_host 'XXX.XXX.XXX.XXX'
        option endpoint_port 'XXXXX'
        option persistent_keepalive '25'
        option route_allowed_ips '1'
cat /etc/config/firewall

config defaults
        option input 'ACCEPT'
        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'

config zone 'wan'
        option name 'wan'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option masq '1'
        option mtu_fix '1'
        list network 'wan'
        list network 'wan6'
        list network 'WG0'
        option family 'ipv4'

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 forwarding
        option src 'lan'
        option dest 'wan'

In this case, you should probably connect directly rather than via the VPS.

As long as you have a public IP (even if it is dynamic), direct connections are easy... just use a ddns service.

This is reasonable... but, it's more complex, and therefore maybe a good thing to play with after you've got a setup working in the direct connection method.

However, right off the bat... I see a few things happening.

remove the all of the lines below the list address (keep that line). DNS settings on this interface won't actually do anything.

Next, remove the /8 from the address. Just make it 10.8.0.3 pure and simple.

From the peer config, it appears that you are tunneling all your traffic through the VPS. Is that your goal? If you're simply looking for remote access, your current config is not the most efficient method. But if you intend to prevent your ISP (and maybe government) from observing the traffic between your network and the VPS, obviously this will do what you want.

Next, let's talk firewall...

Because the WG0 interfcae is currently associated with the wan zone, there will be no inbound connecftion capability in the default config, and this is by design (and I'd recommend that you don't alter the wan zone behaviors). remove the WG0 network from the wan zone and create a new zone for your WG network.

Now, assuming you control the VPS and it is considered trusted, you can make the VPN zone work like this:

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

config forwarding
        option src 'lan'
        option dest 'vpn'

config forwarding
        option src 'vpn'
        option dest 'lan'

Reboot your router and try again. If that doesn't work, we'll have to look at the VPS and the remote peer.

Oh, two important things - 1. my router is behind my modem (it's plugged into a manageable switch with some other devices I don't care masking or making more secure) and 2. I actually mostly use the LuCI GUI to configure the OpenWRT router.

Yeah, that was one of the options I've considered, but decided to go with the WG VPN, again, for learning purposes and I also had the idea that it might reduce my attack surface as I'm planning to experiment with hosting services and making devices, and yes, to prevent the ISP from observing the traffic.

Huh, okay, some of them I don't see in the GUI (i.e. delegate). Also, with regards to the DNS, I read that by using my WG server's DNS (my VPS's, in this case), I can prevent DNS leaks. Is that not true or why would it not matter? If you don't mind explaining or point to a resource that does?

Also, I just tried deleting the DNS address and that leads to my device 'losing' internet address (I can still ping the server, but I can't access webpages); is it fine if I leave it for now? Some of my devices will need to resolve domain names to update and I don't know how to split traffic yet.

Okay, let me try that right now; in the first post, when I was just setting up Wireguard stuff, I was recommended to keep the WG0 interface associated with the WAN zone.

Okay, I'm realizing why now that was recommended - that's because of the modem. If I set up forwarding directly between the VPN zone and the LAN as you've outlined, I can't access internet. What would be the workaround for that? I assume I need to somehow use my default gateway from the WAN to actually access internet.

The theory is correct (mostly). The problem is that the actual fields don't do anything. You need to set it in the dnsmasq configuration, instead. And you can actually use any public DNS or your VPS... there is one major caveat here... if the WG peer config to (on OpenWrt pointing to the VPS) uses a domain name (rather than an IP address), the DNS server must be accessable before the WG tunnel starts.... otherwise it cannot lookup the VPS by its domain name and thus can't start the tunnel.

For some context, see this.

Is the modem a combo unit (modem+router)? Are your lan devices directly connected to the OpenWrt router or to the modem device?

Thank you for explaining and thank you for the link, I'll take a look!

So I have 2 LANs - one which is based off the modem, which is indeed a combo unit, and one that's based off the router. The router is connected to the modem via a switch. I want to specifically access devices that are connected to my router (via WiFi or via Ethernet).

How does the OpenWrt router connect to the upstream network? Is it via the wan port or lan port?
Can you draw a diagram of your network?

It's thru the WAN port, yes. Let me know if this is helpful:

Edit: this is probably more accurate:

Ok... thanks.

So, in a direct-connect scenario from your remote peer, you should be able to access both LANs. However, you currently won't be able to do that because your WG tunnel (to the VPS) will preclude connecting to the LAN1 devices. LAN2 devices should be accessable.

If this was my network, I'd actually put the modem into bridge mode and then put both LANs behind the OpenWrt router. This would make routing more straight forward in terms of the remote access context.

But, based on your current configuration and the changes I recommended earlier, you should be able to reach LAN 2 devices.... can you confirm if that is indeed working?

Yes, I want to be able to connect just to LAN2 devices.

My logic for this was so that I can separate more insecure devices and keep them contained, especially since I want to experiment with them; now, I can just separate all of the devices via VLANs, but it's easy to just "plug and play" other devices, which I want to easily use, into the modem. Maybe the way it's setup right now won't actually help much with containment, I'm still learning :slight_smile:

Okay, let me try again, just to be sure. Should I be able to access the OpenWRT router over WG VPN? As in, the LuCI GUI webpage?

Do I have to have the LAN2 IP address range in the allowed IPs for the peer that will try to access them?

You can do this with your current config, but it is more efficient and easier to control when done on a single router with multiple networks defined there.

Yes.

Yes, unless you have 0.0.0.0/0 defined in the remote peer.

Fair enough, that'll go into my project heap!

I'm not having luck accessing the LuCI or pinging other LAN2 devices over Wireguard with the config you've provided. Right now I had just connected to the router via an ethernet cable and I couldn't ping other devices on the LAN2 or get to the webpages, but I could still access the LuCI; SSH-ing into the router as a LAN2 connection, I can ping both webservers (e.g. 8.8.8.8), LAN2 devices, and the modem (which works as intended, I assume). Maybe it's got something to do with my VLAN settings on the OpenWRT router? As I understood it simply separates the LAN from the WAN though.

Any suggestions?

We will need to look at the remote peer and the vps configs. The vps will need a static route.

This should not be a problem. Are the hosts windows based? If so, try adjusting the windows firewall (or better yet, temporarily turn off the firewall).

Okay. Can you tell me what you need to know for that?

You are right; for convenience, I've been using my Windows-based PC for testing. Turned off the firewall and was able to ping other LAN2 devices, when plugged into the router.

If you don't mind, I'll follow up to part 1 tomorrow, it's very late here. Have a good night or good day and thank you for all the help so far!

The static route will be:

192.168.1.0/24 via 10.8.0.3

This needs to be added to the vps. If it is a Linux host is, you’ll likely use the route command to add the route described above.

1 Like

Okay, I just did that (sudo ip route add 192.168.1.0/24 via 10.8.0.3 dev wg0) and I still can't access LAN2 devices or the OpenWRT router over my Windows host device with Wireguard enabled and firewall off. Now though, once I plug into the router, I can access the modem and the router even with my firewall still on.

Also, just checked, and now I can't ping my OpenWRT router WG client from other peers.

Let's see the VPS and remote peer configurations.

Wireguard server config:

#cat /etc/wireguard/wg0.conf

[Interface]
#VPS server
Address = 10.8.0.1/24
SaveConfig = true
PostUp = ufw route allow in on wg0 out on enp1s0
PostUp = iptables -t nat -I POSTROUTING -o enp1s0 -j MASQUERADE
PreDown = ufw route delete allow in on wg0 out on enp1s0
PreDown = iptables -t nat -D POSTROUTING -o enp1s0 -j MASQUERADE
ListenPort = XXXXX
PrivateKey = [PRIVATE KEY]

[Peer]
#Mobile device
PublicKey = [PUBLIC KEY]
AllowedIPs = 10.8.0.2/32, 192.168.0.0/16
Endpoint = XXX.XXX.XXX.XXX:XXXXX

[Peer]
#OpenWRT Router
PublicKey = [PUBLIC KEY]
AllowedIPs = 10.8.0.3/32, 192.168.0.0/16
Endpoint = XXX.XXX.XXX.XXX:XXXXX

[Peer]
#Windows Host
PublicKey = [PUBLIC KEY]
AllowedIPs = 10.8.0.5/32, 192.168.0.0/16
Endpoint = XXX.XXXX.XXX.XXX:XXXXX

Network interface info:

#ip address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UP group default qlen 1000
    link/ether XXX
    inet XXX.XXX.XXX.XXX/23 metric 100 brd XXX.XXX.XXX.XXX scope global dynamic enp1s0
       valid_lft 55825sec preferred_lft 55825sec
    inet6 XXXX scope global dynamic mngtmpaddr noprefixroute
       valid_lft 2591837sec preferred_lft 604637sec
    inet6 XXXX scope link
       valid_lft forever preferred_lft forever
8: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none
    inet 10.8.0.1/24 scope global wg0
       valid_lft forever preferred_lft forever

Firewall rules:

#iptables --list

Chain INPUT (policy DROP)
target     prot opt source               destination
ufw-before-logging-input  all  --  anywhere             anywhere
ufw-before-input  all  --  anywhere             anywhere
ufw-after-input  all  --  anywhere             anywhere
ufw-after-logging-input  all  --  anywhere             anywhere
ufw-reject-input  all  --  anywhere             anywhere
ufw-track-input  all  --  anywhere             anywhere

Chain FORWARD (policy DROP)
target     prot opt source               destination
ufw-before-logging-forward  all  --  anywhere             anywhere
ufw-before-forward  all  --  anywhere             anywhere
ufw-after-forward  all  --  anywhere             anywhere
ufw-after-logging-forward  all  --  anywhere             anywhere
ufw-reject-forward  all  --  anywhere             anywhere
ufw-track-forward  all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ufw-before-logging-output  all  --  anywhere             anywhere
ufw-before-output  all  --  anywhere             anywhere
ufw-after-output  all  --  anywhere             anywhere
ufw-after-logging-output  all  --  anywhere             anywhere
ufw-reject-output  all  --  anywhere             anywhere
ufw-track-output  all  --  anywhere             anywhere

Chain ufw-after-forward (1 references)
target     prot opt source               destination

Chain ufw-after-input (1 references)
target     prot opt source               destination
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:netbios-ns
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:netbios-dgm
ufw-skip-to-policy-input  tcp  --  anywhere             anywhere             tcp dpt:netbios-ssn
ufw-skip-to-policy-input  tcp  --  anywhere             anywhere             tcp dpt:microsoft-ds
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:bootps
ufw-skip-to-policy-input  udp  --  anywhere             anywhere             udp dpt:bootpc
ufw-skip-to-policy-input  all  --  anywhere             anywhere             ADDRTYPE match dst-type BROADCAST

Chain ufw-after-logging-forward (1 references)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "

Chain ufw-after-logging-input (1 references)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "

Chain ufw-after-logging-output (1 references)
target     prot opt source               destination

Chain ufw-after-output (1 references)
target     prot opt source               destination

Chain ufw-before-forward (1 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere             icmp destination-unreachable
ACCEPT     icmp --  anywhere             anywhere             icmp time-exceeded
ACCEPT     icmp --  anywhere             anywhere             icmp parameter-problem
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request
ufw-user-forward  all  --  anywhere             anywhere

Chain ufw-before-input (1 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ufw-logging-deny  all  --  anywhere             anywhere             ctstate INVALID
DROP       all  --  anywhere             anywhere             ctstate INVALID
ACCEPT     icmp --  anywhere             anywhere             icmp destination-unreachable
ACCEPT     icmp --  anywhere             anywhere             icmp time-exceeded
ACCEPT     icmp --  anywhere             anywhere             icmp parameter-problem
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request
ACCEPT     udp  --  anywhere             anywhere             udp spt:bootps dpt:bootpc
ufw-not-local  all  --  anywhere             anywhere
ACCEPT     udp  --  anywhere             XXX.XXX.XXX.XXX          udp dpt:mdns
ACCEPT     udp  --  anywhere             XXX.XXX.XXX.XXX      udp dpt:1900
ufw-user-input  all  --  anywhere             anywhere

Chain ufw-before-logging-forward (1 references)
target     prot opt source               destination

Chain ufw-before-logging-input (1 references)
target     prot opt source               destination

Chain ufw-before-logging-output (1 references)
target     prot opt source               destination

Chain ufw-before-output (1 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ufw-user-output  all  --  anywhere             anywhere

Chain ufw-logging-allow (0 references)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW ALLOW] "

Chain ufw-logging-deny (2 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere             ctstate INVALID limit: avg 3/min burst 10
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 10 LOG level warning prefix "[UFW BLOCK] "

Chain ufw-not-local (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL
RETURN     all  --  anywhere             anywhere             ADDRTYPE match dst-type MULTICAST
RETURN     all  --  anywhere             anywhere             ADDRTYPE match dst-type BROADCAST
ufw-logging-deny  all  --  anywhere             anywhere             limit: avg 3/min burst 10
DROP       all  --  anywhere             anywhere

Chain ufw-reject-forward (1 references)
target     prot opt source               destination

Chain ufw-reject-input (1 references)
target     prot opt source               destination

Chain ufw-reject-output (1 references)
target     prot opt source               destination

Chain ufw-skip-to-policy-forward (0 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere

Chain ufw-skip-to-policy-input (7 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere

Chain ufw-skip-to-policy-output (0 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere

Chain ufw-track-forward (1 references)
target     prot opt source               destination

Chain ufw-track-input (1 references)
target     prot opt source               destination

Chain ufw-track-output (1 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             ctstate NEW
ACCEPT     udp  --  anywhere             anywhere             ctstate NEW

Chain ufw-user-forward (1 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere

Chain ufw-user-input (1 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     udp  --  anywhere             anywhere             udp dpt:22
DROP       udp  --  anywhere             anywhere             udp dpt:XXXXX
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     udp  --  anywhere             anywhere             udp dpt:XXXXX #matches listening port on interface

Chain ufw-user-limit (0 references)
target     prot opt source               destination
LOG        all  --  anywhere             anywhere             limit: avg 3/min burst 5 LOG level warning prefix "[UFW LIMIT BLOCK] "
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable

Chain ufw-user-limit-accept (0 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere

Chain ufw-user-logging-forward (0 references)
target     prot opt source               destination

Chain ufw-user-logging-input (0 references)
target     prot opt source               destination

Chain ufw-user-logging-output (0 references)
target     prot opt source               destination

Chain ufw-user-output (1 references)
target     prot opt source               destination

Remove 192.168.0.0/16 from these peer configs.

Let's see the other remote peer config.