fix(lightning): don't let the LNBits Host header break TLS verification#3899
Merged
Conversation
#3893 added a 'Host: <public hostname>' header to the LNBits requests so LNBits can build correct public LNURLs and pass its HTTPS check. But the HTTP client derives the TLS servername from that Host header, so Node began validating the node's self-signed cert against api.dfx.swiss. LND and LNBits are reached over the private IP on PRD and serve a cert whose SANs are localhost/lnd/<vm-dns>/<private-ip> — api.dfx.swiss is not among them, so every /v1/lnurlp/* (and lnurlw/lnurld) call failed with ERR_TLS_CERT_ALTNAME_INVALID (500). The cert is already pinned via the CA on the shared agent, which is the real identity guarantee for a private self-signed node; the SAN/hostname match is redundant and is exactly what the spoofed Host header poisons. Skip the hostname check (keep full chain verification) so the Host header stays intact for LNBits while TLS no longer depends on it. Host-agnostic, so it also holds once dfxprd reaches LNBits as 'lnd'.
davidleomay
approved these changes
Jun 16, 2026
davidleomay
left a comment
Member
There was a problem hiding this comment.
Approved. Just needs to survive 24h until Azure cutover — on dfxprd LNBits is HTTP so this becomes dead code. Cleanup tracked in DFXServer/server#408.
This was referenced Jun 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
GET /v1/lnurlp/:id(andlnurlw/lnurld) started returning 500 on PRD:Root cause
#3893 added a
Host: <public hostname>header to the LNBits requests so LNBits buildscorrect public LNURLs and passes its HTTPS check. But the HTTP client derives the TLS
SNI/
servernamefrom thatHostheader, so Node began validating the node'sself-signed cert against
api.dfx.swiss.On PRD, LND and LNBits are reached over the private IP and serve a cert whose SANs
are
localhost / lnd / <vm-dns> / <private-ip>—api.dfx.swissis not among them, soevery LNURL call failed with
ERR_TLS_CERT_ALTNAME_INVALID.Fix
The cert is already pinned via the
caon the shared agent — that pin is the realidentity guarantee for a private self-signed node, and full chain verification is kept
(
rejectUnauthorizedstays on). The SAN/hostname match is redundant here and is exactlywhat the spoofed
Hostheader poisons, so we skip only the hostname check. TheHostheader stays intact for LNBits, and the fix is host-agnostic, so it also holds once
dfxprd reaches LNBits as
lnd.Note / follow-up for review
This drops the hostname check (not chain verification) — a fast, safe unblock for the
live outage. The cleaner long-term fix is to add the public hostname to the node cert
SANs (
tlsextradomain=api.dfx.swissalready exists in the dfxprd migrationlnd.conf;the live cert just predates it). Once the cert carries the SAN, this override can be
removed. @davidleomay — flagging since this is your #3893 area; happy to switch to the
SAN approach if you prefer.