[Kea-users] DDNS TSIG verification failed: BADSIG

Randy McEoin rmceoin at freedom.com
Thu Feb 11 17:55:09 UTC 2016


I think this is a bug in PowerDNS bought to light by another bug in Kea.

When Kea constructs a DDNS query packet with a TSIG, it mistakenly sets the Original ID to 0 instead of the Transaction Id.  The TSIG MAC is calculated correctly, so PowerDNS considers the packet valid.

The breaking bug is on the PowerDNS side.  When PowerDNS constructs the DDNS response packet, it appears to use the unmodified real Transaction ID in the calculation of the HMAC.  It then proceeds to append a TSIG with the Original ID provided by the query of 0 which is not equal to the Transaction ID used in the calculation.  So Kea legitimately detects a BADKEY in the response.

For comparison, I looked at a packet capture of Kea DDNS'ing with BIND.  Of course Kea still uses 0 for the Original ID, but what's different is that BIND's response uses an Original ID == Transaction ID.  It does not use the Original ID of 0 that Kea specified in the query.

I was able to make Kea happy with the following hack on the PowerDNS side...

---------------------------------------------------
diff --git a/pdns/dnspacket.cc b/pdns/dnspacket.cc
index 5b144e6..af5822f 100644
--- a/pdns/dnspacket.cc
+++ b/pdns/dnspacket.cc
@@ -365,8 +365,10 @@ void DNSPacket::wrapup()
     }
   }
   
-  if(d_trc.d_algoName.countLabels())
+  if(d_trc.d_algoName.countLabels()) {
+    d_trc.d_origID = (((d.id & 0xFF)<<8) | ((d.id & 0xFF00)>>8));
     addTSIG(pw, &d_trc, d_tsigkeyname, d_tsigsecret, d_tsigprevious, d_tsigtimersonly);
+  }
   
   d_rawpacket.assign((char*)&packet[0], packet.size());
---------------------------------------------------

There might be an earlier spot to assign d_origID and I can fully believe there's likely a helper to deal with the Endian, but it worked like a charm.  Kea sees the responses as a SUCCESS with NOERROR.  Bert, let me know if you'd like me to open a github issue, handle the d_origID differently, or anything else I can do to help.

I rummaged but couldn't find a spot in Kea to make the Original ID equal to the Transaction ID.  If that was corrected, I suspect the bug with PowerDNS would not show itself until a legitimate situation where Original ID <> Transaction ID.  I setup a PowerDNS Master and Slave with the slave doing a forward and that didn't do the trick.  The slave re-used the Transaction ID in the forward to the master.

Randy


More information about the Kea-users mailing list