Linux Firewall Hardening
/install linux-firewall-hardening
Linux Firewall Hardening
When to Use
- Check if a Linux server has active firewall protection.
- Enable and configure a firewall without locking yourself out of SSH.
- Audit existing rules, troubleshoot connectivity, or apply a security profile.
- Automate firewall hardening via an AI agent or CI/CD pipeline.
When NOT to Use
| Condition | Alternative |
|---|---|
| Kubernetes worker node | Use NetworkPolicies / CiliumNetworkPolicy |
| Firewall managed by Terraform/Ansible/Puppet/Chef | Update IaC source of truth |
| Cloud workload with Security Group / NSG only | Use cloud provider's firewall API |
| Inside a container | Escalate to host operator |
| WSL2, macOS, or shared/managed hosting | See references/special-environments.md |
Support files:
scripts/audit-firewall.sh(run first),scripts/firewall-plan.sh(dry-run),scripts/firewall-verify.sh(post-apply). Detailed backend guides, Docker/K8s policies, observability, compliance, and recovery are inreferences/.
Prerequisites
- Root or sudo access.
- An active SSH session (risk of lockout).
- Know which ports your services use.
NEVER DO (14 Rules)
- Never flush iptables/nftables on Kubernetes nodes. CNI plugins manage netfilter.
- Never run
iptables -Fornft flush rulesetwithout a verified backup. Docker/K8s networking will break. - Never disable firewalld and use raw iptables simultaneously. Undefined behavior.
- Never set
DROPpolicy on INPUT before allowing your current SSH port. Immediate lockout. - Never disable Docker's
iptablesmanagement without replacement NAT/routing rules. - Never restart
networking.serviceorNetworkManagerremotely without console access. - Never apply cloud SG and host firewall changes simultaneously without testing.
- Never enable logging on high-traffic DROP rules without
limit rate. Disk flood. - Never manage nftables/iptables directly when ufw or firewalld owns the policy. Split-brain state.
- Never apply outbound default-deny without explicitly allowing DNS, NTP, package mirrors.
- Never restore firewall backups from a different host, kernel version, or backend mode.
- Never assume IPv4 rules protect IPv6. Verify both stacks separately.
- Never change sysctl hardening values on K8s/CNI hosts without explicit CNI profile support.
- Never enable verbose packet logging without rate limits and log rotation.
State Machine
Follow states in order. Do not skip.
DETECT → SELECT → PLAN → VALIDATE → APPLY → VERIFY
State: DETECT
Run the audit script:
bash scripts/audit-firewall.sh # Human-readable
bash scripts/audit-firewall.sh --json # Machine-readable
Key outputs: confidence, risk_tier, recommended_backend, halt_reasons, k8s_node, iac_owner.
Risk Tiers & Confidence Gating
| Tier | Confidence | Agent Behavior |
|---|---|---|
auto |
≥ 90% | Proceed automatically to PLAN |
confirmed |
70–89% | Proceed but require human confirmation before APPLY |
manual |
50–69% | Audit-only mode. Generate recommendations, do not apply. |
halt |
\x3C 50% | Stop immediately. Escalate findings to operator. |
Additional halt triggers (regardless of confidence): containerized, K8s node, IaC managed, no rollback mechanism available.
Decision Tree
| Condition | Path | Detail |
|---|---|---|
Risk tier = halt |
STOP | Resolve blockers first |
| Inside container | STOP | Escalate to host operator |
| K8s node detected | STOP | references/k8s-policy.md |
| Ubuntu/Debian + ufw active | Phase: UFW | references/backend-ufw.md |
| ufw + firewalld both active | STOP | Resolve conflict |
| RHEL/Rocky/Alma + firewalld active | Phase: firewalld | references/backend-firewalld.md |
| nftables active, no frontend | Phase: nftables | references/backend-nftables.md |
| iptables only | Phase: iptables | references/backend-iptables.md |
| Docker host | Apply Docker Hardening after phase above | references/docker-hardening.md |
Ownership Boundary
Before modifying rules, verify no IaC tool manages the firewall. If Terraform/Ansible/Puppet/Chef/cloud-init is detected → do not mutate. Update the source of truth instead. Full detection logic is in scripts/audit-firewall.sh.
State: SELECT
Optionally load a pre-built security profile (references/security-profiles.md):
| Profile | Use Case |
|---|---|
public-web-server |
Open 22, 80, 443. Rate-limit SSH. |
internal-database |
SSH from mgmt subnet only. DB port from app subnet only. |
bastion-host |
SSH only. Aggressive rate limiting. |
zero-trust-node |
Default deny all inbound and outbound. |
Or use declarative YAML (references/declarative-policy.md):
Imperative (state machine) → Ad-hoc hardening, incident response
Declarative (YAML) → GitOps, multi-host, reproducible
Mixed → YAML as source-of-truth, state machine for verification
State: PLAN (NEW)
Generate a dry-run diff before applying:
bash scripts/firewall-plan.sh --profile public-web-server
bash scripts/firewall-plan.sh --ports 22,80,443
bash scripts/firewall-plan.sh --json # Machine-readable diff
Review the output. If risk_tier is confirmed, present the plan and wait for human confirmation before APPLY.
State: VALIDATE
1. Create Backup (Mandatory)
BACKUP_DIR="$HOME/firewall-backup-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
sudo iptables-save > "$BACKUP_DIR/iptables-v4.rules" 2>/dev/null || true
sudo ip6tables-save > "$BACKUP_DIR/iptables-v6.rules" 2>/dev/null || true
sudo nft list ruleset > "$BACKUP_DIR/nftables.rules" 2>/dev/null || true
sudo ufw status verbose > "$BACKUP_DIR/ufw-status.txt" 2>/dev/null || true
sudo firewall-cmd --list-all --zone=$(sudo firewall-cmd --get-default-zone) > "$BACKUP_DIR/firewalld-default.txt" 2>/dev/null || true
echo "Backup saved to $BACKUP_DIR"
2. Schedule Rollback (Mandatory for Remote)
The rollback restores from backup — not just disables the firewall — so Docker NAT and pre-existing rules are preserved. Dual-backend: at preferred, systemd-run fallback. Full script in SKILL.md under Validate state (see previous version), also summarized in references/recovery.md.
3. Pre-Flight Checklist
- Backup created successfully
- Rollback scheduled (verify with
atqorsystemctl --user list-units) - Second SSH session open and idle
- Real SSH port identified
- Confidence ≥ 70% and risk_tier is
autoorconfirmed - Ownership verified — no IaC managing firewall
- Change window appropriate (maintenance window or low traffic)
- PLAN output reviewed and approved
State: APPLY
All commands use idempotent patterns: check-before-set. Safe to run repeatedly.
| Backend | Pattern |
|---|---|
| ufw | sudo ufw status | awk '{print $1}' | grep -qx "22/tcp" || sudo ufw allow 22/tcp |
| firewalld | sudo firewall-cmd --query-service=ssh || sudo firewall-cmd --permanent --add-service=ssh |
| iptables | sudo iptables -C INPUT -p tcp --dport 22 -j ACCEPT 2>/dev/null || sudo iptables -A ... |
| nftables | Atomic ruleset: nft -c -f /etc/nftables.conf.new && nft -f /etc/nftables.conf.new |
Full step-by-step commands per backend: references/backend-ufw.md, references/backend-firewalld.md, references/backend-nftables.md, references/backend-iptables.md.
Docker Hosts
Docker bypasses ufw by default. Use DOCKER-USER chain. Full guide: references/docker-hardening.md.
Kubernetes Nodes
Default: AUDIT-ONLY. Never modify host firewall. Full policy: references/k8s-policy.md.
State: VERIFY
Run post-hardening checks:
bash scripts/firewall-verify.sh
Success criteria (all must pass):
- SSH remains reachable from current and second session
- Only intended ports are externally reachable
- Rules survive reboot (verified via service persistence)
- IPv6 exposure matches IPv4 policy
- Docker-published ports are intentional (no accidental
0.0.0.0) - fail2ban jails active (if installed) with correct backend
- Rollback timer cancelled after successful verification
fail2ban Integration
If fail2ban is installed:
| Host Firewall | Recommended backend |
|---|---|
| ufw | ufw or systemd |
| firewalld | firewalld |
| nftables | nftables |
| iptables | auto (default) |
After changing backend: sudo fail2ban-client restart && sudo fail2ban-client status sshd.
Recovery
If you lose connectivity, priority order:
- Wait for auto-rollback (scheduled during VALIDATE)
- Use second SSH session
- Cloud serial console / hypervisor console
- Restore from backup
- Emergency ACCEPT (last resort — exposes host completely)
Full procedures: references/recovery.md.
Cloud Security Group Reminder
The host firewall is your second layer. Verify cloud SGs are aligned:
| Cloud | Outer Firewall |
|---|---|
| AWS | Security Groups |
| GCP | VPC Firewall Rules |
| Azure | Network Security Groups |
| DigitalOcean/Linode/Vultr | Cloud Firewall |
Observability
Establish baselines after hardening: conntrack usage, dropped packet rates, fail2ban ban rate. Monitor for anomalies. Full guide: references/observability.md.
Compliance
Practices map to CIS, PCI-DSS, and SOC2 controls. Full mapping: references/compliance.md.
Quick Reference
| Task | Command |
|---|---|
| Audit environment | bash scripts/audit-firewall.sh --json |
| Plan changes | bash scripts/firewall-plan.sh --profile web |
| Verify after apply | bash scripts/firewall-verify.sh |
| Allow port (ufw, idempotent) | sudo ufw status | awk '{print $1}' | grep -qx "80/tcp" || sudo ufw allow 80/tcp |
| View ufw rules | sudo ufw status numbered |
| View nft rules | sudo nft list ruleset |
| View iptables rules | sudo iptables -L -n -v |
| View ip6tables rules | sudo ip6tables -L -n -v |
| Atomic iptables replace | sudo iptables-restore \x3C /tmp/rules.v4 |
| Dry-run nftables | sudo nft -c -f /etc/nftables.conf |
| Backup rules | sudo iptables-save > ~/iptables.backup |
| fail2ban status | sudo fail2ban-client status sshd |
| Cancel rollback (at) | atrm \x3Cjobid> |
| Cancel rollback (systemd-run) | systemctl --user stop firewall-rollback-\x3Cpid> |
See Also
references/backend-ufw.md— Full UFW phasereferences/backend-firewalld.md— Full firewalld phasereferences/backend-nftables.md— Full nftables phasereferences/backend-iptables.md— Full iptables phasereferences/docker-hardening.md— Docker firewall hardeningreferences/k8s-policy.md— Kubernetes node policyreferences/security-profiles.md— Pre-built configurationsreferences/declarative-policy.md— YAML policy schemareferences/observability.md— Monitoring and baselinesreferences/compliance.md— CIS/PCI-DSS/SOC2 mappingreferences/recovery.md— Recovery proceduresreferences/special-environments.md— WSL2, containers, exit codesscripts/audit-firewall.sh— Environment detectionscripts/firewall-plan.sh— Dry-run diffscripts/firewall-verify.sh— Post-apply verification
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install linux-firewall-hardening - 安装完成后,直接呼叫该 Skill 的名称或使用
/linux-firewall-hardening触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
Linux Firewall Hardening 是什么?
Safe Linux firewall hardening with backend detection, idempotent atomic rules, rollback protection, and AI-executable state-machine workflows. Covers ufw, fi... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 55 次。
如何安装 Linux Firewall Hardening?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install linux-firewall-hardening」即可一键安装,无需额外配置。
Linux Firewall Hardening 是免费的吗?
是的,Linux Firewall Hardening 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。
Linux Firewall Hardening 支持哪些平台?
Linux Firewall Hardening 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。
谁开发了 Linux Firewall Hardening?
由 discovery219(@discovery219)开发并维护,当前版本 v1.0.0。