Confounding the Belkin Heartbeat
I noticed that my DNS aggregator, DNSMasq, was periodically getting bursts of queries about “www.belkin.com” and “heartbeat.belkin.com”.
I looked into the logs with journalctl -u dnamasq --since 2025-03-05T08:00:00
I found two different bursts of queries.
Type A burst of queries
1 Mar 05 08:00:48 monarch dnsmasq[13745]: query[PTR] 1.0.0.10.in-addr.arpa from 10.0.0.77
2 Mar 05 08:00:48 monarch dnsmasq[13745]: /etc/hosts 10.0.0.1 is monarch.glump
3 Mar 05 08:00:48 monarch dnsmasq[13745]: query[AAAA] www.belkin.com from 10.0.0.77
4 Mar 05 08:00:48 monarch dnsmasq[13745]: cached www.belkin.com is <CNAME>
5 Mar 05 08:00:48 monarch dnsmasq[13745]: cached commcloud.prod-bgbh-belkin-com.cc-ecdn.net is <CNAME>
6 Mar 05 08:00:48 monarch dnsmasq[13745]: cached commcloud.prod-bgbh-belkin-com.cc-ecdn.net.cdn.cloudflare.net is NODATA-IPv6
7 Mar 05 08:00:48 monarch dnsmasq[13745]: query[A] www.belkin.com from 10.0.0.77
8 Mar 05 08:00:48 monarch dnsmasq[13745]: cached www.belkin.com is <CNAME>
9 Mar 05 08:00:48 monarch dnsmasq[13745]: cached commcloud.prod-bgbh-belkin-com.cc-ecdn.net is <CNAME>
10 Mar 05 08:00:48 monarch dnsmasq[13745]: cached commcloud.prod-bgbh-belkin-com.cc-ecdn.net.cdn.cloudflare.net is 104.18.34.100
11 Mar 05 08:00:48 monarch dnsmasq[13745]: cached commcloud.prod-bgbh-belkin-com.cc-ecdn.net.cdn.cloudflare.net is 172.64.153.156
12 Mar 05 08:00:48 monarch dnsmasq[13745]: query[PTR] 100.34.18.104.in-addr.arpa from 10.0.0.77
13 Mar 05 08:00:48 monarch dnsmasq[13745]: cached 104.18.34.100 is NXDOMAIN
14 Mar 05 08:00:48 monarch dnsmasq[13745]: query[PTR] 156.153.64.172.in-addr.arpa from 10.0.0.77
15 Mar 05 08:00:48 monarch dnsmasq[13745]: cached 172.64.153.156 is NXDOMAIN
Type A bursts originated from 10.0.0.77 and 10.0.10.77.
Emulating queries from command line
- The message “cached www.belkin.com is
” can be had with dig -t CNAME +norecurse www.belkin.com
- Similarly, “cached commcloud.prod-bgbh-belkin-com.cc-ecdn.net is
” generated with dig -t CNAME +norecurse commcloud.prod-bgbh-belkin-com.cc-ecdn.net
DNS resolvers 8.8.8.8 and 9.9.9.9 both give back one FQDN for that CNAME, “commcloud.prod-bgbh-belkin-com.cc-ecdn.net.cdn.cloudflare.net”. dig -t A commcloud.prod-bgbh-belkin-com.cc-ecdn.net.cdn.cloudflare.net
gives back two IP addresses, 104.18.34.100 and 104.18.34.100dig -t PTR 100.34.18.104.in-addr.arpa
anddig -t PTR 156.153.64.172.in-addr.arpa
yield the twoNXDOMAIN
responses on lines 14 and 15 above.
Looks like Belkin the corporate entity has www.belkin.com on a Cloudflare IP address, and that two of my Velops know that - they are setting CNAME type on the query for “www.belkin.com”. The Velops only bother doing an “A” query once they get to the two FQDNs that have cloudflare.net domains.
Type B burst of queries
1 Mar 05 08:02:19 monarch dnsmasq[13745]: query[AAAA] heartbeat.belkin.com from 10.0.20.77
2 Mar 05 08:02:19 monarch dnsmasq[13745]: cached heartbeat.belkin.com is NODATA-IPv6
3 Mar 05 08:02:19 monarch dnsmasq[13745]: query[A] heartbeat.belkin.com from 10.0.20.77
4 Mar 05 08:02:19 monarch dnsmasq[13745]: cached heartbeat.belkin.com is 3.101.0.200
5 Mar 05 08:02:19 monarch dnsmasq[13745]: cached heartbeat.belkin.com is 13.56.60.198
6 Mar 05 08:02:19 monarch dnsmasq[13745]: cached heartbeat.belkin.com is 184.169.236.125
7 Mar 05 08:02:19 monarch dnsmasq[13745]: cached heartbeat.belkin.com is 50.18.193.10
Type B bursts originated only from 10.0.20.77.
Emulating this from the command line is a lot easier: dig -t A heartbeat.belkin.com
causes the same messages as in lines 3 through 7 just above.
A single query, not PTR type double checks.
Homelab notes
This will all make more sense if you understand how I’ve got my network put together right now. Here’s my current homelab network:
For purposes of figuring out this heartbeat, velop3 replaces my AX6000. I’ve cabled my OpenWrt One to my Qotom fanless server for the moment.
DNS Information
The DHCP server system I’m using, Kea, gives out these DNS relation options:
"option-data": [
{
"name": "domain-name-servers",
"csv-format": true,
"space": "dhcp4",
"data": "10.0.0.1"
},
{
"name": "domain-search",
"data": "glamour, salmon, walrustitty, glump, spork"
}
],
I piously assigned the domain names to various IPv4-address based subnets and interfaces to avoid the having a single undifferentiated, boring, “intranet” domain.
- 10.0.0.0/16 → glump, eno1
- 10.0.10.0/16 → walrustitty, eno2
- 10.0.20.0/16 → salmon, eno4
- 10.0.30.0/16 → spork, ens4
- 10.0.40.0/16 → glamour, ens5
The Dell R530 has 6 ethernet cards installed in total.
It’s my belief that I had to assign IP address subnets to each interface, otherwise I would have to put in per-host routing info, which would be a pain to keep straight.
Velops are sold under the Linksys brand, but bargain basement vendor Belkin bought Linksys from Cisco in 2013. I bought 3 Velops as a set in 2020, and I’ve used them ever since. The hardware seems reliable, and the networking is at least robust.
My biggest beef with Velops is that you can only configure them with a “The App” and a smartphone. Velops do not have a intranet-accessible web UI. You do everything through “The App”. “The App” is a bit of a nightmare bicycle, you can only click certain buttons or vaguely defined areas of the screen, and it’s really hard for documentation to describe these actions. “The App” assumes you know Linksys’ jargon for networking, which isn’t exactly the same as anyone else’s, and has a lot of baby talk. You can’t be sure of what you’re doing. You can use “The App” from anywhere, on or off your intranet, which means that the Velops are sending a bunch of info about your network back to Belkin. Convenient, but annoying if you care even slightly about your own privacy.
The other bad aspect of Velops is that “The App” implies you can do some kind of mesh networking, where you locate an uncabled Velop some distance from the primary, cabled in Velop. All your Velops have the same SSID, so your phone or laptop should just connect to the Velop with the strongest signal. There’s no good way to test this that I could figure out. If you use this, you’re stuck with a poorly configured NAT network on 192.168.1.0/24, which gets NATted again by whatever router fronts your home network to the internet. Potentially 2 layers of 192.168.x.y addresses to puzzle out if there’s any problem, or you want to understand the mesh networking.
I have my 3 Velops in “bridging” mode, which means the mesh networking stuff probably shouldn’t work, although my home network is awash in STP 802.1d packets.
Back to the bursts of queries
There’s a number of things about these bursts that puzzle me.
Type A burst puzzlers
- Why do a PTR lookup on 10.0.0.1? That’s clearly the DNS server it gets from DHCP, why bother to double-check it? And what do you do with the FQDN?
- If the velop’s got an IPv4 address DNS server (10.0.0.1), why bother to do AAAA (IPv6) address look ups? It’s unlikely to succeed.
- Similarly, why do PTR look ups on the IPv4 addresses that “commcloud.prod-bgbh-belkin-com.cc-ecdn.net.cdn.cloudflare.net” resolves to?
Burst comparison puzzles
- Why do so many of these things? Is the timeout that short?
- Why do 10.0.0.77 and 10.0.10.77 Velops start with “www.belkin.com”, but 10.0.20.77 starts with “heartbeat.belkin.com”?
- Why not just set the “recursion desired” bit on an A query and be done with it?
I guess that I have a different firmware revision on 10.0.20.77 than the other two, which causes the different behavior. I do not remember updating firmware, but that doesn’t mean anything.
Frequency
Eyeballing the dnsmasq
journal output shows the bursts appearing
at varying intervals.
At about 2025-03-09T15:34:00-0700,
I ran: journalctl -u dnsmasq.service --since 2025-03-05T00:00:00
I calculated intervals between timestamps of A type bursts
(for 10.0.0.77 and 10.0.10.77) and B type bursts (for 10.0.20.77).
Velop | burst count | mean interval | median interval | min interval | max interval |
---|---|---|---|---|---|
10.0.0.77 | 6145 | 64.8 | 65 | 5 | 167 |
10.0.10.77 | 5445 | 65.0 | 65 | 5 | 124 |
10.0.20.77 | 3193 | 124.6 | 124 | 66 | 187 |
I included burst count only to demonstrated that I watched these queries for a while, to give some statistical heft to the mean and median values.
Above, a histogram to give some idea of the distribution of intervals between bursts. I put all the intervals into 5-second buckets, then plotted the middle of the bucket versus the count of intervals in each bucket. It appears that A type burst intervals are normally distributed, with a mean of 60 seconds. B type burst intervals are also normally distributed, with a mean of 120 seconds.
I hypothesize that the Velop operating system (whatever it may be) uses a
The Problem
That’s a lot of DNS queries that aren’t doing me any good. I’ve got the Velops in “bridging” mode. They don’t do NAT, or provide DHCP to clients. I don’t like to assign IP addresses on 192.168.0.0/16 subnets because then I can’t get to printers, scanners, etc from most of the subnets.
It looks like Velops deny DNS to clients if they can’t get a heartbeat out of Belkin. Why would anybody do that? It’s dumb and it’s extra work.
Fixing it
I just realized I should check to see if OpenWrt runs on Velop hardware.
It looks like I might be able to install OpenWrt on them.
Until then, I’m modifying /etc/dnsmasq.conf
.
I’m putting in these two lines:
# Add domains which you want to force to an IP address here.
# The example below send any host in double-click.net to a local
# web-server.
#address=/double-click.net/127.0.0.1
address=/belkin.com/0.0.0.0
address=/belkin.com/::1
These two lines make my DNS aggregator send back 0.0.0.0 for any belkin.com DNS lookup.
Type A bursts of queries now log like this:
Mar 09 23:07:38 monarch dnsmasq[20283]: query[PTR] 1.0.0.10.in-addr.arpa from 10.0.0.77
Mar 09 23:07:38 monarch dnsmasq[20283]: /etc/hosts 10.0.0.1 is monarch.glump
Mar 09 23:07:38 monarch dnsmasq[20283]: query[AAAA] www.belkin.com from 10.0.0.77
Mar 09 23:07:38 monarch dnsmasq[20283]: config www.belkin.com is ::1
Mar 09 23:07:38 monarch dnsmasq[20283]: query[A] www.belkin.com from 10.0.0.77
Mar 09 23:07:38 monarch dnsmasq[20283]: config www.belkin.com is 0.0.0.0
Mar 09 23:07:38 monarch dnsmasq[20283]: query[PTR] 0.0.0.0.in-addr.arpa from 10.0.0.77
Mar 09 23:07:38 monarch dnsmasq[20283]: /etc/hosts 0.0.0.0 is sli.washingtonpost.com
Type B bursts of queries look like this:
Mar 09 23:04:54 monarch dnsmasq[20283]: query[AAAA] heartbeat.belkin.com from 10.0.20.77
Mar 09 23:04:54 monarch dnsmasq[20283]: config heartbeat.belkin.com is ::1
Mar 09 23:04:54 monarch dnsmasq[20283]: query[A] heartbeat.belkin.com from 10.0.20.77
Mar 09 23:04:54 monarch dnsmasq[20283]: config heartbeat.belkin.com is 0.0.0.0
Nothing goes out to a big DNS resolver.
Around the web
Looks like the heartbeat failure is the big issue dragging on Velops.
https://www.reddit.com/r/pihole/comments/gn7rtf/linksys_velop_red_light_despite_devices_connected/