From 9739bbb3db00e0ffda3c5a3fa7cf47907ff09f04 Mon Sep 17 00:00:00 2001 From: Dorian Date: Sun, 26 Jul 2026 22:03:25 +0100 Subject: [PATCH] docs+fix: ship fips0 web-UI firewall allowance from core; changelog + What's New for v1.7.115-alpha MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fips::config::install() now writes /etc/fips/fips.d/80-web-ui.nft (tcp 80/8443 accept) and reloads the baseline on every install/upgrade — the hardening firewall default-denies inbound on fips0 and the UI was unreachable over the mesh without it (root-caused live 2026-07-26). Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 6 ++++ core/archipelago/src/fips/config.rs | 36 +++++++++++++++++++ .../src/views/settings/AccountInfoSection.vue | 12 +++++++ 3 files changed, 54 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bf18ddd..d2b4ea39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v1.7.115-alpha (2026-07-26) + +- The companion app can reach your node's screen from anywhere again. The recent security hardening locked down the node's mesh interface so tightly that the dashboard itself was blocked — the phone would pair and connect, then sit on a blank screen. The node now explicitly opens its own web interface (and only that) through the mesh firewall on every install and upgrade, so the phone's view of your node works out of the box, on any network, and can't silently break in a future update. +- The node's web interface also answers on IPv6 everywhere it answers on IPv4 — the mesh runs entirely on IPv6, and one v4-only listener was enough to make a working connection show nothing. +- Nodes now come back onto the mesh in seconds instead of minutes after their rendezvous anchor restarts: the fast-reconnect tuning proven on the phone this week is now baked into every node's mesh configuration, and it survives upgrades. + ## v1.7.114-alpha (2026-07-26) - Plugging in a mesh radio no longer traps it in an endless reboot loop. The device detector itself was causing it: every scan pulsed the radio's reset line, the same board was probed twice under two names, and retries came so fast the radio never finished booting before the next reset hit. Detection now gives the board real time to boot, probes it once, backs off properly between attempts, and no longer fights the "device detected" popup for the port. Radios that could never connect now come up within a minute of being plugged in. diff --git a/core/archipelago/src/fips/config.rs b/core/archipelago/src/fips/config.rs index d682277c..29112ac1 100644 --- a/core/archipelago/src/fips/config.rs +++ b/core/archipelago/src/fips/config.rs @@ -233,6 +233,42 @@ pub async fn install(identity_dir: &Path) -> Result<()> { let _ = tokio::fs::remove_file(&stage).await; install_result?; + // The release-hardening firewall (/etc/fips/fips.nft, provisioned + // out-of-band) default-denies inbound on fips0 — without an explicit + // allowance the node's web UI is unreachable over the mesh (phones got + // RST on :80 with a healthy session; root-caused 2026-07-26 on + // framework-pt). Ship the allowance as a fips.d drop-in on every + // install/upgrade so no node ever regresses to a UI-less mesh. + sudo_install_dir("/etc/fips/fips.d").await?; + let dropin = "# Written by archipelago on every daemon config install.\n\ + # Allows the web UI + peer API through the fips0\n\ + # default-deny inbound baseline (fips.nft).\n\ + tcp dport 80 accept\n\ + tcp dport 8443 accept\n"; + let nft_stage = std::env::temp_dir().join(format!("fips-webui-{}.nft", std::process::id())); + tokio::fs::write(&nft_stage, dropin) + .await + .context("Failed to stage web-ui nft drop-in")?; + let nft_install = sudo_install_file(&nft_stage, "/etc/fips/fips.d/80-web-ui.nft", "0644").await; + let _ = tokio::fs::remove_file(&nft_stage).await; + nft_install?; + // Make the allowance live immediately; a no-op error when the + // hardening baseline isn't installed on this node yet. + if tokio::fs::try_exists("/etc/fips/fips.nft").await.unwrap_or(false) { + match Command::new("sudo") + .args(["nft", "-f", "/etc/fips/fips.nft"]) + .output() + .await + { + Ok(out) if !out.status.success() => tracing::warn!( + "nft reload after web-ui drop-in failed: {}", + String::from_utf8_lossy(&out.stderr).trim() + ), + Err(e) => tracing::warn!("nft reload after web-ui drop-in failed: {e}"), + _ => {} + } + } + sudo_install_file(&src_key, DAEMON_KEY_PATH, "0600").await?; // Heal a legacy fips_key.pub that was written as bech32 npub text // (pre-fix identity::write_fips_key_from_seed did this). Upstream diff --git a/neode-ui/src/views/settings/AccountInfoSection.vue b/neode-ui/src/views/settings/AccountInfoSection.vue index 252ae64f..c6a101fb 100644 --- a/neode-ui/src/views/settings/AccountInfoSection.vue +++ b/neode-ui/src/views/settings/AccountInfoSection.vue @@ -362,6 +362,18 @@ init()
+ +
+
+ v1.7.115-alpha + July 26, 2026 +
+
+

The companion app can reach your node's screen from anywhere again. The recent security hardening locked down the node's mesh interface so tightly that the dashboard itself was blocked — the phone would pair and connect, then sit on a blank screen. The node now explicitly opens its own web interface (and only that) through the mesh firewall on every install and upgrade, so the phone's view of your node works out of the box, on any network, and can't silently break in a future update.

+

The node's web interface also answers on IPv6 everywhere it answers on IPv4 — the mesh runs entirely on IPv6, and one v4-only listener was enough to make a working connection show nothing.

+

Nodes now come back onto the mesh in seconds instead of minutes after their rendezvous anchor restarts: the fast-reconnect tuning proven on the phone this week is now baked into every node's mesh configuration, and it survives upgrades.

+
+