monero-project / monero

Monero: the secure, private, untraceable cryptocurrency
https://getmonero.org
Other
8.81k stars 3.08k forks source link

Warning "Invalid DNSSEC TXT record signature for updates.moneropulse.org" #8452

Open stmax82 opened 2 years ago

stmax82 commented 2 years ago

I'm getting the following warning soon after starting monerod since I updated to v0.18:

W Invalid DNSSEC TXT record signature for updates.moneropulse.org: validation failure <updates.moneropulse.org. TXT IN>: no DNSKEY rrset from 127.0.0.11 for trust anchor . while building chain of trust

Not sure what it's trying to tell me.

Tested on Ubuntu 18.04 and 22.04 in Docker.

selsta commented 2 years ago

From IRC

09:49 <@fluffypony> "no DNSKEY rrset for trust anchor . while building chain of trust"
09:49 <@fluffypony> ok so that's the root domain
09:49 <@fluffypony> the way DNSSEC works is it only has one key hardcoded, the one for .
09:50 <@fluffypony> then it checks the trust anchor for .net based on the trust anchor for .
09:50 <@fluffypony> then the trust anchor for moneropulse.net, and then for updates.moneropulse.net
09:50 <@fluffypony> so if it's failing on . that means that either your ISP isn't serving DNSSEC records when requested, OR the utility is busted

At the moment it's unclear if this is a monero bug or if it's an ISP issue. You can ignore it for now.

OrvilleRed commented 2 years ago

I also got this same DNSSEC warning upon running v18.0

Debugged a little on IRC with moo.

dig -t TXT updates.moneropulse.org returned success: ; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20843

I ran monerod with --log-level 4 and pared down the log to what I think are the relevant bits; saved here https://paste.debian.net/1248443/

I do see that after the initial warning, monerod is "falling back to TCP with well known DNSSEC resolvers". It's not 100% clear from the log whether that fallback worked, but afterwards I do see further messages like "Performing DNSSEC TXT record query for updates.moneropulse.fr" that are not followed by any error.

I'm happy to provide more debug info as requested

I'm happy to provide any other debug output to help

sanderfoobar commented 2 years ago

This error is reproducible with my (possibly stupid) router, /etc/resolv.conf having the common value of:

nameserver 127.0.0.53

And the following code:

// gcc main.cpp -lunbound -o main
#include <stdio.h>
#include <string.h>
#include <unbound.h>

static struct ub_ctx *uctx = NULL;
#define TYPE_TXT 16

int main() {
  struct ub_result *result;
  char domain[] = "updates.moneropulse.org";

  if (uctx == NULL) { uctx = ub_ctx_create(); }
  ub_ctx_add_ta(uctx, ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n");

  ub_ctx_resolvconf(uctx, NULL);
  ub_resolve(uctx, domain, TYPE_TXT, 1, &result);

  if (result->secure)
    fprintf(stdout, "DNSSEC validation successful for domain %s.\n", domain);
  else
    fprintf(stdout, "DNSSEC validation failed: %s\n", result->why_bogus);

  if (result->bogus)
    fprintf(stdout, "Possible attack on this domain :(\n");

  if (result->data[0] != NULL)
    fprintf(stdout, "DNS reply received: %s\n", result->data[0]);
 else
    fprintf(stdout, "DNS empty :(");
  return 1;
}

When getting rid of the function ub_ctx_resolvconf the error goes away. In the Monero codebase this function is called here and can be 'skipped' by setting an env. var:

DNS_PUBLIC="tcp://8.8.8.8" ./monerod 

Or you can modify /etc/resolv.conf such that it includes nameserver 8.8.8.8

In my case 127.0.0.53 goes to systemd-resolved which in turn is configured by my router via DHCP. Not sure where exactly this DNSSEC query breaks.

side-note

Unrelated to this issue, I believe the DS on the first line here is outdated (since 2019):

https://github.com/monero-project/monero/blob/b6a029f222abada36c7bc6c65899a4ac969d7dee/src/common/dns_utils.cpp#L105-L106

You can confirm this by using get_trust_anchor.py or looking at root-anchors.xml

sanderfoobar commented 2 years ago

The naming of DNS_PUBLIC env. var is a bit 'weird' here because it kind of implies a bool switch that will make unbound use public server(s). Indeed, if we call ub_resolve without using ub_ctx_resolvconf, libunbound's default behavior is to use some internally defined public servers.

Maybe an env. var by the name of DNS_ADDRESS (or some such) is better suited should one feel the need to supply their own DNS.

sanderfoobar commented 2 years ago

To conclude, I think my default DNS server (and OPs) do not handle DNSSEC correctly. Monero operates in 2 ways:

  1. it either respects the network config (/etc/resolv.conf)
  2. or you manually supply it an alternative via e.g DNS_PUBLIC

Monero cannot automatically fallback on alternatives like the DNS servers provided by unbound because that would be considered a privacy leak.

So make sure your network infra is up to spec. Issue can be closed if someone agrees with this conclusion.

OrvilleRed commented 2 years ago

Yes, my resolv.conf was also using the "special" systemd-resolved address (127.0.0.53); it seems my current VPS mandates this.

I've verified that after setting DNS_PUBLIC to a more reliable DNS, I no longer get the DNSSEC warning

How about adding some info to the existing warning message? For example:

WARNING Invalid DNSSEC TXT record signature for ...
WARNING Your DNS server isn't behaving well. You can tell monerod to use an alternate via env variable DNS_PUBLIC. Example: DNS_PUBLIC="tcp://9.9.9.9" 

BTW, 9.9.9.9 is the IP address for Quad9, a Swiss public-benefit, not-for-profit foundation which purports to be privacy-respecting. It's probably a better example suggestion that Google's 8.8.8.8

flipkickmedia commented 1 year ago

I'm also seeing this. IMO this is a highly worrying message as it suggests there is an issue with the validity of the DNS records being provided to your monerod.

https://dnsviz.net/d/updates.moneropulse.org/dnssec/

This shows the chain of trust is correct. There shouldn't be any problems with this record, as its just another DNS entry which should be supported by all DNS providers.

Furthermore, it appears that the DS record is stored inside some code: https://github.com/monero-project/monero/issues/8474

This is even more worrying. If a dev can provide a good explanation of why this is so. I cant think of any scenario where you would store a DS record in code.

These records should be checked live and the chain of trust should come from the TLD provider, not some record in code which can be modified.

selsta commented 1 year ago

If a dev can provide a good explanation of why this is so

This is the commit where it got added, doesn't really say why, just that it should not be hardcoded in the future: https://github.com/monero-project/monero/pull/244/commits/dbf46a721af5d54792bca80fc1c439c1badc9069

qrhfz commented 1 year ago

i have the same problem. what is updates.moneropulse.org? i can't access it from browser.

flguy76 commented 1 year ago

did you notice what IP monerod is falling back to? is it a root server or a public run server like googles?

flguy76 commented 1 year ago

storing a non authoritive server inside code can lead to dangerous outcomes. and if someone wants to redirect all our traffic by changing the IP address of that record thats on the server embedded in the code things can get pretty nasty for your solo server quickly. thats why security on DNS servers and the records that you server and are authorities for its important because you could be routed to some script kiddies home based DNS server and theres a lot that can go wrong from there. esp for the windows guys.. I kind of want some form of explaination why this made it from the development tree into the production release tree. thats the point of having one tree you develop in and another you release from. so you can double and tripple check in a lab environment before it ever goes into production. I have been a system engineer for 25 years and never once have we embedded DNS servers in release code. its just not safe. Makes us the lab rat not the end user.

sanderfoobar commented 1 year ago

@flguy76

storing a non authoritive server inside code can lead to dangerous outcomes.

If you actually read (or understood) my replies you would find that Monero does not "store non-authoritative servers inside the code". It doesn't even fallback on any DNS servers, as unbound's default behavior is actively disabled. Monero simply follows the network configuration of the OS it runs on.

In fact, Monero is probably 'stricter' than most applications because it refuses to fallback - instead it screams at the user, which is why this thread exists.

uyriq commented 1 year ago
DNS_PUBLIC="tcp://8.8.8.8" 

are the variants tls (DOT), https (DOH) possible, in addition to simple tcp?

OrvilleRed commented 1 year ago

are the variants tls (DOT), https (DOH) possible, in addition to simple tcp?

No; the format and protocol must be "tcp". sscanf(s, "tcp://%u.%u.%u.%u%c"

blackzbr4 commented 9 months ago

i figured out that my blockchain got somehow corrupted. After removing it of course daemon starts to download the chain again. Other then before it now started to do so immediately. However, after the first few messages about the status of the update the "invalid dnssec txt..." message appeared couple times but then I did not got it any more after i downloaded 1% of the chain or so. But importantly the daemon keeped updating. i think the damage accrued when i started the daemon and it was updating my blockchain when suddenly the grid went down. when turning the computer back on i had this message the first time.