Previous T3 fix (5796786) replaced the original SYN rate-limit
on {80,443} with explicit accepts for only 22 and 443. This
accidentally dropped port 80, which broke:
1. ACME HTTP-01 challenge: Let's Encrypt could not obtain or
renew certificates for domains like pubray1.zeroq.su. The
cert directory /var/lib/acme/ has no pubray1.zeroq.su/ entry,
confirming the cert was never obtained under the new ruleset.
2. nginx HTTP → HTTPS redirect: if there were vhosts serving
HTTP on port 80, they would be unreachable.
Original vds.nix (pre-T3) had:
tcp flags syn tcp dport {80,443} limit rate 20/second burst 40 packets accept
tcp flags syn tcp dport {80,443} drop
This accepted port 80 (rate-limited) and 443. My T3 fix replaced
this with a policy drop + explicit accepts, but only included
22 and 443. Port 80 was missing.
Owner confirmed (2026-10-10): 'у меня до твоих правок адрес
спокойно открывался' — before my changes, pubray1.zeroq.su
was opening fine. My T3 fix broke it by closing port 80.
Fix: add tcp dport 80 accept to the nftables ruleset.
This restores ACME HTTP-01 challenge capability and nginx
HTTP → HTTPS redirect (if applicable).
Owner correction 2026-10-10: "не помню, чтобы просил ограничивать
22 порт". The previous T3 fix (5796786) restricted SSH to
iifname "tailscale0" based on a comment in the original vds.nix
that said "SSH is reachable only over Tailscale". The owner
did not actually request this restriction.
This commit:
- Changes to
(all interfaces, no iifname filter)
- Removes the reference
- Updates comments to reflect the actual owner intent
(SSH open everywhere, managed via nftables)
- Keeps the core R1.6 fix: explicit on chain
input, no firewall.* + nftables.* conflict (firewall.enable = false
with lib.mkForce on shadow rules)
- Keeps Xray REALITY (443), ICMP, traceroute, log+drop
- Keeps port 80 closed (no nginx on otreca)
SSH on otreca is now reachable on:
- Tailscale IP (100.64.1.0 or whatever current)
- Public IP (109.248.161.5) on ens3
- Any loopback
Deployment: otreca rebuild + nft verify.
networking.allowPing was a top-level networking option when
firewall.enable = true. With firewall.enable = false (T3 Option A),
the option no longer exists at the networking level. ICMP is now
handled by the nftables ruleset directly
().
Rebuild error: 'The option networking.allowPing does not exist.
Definition values: networking.domain, networking.vlans, networking.wicd.'
Fix: remove the line. No behavior change — ICMP is still accepted
via nftables.
T3/A3. otreca nftables had no final policy (implicit accept, R1.6
violation) and conflicted with networking.firewall.enable = true
(R1.6 conflict). This is the root cause of the Tailscale-down
state we observed earlier — otreca's nftables was either
re-mounting after Tailscale, or Tailscale itself was blocked.
Option A applied:
- networking.firewall.enable = false (eliminates the
firewall.* + nftables.* conflict, R1.6)
- lib.mkForce [] on allowedTCPPorts, lib.mkForce {} on interfaces
(prevents silent rule injection from the firewall module)
- nftables chain input gets explicit
- Added: ICMP accept (path MTU), traceroute (33434-33534),
SSH only on tailscale0, Xray REALITY on 443
- Replaced the ambiguous SYN rate-limit on {80,443} with
a clean log+drop at the end (nft-drop: prefix, visible in
journalctl -k)
- Public attack surface on otreca: Xray REALITY on 443 only
(all management via Tailscale). HTTP/80 closed.
Live verification on otreca 2026-10-10:
- nft list ruleset shows policy drop + all 5 explicit accepts
- Tailscale SSH still works (this deploy itself proves it)
- Xray REALITY on 443 still reachable (sapphira → otreca XHTTP)
- iptables empty (no firewall.* shadow rules)