linux-firewall-hardening
Safe Linux firewall hardening with backend detection, idempotent atomic rules, rollback protection, and AI-executable state-machine workflows. Covers ufw, firewalld, nftables, iptables, Docker, Kubernetes CNI awareness, and fail2ban with compliance mapping to CIS/PCI-DSS/SOC2. Skill: linux-firewall-hardening Owner: discovery219 Summary: Safe Linux firewall hardening with backend detection, idempotent atomic rules, rollback protection, and AI-executable state-machine workflows. Covers ufw, firewalld, nftables, iptables, Docker, Kubernetes CNI awareness, and fail2ban with compliance mapping to CIS/PCI-DSS/SOC2. Tags: devsecops:2.1.0, docker:2.1.0, fail2ban:2.1.0, firewall:2.1.0, firewalld:2.
Rank
62
Safety
84
Downloads
1.3k
Updated
Oct 10, 2026
Version
2.7.0
Source
CLAWHUB
About
What it does, and when to use it.
Capability contract not published. No trust telemetry is available yet. 1.3K downloads reported by the source. Last updated 10/10/2026.
Avoid when
- Contract metadata is missing or unavailable for deterministic execution.
Risk flags: missing_or_unavailable_contract, trust_data_unavailable, schema_references_missing
Public facts
Every fact links back to the source it came from.
- Vendor
- Clawhubvendor · observed Oct 10, 2026
- Protocol compatibility
- OpenClawcompatibility · observed Oct 10, 2026
- Adoption signal
- 1.3K downloadsadoption · observed Oct 10, 2026
- Latest release
- 2.7.0release · observed Aug 7, 2026
- Handshake status
- UNKNOWNsecurity
Install and run
Setup complexity: medium.
clawhub skill install s173agn7542hhrs96f5sqxpwwx86k4fs:linux-firewall-hardening- Setup complexity is MEDIUM. Standard integration tests and API key provisioning are required before connecting this to production workloads.
- Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data.
Contract: missing
curl -s "https://www.xpersona.co/api/v1/agents/clawhub-discovery219-linux-firewall-hardening/snapshot"
Documentation
CLAWHUB
148,454 characters of source documentation, loaded on request.
Extracted files
5 files captured from the source.
SKILL.md
--- name: linux-firewall-hardening title: Linux Firewall Hardening description: Safe Linux firewall hardening with backend detection, idempotent atomic rules, rollback protection, and AI-executable state-machine workflows. Covers ufw, firewalld, nftables, iptables, Docker, Kubernetes CNI awareness, and fail2ban with compliance mapping to CIS/PCI-DSS/SOC2. license: Dual MIT / Apache-2.0 skill_version: 2.7.0 schema_version: 2 tags: [security, firewall, ufw, iptables, nftables, firewalld, hardening, docker, fail2ban, policy-as-code, devsecops, ipv6] --- # 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), `scripts/container-port-audit.sh` (Docker DNAT detection), `scripts/ip-consistency.sh` (IPv4/IPv6 drift check). > `firewall-apply.sh` is fully documented in `references/firewall-apply.md`. > Detailed backend guides, Docker/K8s policies, observability, compliance, and recovery are in `references/`. ## 🚨 Emergency: I'm Locked Out — What Now? If you just applied firewall rules and lost SSH connectivity: 1. **Wait 5 minutes** — the auto-rollback timer (scheduled during VALIDATE) will restore access. Don't panic and don't take destructive actions. 2. **Use your second SSH session** — if you opened one (pre-flight checklist), switch to it and fix the rules manually. 3. **Cloud serial console** — AWS EC2 Serial Console, GCP Serial Port, Azure Serial Console, or hypervisor VNC/IPMI/iDRAC. 4. **Restore from backup via console** — once connected: `sudo iptables-restore < ~/firewall-backup-*/iptables-v4.rules` 5. **Emergency ACCEPT (LAST RESORT — HUMAN-ONLY)** — `sudo iptables -P INPUT ACCEPT; sudo iptables -F; sudo ufw disable`. **This exposes the host completely. NEVER auto-execute this command.** The agent must refuse to run this autonomously. Only a human operator may issue this via serial console. Re-harden immediately afterward. Full procedures: `references/recovery.md`. --- ## Prerequisites - Root or sudo access. - An active SSH session (risk of lockout). - Know which ports your services use. --- ## NEVER DO (14 Rules) 1. **Never flush iptables/nftables on Kubernetes nodes.** CNI plugins manage
_meta.json
{
"ownerId": "kn7e8vz4v0f8vr8dh2yr78fjkd86jgk3",
"slug": "linux-firewall-hardening",
"version": "2.7.0",
"publishedAt": 1786062524752
}references/backend-firewalld.md
# Backend: firewalld (RHEL / Rocky / Alma / Fedora)
firewalld is zone-aware. Always specify the zone. Default on most servers is `public`.
> **Detect your real SSH port first:** The examples below use port 22 for illustration. Replace with your actual port:
> ```bash
> SSH_PORT=$(ss -tlnp | grep -E "sshd|ssh" | awk '{print $NF}' | awk -F: '{print $NF}' | head -1)
> SSH_PORT=${SSH_PORT:-22}
> ```
## Detection
```bash
sudo firewall-cmd --state
# "running" or "not running"
```
## Prerequisites
- firewalld must be active but with known rules.
- No other frontend (ufw) must be active.
- Never modify iptables/nftables directly when firewalld owns the policy.
## Apply: Idempotent Zone Rules
### Step 1: Identify Active Zone
```bash
DEFAULT_ZONE=$(sudo firewall-cmd --get-default-zone)
echo "Default zone: $DEFAULT_ZONE"
sudo firewall-cmd --get-active-zones
```
### Step 2: Add Rules
```bash
ZONE="${DEFAULT_ZONE:-public}"
SSH_PORT=$(ss -tlnp | grep -E "sshd|ssh" | awk -F: '{print $NF}' | head -1)
SSH_PORT=${SSH_PORT:-22}
# SSH (service definition)
sudo firewall-cmd --zone="$ZONE" --query-service=ssh >/dev/null 2>&1 || sudo firewall-cmd --permanent --zone="$ZONE" --add-service=ssh
# HTTP / HTTPS
sudo firewall-cmd --zone="$ZONE" --query-service=http >/dev/null 2>&1 || sudo firewall-cmd --permanent --zone="$ZONE" --add-service=http
sudo firewall-cmd --zone="$ZONE" --query-service=https >/dev/null 2>&1 || sudo firewall-cmd --permanent --zone="$ZONE" --add-service=https
# Custom port
# sudo firewall-cmd --zone="$ZONE" --query-port=8080/tcp >/dev/null 2>&1 || # sudo firewall-cmd --permanent --zone="$ZONE" --add-port=8080/tcp
# Rate-limit SSH (rich rule)
sudo firewall-cmd --zone="$ZONE" --query-rich-rule='rule service name=ssh limit value=3/m accept' >/dev/null 2>&1 || sudo firewall-cmd --permanent --zone="$ZONE" --add-rich-rule='rule service name=ssh limit value=3/m accept'
# Apply
sudo firewall-cmd --reload
```
### Step 3: Verify
```bash
sudo firewall-cmd --list-all --zone="$ZONE"
```
## Zone Commands Quick Reference
```bash
# List all zones
sudo firewall-cmd --get-zones
# List all zones with rules
sudo firewall-cmd --list-all-zones
# Change default zone
sudo firewall-cmd --set-default-zone=drop
# Move interface to different zone
sudo firewall-cmd --zone=internal --change-interface=eth1
```
## Related
- `references/security-profiles.md` — Pre-built firewalld configurations
- `references/declarative-policy.md` — YAML-to-firewalld renderingreferences/backend-iptables.md
# Backend: iptables (Legacy Fallback)
Use atomic `iptables-restore` instead of `-F` followed by individual `-A` commands. Build a complete ruleset file, then swap it in one operation. Always manage IPv4 (`iptables`) and IPv6 (`ip6tables`) separately.
> **Detect your real SSH port first:** The examples below use port 22 for illustration. If your SSH runs on a different port, replace `22` with your actual port:
> ```bash
> SSH_PORT=$(ss -tlnp | grep -E "sshd|ssh" | awk '{print $NF}' | awk -F: '{print $NF}' | head -1)
> SSH_PORT=${SSH_PORT:-22}
> echo "Detected SSH port: $SSH_PORT"
> ```
> Using the wrong SSH port in the ruleset below will lock you out.
## Key Principle: Atomic Restore
```bash
# Validate syntax first
sudo iptables-restore --test /tmp/iptables-v4.rules
sudo ip6tables-restore --test /tmp/iptables-v6.rules
# Apply atomically
sudo iptables-restore /tmp/iptables-v4.rules
sudo ip6tables-restore /tmp/iptables-v6.rules
```
## Apply: Atomic Rulesets
### Step 1: Build IPv4 Ruleset (`/tmp/iptables-v4.rules`)
```
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p tcp --dport 22 -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
COMMIT
```
### Step 2: Build IPv6 Ruleset (`/tmp/iptables-v6.rules`)
```
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmpv6 -j ACCEPT
-A INPUT -p tcp --dport 22 -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
COMMIT
```
### Step 3: Persist
- **Debian/Ubuntu**: `sudo apt install iptables-persistent`, then `sudo netfilter-persistent save`
- **RHEL/CentOS**: `sudo service iptables save` or migrate to `firewalld`
## Idempotent Single-Rule Pattern
If adding a single rule instead of full restore:
```bash
# Check if rule exists before adding
sudo iptables -C INPUT -p tcp --dport 8080 -j ACCEPT 2>/dev/null || sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
```
## Related
- `references/security-profiles.md` — Pre-built iptables configurations
- `references/declarative-policy.md` — YAML-to-iptables renderingreferences/backend-nftables.md
# Backend: nftables (Modern Dual-Stack)
nftables is the modern replacement for iptables. It supports IPv4 and IPv6 in a single `inet` table, has atomic ruleset replacement, and uses a cleaner syntax.
> **Detect your real SSH port first:** The examples below use port 22 for illustration. Replace with your actual port:
> ```bash
> SSH_PORT=$(ss -tlnp | grep -E "sshd|ssh" | awk '{print $NF}' | awk -F: '{print $NF}' | head -1)
> SSH_PORT=${SSH_PORT:-22}
> ```
## Detection
```bash
sudo nft list ruleset
# Shows current rules if active
```
## Key Principle: Atomic Replacement
Build a new ruleset file, validate with `nft -c`, then apply in one shot. **Never `flush ruleset` manually** on a production host without a backup.
## Apply: Atomic Ruleset
### Step 1: Build Ruleset File
```bash
sudo tee /etc/nftables.conf.new << 'EOF'
#!/usr/sbin/nft -f
table inet filter {
set allowed_tcp_ports {
type inet_service
flags interval
elements = { 22, 80, 443 }
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
ct state invalid drop
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
tcp dport @allowed_tcp_ports accept
# Rate limit new SSH connections
tcp dport 22 ct state new limit rate 10/second burst 20 packets accept
# Log with rate limit to prevent syslog flood
log prefix "nft-drop: " limit rate 5/second
drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
EOF
```
> **Warning**: Excessive logging can overwhelm syslog/journald on high-traffic systems. Always use `limit rate` on log rules and monitor after enabling.
### Step 2: Dry-Run (Validate Syntax)
```bash
sudo nft -c -f /etc/nftables.conf.new
```
If this returns errors, fix the file and re-validate. **Do not proceed until dry-run passes.**
### Step 3: Atomic Apply
```bash
# Backup current ruleset (belt-and-suspenders)
sudo nft list ruleset > "$BACKUP_DIR/nftables-pre-apply.rules" 2>/dev/null || true
# Atomic replace
sudo nft -f /etc/nftables.conf.new
sudo mv /etc/nftables.conf.new /etc/nftables.conf
# Enable persistence
sudo systemctl enable nftables
sudo systemctl restart nftables
```
### Step 4: Verify
```bash
sudo nft list ruleset
```
## Related
- `references/security-profiles.md` — Pre-built nftables configurations
- `references/declarative-policy.md` — YAML-to-nftables renderingAionUi
Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!
activepieces
AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents
cherry-studio
AI productivity studio with smart chat, autonomous agents, and 300+ assistants.
CopilotKit
The Frontend for Agents & Generative UI. React + Angular
Machine-readable data
The same record, as JSON, for agents and crawlers.
{
"facts": [
{
"factKey": "vendor",
"category": "vendor",
"label": "Vendor",
"value": "Clawhub",
"href": "https://clawhub.ai/discovery219/skills/linux-firewall-hardening",
"sourceUrl": "https://clawhub.ai/discovery219/skills/linux-firewall-hardening",
"sourceType": "profile",
"confidence": "medium",
"observedAt": "2026-10-10T17:35:08.257Z",
"isPublic": true
},
{
"factKey": "protocols",
"category": "compatibility",
"label": "Protocol compatibility",
"value": "OpenClaw",
"href": "https://www.xpersona.co/api/v1/agents/clawhub-discovery219-linux-firewall-hardening/contract",
"sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-discovery219-linux-firewall-hardening/contract",
"sourceType": "contract",
"confidence": "medium",
"observedAt": "2026-10-10T17:35:08.257Z",
"isPublic": true
},
{
"factKey": "traction",
"category": "adoption",
"label": "Adoption signal",
"value": "1.3K downloads",
"href": "https://clawhub.ai/discovery219/linux-firewall-hardening",
"sourceUrl": "https://clawhub.ai/discovery219/linux-firewall-hardening",
"sourceType": "profile",
"confidence": "medium",
"observedAt": "2026-10-10T17:35:08.257Z",
"isPublic": true
},
{
"factKey": "latest_release",
"category": "release",
"label": "Latest release",
"value": "2.7.0",
"href": "https://clawhub.ai/discovery219/linux-firewall-hardening",
"sourceUrl": "https://clawhub.ai/discovery219/linux-firewall-hardening",
"sourceType": "release",
"confidence": "medium",
"observedAt": "2026-08-07T00:28:44.752Z",
"isPublic": true
},
{
"factKey": "handshake_status",
"category": "security",
"label": "Handshake status",
"value": "UNKNOWN",
"href": "https://www.xpersona.co/api/v1/agents/clawhub-discovery219-linux-firewall-hardening/trust",
"sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-discovery219-linux-firewall-hardening/trust",
"sourceType": "trust",
"confidence": "medium",
"observedAt": null,
"isPublic": true
}
],
"events": [
{
"eventType": "release",
"title": "Release 2.7.0",
"description": "linux-firewall-hardening 2.7.0 - Added container and network audit tools: `scripts/container-port-audit.sh` (detects Docker DNAT/port-forwarding) and `scripts/ip-consistency.sh` (checks IPv4/IPv6 drift). - Expanded emergency lockout procedure: clarified that the \"emergency ACCEPT\" command may not be auto-executed and must only be performed by a human via serial console. - Introduced explicit CONFIRM state in the state machine, making human confirmation mandatory before any firewall changes. - Added full documentation for `firewall-apply.sh` in `references/firewall-apply.md`. - Removed files related to publishing and the skill card (PUBLISH.md, skill-card.md) to streamline the distribution. - Updated documentation and references to reflect all new scripts and required confirmation process.",
"href": "https://clawhub.ai/discovery219/linux-firewall-hardening",
"sourceUrl": "https://clawhub.ai/discovery219/linux-firewall-hardening",
"sourceType": "release",
"confidence": "medium",
"observedAt": "2026-08-07T00:28:44.752Z",
"isPublic": true
}
]
}Record generated Oct 10, 2026.
