Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENS lookups are being done with DNSLink and failing. #10639

Open
3 tasks done
MicahZoltu opened this issue Dec 22, 2024 · 4 comments
Open
3 tasks done

ENS lookups are being done with DNSLink and failing. #10639

MicahZoltu opened this issue Dec 22, 2024 · 4 comments
Labels
kind/bug A bug in existing code (including security flaws) need/triage Needs initial labeling and prioritization

Comments

@MicahZoltu
Copy link

MicahZoltu commented Dec 22, 2024

Checklist

Installation method

ipfs-desktop

Version

Gateway version page in the GitHub issue template results in a 404.

IPFS Desktop 0.40.0

Config

You cannot run ipfs CLI commands with IPFS desktop. I think what you want is this though (some redacted):

{
	"API": {
		"HTTPHeaders": {
			"Access-Control-Allow-Origin": [
				"https://webui.ipfs.io",
				"http://webui.ipfs.io.ipns.localhost:8080",
				"http://127.0.0.1:5001"
			]
		}
	},
	"Addresses": {
		"API": "/ip4/127.0.0.1/tcp/5001",
		"Announce": null,
		"AppendAnnounce": null,
		"Gateway": "/ip4/0.0.0.0/tcp/8080",
		"NoAnnounce": null,
		"Swarm": [
			"/ip4/0.0.0.0/tcp/4001",
			"/ip6/::/tcp/4001",
			"/ip4/0.0.0.0/udp/4001/webrtc-direct",
			"/ip4/0.0.0.0/udp/4001/quic-v1",
			"/ip4/0.0.0.0/udp/4001/quic-v1/webtransport",
			"/ip6/::/udp/4001/webrtc-direct",
			"/ip6/::/udp/4001/quic-v1",
			"/ip6/::/udp/4001/quic-v1/webtransport"
		]
	},
	"AutoNAT": {},
	"Bootstrap": [
		"/dnsaddr/bootstrap.libp2p.io/p2p/****",
		"/dnsaddr/bootstrap.libp2p.io/p2p/****",
		"/ip4/104.131.131.82/tcp/4001/p2p/****",
		"/ip4/104.131.131.82/udp/4001/quic-v1/p2p/****",
		"/dnsaddr/bootstrap.libp2p.io/p2p/****",
		"/dnsaddr/bootstrap.libp2p.io/p2p/****",
		"/ip4/45.76.185.63/tcp/4001/p2p/****",
		"/ip4/45.76.185.63/udp/4001/quic/p2p/****"
	],
	"DNS": {
		"Resolvers": {}
	},
	"Datastore": {
		"BloomFilterSize": 0,
		"GCPeriod": "1h",
		"HashOnRead": false,
		"Spec": {
			"mounts": [
				{
					"child": {
						"path": "blocks",
						"shardFunc": "/repo/flatfs/shard/v1/next-to-last/2",
						"sync": true,
						"type": "flatfs"
					},
					"mountpoint": "/blocks",
					"prefix": "flatfs.datastore",
					"type": "measure"
				},
				{
					"child": {
						"compression": "none",
						"path": "datastore",
						"type": "levelds"
					},
					"mountpoint": "/",
					"prefix": "leveldb.datastore",
					"type": "measure"
				}
			],
			"type": "mount"
		},
		"StorageGCWatermark": 90,
		"StorageMax": "10GB"
	},
	"Discovery": {
		"MDNS": {
			"Enabled": true,
			"Interval": 10
		}
	},
	"Experimental": {
		"FilestoreEnabled": false,
		"GraphsyncEnabled": false,
		"Libp2pStreamMounting": false,
		"P2pHttpProxy": false,
		"StrategicProviding": false,
		"UrlstoreEnabled": false
	},
	"Gateway": {
		"APICommands": [],
		"HTTPHeaders": {},
		"NoDNSLink": false,
		"NoFetch": false,
		"PathPrefixes": [],
		"PublicGateways": null,
		"RootRedirect": "",
		"Writable": false
	},
	"Identity": {
		"PeerID": "****"
	},
	"Internal": {},
	"Ipns": {
		"RecordLifetime": "",
		"RepublishPeriod": "",
		"ResolveCacheSize": 128
	},
	"Migration": {
		"DownloadSources": [],
		"Keep": ""
	},
	"Mounts": {
		"FuseAllowOther": false,
		"IPFS": "/ipfs",
		"IPNS": "/ipns"
	},
	"Peering": {
		"Peers": [
			{
				"Addrs": [],
				"ID": "****"
			}
		]
	},
	"Pinning": {
		"RemoteServices": {}
	},
	"Plugins": {
		"Plugins": null
	},
	"Provider": {
		"Strategy": ""
	},
	"Pubsub": {
		"DisableSigning": false,
		"Router": ""
	},
	"Reprovider": {},
	"Routing": {
		"AcceleratedDHTClient": false,
		"Routers": null
	},
	"Swarm": {
		"AddrFilters": null,
		"ConnMgr": {},
		"DisableBandwidthMetrics": false,
		"DisableNatPortMap": false,
		"RelayClient": {},
		"RelayService": {},
		"ResourceMgr": {},
		"Transports": {
			"Multiplexers": {},
			"Network": {},
			"Security": {}
		}
	}
}

Description

Attempting to navigate to ipns://2.horswap.eth with IPFS Companion installed redirects me to http://2.horswap.eth.ipns.localhost:8080/. That page results in an IPFS 500 error page that says:

failed to resolve /ipns/2.horswap.eth/: DNSLink lookup for "2.horswap.eth." failed: could not resolve name: DNSLink lookup could not find a TXT record (https://docs.ipfs.tech/concepts/dnslink/)

Based on the error, it appears that IPFS is attempting to resolve 2.horswap.eth using DNS rather than using ENS.

This used to work. I recently updated IPFS Desktop which seems like the most likely cause of this the problem.

@MicahZoltu MicahZoltu added kind/bug A bug in existing code (including security flaws) need/triage Needs initial labeling and prioritization labels Dec 22, 2024
@aschmahmann
Copy link
Contributor

using DNS rather than using ENS.

Kubo is using the DNSLink standard to do the ENS lookups, it's not falling back to ICANN DNS here. Instead this looks like an issue with the default ENS resolver in kubo which is cloudflare's https://github.com/ipfs/kubo/blob/master/docs/config.md#dnsresolvers. It looks like their resolver is having a problem, but if you switched to another one (e.g. I tried https://dns.eth.limo/dns-query and things looked good).

Examples:

❯ curl -H "accept: application/dns-json" "https://resolver.cloudflare-eth.com/dns-query?name=2.horswap.eth&type=TXT"
{"AD":true,"CD":false,"RA":true,"RD":true,"TC":false,"Status":3,"Question":[{"name":"2.horswap.eth.","type":16}],"Answer":[]}
❯ curl -H "accept: application/dns-json" "https://dns.eth.limo/dns-query?name=2.horswap.eth&type=TXT"
{"Status":"0","TC":false,"Question":[{"name":"2.horswap.eth","type":16}],"Answer":[{"name":"2.horswap.eth","data":"dnslink=/ipfs/bafybeibtdjzmhx77pxlpmy7fqnwyb7dmrtwbk3n6fpyw3qdgmxaznzwm44","type":16,"ttl":300}]}

It seems to be an outage on their end and similar to other ones in the past #8836.

The simplest incremental improvement here is likely being able to support multiple DNSLink resolvers from the ENS community (e.g. #8173 (comment)) so that if the ENS community designates multiple trusted resolvers (e.g. Cloudflare + eth.limo) there'd be some operational resiliency

A next stage would be being able to make performing ENS queries easy and inexpensive enough that many people (or ideally anyone) could run them rather than just a few bigger infra providers. My understanding is that right now this isn't doable, but I would definitely be interested in engaging with the broader ENS community on this if there was interest. Note: in my capacity working with the Shipyard team (https://blog.ipfs.tech/shipyard-hello-world/) I've had some conversations with the ENS Labs and eth.limo folks about this, while I think there's interest I suspect more community demand is required to make this into a reality though given that having more resilient / decentralized ENS resolution is a big task. This issue will likely get closed if there's nothing else I'm missing but if there's interest in chatting more about this we can do so on https://discuss.ipfs.tech/ or the IPFS Chat channels (Matrix, Slack, Discord, etc.)

@MicahZoltu
Copy link
Author

Why isn't this just using an Ethereum JSON-RPC server? That would also make it trivial to configure, as users would just have to specify an Ethereum JSON-RPC server of their choice, which some ENS users may already have and of which there are many ways to gain access to one and several public ones.

@lidel
Copy link
Member

lidel commented Dec 23, 2024

Why isn't this just using an Ethereum JSON-RPC server?

There are various reasons, but imo the most important one is to keep maintenance cost low and prefer vendor-agnostic way of doing things to ensure our code does not pick "winners" and is not artificially locking people into using specific project/blockchain/smartcontract to do name mapping.

As Kubo maintainers:

  • We don't want to include proprietary client libraries / HTTP APIs / hardcoding even more HTTP endpoints
  • We also don't want to act as gatekeepers and triage every blockchain-based ENS clone that also wants their own RPC and smart contract to be supported in IPFS stack.

👉 https://dnslink.dev is vendor-agnostic way of mapping DNS names to content paths and acts as universal bridge. Does not require anyone's blessing, you can create DNSLnk bridge for your own blockchain naming system and it will work with every deployment.

Note

TLDR Kubo/IPFS stack does not support ENS. Kubo supports DNSLink, and ENS happens to work if compatible ENS 2 DNSLink bridge is set up

On solving ENS issue at hand: use different DoH resover

ENS DoH resolver at https://resolver.cloudflare-eth.com/dns-query is down.

We are tracking upstream fix in ipfs/boxo#771.

If you want to fix your Kubo without waiting for upstream fix, set eth. in DNS.Resolvers to https://dns.eth.limo/dns-query and restart your node.

On running own ENS-based DNSLink resolver

You can also create / run your own ENS 2 DNS gateway (prior art: https://github.com/wealdtech/coredns-ens), expose things as DNS TXT record and be compatible with every legacy Kubo/Boxo without having to change any line of code.

We are open to discussing adding verifiable ENS in some way, but as far I understand, there is no public JSON-RPC that allows client to retrieve enough information to verify the name, making entire idea moot. Happy to be proven otherwise with a working PoC, but at the end of the day, whatever you expose over proprietary Ethereum JSON-RPC, you can also expose over RFC-compliant DNS TXT response.

@MicahZoltu
Copy link
Author

Your points about having an agnostic system for resolution make sense to me.

On verifiable ENS, if you have a recent blockhash to anchor to (which is widely available from many places on the internet), you can get a proof of ENS name resolution from an Ethereum JSON-RPC client and then validate that proof client side. Without a blockhash to anchor to though, you cannot prove anything (this is true for all blockchains).

Is it reasonable to acquire a blockhash from one or more centralized sources and then ask a configured Ethereum JSON-RPC server for a proof, or were you hoping for something that wouldn't require a blockhash anchor even?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug A bug in existing code (including security flaws) need/triage Needs initial labeling and prioritization
Projects
None yet
Development

No branches or pull requests

3 participants