#!/bin/bash # PaladinVPN — Full Server Picture (VLESS era) # Copy-paste this entire block into your SSH terminal on the Hetzner Debian box. # Read-only — makes no changes to the system. # Run as root or with sudo. bash <<'REPORT' echo "============================================================" echo " PaladinVPN — Server State Report" echo " $(date '+%Y-%m-%d %H:%M:%S %Z')" echo "============================================================" # ── 1. System ──────────────────────────────────────────────── echo ""; echo "=== SYSTEM ===" echo "Hostname : $(hostname)" echo "Uptime : $(uptime -p)" echo "Debian : $(cat /etc/debian_version 2>/dev/null || echo 'N/A')" echo "Kernel : $(uname -r)" echo "Arch : $(uname -m)" echo "Load : $(uptime | awk -F'load average:' '{print $2}' | xargs)" echo "" echo "CPU:" echo "$(lscpu | grep -E 'Model name|CPU\(s\)|Thread' | sed 's/^/ /')" 2>/dev/null echo "" echo "Memory:" free -h | grep -E '^Mem:|^Swap:' | sed 's/^/ /' echo "" echo "Disk:" df -h / | tail -1 | awk '{print " Root: " $3 "/" $2 " (" $5 ")"}' # ── 2. Network Interfaces ──────────────────────────────────── echo ""; echo "=== NETWORK INTERFACES ===" ip -br addr 2>/dev/null || ifconfig -a 2>/dev/null echo "" echo "Routes:" ip route show 2>/dev/null | grep -v '^fe80' || route -n echo "" echo "DNS:" cat /etc/resolv.conf 2>/dev/null | grep -v '^#' | grep -v '^$' | sed 's/^/ /' # ── 3. Open Ports ──────────────────────────────────────────── echo ""; echo "=== LISTENING PORTS ===" ss -tlnp 2>/dev/null | head -30 || netstat -tlnp 2>/dev/null | head -30 # ── 4. IPv6 Status ─────────────────────────────────────────── echo ""; echo "=== IPv6 ===" echo "Forwarding:" sysctl net.ipv6.conf.all.forwarding 2>/dev/null echo "" echo "IPv6 routes:" ip -6 route show 2>/dev/null | head -10 echo "" echo "IPv6 NAT (ip6tables):" ip6tables -t nat -L POSTROUTING -n 2>/dev/null | head -10 || echo " ip6tables not available" # ── 5. Firewall (iptables) ─────────────────────────────────── echo ""; echo "=== IPTABLES NAT ===" iptables -t nat -L POSTROUTING -n -v 2>/dev/null | head -20 || echo " iptables not available" # ── 6. Services ────────────────────────────────────────────── echo ""; echo "=== SERVICES ===" for svc in hivemind xray nginx docker certbot; do if systemctl is-enabled "$svc" &>/dev/null; then printf " %-12s : %s (enabled)\n" "$svc" "$(systemctl is-active "$svc")" elif systemctl is-active "$svc" &>/dev/null; then printf " %-12s : %s (not enabled)\n" "$svc" "$(systemctl is-active "$svc")" else printf " %-12s : not found\n" "$svc" fi done echo "" echo "Certbot timer:" systemctl list-timers --all 2>/dev/null | grep -i certbot || echo " No certbot timer found" # ── 7. Xray ────────────────────────────────────────────────── echo ""; echo "=== XRAY ===" if command -v xray &>/dev/null; then echo "Binary : $(which xray)" echo "Version : $(xray version 2>&1 | head -1)" echo "Status : $(systemctl is-active xray 2>/dev/null || echo 'N/A')" echo "" echo "Config file exists?" if [ -f /usr/local/etc/xray/config.json ]; then echo " YES — $(wc -c < /usr/local/etc/xray/config.json) bytes" echo " Clients: $(python3 -c "import json; c=json.load(open('/usr/local/etc/xray/config.json')); print(len(c['inbounds'][0]['settings']['clients']))" 2>/dev/null || echo 'ERROR reading config')" else echo " NO — /usr/local/etc/xray/config.json not found" fi echo "" echo "Stats API:" curl -s --max-time 3 http://127.0.0.1:10085/stats/query -d '{"pattern":"","reset":false}' 2>/dev/null | python3 -m json.tool 2>/dev/null | head -10 || echo " Stats API unreachable" echo "" echo "Last 5 Xray log lines:" journalctl -u xray --no-pager -n 5 2>/dev/null | sed 's/^/ /' || echo " No journal entries" else echo " Xray NOT INSTALLED" fi # ── 8. Hivemind ────────────────────────────────────────────── echo ""; echo "=== HIVEMIND ===" echo "Status : $(systemctl is-active hivemind 2>/dev/null || echo 'N/A')" echo "Config : $(systemctl cat hivemind 2>/dev/null | grep -i execstart | sed 's/^/ /')" echo "" echo "Active sessions:" python3 -c " import sys; sys.path.insert(0, '/root') try: from server_hivemind_5_0 import active_sessions, sessions_lock with sessions_lock: count = len(active_sessions) throttled = sum(1 for s in active_sessions.values() if s.get('is_throttled')) print(f' Total: {count} Throttled: {throttled}') except Exception as e: print(f' Could not read sessions: {e}') " 2>/dev/null || echo " Could not import hivemind module" echo "" echo "Hivemind script:" if [ -f /root/server_hivemind_5_0.py ]; then echo " /root/server_hivemind_5_0.py — $(wc -l < /root/server_hivemind_5_0.py) lines" elif [ -f /root/server_hivemind_* ]; then ls -la /root/server_hivemind_* 2>/dev/null | sed 's/^/ /' else echo " No hivemind script found in /root" fi echo "" echo "Last 10 Hivemind log lines:" journalctl -u hivemind --no-pager -n 10 2>/dev/null | sed 's/^/ /' || echo " No journal entries" # ── 9. Nginx ───────────────────────────────────────────────── echo ""; echo "=== NGINX ===" if command -v nginx &>/dev/null; then echo "Binary : $(which nginx)" echo "Version : $(nginx -v 2>&1)" echo "Status : $(systemctl is-active nginx 2>/dev/null || echo 'N/A')" echo "" echo "Config test:" nginx -t 2>&1 | sed 's/^/ /' echo "" echo "Sites enabled:" ls -la /etc/nginx/sites-enabled/ 2>/dev/null | sed 's/^/ /' echo "" echo "/tunnel location block exists?" grep -r "location /tunnel" /etc/nginx/sites-enabled/ 2>/dev/null | sed 's/^/ /' || echo " NOT FOUND" echo "" echo "/api location block exists?" grep -r "location /api" /etc/nginx/sites-enabled/ 2>/dev/null | sed 's/^/ /' || echo " NOT FOUND" else echo " NGINX NOT INSTALLED" fi # ── 10. SSL ────────────────────────────────────────────────── echo ""; echo "=== SSL CERTIFICATES ===" if command -v certbot &>/dev/null; then certbot certificates 2>/dev/null | sed 's/^/ /' || echo " No certificates found" echo "" echo "Certificate files:" ls -la /etc/letsencrypt/live/ 2>/dev/null | sed 's/^/ /' || echo " /etc/letsencrypt/live/ not found" else echo " certbot not installed" fi # ── 11. Docker ──────────────────────────────────────────────── echo ""; echo "=== DOCKER ===" if command -v docker &>/dev/null; then echo "Running containers:" docker ps --format ' {{.Names}} {{.Image}} {{.Status}} {{.Ports}}' 2>/dev/null || echo " None" else echo " Docker not installed" fi # ── 12. Traffic Control (tc) ───────────────────────────────── echo ""; echo "=== TRAFFIC CONTROL (tc) ===" if command -v tc &>/dev/null; then for iface in $(ip -br link 2>/dev/null | awk '{print $1}'); do rules=$(tc qdisc show dev "$iface" 2>/dev/null | grep -v "noqueue\|fq_codel\|pfifo_fast" | head -5) if [ -n "$rules" ]; then echo " Interface $iface:" echo "$rules" | sed 's/^/ /' fi done echo " (no custom tc rules found unless listed above)" else echo " tc not available" fi # ── 13. AWG leftovers ──────────────────────────────────────── echo ""; echo "=== AWG LEFTOVERS ===" echo "awg0 interface : $([ -d /sys/class/net/awg0 ] && echo 'STILL EXISTS' || echo 'gone ✓')" echo "awg binary : $(command -v awg 2>/dev/null && echo 'STILL INSTALLED' || echo 'gone ✓')" echo "wg-easy docker : $(docker ps -a --filter 'name=wg-easy' --format '{{.Names}}' 2>/dev/null || echo 'gone ✓')" echo "iptables 10.8.x: $(iptables -t nat -L POSTROUTING 2>/dev/null | grep '10\.8\.' | head -3 || echo 'gone ✓')" # ── 14. Recent Errors ──────────────────────────────────────── echo ""; echo "=== RECENT ERRORS (last 50 journal lines, filtered) ===" journalctl -u hivemind -u xray -u nginx --no-pager -n 50 --since "1 hour ago" 2>/dev/null | grep -iE 'error|fail|warn|exception|cannot|denied|timeout' | tail -10 | sed 's/^/ /' || echo " No recent errors" echo ""; echo "============================================================" echo " Report complete — $(date '+%H:%M:%S')" echo "============================================================" REPORT