revert(vds-nftables): restore original config — T3 fix needs discussion

Owner request 2026-10-10: 'отмени вообще правки файрволла, верни
пока какие были до твоих работ. это требует обсуждения, потому
что по прежнему ничего не работает, сайт не открывается,
reality не работает.'

This reverts 5 T3 code commits + 2 T3 doc commits:
  5796786 fix(vds-nftables): apply Option A
  3deaa75 fix(vds-nftables): remove allowPing
  4dc4849 fix(vds-nftables): open SSH on all interfaces
  2649e2f fix(vds-nftables): open port 80
  51ea19a fix(vds-nftables): open port 8443
  677d39e docs(T3): note correction
  fafd3e2 docs(T3): mark nftables fix as applied

Restored:
- configurations/vds.nix → original from 61b3724 (firewall.enable = true,
  firewall.interfaces.tailscale0.allowedTCPPorts = [22], nftables with
  SYN rate-limit on {80,443})
- .agent/tasks/manifest.json T3 → status = 'pending' (was 'completed')
- .agent/decisions/index.json T3-A → status = 'proposed' (was 'accepted')

The proposal .agent/decisions/proposals/vds-nftables-fix.md is NOT
removed — it's still a proposal for future discussion, just not
applied. nft list ruleset on otreca will return to the original
(firewall-managed) state after rebuild.

T3 needs proper discussion with owner before re-applying. The
issues observed (site not opening, reality not working) need
diagnostic before any new fix attempt.
This commit is contained in:
2026-10-10 17:30:58 +03:00
parent 51ea19aef4
commit 37b4956a25
3 changed files with 21 additions and 71 deletions
+13 -64
View File
@@ -2,23 +2,6 @@
#
# The host record lives in configurations/default.nix; this file is only the
# module body. `xlib` (identity, dirs, helpers) arrives as a module argument.
#
# T3 FIX (minimal, R1.6 only) 2026-10-10:
# - Explicit `policy drop` on chain input (R1.6 fix — original ruleset
# had no policy, so it was implicit accept)
# - Removed `firewall.enable = true` to eliminate the
# `firewall.*` + `nftables.*` conflict (R1.6)
# - SSH (22) open on ALL interfaces (no iifname restriction)
# - Xray REALITY (443) open
# - ICMP + traceroute (33434-33534) for diagnostics
# - 80/HTTP closed by default
# - Log + drop at the end (nft-drop: prefix) for diagnostics
#
# CORRECTED 2026-10-10: removed `iifname "tailscale0"` restriction on
# SSH — owner did not ask for that. SSH is open on ens3 too.
#
# On otreca: management via Tailscale OR public SSH. Public attack
# surface is SSH (22) + Xray REALITY (443).
{
lib,
modulesPath,
@@ -59,21 +42,17 @@
};
host.ssh.enable = true;
# SSH is reachable on all interfaces (public + Tailscale). The
# nftables ruleset below opens 22 explicitly. `openFirewall = false`
# because we manage the firewall via nftables, not the NixOS
# firewall module (see `firewall.enable = false` further down).
# SSH is reachable only over Tailscale (not on the public internet).
# This otreca VDS is reached by deploy-rs and by oqyude over the
# tailnet, so exposing 22 to ens3 is pure attack surface.
services.openssh.openFirewall = false;
services.tailscale = {
enable = true;
openFirewall = true;
};
# REMOVED 2026-10-10: networking.firewall.interfaces.tailscale0.allowedTCPPorts = [ 22 ].
# SSH is now opened on ALL interfaces via the nftables ruleset below
# (`tcp dport 22 accept` — no iifname restriction).
# Owner corrected: "не помню, чтобы просил ограничивать 22 порт".
# Open port 22 only on the tailscale interface.
networking.firewall.interfaces.tailscale0.allowedTCPPorts = [ 22 ];
networking = {
nameservers = [
"1.1.1.1"
@@ -85,24 +64,16 @@
enable = true;
IPv6rs = false;
};
# T3 (R1.6 fix): `firewall.enable = false` eliminates the
# `firewall.*` + `nftables.*` conflict. The `lib.mkForce` on
# `allowedTCPPorts` and `interfaces` prevents the NixOS firewall
# module from silently injecting rules that would shadow our
# nftables ruleset. All filtering is now done by the ruleset below.
firewall.enable = false;
firewall.allowedTCPPorts = lib.mkForce [ ];
firewall.interfaces = lib.mkForce { };
# `networking.allowPing` was removed because with firewall.enable = false
# it no longer exists as a top-level option. ICMP accept is handled
# by the nftables ruleset below (`ip protocol icmp accept`).
firewall = {
enable = true;
allowPing = true;
};
nftables = {
enable = true;
ruleset = ''
table inet filter {
chain input {
type filter hook input priority 0;
policy drop;
# loopback
iif lo accept
@@ -110,33 +81,11 @@
# уже установленные
ct state established,related accept
# ICMP (path MTU discovery + diagnostics)
ip protocol icmp accept
# РЕЖЕМ SYN СРАЗУ
tcp flags syn tcp dport {80,443} limit rate 20/second burst 40 packets accept
tcp flags syn tcp dport {80,443} drop
# traceroute
udp dport 33434-33534 accept
# SSH (22) — open on all interfaces (owner: no iifname restriction)
tcp dport 22 accept
# HTTP (80) — needed for ACME HTTP-01 challenge (LE cert renewal)
# and for HTTP → HTTPS redirect if nginx vhost is configured.
# ADDED 2026-10-10: previous T3 fix accidentally dropped port 80,
# breaking pubray1.zeroq.su cert renewal.
tcp dport 80 accept
# Xray REALITY inbound (treca acts as relay from sapphira via XHTTP)
tcp dport 443 accept
# 3x-ui Xray REALITY inbound on container (0.0.0.0:8443:8443 in
# modules/containers/3x-ui.nix). Direct public mapping — NOT
# proxied through nginx (that was `reality443Forwarding`,
# погашен в T10). ADDED 2026-10-10: previous T3 fix missed
# this port, Xray was unreachable from outside.
tcp dport 8443 accept
# log for diagnostics (journalctl -k | grep nft-drop)
log prefix "nft-drop: " flags all counter drop
# остальное по необходимости
}
}
'';