Add token expiry, edit notice, log allowlist, local-zone test; merge PLAN.md into SPECS.md
get_logs needs a unit from an allowlist (router-*, kea, unbound, networkd, nftables, ddclient, acme, sshd, kernel). API tokens are valid for 1, 7, 30 (default) or 90 days, or without limit. The overview and the Changes page say which token made the unapplied changes. options.json (router://options) no longer holds the options' source paths: they differ between builds of a release, so a router rebuilding itself offline had to build the file and failed (found by the update test). Web UI: panels flow into columns on wide screens and the width is no longer capped; on phones the navigation is a menu button; the Advanced page uses panels; VLAN dropdowns show their chosen names; the duplicate WireGuard heading is gone. basic: a subtest for wan -> local rules. SPECS.md is now the only document (decisions, how each part works, and what is not done yet); PLAN.md is gone. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AeFqV9dZrK6nipHkPfyM4F
This commit is contained in:
+35
-1
@@ -228,7 +228,7 @@ pkgs.testers.runNixOSTest {
|
||||
})
|
||||
];
|
||||
|
||||
router = { lib, ... }: {
|
||||
router = { lib, pkgs, ... }: {
|
||||
imports = [ self.nixosModules.router ];
|
||||
virtualisation.vlans = [
|
||||
1
|
||||
@@ -348,6 +348,27 @@ pkgs.testers.runNixOSTest {
|
||||
protocol = "tcp";
|
||||
ports = [ 8081 ];
|
||||
}
|
||||
# The router itself: no destination, only these senders and ports.
|
||||
{
|
||||
from = "wan";
|
||||
to = "local";
|
||||
protocol = "tcp";
|
||||
ports = [ 8022 ];
|
||||
sources = [ "${ispV4}/32" ];
|
||||
}
|
||||
{
|
||||
from = "wan";
|
||||
to = "local";
|
||||
protocol = "tcp";
|
||||
ports = [ 8023 ];
|
||||
sources = [ "192.0.2.0/24" ];
|
||||
}
|
||||
{
|
||||
from = "main";
|
||||
to = "local";
|
||||
protocol = "tcp";
|
||||
ports = [ 8024 ];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
@@ -355,6 +376,7 @@ pkgs.testers.runNixOSTest {
|
||||
# Unbound answers `.test` locally (RFC 6761) and would validate DNSSEC
|
||||
# against a fake ISP resolver that cannot provide it; neither applies to
|
||||
# a real forwarder, so relax both for the made-up test domain only.
|
||||
environment.systemPackages = [ pkgs.netcat ];
|
||||
services.unbound.settings.server = {
|
||||
local-zone = [ "test. transparent" ];
|
||||
domain-insecure = [ "example.test" ];
|
||||
@@ -465,6 +487,18 @@ pkgs.testers.runNixOSTest {
|
||||
client_ip = client.succeed("ip -4 -o addr show dev eth1 | awk '{print $4}' | cut -d/ -f1").strip()
|
||||
upstream.fail(f"ping -c 1 -W 2 {client_ip}")
|
||||
|
||||
with subtest("a wan -> local rule opens the router's port to the named sender only"):
|
||||
for port in (8022, 8023, 8024, 8025):
|
||||
router.succeed(f"systemd-run --unit=probe{port} ${pkgs.bash}/bin/bash -c 'while true; do ${pkgs.netcat}/bin/nc -l {port} < /dev/null; done'")
|
||||
router.wait_until_succeeds("ss -ltn | grep -c ':8025 ' >/dev/null", timeout=30)
|
||||
upstream.succeed("nc -z -w 2 ${routerV4} 8022")
|
||||
# Open for another sender only, for the LAN only, and not at all.
|
||||
upstream.fail("nc -z -w 2 ${routerV4} 8023")
|
||||
upstream.fail("nc -z -w 2 ${routerV4} 8024")
|
||||
upstream.fail("nc -z -w 2 ${routerV4} 8025")
|
||||
client.succeed("nc -z -w 2 192.168.10.1 8024")
|
||||
client.fail("nc -z -w 2 192.168.10.1 8022")
|
||||
|
||||
with subtest("router gets an IPv6 address, the delegated /64 and a default route"):
|
||||
router.wait_until_succeeds("ip -6 addr show dev eth1 scope global | grep -q 2001:db8:1::100")
|
||||
router.wait_until_succeeds("ip -6 addr show dev eth2 scope global | grep -q 2001:db8:2:")
|
||||
|
||||
Reference in New Issue
Block a user