Files
lou b55c0cb7bb 开源化: MIT LICENSE + 详细 README + deploy/watchdog + 全仓脱敏(云服IP/学校域/凭据 → RFC5737 占位)
- LICENSE: MIT © 2026 edgevoid
- README: 三层架构/逐字段伪装对照/部署/验证/安全边界/看门狗自启
- 脱敏(filter-repo 全历史): 8.136.202.225→203.0.113.10, .zjipc.cn→.internal.example, 学校DNS→192.0.2.53
- hook.sh 更新为安全形态(FORWARD-only 绑 WAN, 去掉 OUTPUT 全挂断网形态)
- router_deploy.sh: SSHPASS 改环境变量注入(明文密码清除)
- watchdog.sh 纳入 deploy/(接口变量化)
- 内部语境泛化(认证网关/学校DNS/寝室部署备注)
2026-09-09 18:14:10 +08:00

80 lines
3.7 KiB
Bash
Executable File

#!/bin/bash
# 网关一键部署(在 LAN 内从管理机跑): ./deploy/router_deploy.sh
# 职责: 传代码 -> 检查 python3 依赖 -> 起 L1 伪装器 + L2 代理 -> hook 规则
# 不做(配置敏感, 手动): smartdns 上游指向 127.0.0.1#8053
set -euo pipefail
ROUTER="${ROUTER:-root@192.168.1.1}" # 按实际网关地址
REMOTE_DIR="${REMOTE_DIR:-/root/masq}"
LOCAL_DIR="$(cd "$(dirname "$0")/.." && pwd)"
# 凭据从环境变量注入(绝不落盘): export SSHPASS=<网关密码> ./deploy/router_deploy.sh
export SSHPASS="${SSHPASS:?请先 export SSHPASS=<网关密码>}"
echo "==> 传代码到软路由 $REMOTE_DIR"
sshpass -e ssh -o StrictHostKeyChecking=no "$ROUTER" "mkdir -p $REMOTE_DIR/{masquerader,channel,config}"
sshpass -e scp -o StrictHostKeyChecking=no \
"$LOCAL_DIR/masquerader/rewrite.py" \
"$ROUTER:$REMOTE_DIR/masquerader/"
sshpass -e scp -o StrictHostKeyChecking=no \
"$LOCAL_DIR/masquerader/__init__.py" \
"$ROUTER:$REMOTE_DIR/masquerader/"
sshpass -e scp -o StrictHostKeyChecking=no \
"$LOCAL_DIR/channel/__init__.py" \
"$LOCAL_DIR/channel/proto.py" \
"$LOCAL_DIR/channel/httpmsg.py" \
"$LOCAL_DIR/channel/dnsmsg.py" \
"$LOCAL_DIR/channel/client.py" \
"$LOCAL_DIR/channel/proxy_http.py" \
"$LOCAL_DIR/channel/proxy_dns.py" \
"$ROUTER:$REMOTE_DIR/channel/"
sshpass -e scp -o StrictHostKeyChecking=no \
"$LOCAL_DIR/config/masquerader.json" \
"$ROUTER:$REMOTE_DIR/config/"
echo "==> 软路由 python3 依赖检查"
sshpass -e ssh -o StrictHostKeyChecking=no "$ROUTER" '
for pkg in python3 python3-openssl libnetfilter-queue1; do
opkg list-installed 2>/dev/null | grep -q "^$pkg " || echo "缺包: $pkg (opkg install $pkg)"
done
python3 -c "import ssl, socket" 2>&1 && echo "python3 + ssl OK"
'
echo "==> 写入通道 token/配置(从本地 config/channel.json 读取 cloud 段)"
# token 由调用方用环境变量 CHANNEL_TOKEN 提供, 或提示手动填
if [ -n "${CHANNEL_TOKEN:-}" ]; then
sshpass -e ssh -o StrictHostKeyChecking=no "$ROUTER" "cat > $REMOTE_DIR/config/channel.json" <<EOF
{
"cloud": {"host": "203.0.113.10", "port": 8444, "token": "$CHANNEL_TOKEN", "ca_path": ""},
"http_proxy": {"listen_port": 8080},
"dns_proxy": {"listen_port": 8053, "school_dns": "192.0.2.53", "internal_suffixes": [".internal.example"]},
"heartbeat": 30
}
EOF
echo "channel.json 已写入"
else
echo "提示: CHANNEL_TOKEN 未设置, 通道配置需手动写入 $REMOTE_DIR/config/channel.json"
fi
echo "==> 起服务(nohup, 日志在 /root/masq/*.log)"
sshpass -e ssh -o StrictHostKeyChecking=no "$ROUTER" "
cd $REMOTE_DIR
[ -z \"\$(pgrep -f masquerader.worker)\" ] && PYTHONPATH=$REMOTE_DIR nohup python3 -m masquerader.worker config/masquerader.json > worker.log 2>&1 &
[ -z \"\$(pgrep -f proxy_http)\" ] && PYTHONPATH=$REMOTE_DIR nohup python3 -m channel.proxy_http config/channel.json > proxy_http.log 2>&1 &
[ -z \"\$(pgrep -f proxy_dns)\" ] && PYTHONPATH=$REMOTE_DIR nohup python3 -m channel.proxy_dns config/channel.json > proxy_dns.log 2>&1 &
sleep 2
echo '--- 进程 ---'; pgrep -af 'masquerader.worker|proxy_http|proxy_dns' | grep -v bash
echo '--- worker.log ---'; cat worker.log 2>/dev/null | head -5
echo '--- proxy_http.log ---'; cat proxy_http.log 2>/dev/null | head -3
echo '--- proxy_dns.log ---'; cat proxy_dns.log 2>/dev/null | head -3
"
echo "==> hook 规则"
sshpass -e scp -o StrictHostKeyChecking=no "$LOCAL_DIR/deploy/hook.sh" "$ROUTER:/tmp/hook.sh"
sshpass -e ssh -o StrictHostKeyChecking=no "$ROUTER" 'sh /tmp/hook.sh add'
echo ""
echo "==> 剩余手动步骤(部署现场确认):"
echo " 1. smartdns/dnsmasq 上游指向 127.0.0.1#8053"
echo " 2. 若软路由自身也要伪装, 确认 mangle OUTPUT 链 TTL 规则存在"
echo " 3. tcpdump 抓包: ssh 软路由后 tcpdump -i <wan口> -w /tmp/cap.pcap -G 5 -W 1"