Lock down the SLV host's network perimeter: nftables default-drop, fail2ban for brute-force, SSH key-based login with password auth off. Non-engineer friendly — three commands, zero file editing. **Related:** For phone/laptop VPN on top of this, see the **slv-wireguard** skill. For automatic HTTPS on the chat UI, see `slv install nginx`. Use this skill when the user says anything like: - "help me lock down the firewall / SSH" - "is my box exposed? / what ports are open?" - "allow only my IP" ...
Scanned 5/27/2026
Install to Claude Code
npx -y skills add ValidatorsDAO/slv --skill slv-firewall --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Slv Firewall?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/validatorsdao-slv-firewall)More formats (shields.io, HTML) on the badges page.
# SLV Firewall Skill
Lock down the SLV host's network perimeter: nftables default-drop,
fail2ban for brute-force, SSH key-based login with password auth
off. Non-engineer friendly — three commands, zero file editing.
**Related:** For phone/laptop VPN on top of this, see the
**slv-wireguard** skill. For automatic HTTPS on the chat UI, see
`slv install nginx`.
Use this skill when the user says anything like:
- "help me lock down the firewall / SSH"
- "is my box exposed? / what ports are open?"
- "allow only my IP" / "whitelist my laptop"
- "turn off SSH passwords" / "disable password login"
- "nftables" / "fail2ban" / "brute force"
---
## EL's walkthrough (run in this order — skipping ahead locks users out)
### Step 0 — Sanity probe (read-only, parallelizable)
Fire these in parallel so the rest of the conversation has real
data to work with:
- `get_premium_vps_my_vps` (MCP) — user's Premium VPS list.
- `get_super_vps_my_vps` (MCP) — Super VPS list.
- `get_baremetal_status` (MCP) — BareMetal list.
- `run_command: curl -s https://api.ipify.org` — THIS host's public IP (so you filter it out of whitelist candidates — no point whitelisting the server to itself).
- `run_command: sudo nft list ruleset 2>/dev/null | head -3` — is nftables already configured?
- `run_command: systemctl is-active fail2ban 2>/dev/null` — is fail2ban running?
- `run_command: sudo grep -r PasswordAuthentication /etc/ssh/` — is password auth still on?
Use the results to:
- Say what's already on / off.
- Build the **whitelist candidate list**: every `ip` from the MCP VPS/BM calls that isn't THIS host's IP. Present to the user verbatim:
> "Your SLV account has these other hosts — want them whitelisted? You'll still be able to SSH between them after we lock down."
### Step 1 — How will the user reach this box from outside?
Before collecting any `--allow` IPs, decide the remote-access
method with the user. This single question prevents the #1
support ticket (self-lockout from a rotating home IP).
Ask, in plain language:
> "How do you want to reach this server from home / your phone?
> For non-engineers we strongly recommend option 1.
>
> 1. **WireGuard VPN** (recommended) — works on any device (phone,
> desktop, laptop — all supported). Once you connect to the
> VPN, the server sees your traffic as coming from the same
> fixed IP every time. The firewall only has to allow that one
> IP, so it stops mattering how often your home router's IP
> rotates, and nobody else can get in. Safe and low-friction
> for everyday use.
>
> 2. **Whitelist a fixed public IP** — if you have a business
> line / office address with a guaranteed-stable IP, register
> that. **Home internet IPs rotate every few days or weeks
> depending on the ISP, so whitelisting one will lock you out
> later.** Only register an IP you can personally guarantee is
> static.
>
> 3. **Both** — whitelist your static IP AND set up VPN."
**Default recommendation: option 1.** If the user picks 1 or is
unsure, proceed with firewall install WITHOUT any `--allow` IPs,
then immediately hand off to the **slv-wireguard** skill as Step
1.5 below. If they pick 2 or 3, collect the IPs now.
**Never auto-add the user's current SSH source IP.** Their home
IP is probably dynamic; hardcoding it leads to "my firewall locked
me out next Tuesday" support tickets. Invite them to add it
explicitly only if they swear it's static.
### Step 1.5 — Install the firewall
Combine MCP-derived IPs (from Step 0) + user-supplied IPs, then run:
```bash
slv install firewall --allow <ip1> --allow <ip2> -y
```
`--allow` is repeatable. Order doesn't matter. The CLI dedupes.
If the user picked WireGuard-only (option 1 above), omit `--allow`
entirely — the box will still be reachable via SSH (port 22 open,
fail2ban-protected) and via WG once it's up.
### Step 1.6 — If they picked WireGuard, hand off now
After the firewall install succeeds, and BEFORE SSH hardening:
> "Firewall is live. Now let's set up the VPN. I'll switch to
> the **slv-wireguard** skill — we can't proceed without a
> separate VPS dedicated to the VPN, so we'll check that first."
Invoke the slv-wireguard skill. It will (a) check whether the user
has a dedicated core1 VPS for the VPN or needs to buy one, and
(b) walk them through the phone pairing. Once WG is up, come back
to Step 2 below.
**What this does:**
- Always-open: SSH (22), HTTP (80), HTTPS (443), WireGuard (51820/udp), lo, WG peer subnet 10.0.0.0/24.
- Whitelist IPs get ALL ports unconditionally.
- Everything else silently dropped.
- fail2ban watches sshd: 5 wrong passwords in 10 min → 1 h ban.
### Step 2 — SSH hardening (ADD → VERIFY → DISABLE, in that order)
This order is load-bearing.
**Step 2a — Install the public key.** Ask:
> "Paste your SSH public key. It's a one-line string starting with `ssh-ed25519` or `ssh-rsa` — usually in `~/.ssh/id_ed25519.pub` on your laptop.
>
> If you don't have one: run `ssh-keygen -t ed25519` on your laptop first and paste the `.pub` contents here."
Run:
```bash
slv add:ssh '<the pubkey line>'
```
**Step 2b — VERIFY in a second terminal.** Tell the user:
> "Open a NEW terminal and try `ssh ubuntu@<this-host-ip>`. If it logs you in without asking for a password, key-based login is working. LEAVE THAT TERMINAL OPEN as a safety net — if the next step goes wrong you can fix it from there."
**Do not proceed until the user confirms this works.** Running
`slv disable pwd-login` after a bad `slv add:ssh` is how people
permanently lock themselves out.
**Step 2c — Disable password auth:**
```bash
slv disable pwd-login
```
Frame it: "this removes a huge attack surface — password guessing is now impossible."
### Step 3 — Verify + read-back
State the final posture plainly:
```
🛡 Firewall + SSH locked down:
• nftables: default-drop, SSH/HTTP/HTTPS/WireGuard always open
• Whitelist: <ips> (all ports)
• fail2ban: sshd jail, 5/10m → 1h ban
• SSH: password auth OFF, key-only
```
Offer to back up the ssh key to the user's laptop if they haven't
already.
If they also want VPN access from their phone, hand off to the
**slv-wireguard** skill.
---
## Why SSH stays open to the world
Engineer impulse: "whitelist SSH too." Don't. Two reasons:
1. **Non-engineer users on dynamic home IPs lock themselves out.** Their ISP rotates their IP, the firewall rule silently stops matching, they panic. fail2ban + key-only auth is equivalent defense without the foot-gun.
2. **SSH key auth is already near-unbreakable.** An attacker without the key gets nowhere; an attacker WITH the key would bypass a whitelist (they'd spoof the source IP or tunnel through an allowed host anyway).
Repeat this explanation to every user who asks "why is SSH open?" — it's the #1 security question on this skill.
---
## Reference
### `slv install firewall`
```
slv install firewall [--allow <ip>]... [-y]
```
- `--allow <ip>` — repeatable. IPv4 dotted-quad. Gets all-port access.
- `-y` — skip the confirmation prompt.
- Idempotent: re-running with a different set **overwrites** the ruleset.
- Playbook: `template/latest/ansible/cmn/software/install-firewall.yaml`.
### `slv add:ssh`
```
slv add:ssh '<pubkey line>'
```
- Appends to `~/.ssh/authorized_keys`. De-dupes.
### `slv disable pwd-login`
```
slv disable pwd-login
```
- Sets `PasswordAuthentication no` in sshd config, reloads sshd.
- **Destructive:** if you haven't verified key login, this locks you out.
---
## Common failure modes + fixes
| User says | Likely cause | Fix |
|-----------|-------------|-----|
| "I ran `slv disable pwd-login` and now I'm locked out" | `slv add:ssh` was skipped or pubkey was malformed | Cloud provider rescue console → re-enable password in `/etc/ssh/sshd_config.d/` or fix `authorized_keys` |
| "My whitelist IP rotated" | Dynamic home IP changed | `slv install firewall --allow <new-ip> [<rest>]` — idempotent rewrite |
| "fail2ban banned me" | Typed wrong password 5× | `sudo fail2ban-client set sshd unbanip <your-ip>` |
| "nftables says default-deny but SSH still works" | Expected — SSH is an always-open exception | Not a bug |
---
## Don't do
- Don't disable password auth BEFORE verifying key login works in a second terminal.
- Don't whitelist `0.0.0.0/0` — it defeats default-deny.
- Don't auto-add the operator's current SSH source IP — dynamic home IPs rotate.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!