#!/bin/bash
export LC_ALL=C
have(){ command -v "$1" >/dev/null 2>&1; }
s(){ echo; echo "===== $1 ====="; }
s "SYSTEM"
uname -r; grep PRETTY_NAME /etc/os-release; uptime; nproc
free -m; swapon --show 2>/dev/null; df -h / | tail -1
s "IP / ROUTE"
ip -4 -br addr; ip route | head -3
curl -s -m5 https://ifconfig.me; echo
s "LISTENING PORTS"
ss -tulpn 2>/dev/null | head -40
s "VPN/PROXY PROCESSES"
ps -eo pid,user,rss,etime,args | grep -Ei 'xray|v2ray|sing-box|x-ui|hysteria|tuic|trojan|wg|amnezia|openvpn|nginx|caddy|haproxy|cloudflared|docker' | grep -v grep | cut -c1-180
s "SYSTEMD RUNNING (relevant)"
systemctl list-units --type=service --state=running --no-pager 2>/dev/null | grep -Ei 'xray|v2ray|sing|x-ui|hysteria|wg|openvpn|nginx|caddy|docker|cloudflared|ssh'
s "DOCKER"
have docker && docker ps --format '{{.Names}} | {{.Image}} | {{.Ports}}' 2>/dev/null || echo "no docker"
s "XRAY/SING-BOX CONFIGS (summary, no secrets)"
python3 - <<'EOF' 2>&1
import json, glob
files = ["/usr/local/etc/xray/config.json","/etc/xray/config.json",
"/usr/local/etc/sing-box/config.json","/etc/sing-box/config.json"] + glob.glob("/etc/*/config.json")
seen = set()
for f in files:
if f in seen: continue
seen.add(f)
try: c = json.load(open(f))
except Exception: continue
print("FILE", f)
for ib in c.get("inbounds", []):
ss = ib.get("streamSettings") or {}
st = ss.get("network"); sec = ss.get("security")
ws = (ss.get("wsSettings") or {}).get("path")
xh = (ss.get("xhttpSettings") or {}).get("path")
n = len((ib.get("settings") or {}).get("clients", []))
print(" in:", ib.get("protocol"), "port", ib.get("port"), "listen", ib.get("listen"),
"net", st, "sec", sec, "ws", ws, "xhttp", xh, "clients", n)
for ob in c.get("outbounds", []):
print(" out:", ob.get("protocol"), ob.get("tag"))
EOF
s "X-UI DB (inbounds)"
if [ -f /etc/x-ui/x-ui.db ] && have sqlite3; then
sqlite3 /etc/x-ui/x-ui.db "select id,remark,protocol,port,enable from inbounds;" 2>&1
else echo "no x-ui db"; fi
s "SSHD"
sshd -T 2>/dev/null | grep -Ei '^(port|listenaddress|passwordauthentication|permitrootlogin|pubkeyauthentication|allowusers) ' || echo "sshd -T unavailable"
(echo > /dev/tcp/127.0.0.1/22) 2>/dev/null && echo "local 127.0.0.1:22 OPEN" || echo "local 127.0.0.1:22 CLOSED"
s "FIREWALL"
have ufw && ufw status 2>/dev/null | head -20
iptables -S 2>/dev/null | head -40
nft list ruleset 2>/dev/null | head -40
s "CERTS"
ls /etc/letsencrypt/live 2>/dev/null || echo "no letsencrypt"
ls /etc/ssl/private 2>/dev/null | head
s "KERNEL NET"
sysctl net.ipv4.ip_forward net.ipv4.tcp_congestion_control net.core.default_qdisc 2>/dev/null
s "OUTBOUND CHECKS"
for h in www.cloudflare.com 1.1.1.1 google.com; do
curl -sI -m6 https://$h -o /dev/null -w "$h https:%{http_code} %{time_total}s\n" || echo "$h https FAIL"
done
ping -c2 -W2 1.1.1.1 2>/dev/null | tail -2
s "DONE"