Ariadne 0.1.5: route and certify every live registry TLD, not the legacy nine
Other browsers stopped opening most BNS names because two lists had drifted. The installer took its TLD set from the gateway's `advertised` field — the legacy tlds.bch record, nine TLDs — while the registry had moved to per-TLD NFTs with twenty (including .x, where most Silent Mode sites live). And the daemon's permitted-TLD list came from the bundled ariadne.config.json (seven TLDs) rather than the CA the installer had just minted, so only the overlap — .bch, .p2p, .deviant, .nav — actually worked; .sia, .nt and the rest got no certificate, .x got no route at all. Now: the gateway publishes `routable` (every live TLD on the public listing plus the legacy advertised set); the installer routes and certifies that, skipping ICANN-delegated collision TLDs (.cash, .gt, .sc — checked against the live IANA root zone, bundled snapshot as fallback) since the local CA must never be constrained to a real internet TLD; it writes the certified list into ariadne.config.json; and the daemon reads its permitted list from the installed CA's own name constraints, so the two can no longer disagree.
This commit is contained in:
parent
0b6c8093e1
commit
8904c1d7ba
3 changed files with 1494 additions and 2 deletions
1438
setup/iana-tlds.txt
Normal file
1438
setup/iana-tlds.txt
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -126,6 +126,19 @@ function Fetch-TldsFromIndexer([string]$IndexerUrl) {
|
|||
$url = $IndexerUrl.TrimEnd('/') + "/api/tlds"
|
||||
Write-Host "[..] indexer: $url"
|
||||
$r = Invoke-RestMethod -Uri $url -TimeoutSec 5 -UseBasicParsing -Headers @{ 'User-Agent' = 'AriadneResolverInstaller/1' }
|
||||
# Prefer the registry's routable list (every live per-TLD NFT plus the
|
||||
# legacy advertised set); fall back to assembling it from tlds[] + advertised
|
||||
# for a gateway that predates the field; last resort: advertised alone (the
|
||||
# legacy tlds.bch record — nine TLDs, which is how 0.1.4 missed .x).
|
||||
if ($r -and $r.routable -and $r.routable.Count -gt 0) {
|
||||
return @{ tlds = @($r.routable | ForEach-Object { [string]$_ }); source = "indexer($IndexerUrl)" }
|
||||
}
|
||||
if ($r -and $r.tlds -and $r.tlds.Count -gt 0) {
|
||||
$live = @($r.tlds | Where-Object { -not $_.hidden } | ForEach-Object { [string]$_.tld })
|
||||
$adv = @(); if ($r.advertised) { $adv = @($r.advertised | ForEach-Object { [string]$_ }) }
|
||||
$u = @($live + $adv | Where-Object { $_ } | Select-Object -Unique)
|
||||
if ($u.Count -gt 0) { return @{ tlds = $u; source = "indexer($IndexerUrl)" } }
|
||||
}
|
||||
if ($r -and $r.advertised -and $r.advertised.Count -gt 0) {
|
||||
return @{ tlds = @($r.advertised | ForEach-Object { [string]$_ }); source = "indexer($IndexerUrl)" }
|
||||
}
|
||||
|
|
@ -185,6 +198,31 @@ if ($result.source -like 'indexer(*)' -or $result.source -eq 'electrum') {
|
|||
} catch { Write-Host "[!] could not write cache: $($_.Exception.Message)" -ForegroundColor Yellow }
|
||||
}
|
||||
|
||||
# Split the activated set: TLDs that ICANN has delegated (.cash, .gt, .sc are
|
||||
# registered in BNS on purpose as collision tests) are neither routed to the
|
||||
# daemon nor certified by the local CA — the daemon's upstream forwarding has
|
||||
# an open EDNS/AAAA concern, and a CA constrained to a real internet TLD could
|
||||
# vouch for real sites. The IANA root-zone list is fetched live (8 s) and falls
|
||||
# back to the snapshot bundled next to this script. "bcnr" is always certified:
|
||||
# the daemon's default certificate is issued for gateway.bcnr.
|
||||
$ianaList = @()
|
||||
try {
|
||||
$ianaText = (Invoke-WebRequest -Uri 'https://data.iana.org/TLD/tlds-alpha-by-domain.txt' -TimeoutSec 8 -UseBasicParsing).Content
|
||||
$ianaList = @($ianaText -split "`n" | ForEach-Object { $_.Trim().ToLower() } | Where-Object { $_ -and -not $_.StartsWith('#') })
|
||||
Write-Host "[ok] IANA root zone: $($ianaList.Count) delegated TLDs (live)"
|
||||
} catch {
|
||||
$snap = Join-Path $PSScriptRoot 'iana-tlds.txt'
|
||||
if (Test-Path $snap) { $ianaList = @(Get-Content $snap | ForEach-Object { $_.Trim().ToLower() } | Where-Object { $_ }); Write-Host "[!] IANA list from bundled snapshot ($($ianaList.Count) TLDs)" -ForegroundColor Yellow }
|
||||
else { Write-Host "[!] no IANA list available -- routing every activated TLD" -ForegroundColor Yellow }
|
||||
}
|
||||
$ianaSet = @{}; foreach ($t in $ianaList) { $ianaSet[$t] = $true }
|
||||
$COLLISION_TLDS = @($ACTIVATED_TLDS | Where-Object { $ianaSet.ContainsKey($_.ToLower()) })
|
||||
$ROUTE_TLDS = @($ACTIVATED_TLDS | Where-Object { -not $ianaSet.ContainsKey($_.ToLower()) })
|
||||
if ($ROUTE_TLDS.Count -eq 0) { $ROUTE_TLDS = @('bch') }
|
||||
$CA_TLDS = @($ROUTE_TLDS + 'bcnr' | Select-Object -Unique)
|
||||
if ($COLLISION_TLDS.Count -gt 0) { Write-Host "[info] left to ICANN (delegated, resolved by the upstream): $($COLLISION_TLDS -join ', ')" }
|
||||
Write-Host "[ok] routing + certifying: $($ROUTE_TLDS -join ', ')"
|
||||
|
||||
# Generate the name-constrained local root CA now (on THIS machine; the key
|
||||
# never ships). If ca/ exists but its permitted-TLD set no longer matches, we
|
||||
# rotate: delete the stale CA so loadOrCreateRootCA writes a fresh one with
|
||||
|
|
@ -192,7 +230,7 @@ if ($result.source -like 'indexer(*)' -or $result.source -eq 'electrum') {
|
|||
# newly-added TLD.
|
||||
$caCrt = Join-Path $root "ca\root-ca.crt"
|
||||
$caKey = Join-Path $root "ca\root-ca.key"
|
||||
$tldsArg = ($ACTIVATED_TLDS | ForEach-Object { "'" + ($_ -replace "'","''") + "'" }) -join ","
|
||||
$tldsArg = ($CA_TLDS | ForEach-Object { "'" + ($_ -replace "'","''") + "'" }) -join ","
|
||||
|
||||
if (Test-Path $caCrt) {
|
||||
$r = Invoke-NodeCapture "import('./src/lib/ca.js').then(m=>{try{m.loadOrCreateRootCA([$tldsArg]);console.log('ok')}catch(e){console.log('err')}}).catch(e=>console.log('err'))"
|
||||
|
|
@ -211,6 +249,17 @@ if ($r.ExitCode -ne 0) {
|
|||
if (-not (Test-Path $caCrt)) { throw "CA generation produced no root-ca.crt" }
|
||||
Write-Host "[ok] CA at $caCrt"
|
||||
|
||||
# The daemon reads its permitted-TLD list from ariadne.config.json (and, since
|
||||
# 0.1.5, from the CA's own constraints); write the same list the CA was minted
|
||||
# with so the two can never drift apart again.
|
||||
$cfgPath = Join-Path $root 'ariadne.config.json'
|
||||
try {
|
||||
$cfg = Get-Content $cfgPath -Raw | ConvertFrom-Json
|
||||
$cfg.tlds = @($CA_TLDS)
|
||||
$cfg | ConvertTo-Json -Depth 10 | Set-Content -Path $cfgPath -Encoding utf8
|
||||
Write-Host "[ok] ariadne.config.json tlds = $($CA_TLDS -join ', ')"
|
||||
} catch { Write-Host "[!] could not update ariadne.config.json tlds: $($_.Exception.Message)" -ForegroundColor Yellow }
|
||||
|
||||
# 0) Idempotency: clear every previous NRPT rule we own (any TLD).
|
||||
Get-DnsClientNrptRule | Where-Object { $_.Comment -like 'BNS *resolver' } | ForEach-Object {
|
||||
Remove-DnsClientNrptRule -Name $_.Name -Force
|
||||
|
|
@ -249,7 +298,7 @@ if ($Mode -eq "nrpt") {
|
|||
# TLD is activated picks it up with no code release. Dual TLDs that collide
|
||||
# with ICANN are still safe to route because the daemon falls through to
|
||||
# UPSTREAM on any BCNR miss.
|
||||
foreach ($tld in $ACTIVATED_TLDS) {
|
||||
foreach ($tld in $ROUTE_TLDS) {
|
||||
$ns = ".$tld"
|
||||
# Idempotent: clean any pre-existing rule for this namespace first.
|
||||
Get-DnsClientNrptRule | Where-Object { $_.Namespace -contains $ns -and $_.Comment -like 'BNS *' } | ForEach-Object {
|
||||
|
|
|
|||
|
|
@ -847,6 +847,11 @@ const server = http.createServer(async (req, res) => {
|
|||
updated_txid: snap.asOfTxid ?? null,
|
||||
root: snap.root ?? null,
|
||||
advertised,
|
||||
// What a client resolver should route and certify: every live TLD
|
||||
// on the public listing plus the legacy advertised set. Ariadne's
|
||||
// installer used `advertised` alone until 0.1.5, which is why .x
|
||||
// and ten other registry TLDs never reached other browsers.
|
||||
routable: [...new Set([...tlds.map((t) => t.tld), ...advertised])],
|
||||
hidden_count: all.filter((t) => t.hidden).length,
|
||||
tlds,
|
||||
}, null, 2));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue