Adding Wireguard server to dumb AP?

Hi all!
I recently got the idea to add a VPN server on my LAN, so I can connect through a tunnel from the Internet and back out again, so it looks like I'm at my home IP address.
I'm fairly experienced with networking but a complete beginner at Wireguard and OpenWRT.

Here is my current setup, where the lines are cabled Ethernet.

I set the AP up using https://openwrt.org/docs/guide-user/network/wifi/dumbap and it works fine as an AP right now.

The device is a D-Link DIR-842 that I set up using https://openwrt.org/toh/d-link/d-link_dir-842

I wonder, is it possible to also set up a WG server without also converting it to a full-blown router?
This previous topic suggests that it is possible: Setting up a separate Wireguard-Server in LAN

However I tried to follow this instruction: https://openwrt.org/docs/guide-user/services/vpn/wireguard/server but it assumes that the WG server is a router. I tried skipping irrelevant steps but still ended up unable to get a connection in wg show.
I didn't quite understand why the instructions say to add a list of addresses to the vpn interface. The example WG_ADDR="192.168.9.1/24" is a lot more than one address. I set it to '192.168.1.3/32' for now.

I don't really feel like messing with the ISP router and my existing clients, so I would prefer if DHCP, DNS and any port forwarding is handled on that device if possible but do tell me if it would be better to throw it out and just do the routing on the OpenWRT device instead.

root@OpenWrt:~# wg show
interface: vpn
  public key: <my_public_key>
  private key: (hidden)
  listening port: 51820

peer: <test_client's_public_key>
  allowed ips: 192.168.1.4/32

peer: <my_phone's_public_key>
  allowed ips: 0.0.0.0/0

I figured I would test this from an internal IP address first, before I start messing with port forwarding in the ISP router, to allow external incoming connections.

Expected behavior:

  • I should be able to see my test client being connected using wg_show, right?
  • Test client (an iPhone) should be able to access the Internet once connected

Observed behavior:

  • iPhone's VPN settings page reports "Status: connected"
  • iPhone is unable to connect to any web pages, except that of my ISP router's setup page on 192.168.1.1, and I don't even know if that is using the VPN tunnel at all.
  • wg_show is not showing any active connection, just the above output listing the clients.

Here is my /etc/config/network file. What else do you need?

root@OpenWrt:~# cat /etc/config/network

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

config globals 'globals'
        option ula_prefix 'fdf9:e118:bf5d::/48'

config interface 'lan'
        option type 'bridge'
        option ifname 'eth0.1 eth0.2 eth0'
        option proto 'static'
        option ipaddr '192.168.1.2'
        option netmask '255.255.255.0'
        option dns '192.168.1.1'
        option gateway '192.168.1.1'
        option broadcast '192.168.1.255'
        option ipv6 '0'

config device 'lan_eth0_1_dev'
        option name 'eth0.1'
        option macaddr '18:0f:76:39:70:c0'

config device 'wan_eth0_2_dev'
        option name 'eth0.2'
        option macaddr '18:0f:76:39:70:c2'

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 0t'

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

config interface 'vpn'
        option proto 'wireguard'
        option listen_port '51820'
        option private_key '<hidden, of course>'
        list addresses '192.168.1.3/32'

config wireguard_vpn 'wgclient'
        description 'my test client on local network'
        option public_key '<test_client's_public_key>'
        list allowed_ips '192.168.1.4/32'

config wireguard_vpn 'wgclient2'
        description 'external user'
        option public_key '<my_phone's_public_key>'
        list allowed_ips '0.0.0.0/0'

If you use /32 as the interface address then I think dnsmasq won't process DNS requests from your clients, since it only allows clients within the LAN subnet. And the /32 is a subnet containing the server address only and no clients.

You also need to enable IP masquerade on the lan zone unless you add a static route to 192.168.9.0/24 on the main router.

2 Likes

In addition, this affects routing since the interface netmask /32 makes netifd to avoid creating the WG subnet/peer routes by default.

Although it's possible to work around with Dnsmasq localservice=0 and WG route_allowed_ips=1, there's typically no point to make it more difficult.

1 Like

That's because it has to be. The purpose of WireGuard (well, any IP-based VPN) is to send certain traffic to a certain destination. This cannot be achieved without routing.

A real-world example from my own network: I have a site-to-site VPN using WireGuard on a pair of Raspberry Pi 3B+ devices, running Raspberry Pi OS (née Raspbian). Neither device is a "router", and neither device is on the Internet-facing perimeter of its respective network.

However, to intercept and redirect the traffic, both devices have the line net.ipv4.ip_forward=1 in the file /etc/sysctl.conf. And that line tells the kernel to enable the function which permits routing to happen. As a result, the Raspberry Pi becomes a router.

So, you can run WireGuard on any supported device, whether it's a "router" or not. But in the process, you will turn that device into a router.

2 Likes

Thank you so much, folks! I suspected I would have to add some component of routing, I'm glad to have confirmation that this should be possible.

If I understand your answers right, I need to:
(1) assign a whole subnet of some size for the VPN interface (as in the WG example)
(2) setup dnsmasq (which I presume should handle DNS request forwarding, from the VPN clients to my preferred DNS server, and forward DHCP requests to my ISP router (192.168.1.1))
(3) set up IP forwarding from the VPN interface(s) to the AP's LAN interface

(1) seems straightforward enough.
If anyone has concrete example configurations for how to accomplish (2) and (3) in OpenWRT, I'd be most grateful.

/etc/init.d/dnsmasq enable
/etc/init.d/dnsmasq start

uci set firewall.@zone[0].masq="1"
uci commit firewall
/etc/init.d/firewall restart

uci del_list network.vpn.addresses="192.168.1.3/32"
uci add_list network.vpn.addresses="192.168.9.1/24"
uci del_list network.wgclient.allowed_ips="192.168.1.4/32"
uci add_list network.wgclient.allowed_ips="192.168.9.2/32"
uci del_list network.wgclient2.allowed_ips="0.0.0.0/0"
uci add_list network.wgclient2.allowed_ips="192.168.9.3/32"
uci commit network
/etc/init.d/network restart
  • Make sure to match allowed IPs with each client peer config.
  • The router must have a public IP address.
  • Set up port forwarding for 51820/UDP on the router to the AP.
1 Like

As part of setting up the "dump AP", I did

/etc/init.d/dnsmasq disable
/etc/init.d/dnsmasq stop

Now, we seem to be enabling DHCP again. I want to avoid running DHCP for non-VPN clients on the network since my ISP router is already doing this - is there any danger in enabling dnsmasq like you suggest? Should I specify e.g.
uci set dhcp.lan.ignore=1?

1 Like

https://openwrt.org/docs/guide-user/base-system/dhcp_configuration#disabling_dhcp_role

1 Like

You shouldn't need dnsmasq running at all on the AP. You can't use DHCP for wireguard addressing so you don't need that functionality at all and there shouldn't be any reason you can't just use the existing DNS setup within your network.

Are you able to add static routes to your ISP router?

1 Like

Thanks, turning dnsmasq back off.

I don't think I'm able to add static routes to the ISP router, at least I can't find any option for it in their web UI.

Apart from enabling option route_allowed_ips '1' on each peer config, should I also add some config route clause to my /etc/config/network file?
Like:

config route                                     
        option interface 'vpn'
        option target '192.168.1.1'
        option netmask '255.255.255.0'

BTW, could my problems be caused by having my primary connection to the gateway be a "br" type interface?
I mean, to my ISP router, this AP doesn't even appear in the list of DHCP clients, perhaps I really should reconfigure my network from scratch and stop using "bridge mode"?

config interface 'lan'
        option type 'bridge'

No.

Also no.

Can you post an up to date output of /etc/config/network and /etc/config/firewall?

1 Like

It might be unwise to disable since there are many use cases for Dnsmasq including ad-blocking, selective DNS forwarding, DoH/DoT, etc.

No need for that, unless each of your peers is a router.

No.

From the sounds of it, dnsmasq was already disabled when the device was configured as a dumb AP. Unless there's some specific usage the OP requires, which they haven't suggested is the case, then re-enabling it just has the potential to cause issues with their existing setup.

If you've assigned the WG interface an address with a suitable subnet mask (such as /24) and all your peers have addresses from that subnet then yeah you won't need to use route_allowed_ips. However, if you haven't (or don't want to) assign an address to the WG interface then you should enable it. You should also enable it for any peer that doesn't have an address from the subnet you've assigned to Wireguard.

This is a router now, not a dumb AP any longer.

That's the goal and I see no point to make it different.

While technically yes it will now be doing routing it doesn't necessarily follow that you need to (or should) add/enable things like DHCP/DNS. The AP needs to route traffic from the WG interface to the LAN and vice versa, but that's it. The OP hasn't suggested they need anything else that isn't already provided for by existing services within their network. Adding services for the sake of it just needlessly complicates matters.

I guess it's just a difference in approach. I prefer to not assign an address to the WG interface and use route allowed_ips on my peers. I only added to your answer so the OP was aware there are multiple approaches that can be taken and that there may be times when route allowed_ips is required. For all we know they may decide at some point down the line to set up a site to site VPN or a travel router.

Hi all,
I'm facing a similar issue. Also my dumb l AP is remote (i.e. I don't currently have physical access to it) so I need to be extra careful not to mess with network which would make my openwrt AP inaccessible.
I tried connecting from my client but no wireguard connection can be established.
Any ideas? Here's my configuration

root@OpenWrt:~# 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 'fd77:2829:f022::/48'

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

config interface 'lan'
        option device 'br-lan'
        option proto 'dhcp'
        option delegate '0'

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

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

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

config interface 'lan6'
        option proto 'dhcpv6'
        option device '@lan'
        option reqaddress 'try'
        option reqprefix 'no'

config interface 'wg0'
        option proto 'wireguard'
        option private_key '<private_key>'
        option listen_port '<port>'
        list addresses '10.14.0.1/24'

config wireguard_wg0
        option description 'HP Pavilion'
        option public_key '<test_client's_public_key>'
        list allowed_ips '10.14.0.3/32'
        option route_allowed_ips '1'
        option persistent_keepalive '25'

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

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

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

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

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 src_ip 'fc00::/6'
        option dest_ip 'fc00::/6'
        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 rule
        option name 'Support-UDP-Traceroute'
        option src 'wan'
        option dest_port '33434:33689'
        option proto 'udp'
        option family 'ipv4'
        option target 'REJECT'
        option enabled 'false'

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

root@OpenWrt:~# wg
interface: wg0
  public key: <public_key>
  private key: (hidden)
  listening port: <wireguard port>

peer: <test_client's_public_key>
  allowed ips: 10.14.0.3/32
  persistent keepalive: every 25 seconds

What is the router your AP lives behind? Is the port open to allow the WG peer to connect? I've got a Turris Omnia connected to a Mikrotik 4011 and it's working fine. I've also done a few with Meraki Mx60's and they all worked very easily. I did the config using the configuration file method, then I installed the Luci-app-wireguard and it read all the settings easily. I started out with Allowed IP's = 0.0.0.0/0 at first so I could make sure it wasn't some dumb routing issue messing me up. I then created static routes across the wg0 interface and everything is A-OK.

Yes I have forwarded the port. Its an ISP-provided DSL router. Will try the Allowed IP's = 0.0.0.0/0 tomorrow and report if anything changes.

Yes, on a road warrior client, allowed_ips should be set to 0.0.0.0/0 since all of its Internet use (from various sites) will be coming back to it through the tunnel.

Without any consideration of routing at all you should be able to ping the server's end of the tunnel (10.14.0.1) from your client. If that doesn't work, consider that the encrypted packets are not making it to the server. Getting the wireguard status (wg with no parameters) will show a "last handshake time" if the encrypted path is intact.

Since you're doing intrazone forwarding (vpn outputs to lan which is in the same zone), there is no NAT. When your client makes a request for the Internet (or one of your LAN machines), packets from 10.14.0.3 will appear on the LAN. The main router needs to be set with a static route so that it knows that the gateway back to that network is your dumb AP / VPN server.

If you can't install routes on the main router, you'll need to have separate zones in the VPN server with masquerade enabled on the destination zone, so that your client IP is NATd to a regular LAN IP which the main router can handle. The simplest way to do that is to create a vpn zone containing wg0, a forward from vpn to lan, and turn on masq on the lan.

1 Like