"""pfSense diagnostic for azcomputerguru.com 521 — suspected CF IP blocks. Runs a single SSH session with batched diagnostics targeted at identifying why Cloudflare PHX PoP can't reach 72.194.62.5:443. """ import paramiko, socket socket.setdefaulttimeout(60) HOST = '172.16.0.1' PORT = 2248 USER = 'admin' import subprocess as _sp, yaml as _y PWD = _y.safe_load(_sp.run(['sops','-d','D:/vault/infrastructure/pfsense-firewall.sops.yaml'],capture_output=True,text=True,timeout=30,check=True).stdout)['credentials']['password'] CMDS = [ ('installed packages (IDS/IPS/blocker)', 'pkg info 2>/dev/null | egrep -i "suricata|snort|pfblocker|crowdsec" || echo "(none)"'), ('NAT rules for 72.194.62.5 / port 443', 'pfctl -s nat 2>/dev/null | grep -E "72\\.194\\.62\\.5|443" | head -30 || echo "(pfctl nat empty)"'), ('Rules in PF referencing .62.5', 'pfctl -sr 2>/dev/null | grep "72\\.194\\.62\\.5" | head -20 || echo "(none)"'), ('PF aliases referencing Cloudflare (case-insensitive)', 'pfctl -T show -a cloudflare 2>/dev/null | head -30 ; pfctl -sT 2>/dev/null | grep -i "cloudflare\\|cf_\\|_cf"'), ('Recent filter.log entries mentioning 72.194.62.5 (last 200 binary-decoded)', 'clog /var/log/filter.log | tail -2000 | grep "72\\.194\\.62\\.5" | tail -40 || echo "(no recent entries)"'), ('Recent BLOCK actions from filter.log (last 500 lines)', 'clog /var/log/filter.log | tail -500 | grep -E "block|reject" | head -40 || echo "(no blocks)"'), ('Current states for :443 dst (limit 15)', 'pfctl -s states 2>/dev/null | awk \'$6 ~ /:443$/\' | head -15 || echo "(no :443 states)"'), ('State table total count', 'pfctl -s info 2>/dev/null | grep -i "states\\|limit\\|current" | head -10'), ('Suricata status + alert log if installed', 'service suricata status 2>/dev/null ; ls -la /var/log/suricata/ 2>/dev/null | head'), ('pfBlockerNG log if installed', 'ls -la /var/log/pfblockerng/ 2>/dev/null | head ; cat /var/log/pfblockerng/block.log 2>/dev/null | tail -30'), ('IP reputation / GeoIP blocks on WAN', 'pfctl -sr 2>/dev/null | grep -iE "geoip|pfblocker|block in" | head -20'), ('Last 30 dropped packets to :443 (any dst)', 'clog /var/log/filter.log | tail -2000 | grep -E "port 443" | grep -E "block|reject" | tail -30 || echo "(none)"'), ] def main(): c = paramiko.SSHClient() c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect(HOST, port=PORT, username=USER, password=PWD, timeout=30, banner_timeout=30, look_for_keys=False, allow_agent=False) try: for label, cmd in CMDS: print(f'\n===== {label} =====', flush=True) stdin, stdout, stderr = c.exec_command(cmd, timeout=60) out = stdout.read().decode('utf-8','replace') err = stderr.read().decode('utf-8','replace') if out.strip(): print(out.rstrip()) if err.strip() and 'stty' not in err and 'terminal' not in err.lower(): print(f' [stderr] {err.rstrip()[:300]}') finally: c.close() if __name__ == '__main__': main()