mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-27 04:42:51 +08:00
97 lines
3.9 KiB
Bash
Executable File
97 lines
3.9 KiB
Bash
Executable File
#!/bin/sh
|
||
# deploy.sh —— 把「DNS 防绕过」LuCI 应用从电脑部署到路由器(在电脑上执行)
|
||
#
|
||
# ./deploy.sh --check 只做语法检查,不往路由器写任何文件
|
||
# ./deploy.sh --install 上传并安装(会先备份旧文件到 /mnt/data/backup-dnsguard/)
|
||
#
|
||
# 生成:WorkBuddy 2026-09-26
|
||
# 注意:本机 Git Bash 的 PATH 里可能没有 coreutils,先执行
|
||
# export PATH="/c/Users/27970/.workbuddy/binaries/PortableGit/versions/1.2.0/usr/bin:$PATH"
|
||
|
||
set -u
|
||
DIR=$(cd "$(dirname "$0")" && pwd)
|
||
MODE="${1:---check}"
|
||
LUA_CTRL="$DIR/root/usr/lib/lua/luci/controller/dnsguard.lua"
|
||
LUA_VIEW="$DIR/root/usr/lib/lua/luci/view/dnsguard/main.htm"
|
||
SH_APPLY="$DIR/root/usr/bin/dnsguard-apply"
|
||
SH_TEST="$DIR/root/usr/bin/dnsguard-selftest"
|
||
SH_ROLL="$DIR/root/usr/bin/dnsguard-rollback"
|
||
SH_INIT="$DIR/root/etc/init.d/dnsguard"
|
||
SH_INSTALL="$DIR/install.sh"
|
||
|
||
echo "== 1) 本地 shell 语法检查 =="
|
||
for f in "$SH_APPLY" "$SH_TEST" "$SH_ROLL" "$SH_INIT" "$SH_INSTALL"; do
|
||
if [ -f "$f" ] && sh -n "$f" 2>/tmp/.dg-sh.err; then
|
||
echo " OK $(basename "$f")"
|
||
else
|
||
echo " FAIL $(basename "$f")"; cat /tmp/.dg-sh.err 2>/dev/null; exit 1
|
||
fi
|
||
done
|
||
rm -f /tmp/.dg-sh.err
|
||
|
||
echo "== 2) JSON 检查(acl 文件)=="
|
||
if command -v python >/dev/null 2>&1; then
|
||
python -c "import json,sys;json.load(sys.stdin);print(' OK acl json')" \
|
||
< "$DIR/root/usr/share/rpcd/acl.d/luci-app-dnsguard.json" || exit 1
|
||
else
|
||
echo " SKIP 没有 python,跳过(内容很短,可肉眼核对)"
|
||
fi
|
||
|
||
echo "== 3) Lua 语法检查(借路由器上的 lua 解释器,只读 stdin,不在设备上写文件)=="
|
||
if ssh -o ConnectTimeout=8 router 'command -v lua >/dev/null 2>&1'; then
|
||
if ssh router 'lua -e "local s=io.read(\"*a\"); local f,e=loadstring(s); if f then print(\" OK controller\") else print(\" FAIL \"..tostring(e)); os.exit(1) end"' < "$LUA_CTRL"; then
|
||
echo " controller 语法通过"
|
||
else
|
||
echo " controller 语法失败"; exit 1
|
||
fi
|
||
# 视图里的 Lua 只取 <% ... %> 块(跳过 <%+include%> 与 <%=expr%>)
|
||
awk '/^<%/ && $0 !~ /^<%[+="]/ { inb=1; sub(/^<%/,"") } inb { if (/%>/) { sub(/%>.*/,""); print; inb=0 } else print }' "$LUA_VIEW" > /tmp/.dg-view.lua
|
||
echo " (视图内嵌 Lua 片段 $(wc -l < /tmp/.dg-view.lua) 行)"
|
||
if ssh router 'lua -e "local s=io.read(\"*a\"); local f,e=loadstring(s); if f then print(\" OK view-lua\") else print(\" FAIL \"..tostring(e)); os.exit(1) end"' < /tmp/.dg-view.lua; then
|
||
echo " 视图 Lua 语法通过"
|
||
else
|
||
echo " 视图 Lua 语法失败"; exit 1
|
||
fi
|
||
rm -f /tmp/.dg-view.lua
|
||
else
|
||
echo " SKIP 路由器上没有 lua 命令"
|
||
fi
|
||
|
||
echo "== 4) 渲染脚本语法自检(在设备上以 --render-only 跑一次,不碰防火墙)=="
|
||
if [ "$MODE" = "--check" ]; then
|
||
if ssh -o ConnectTimeout=8 router 'test -x /usr/bin/dnsguard-apply'; then
|
||
ssh router '/usr/bin/dnsguard-apply --render-only --out /tmp/dg-check.nft' 2>&1 | sed 's/^/ /'
|
||
ssh router 'rm -f /tmp/dg-check.nft'
|
||
else
|
||
echo " SKIP 尚未安装到设备(安装后再跑本项)"
|
||
fi
|
||
fi
|
||
|
||
if [ "$MODE" = "--check" ]; then
|
||
echo
|
||
echo "全部检查通过(未改动路由器上的任何文件)。"
|
||
exit 0
|
||
fi
|
||
|
||
if [ "$MODE" != "--install" ]; then
|
||
echo "未知参数:$MODE(可用 --check / --install)" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "== 5) 打包上传 =="
|
||
TARBALL=/tmp/luci-app-dnsguard.tgz
|
||
STAGE=/tmp/.dg-stage.$$
|
||
rm -rf "$STAGE"; mkdir -p "$STAGE"
|
||
cp -r "$DIR/root" "$DIR/install.sh" "$STAGE/"
|
||
tar czf "$TARBALL" -C "$STAGE" .
|
||
rm -rf "$STAGE"
|
||
echo " 包大小:$(wc -c < "$TARBALL") 字节"
|
||
cat "$TARBALL" | ssh router 'cat > /tmp/luci-app-dnsguard.tgz'
|
||
rm -f "$TARBALL"
|
||
|
||
echo "== 6) 在路由器上安装 =="
|
||
ssh router 'cd /tmp && rm -rf /tmp/luci-app-dnsguard && mkdir -p /tmp/luci-app-dnsguard && tar xzf /tmp/luci-app-dnsguard.tgz -C /tmp/luci-app-dnsguard && sh /tmp/luci-app-dnsguard/install.sh'
|
||
|
||
echo
|
||
echo "部署结束。请在浏览器打开 http://192.168.1.1 -> 服务 -> DNS 防绕过"
|