chore: baseline snapshot before moderation-strictness feature
Repo .git was damaged (refs/ missing, index truncated, object store near-empty). Repaired via git init (rebuilt refs), stale index preserved as .git/index.corrupt-20260910.bak, then full worktree committed as a rollback baseline.
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env bash
|
||||
# TamaBox Cloudflare Tunnel 部署安全自检脚本
|
||||
#
|
||||
# 架构前提:
|
||||
# 访客 → Cloudflare 边缘(a.b.com 自定义主机名证书 / a.a.com 主域)
|
||||
# → cloudflared Tunnel(源站仅出站连接)→ 127.0.0.1:5877 (TamaBox)
|
||||
#
|
||||
# 用法:
|
||||
# 第一部分(在源站服务器上执行): ./security-selfcheck.sh local
|
||||
# 第二部分(在你自己的电脑上执行):SERVER_IP=源站公网IP CF_DOMAIN=a.a.com CUSTOM_DOMAIN=a.b.com ./security-selfcheck.sh remote
|
||||
# 两部分都跑: ./security-selfcheck.sh all
|
||||
#
|
||||
set -u
|
||||
|
||||
MODE="${1:-all}"
|
||||
SERVER_IP="${SERVER_IP:-}"
|
||||
CF_DOMAIN="${CF_DOMAIN:-a.a.com}"
|
||||
CUSTOM_DOMAIN="${CUSTOM_DOMAIN:-a.b.com}"
|
||||
APP_PORT="${APP_PORT:-5877}"
|
||||
|
||||
section() { printf "\n========== %s ==========\n" "$1"; }
|
||||
ok() { echo "[✓] $1"; }
|
||||
warn() { echo "[!] $1"; }
|
||||
bad() { echo "[✗] $1"; }
|
||||
|
||||
# 用 bash /dev/tcp 探测 TCP 端口是否可达(3 秒超时)
|
||||
port_open() {
|
||||
(timeout 3 bash -c "echo > /dev/tcp/$1/$2") 2>/dev/null
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# 第一部分:源站本地检查
|
||||
# ----------------------------------------------------------------
|
||||
local_checks() {
|
||||
section "1. 应用与数据库端口绑定检查(核心)"
|
||||
|
||||
BIND=$(ss -tlnp 2>/dev/null | grep ":${APP_PORT} " || true)
|
||||
echo "$BIND"
|
||||
if echo "$BIND" | grep -qE "127\.0\.0\.1:${APP_PORT}|\[::1\]:${APP_PORT}"; then
|
||||
ok "TamaBox 只绑定在 127.0.0.1:${APP_PORT},外部无法直连(正确)"
|
||||
elif [ -z "$BIND" ]; then
|
||||
warn "端口 ${APP_PORT} 未监听——确认 TamaBox 是否在运行"
|
||||
else
|
||||
bad "TamaBox 绑定在 0.0.0.0/*:${APP_PORT}(监听所有网卡)!"
|
||||
echo " 修复:conf/app.ini [server] 段设置 listen = 127.0.0.1:${APP_PORT} 并重启"
|
||||
fi
|
||||
|
||||
section "2. PostgreSQL / Redis 是否暴露公网"
|
||||
for p in 5432 6379; do
|
||||
BIND=$(ss -tlnp 2>/dev/null | grep ":${p} " || true)
|
||||
if echo "$BIND" | grep -qE "0\.0\.0\.0:${p}|\*:${p}"; then
|
||||
bad "端口 ${p} 绑定在所有网卡!必须改为 127.0.0.1 或加防火墙(云数据库直接暴露=高危)"
|
||||
else
|
||||
ok "端口 ${p} 未对外监听(${BIND:-未运行})"
|
||||
fi
|
||||
done
|
||||
|
||||
section "3. cloudflared 状态与 ingress 配置"
|
||||
if systemctl is-active --quiet cloudflared 2>/dev/null || pgrep -x cloudflared >/dev/null 2>&1; then
|
||||
ok "cloudflared 正在运行"
|
||||
else
|
||||
bad "cloudflared 未运行——Tunnel 断开,所有域名不可达"
|
||||
fi
|
||||
CFG=""
|
||||
for f in /etc/cloudflared/config.yml /root/.cloudflared/config.yml /home/*/.cloudflared/config.yml; do
|
||||
[ -f "$f" ] && CFG="$f" && break
|
||||
done
|
||||
if [ -n "$CFG" ]; then
|
||||
echo "配置文件:$CFG"
|
||||
grep -nE "hostname|service|originRequest" "$CFG" || true
|
||||
if grep -qE "service:\s*http://127\.0\.0\.1:${APP_PORT}|localhost:${APP_PORT}" "$CFG"; then
|
||||
ok "ingress service 指向 127.0.0.1:${APP_PORT}(正确)"
|
||||
else
|
||||
warn "未在 config.yml 中找到指向 127.0.0.1:${APP_PORT} 的 service,请人工核对 ingress 规则"
|
||||
fi
|
||||
else
|
||||
warn "未找到 config.yml(若用 token 模式 + 远端 ingress,请到 Cloudflare 面板核对 Public Hostname 的 service 地址)"
|
||||
fi
|
||||
|
||||
section "4. 本地请求验证(模拟 cloudflared 的视角)"
|
||||
RESP=$(curl -s -m 5 -o /dev/null -w "%{http_code}" "http://127.0.0.1:${APP_PORT}/" || true)
|
||||
if [ "$RESP" = "200" ] || [ "$RESP" = "302" ] || [ "$RESP" = "303" ]; then
|
||||
ok "本地 HTTP 请求返回 $RESP,应用正常"
|
||||
else
|
||||
warn "本地请求返回 ${RESP:-无响应},请人工确认"
|
||||
fi
|
||||
|
||||
section "5. 防火墙状态(仅供参考)"
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
ufw status verbose 2>/dev/null | head -15 || true
|
||||
elif command -v firewall-cmd >/dev/null 2>&1; then
|
||||
firewall-cmd --list-all 2>/dev/null || true
|
||||
else
|
||||
iptables -L INPUT -n --line-numbers 2>/dev/null | head -15 || true
|
||||
fi
|
||||
warn "请人工确认:除 SSH(22) 外,80/443/5877 等端口不应有公网入站放行规则"
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# 第二部分:外部探测(在自己的电脑上执行)
|
||||
# ----------------------------------------------------------------
|
||||
remote_checks() {
|
||||
if [ -z "$SERVER_IP" ]; then
|
||||
bad "未设置 SERVER_IP 环境变量,跳过直连探测(用法见文件头注释)"
|
||||
else
|
||||
section "6. 直连源站 IP 探测(核心:防 IP+端口直连)"
|
||||
for p in "$APP_PORT" 80 443 5432 6379; do
|
||||
if port_open "$SERVER_IP" "$p"; then
|
||||
case "$p" in
|
||||
22) warn "端口 22 开放(SSH,正常,但建议改密钥登录/限来源 IP)" ;;
|
||||
*) bad "端口 ${p} 从公网可达!存在被直连/攻击面,去服务器防火墙封掉它" ;;
|
||||
esac
|
||||
else
|
||||
ok "端口 ${p} 从公网不可达"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
section "7. 经域名的正常访问验证"
|
||||
for d in "$CF_DOMAIN" "$CUSTOM_DOMAIN"; do
|
||||
CODE=$(curl -s -m 10 -o /dev/null -w "%{http_code}" "https://${d}/" || true)
|
||||
RAY=$(curl -sI -m 10 "https://${d}/" | grep -i "^cf-ray:" || true)
|
||||
if [ -n "$RAY" ]; then
|
||||
ok "https://${d}/ 返回 ${CODE:-?},且带 ${RAY%%$'\r'} → 确认流量经过 Cloudflare 边缘"
|
||||
elif [ "$CODE" = "200" ] || [ "$CODE" = "302" ] || [ "$CODE" = "303" ]; then
|
||||
warn "https://${d}/ 返回 ${CODE} 但没有 cf-ray 头 → 流量可能没走 Cloudflare(自定义主机名未生效?)"
|
||||
else
|
||||
bad "https://${d}/ 不可达(${CODE:-无响应})"
|
||||
fi
|
||||
done
|
||||
|
||||
section "8. 伪造头穿透测试(验证 Cloudflare 会重写伪造头)"
|
||||
# 若伪造头被 CF 覆盖,应用侧记录的仍是真实 IP;此测试主要用于演示,无法从响应直接观察,
|
||||
# 需配合 TamaBox 侧日志/封禁记录核对(见第 9 项说明)。
|
||||
curl -s -m 10 -o /dev/null \
|
||||
-H "CF-Connecting-IP: 203.0.113.66" \
|
||||
-H "X-Forwarded-For: 203.0.113.66" \
|
||||
"https://${CUSTOM_DOMAIN}/" || true
|
||||
ok "已发送带伪造 CF-Connecting-IP 的请求(CF 边缘会将其重写为你的真实 IP)"
|
||||
|
||||
section "9. HTTP 明文与 HSTS 检查"
|
||||
LOC=$(curl -sI -m 10 "http://${CUSTOM_DOMAIN}/" | grep -iE "^(HTTP|location):" | tr -d '\r')
|
||||
echo "$LOC"
|
||||
HSTS=$(curl -sI -m 10 "https://${CUSTOM_DOMAIN}/" | grep -i "strict-transport-security" | tr -d '\r')
|
||||
if [ -n "$HSTS" ]; then ok "$HSTS"; else warn "未返回 HSTS 头(若浏览器直访 http 可能被中间人,建议确认 securityHeaders 已生效)"; fi
|
||||
}
|
||||
|
||||
case "$MODE" in
|
||||
local) local_checks ;;
|
||||
remote) remote_checks ;;
|
||||
all) local_checks; remote_checks ;;
|
||||
*) echo "用法: $0 {local|remote|all}"; exit 1 ;;
|
||||
esac
|
||||
|
||||
section "自检完成"
|
||||
echo "逐项核对上面的 [✓]/[!]/[✗],所有 [✗] 都需要修复后再跑一遍。"
|
||||
Reference in New Issue
Block a user