feat(host): add guarded Debian baseline and SSH transactions

This commit is contained in:
kaka
2026-11-04 16:55:00 +08:00
parent 62ef4b458c
commit 873933af35
6 changed files with 471 additions and 12 deletions

View File

@@ -123,13 +123,26 @@ UNIT
systemctl enable platform-firewall.service >/dev/null
systemctl restart platform-firewall.service
}
check_ssh_transaction() {
local transaction=$1 digest=$2 ssh_state=${3:-/var/lib/platform-bootstrap/ssh}
if [[ -e "$ssh_state/pending" ]]; then
trusted_path "$ssh_state/pending" || return 1
trusted_path "$ssh_state/expected-firewall-sha" || return 1
[[ "$transaction" =~ ^[a-f0-9]{64}$ && "$transaction" == "$(cat "$ssh_state/pending")" &&
"$digest" == "$(cat "$ssh_state/expected-firewall-sha")" ]] || {
fail 'SSH maintenance owns the firewall; exact transaction and target policy required'; return 1;
}
else
[[ -z "$transaction" ]] || { fail 'SSH transaction expired or already completed'; return 1; }
fi
}
main() {
local action='' policy='' expected='' state=/run/platform-firewall task digest previous connection
local action='' policy='' expected='' ssh_transaction='' state=/run/platform-firewall task digest previous connection
while (($#)); do
case "$1" in
--help|-h) echo 'Usage: bash firewall.sh --render|--check|--apply --policy ROOT_0600_JSON | --confirm --sha256 SHA'; return 0;;
--help|-h) echo 'Usage: bash firewall.sh --render|--check|--apply --policy ROOT_0600_JSON | --confirm --sha256 SHA [--ssh-transaction SHA during SSH migration]'; return 0;;
--render|--check|--apply|--confirm) [[ -z "$action" ]] || return 1; action=$1; shift;;
--policy|--sha256) (($# >= 2)) || return 1; case "$1" in --policy) policy=$2;; --sha256) expected=$2;; esac; shift 2;;
--policy|--sha256|--ssh-transaction) (($# >= 2)) || return 1; case "$1" in --policy) policy=$2;; --sha256) expected=$2;; --ssh-transaction) ssh_transaction=$2;; esac; shift 2;;
*) fail "Unknown argument: $1"; return 1;;
esac
done
@@ -144,6 +157,7 @@ main() {
[[ "$expected" =~ ^[a-f0-9]{64}$ && -f "$state/pending.nft" ]] || { fail 'Exact pending policy digest required'; return 1; }
digest=$(sha256sum "$state/pending.nft"); digest=${digest%% *}
[[ "$expected" == "$digest" ]] || { fail 'Pending policy differs'; return 1; }
check_ssh_transaction "$ssh_transaction" "$digest"
connection=${SSH_CONNECTION:-}
[[ -n "$connection" && "$connection" != "$(cat "$state/original-ssh")" ]] || { fail 'Confirm from a new SSH transport after checking allowed and denied ports'; return 1; }
nft -s list table inet platform_host > "$state/current.nft"
@@ -172,6 +186,7 @@ main() {
nft --check --file "$task/rules.nft"
digest=$(sha256sum "$task/rules.nft"); digest=${digest%% *}
if [[ "$action" == --check ]]; then echo "Firewall policy checked: $digest"; return; fi
check_ssh_transaction "$ssh_transaction" "$digest"
[[ ! -f "$state/pending.nft" ]] || { fail 'A policy is pending confirmation; inspect it or wait for rollback'; return 1; }
# Rollback only our table, preserving concurrent native Tailscale/Docker rules.
printf 'add table inet platform_host\ndelete table inet platform_host\n' > "$task/rollback.nft"