/vpn-security-check
Infrastructure security audit for VPN server. Use when user asks 'check security', 'is my VPN safe', 'audit security', 'security check'. Also use after deployment when user has security concerns.
$ npx -y skills add Sergei-thinker/vpn-setup --skill vpn-security-check --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/vpn-security-check
Context preview
The summary Claude sees to decide when to auto-load this skill.
Infrastructure security audit for VPN server. Use when user asks 'check security', 'is my VPN safe', 'audit security', 'security check'. Also use after deployment when user has security concerns.
SKILL.md
vpn-security-check.SKILL.mdname: vpn-security-check
description: "Infrastructure security audit for VPN server. Use when user asks 'check security', 'is my VPN safe', 'audit security', 'security check'. Also use after deployment when user has security concerns."
VPN Infrastructure Security Audit
Checks that the VPN server is properly hardened. All checks run via `ssh_exec.py` — no additional tools needed.
When to Use
- User asks about security: "check security", "is my VPN safe"
- After initial deployment (offer proactively)
- User has security concerns
- Periodic security checkup
The Iron Law
EVERY CHECK MUST RUN A COMMAND. NO ASSUMPTIONS.
"quick-rebuild.sh enables the firewall" is not evidence that the firewall is active. Run the check.
Security Checks
Run ALL checks in order. Report each as PASS/FAIL/WARN with evidence.
1. SSH Hardening
**1a. SSH Port**
Command: `python ssh_exec.py exec "grep -E '^Port ' /etc/ssh/sshd_config"`
| Result | Rating | |--------|--------| | Port != 22 (e.g., 49152) | PASS | | Port 22 | FAIL — TSPU scans and blocks port 22 to foreign IPs. Change with: `python ssh_exec.py exec "sed -i 's/^Port 22/Port 49152/' /etc/ssh/sshd_config && systemctl restart sshd"` |
**1b. Root Password Login**
Command: `python ssh_exec.py exec "grep -E '^PasswordAuthentication' /etc/ssh/sshd_config"`
| Result | Rating | |--------|--------| | PasswordAuthentication no | PASS | | PasswordAuthentication yes | WARN — Key-only auth is more secure. Note: some beginners use password auth intentionally. Inform, don't force change | | Not set (commented out) | WARN — defaults to yes on most distros |
2. Firewall
**2a. UFW Status**
Command: `python ssh_exec.py exec "ufw status verbose"`
| Result | Rating | |--------|--------| | Status: active, rules for 443/8443/2053/SSH port | PASS | | Status: inactive | FAIL — `python ssh_exec.py exec "ufw --force enable"` | | Active but missing expected ports | WARN — check if needed ports are open |
**2b. Open Ports (reality check)**
Command: `python ssh_exec.py exec "ss -tnlp | grep -E 'LISTEN' | awk '{print \$4, \$6}'"`
Verify only expected services are listening:
- xray on 443, 8443, 2053 (VPN)
- x-ui panel (some high port)
- sshd on configured port
- nginx on 80 (camouflage)
Any unexpected service = WARN
3. Intrusion Prevention
**3a. fail2ban**
Command: `python ssh_exec.py exec "systemctl is-active fail2ban && fail2ban-client status sshd 2>/dev/null | grep -E 'Currently|Total'"`
| Result | Rating | |--------|--------| | active + shows ban stats | PASS | | inactive or not installed | FAIL — `python ssh_exec.py exec "apt install -y fail2ban && systemctl enable --now fail2ban"` |
4. VPN Service Security
**4a. 3X-UI Panel Access**
Command: `python ssh_exec.py exec "grep -E 'webPort|webBasePath' /etc/x-ui/x-ui.db 2>/dev/null || echo 'db not readable as text'"`
Check:
- Panel is on non-standard port (not 80, 443, 8080, 2053)
- Panel base path is randomized (not `/` or `/panel`)
If DB not readable as text, try: `python ssh_exec.py exec "x-ui settings show 2>/dev/null || echo 'cannot read settings'"`
| Result | Rating | |--------|--------| | Non-standard port + randomized path | PASS | | Default port or path = "/" | WARN — Panel is discoverable. Suggest changing via `x-ui settings` |
**4b. Xray Running with Expected Config**
Command: `python ssh_exec.py exec "xray version 2>/dev/null || /usr/local/x-ui/bin/xray-linux-amd64 version 2>/dev/null"`
| Result | Rating | |--------|--------| | Version >= 24.x | PASS | | Old version | WARN — Update with `python ssh_exec.py update-xray` |
5. Camouflage
**5a. Nginx Responding**
Command: `python ssh_exec.py exec "curl -s -o /dev/null -w '%{http_code}' http://localhost:80"`
| Result | Rating | |--------|--------| | 200 | PASS — Camouflage page is active | | Connection refused / other | WARN — Without nginx, port scanners see an unusual server profile |
6. Secrets Management
**6a. .env Not in Git**
Command (local): Check `.gitignore` includes `.env` AND `git ls-files .env` returns nothing
| Result | Rating | |--------|--------| | .env is gitignored and not tracked | PASS | | .env is tracked in git | CRITICAL FAIL — `git rm --cached .env` immediately. Credentials are exposed! |
**6b. Credentials File Permissions (on server)**
Command: `python ssh_exec.py exec "ls -la /root/vpn-credentials.txt 2>/dev/null || echo 'not found'"`
| Result | Rating | |--------|--------| | Permissions -rw------- (600) or not found | PASS | | World-readable (644, 755, etc.) | WARN — `python ssh_exec.py exec "chmod 600 /root/vpn-credentials.txt"` |
7. System Updates
Command: `python ssh_exec.py exec "apt list --upgradable 2>/dev/null | tail -n +2 | wc -l"`
| Result | Rating | |--------|--------| | 0 or <5 pending updates | PASS | | 5+ pending security updates | WARN — `python ssh_exec.py exec "apt update && apt upgrade -y"` |
Report Format
Present as a security scorecard (in Russian):
Аудит безопасности VPN-сервера:
SSH:
1a. SSH-порт: [PASS/FAIL]
1b. Парольная авторизация: [PASS/WARN]
Firewall:
2a. UFW: [PASS/FAIL]
2b. Открытые порты: [PASS/WARN]
Защита от вторжений:
3a. fail2ban: [PASS/FAIL]
VPN-сервис:
4a. Панель 3X-UI: [PASS/WARN]
4b. Версия Xray: [PASS/WARN]
Камуфляж:
5a. Nginx: [PASS/WARN]
Секреты:
6a. .env в git: [PASS/CRITICAL]
6b. Файл credentials: [PASS/WARN]
Обновления:
7. Системные: [PASS/WARN]
Итого: X/10 проверок пройденоFor each FAIL/WARN: provide the specific fix command. For CRITICAL: fix immediately before continuing.
Communication Rules
- Communicate in **Russian**
- Run every check — do not skip "because the deploy script handles it"
- If a check fails, provide the exact fix command
- Do not alarm the user unnecessarily — WARN is informational
Read more
name: vpn-security-check description: "Infrastructure security audit for VPN server. Use when user asks 'check security', 'is my VPN safe', 'audit security', 'security check'. Also use after deployment when user has security concerns."
VPN Infrastructure Security Audit
Checks that the VPN server is properly hardened. All checks run via `ssh_exec.py` — no additional tools needed.
When to Use
- User asks about security: "check security", "is my VPN safe"
- After initial deployment (offer proactively)
- User has security concerns
- Periodic security checkup
The Iron Law
EVERY CHECK MUST RUN A COMMAND. NO ASSUMPTIONS.
"quick-rebuild.sh enables the firewall" is not evidence that the firewall is active. Run the check.
Security Checks
Run ALL checks in order. Report each as PASS/FAIL/WARN with evidence.
1. SSH Hardening
**1a. SSH Port**
Command: `python ssh_exec.py exec "grep -E '^Port ' /etc/ssh/sshd_config"`
| Result | Rating | |--------|--------| | Port != 22 (e.g., 49152) | PASS | | Port 22 | FAIL — TSPU scans and blocks port 22 to foreign IPs. Change with: `python ssh_exec.py exec "sed -i 's/^Port 22/Port 49152/' /etc/ssh/sshd_config && systemctl restart sshd"` |
**1b. Root Password Login**
Command: `python ssh_exec.py exec "grep -E '^PasswordAuthentication' /etc/ssh/sshd_config"`
| Result | Rating | |--------|--------| | PasswordAuthentication no | PASS | | PasswordAuthentication yes | WARN — Key-only auth is more secure. Note: some beginners use password auth intentionally. Inform, don't force change | | Not set (commented out) | WARN — defaults to yes on most distros |
2. Firewall
**2a. UFW Status**
Command: `python ssh_exec.py exec "ufw status verbose"`
| Result | Rating | |--------|--------| | Status: active, rules for 443/8443/2053/SSH port | PASS | | Status: inactive | FAIL — `python ssh_exec.py exec "ufw --force enable"` | | Active but missing expected ports | WARN — check if needed ports are open |
**2b. Open Ports (reality check)**
Command: `python ssh_exec.py exec "ss -tnlp | grep -E 'LISTEN' | awk '{print \$4, \$6}'"`
Verify only expected services are listening:
- xray on 443, 8443, 2053 (VPN)
- x-ui panel (some high port)
- sshd on configured port
- nginx on 80 (camouflage)
Any unexpected service = WARN
3. Intrusion Prevention
**3a. fail2ban**
Command: `python ssh_exec.py exec "systemctl is-active fail2ban && fail2ban-client status sshd 2>/dev/null | grep -E 'Currently|Total'"`
| Result | Rating | |--------|--------| | active + shows ban stats | PASS | | inactive or not installed | FAIL — `python ssh_exec.py exec "apt install -y fail2ban && systemctl enable --now fail2ban"` |
4. VPN Service Security
**4a. 3X-UI Panel Access**
Command: `python ssh_exec.py exec "grep -E 'webPort|webBasePath' /etc/x-ui/x-ui.db 2>/dev/null || echo 'db not readable as text'"`
Check:
- Panel is on non-standard port (not 80, 443, 8080, 2053)
- Panel base path is randomized (not `/` or `/panel`)
If DB not readable as text, try: `python ssh_exec.py exec "x-ui settings show 2>/dev/null || echo 'cannot read settings'"`
| Result | Rating | |--------|--------| | Non-standard port + randomized path | PASS | | Default port or path = "/" | WARN — Panel is discoverable. Suggest changing via `x-ui settings` |
**4b. Xray Running with Expected Config**
Command: `python ssh_exec.py exec "xray version 2>/dev/null || /usr/local/x-ui/bin/xray-linux-amd64 version 2>/dev/null"`
| Result | Rating | |--------|--------| | Version >= 24.x | PASS | | Old version | WARN — Update with `python ssh_exec.py update-xray` |
5. Camouflage
**5a. Nginx Responding**
Command: `python ssh_exec.py exec "curl -s -o /dev/null -w '%{http_code}' http://localhost:80"`
| Result | Rating | |--------|--------| | 200 | PASS — Camouflage page is active | | Connection refused / other | WARN — Without nginx, port scanners see an unusual server profile |
6. Secrets Management
**6a. .env Not in Git**
Command (local): Check `.gitignore` includes `.env` AND `git ls-files .env` returns nothing
| Result | Rating | |--------|--------| | .env is gitignored and not tracked | PASS | | .env is tracked in git | CRITICAL FAIL — `git rm --cached .env` immediately. Credentials are exposed! |
**6b. Credentials File Permissions (on server)**
Command: `python ssh_exec.py exec "ls -la /root/vpn-credentials.txt 2>/dev/null || echo 'not found'"`
| Result | Rating | |--------|--------| | Permissions -rw------- (600) or not found | PASS | | World-readable (644, 755, etc.) | WARN — `python ssh_exec.py exec "chmod 600 /root/vpn-credentials.txt"` |
7. System Updates
Command: `python ssh_exec.py exec "apt list --upgradable 2>/dev/null | tail -n +2 | wc -l"`
| Result | Rating | |--------|--------| | 0 or <5 pending updates | PASS | | 5+ pending security updates | WARN — `python ssh_exec.py exec "apt update && apt upgrade -y"` |
Report Format
Present as a security scorecard (in Russian):
Аудит безопасности VPN-сервера:
SSH:
1a. SSH-порт: [PASS/FAIL]
1b. Парольная авторизация: [PASS/WARN]
Firewall:
2a. UFW: [PASS/FAIL]
2b. Открытые порты: [PASS/WARN]
Защита от вторжений:
3a. fail2ban: [PASS/FAIL]
VPN-сервис:
4a. Панель 3X-UI: [PASS/WARN]
4b. Версия Xray: [PASS/WARN]
Камуфляж:
5a. Nginx: [PASS/WARN]
Секреты:
6a. .env в git: [PASS/CRITICAL]
6b. Файл credentials: [PASS/WARN]
Обновления:
7. Системные: [PASS/WARN]
Итого: X/10 проверок пройденоFor each FAIL/WARN: provide the specific fix command. For CRITICAL: fix immediately before continuing.
Communication Rules
- Communicate in **Russian**
- Run every check — do not skip "because the deploy script handles it"
- If a check fails, provide the exact fix command
- Do not alarm the user unnecessarily — WARN is informational
English: Multi-layer VPN system (VLESS Reality + Russian relay VPS + WebRTC) for bypassing Russian internet censorship (ТСПУ/DPI). Designed to be deployed automatically via Claude Code. See below for Russian documentation.
Repo: Sergei-thinker/vpn-setup
Other skills on vpn-setup.
- /vpn-deploy
Guided VPN deployment wizard. Use when user says 'deploy VPN', 'deploy my VPN', 'set up VPN', 'install VPN'. Also use when opening the project for the first time and user wants to get started.
Open skill - /vpn-troubleshoot
VPN troubleshooting decision tree. Use when user reports VPN problems: 'VPN not working', 'can't connect', 'stopped working', 'no internet through VPN', 'slow VPN', 'troubleshoot'. Also use when deployment fails.
Open skill - /vpn-verify
Post-deployment verification checklist for VPN. Use AUTOMATICALLY after any deployment action (deploy, rebuild, restart) and BEFORE claiming deployment is complete or successful. Evidence before assertions.
Open skill

