How to display wireless client information when using OpenWRT as a simple AP

OpenWRT is an extremely competent little piece of software that breathes new life into wireless routers old and new. But with its main focus being to serve as an all-in-one router and wireless access point, it operates under some assumptions that are not true for all use cases. One of such cases is when you just want to use it as a simple wireless access point (sometimes referred to as a "dumb AP") without routing, DHCP or DNS, making the AP effectively just a "bridge" between your wired network and the wireless clients.

Because OpenWRT assumes it will be the centre of the network, it uses information from DHCP leases to populate the GUI with the names and IP addresses of the wireless clients connected to itself. But when it is not serving DHCP, this information does not exist and all clients are shown only by their MAC addresses, followed by a single question mark.

There are several guides on how to work around this limitation, some of which were the base for what you will see here, but most work under the assumption that your main router will also be running OpenWRT (mine is not), or that you only have a single wireless network (I have four different VLANs!), and as far as I can tell, none mentions This One Weird Trick® that greatly simplifies the workaround.

Assumptions for this guide

  • You have some basic networking experience and know how to get around OpenWRT's GUI.
  • You can SSH into the access point.
  • You have deleted the default WAN interface and its associated firewall rules.
  • For each network/VLAN, there is a bridge combining that VLAN and the related wireless interface.
  • Each of these bridges has a valid IP address in its network (fixed or DHCP, it doesn't matter).
  • Your main router acts as a DHCP and DNS server, having knowledge of all IP <> Name associations and responding to PTR requests.

Getting IP addresses to show

These instructions are adapted from the guides linked above, with changes mainly to make it easier to use with multiple interfaces.

In order for OpenWRT to know which MAC addresses correspond to which IP addresses, we are going to "brute-force" it and make it periodically send a single ping to every host that is live on all targeted networks. This fills up the ARP table with the information we need.

  1. Refresh your package lists and install fping and arp-scan.
  2. SSH into the AP and create the following script, changing the two variables at the top according to your network setup:
#! /bin/sh

# Change the values below as needed
# Local DNS server, usually your router
LOCAL_DNS=192.168.1.1
# Space-separated list of networks to be scanned
INTERFACES="br-lan br-iot br-guest" 

# Run fping against all live hosts in all networks
for interface in $INTERFACES; do
    arp-scan -qxlN -F '${IP}' -I $interface | xargs fping -q -c1
done

/root/arp-refresh.sh

  1. Give the script execution permission: # chmod +x /root/arp-refresh.sh.
  2. In OpenWRT's web interface and go to System > Scheduled Tasks.
  3. Add this line and save: */5 * * * * /root/arp-refresh.sh. This will run the script and refresh ARP information every 5 minutes.

Now, if you wait 5 minutes or run the script manually, you should see all the IPs for the connected clients in the Network > Wireless page.

Getting the hostnames to show

This is the bit the no other guide mentioned, or approached in a more complex way, and the main reason I wrote this guide.

From what I gathered while researching this topic, the most common approach for getting the hostnames to show is to populate the file /etc/ethers with the MAC address and hostname of every client. While this approach works, it requires creating some extra mechanism to get this information there and to keep it up-to-date.

So what is the solution? It's Always DNS!

Turns out OpenWRT tries to perform a reverse DNS lookup (PTR) for each IP address to get their hostnames, but even when the only DNS server configured is your router, this lookup fails because OpenWRT targets its internal DNS server.

The solution is to setup a forwarder specifically for reverse DNS queries, pointing it to your main router:

  1. In the GUI, navigate to Network > DHCP and DNS > Forwards.
  2. Right at the top, in DNS Forwards, add the following (adapting it to your needs) and save/apply:
/*.168.192.in-addr.arpa/192.168.1.1

Boom, names!

Wait, what?

Let's breakdown what this does:

This is a forwarder rule for dnsmasq. The format is /what DNS domain to forward>/<where to forward it to>.

  • *.168.192.in-addr.arpa: This is reverse DNS notation. Let's suppose a device wants to know the name of another device, but all it has is the IP address 192.168.1.99. It makes a PTR query in the format 99.1.168.192.in-addr.arpa (notice the IP is backwards) to the DNS server, and it should get a response containing the name. In our forwarder rule, the asterisk means "anything", so all IPs matching 192.168.xxx.xxx will be caught by it. If you use a different network prefix, change this accordingly. You can also add multiple forwarders if you have multiple network prefixes.
  • 192.168.1.1: The DNS server where requests for this "domain" should be forwarded to (your router).

Hope this helps someone.

antsu

antsu

Some dude who likes computers
UK