Does this violate RFC?

We just got to the bottom of a strange issue one of our users was reporting.
He has an Internet-of-things door lock which wasn’t working. (failed to resolve the service host address)
I.e. it couldn’t find the server to phone home to in the cloud.

When we disabled local DNS cache in the Mikrotik (by assigning 8.8.8.8 in DHCP) the lock instantly worked.
Reverting to assigning the Mikrotik’s cacheing resolver didn’t then break the lock, but after any reboot, the lock would fail.

We ended up analyzing a packet capture to discover that the root cause was . . interesting.

The lock’s DNS query contains mixed-case hostnames.
The Mikrotik’s response contains the original query with all-lowercase characters.
The lock was therefore ignoring the reply.
8.8.8.8’s original query field was un-altered, and the lock worked.

Does this behavior in ROS’s cacheing DNS break any kind of RFC? It would seem not to be the case since there’s an RFC about being case-insensitive in the ASCII character range…

In the end, we reported this to the lock manufacturer’s tech support team, but I was wondering if the ROS behavior would be better by not munging the case of characters. . .

Thoughts?

Think it’s the lock being anal. If there’s a RFC stating case sensitivity on DNS resolution, it would be the first that I hear about it.

No, it was case INsensitivity (the RFC) and I agree that the lock is being anal about it.
Like I said, we reported it to them. I was just curious if anyone thinks that the ROS implementation should not clobber the case of the actual DNS reply.
(again, it shouldn’t matter - I agree 100%)

It more than likely shouldn’t yes. But as you said - it shouldn’t matter either.

I’d perhaps just file a bug, and shove it under the ROS v7 pile of things to do. At least if they know about it, it could be addressed one day when someone doesn’t have enough work to do.

It looks like your average DNS server or resolver does not do this, so even when it is not a bug, it surely is not a wise thing to do.
The DNS service should return the query as it was sent, and of course should do the lookup case-insensitive.
So it is fine that it stores everything in its cache in lowercase, and translates the query to lowercase before comparing it to
the cache, and it can also forward the query to the next server in lowercase, but it should reply in the same case as the query.

There’s draft-vixie-dnsext-dns0x20 from 2008 and the idea behind using random case is to better protect against spoofing. It didn’t make it to RFC, but at least some experimental support exists (I know about “use-caps-for-id” option in Unbound). It can break backward compatibility, but it doesn’t sound like the draft sees it as big problem, because (in my words) most of the software already copies the question to answers as is. DNS cache in RouterOS would be one of rare ones that don’t do it, and would require some fallback. The draft talks about authoritative servers, but the same would make sense also for caches.

To sum up, I think that lock manufacturer found an inspiration in this, but it’s wrong to rely on it.

On the other hand, if RouterOS did the same as most other DNS server software supposedly does, i.e. used the same case for replies to client, it shouldn’t hurt anything (it could still use lowercase names internally). I’m wondering if maybe Playstation problems that show occasionally in this forum are related to this (when it doesn’t work with RouterOS DNS, but works with 8.8.8.8).

Good point there.


Although, one would think that if the lock is trying to be secure, it should use DNSSec. Any spoofer could easily replicate the random case from the original query. I don’t see how that would enhance security…

That draft was a little before DNSSEC. And it’s about those once famous blind cache poisoning attacks, where you just needed to guess correct port and ID and send the right spoofed packet (or a lot of different ones) at the right time. Both should be ideally random and 16-bit each, but were often just single port and predictable ID. And even if you fix that, some extra randomness can’t hurt. Of course if attacker can see the question, nothing can help you, except DNSSEC, but even today it’s still not available everywhere.

In this case, the lock’s request IDs are 0, 1, 2 . . .
And no DNSSec.
And in 2000, planes were supposed to start falling out of the sky because of 2-digit years.
My, what a thin thread our lives all hang by.

Oh, and just for anyone’s morbid curiosity - the RFC about case-insensitivity I was referring to earlier is RFC4343

Hi. Was the IoT Door lock a Doorbird by any chance?
I have one of those in my home network, and experience very long “first connect” times from outside my network. Might be a related issue, as I have Mikrotik DNS as first resolver, and google as second resolver if I remember correctly.

As far as I remember about DNS - there is an optional thing, not the requirement, to respond to queries with the same capitalization as the request, while the lookup is done using query forced to lower case.

There is such feature request filed for “/ip dns”.

one thing about that lock - I do not really like security through obscurity. And this is one bad example of that.

We have fixed it in v7.

yes you did break RFC
review this paper
https://tools.ietf.org/html/rfc4343

If only we could use v7.. :slight_smile:

In that case, Bind did it first. It looks like all other DNS servers keep the case. We will do the same as Bind does in ROS v7

ZeroByte - can you confirm if the IoT clock is a Doorbird? (www.doorbird.com)

No, I think it’s called Lockstate… I’ll double-check with my coworker who was actually the one working the case. I just helped with the packet capture and analysis.

OK thanx anyway. It actually seems that giving 8.8.8.8 to my Doorbird solved my problem, so it seems that wifi doorlocks care about case. :slight_smile:

https://tools.ietf.org/html/rfc4343#page-4

  1. Case on Input and Output

While ASCII label comparisons are case insensitive, [STD13] says case
MUST be preserved on output and preserved when convenient on input.
However, this means less than it would appear, since the preservation
of case on output is NOT required when output is optimized by the use
of indirect labels, as explained below.

It clearly states that case must be preserved when answered, but ignored on match. It even suggests how it could be implemented. I don’t remember I had any similar issue with Bind DNS server or any other DNS server implementation.
There is not an issue with Hurricane Electric Public DNS, Google Public DNS, Yandex Public DNS, my local PowerDNS installation. I’ll try to check djbdns and different versions of Bind later.

I had many of Hikvision and Ezviz cameras with the same issue - they can not be configured in P2P mode with their mobile applications when mikrotik’s DNS used. It’s real pain and we are forced to ignore mikrotik’s DNS in that setups. This also is an issue with my Kingsmith Walkingpad R1 treadmill.


UPD: checked Bind 9.11.3 and systemd’s resolver - no issue

root@pc:~# netstat -pln|grep "udp.*:53\s"
udp        0      0 127.0.0.53:53           0.0.0.0:*                           7495/systemd-resolv
udp        0      0 192.168.44.83:53        0.0.0.0:*                           3715/named
udp        0      0 127.0.0.1:53            0.0.0.0:*                           3715/named
udp6       0      0 :::53                   :::*                                3715/named
root@pc:~# /usr/sbin/named -v
BIND 9.11.3-1ubuntu1.12-Ubuntu (Extended Support Version) <id:a375815>
root@pc:~# dig  @127.0.0.1 a1XJ81n3tV1.iot-as-mqtt.cn-shanghai.aliyuncs.com|grep -A2 ANSWER|grep a1XJ81n3tV1.iot-as-mqtt.cn-shanghai.aliyuncs.com
a1XJ81n3tV1.iot-as-mqtt.cn-shanghai.aliyuncs.com. 300 IN CNAME vpc-sh-prod.mqtt.iotgds.aliyuncs.com.
root@pc:~# dig  @127.0.0.53 a1XJ81n3tV1.iot-as-mqtt.cn-shanghai.aliyuncs.com|grep -A2 ANSWER|grep a1XJ81n3tV1.iot-as-mqtt.cn-shanghai.aliyuncs.com
a1XJ81n3tV1.iot-as-mqtt.cn-shanghai.aliyuncs.com. 299 IN CNAME vpc-sh-prod.mqtt.iotgds.aliyuncs.com.
root@pc:~#

All good with dbndns_1.05 dnscache:

root@pc:~# netstat -pln|grep "udp.*:53\s"
udp        0      0 127.0.0.53:53           0.0.0.0:*                           7495/systemd-resolv
udp6       0      0 127.0.0.1:53            :::*                                20871/dnscache
udp6       0      0 127.0.0.1:53            :::*                                20239/dnscache
root@pc:~# dig  @127.0.0.1 a1XJ81n3tV1.iot-as-mqtt.cn-shanghai.aliyuncs.com|grep -A2 ANSWER|grep a1XJ81n3tV1.iot-as-mqtt.cn-shanghai.aliyuncs.com
a1XJ81n3tV1.iot-as-mqtt.cn-shanghai.aliyuncs.com. 280 IN CNAME vpc-sh-prod.mqtt.iotgds.aliyuncs.com.

This is how it looks when MikroTik’s DNS queried:

omawnakw@pc $ DIG_DOMAIN=a1XJ81n3tV1.iot-as-mqtt.cn-shanghai.aliyuncs.com; dig +noall +answer $DIG_DOMAIN|grep $DIG_DOMAIN
omawnakw@pc $ DIG_DOMAIN=a1XJ81n3tV1.iot-as-mqtt.cn-shanghai.aliyuncs.com; dig +noall +answer $DIG_DOMAIN|grep -i $DIG_DOMAIN
a1xj81n3tv1.iot-as-mqtt.cn-shanghai.aliyuncs.com. 295 IN CNAME vpc-sh-prod.mqtt.iotgds.aliyuncs.com.

Current v7 beta keeps the case. It doesn’t sound as anything too difficult to port to v6, but for some reason it didn’t happen.