Files
nas/scripts/setup-frp-on-nas.sh
T

204 lines
6.2 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 在 NAS 上执行(由 setup-frp-remote.sh 上传并调用,也可手动跑):
# ① 写 frpc 配置 + 安装 frpc 二进制 + systemd 常驻(需 sudo,会提示输 DSM 密码)
# (不用 dockerNAS 出国通道不通拉不了 Docker Hub 镜像;二进制由远端脚本推来)
# ② mihomo 加 hosts 覆盖 / fake-ip-filter / use-hosts(幂等,自动备份,热重载)
# ③ 端到端验证
# 前提:/tmp/frp-setup/ 下有 tokenBitwarden 取来)和 frpclinux_amd64 二进制)。
set -euo pipefail
FRP_DIR=/volume1/docker/frp
CFG=/volume1/docker/proxy/mihomo/config.yaml
TOKEN_FILE=/tmp/frp-setup/token
FRPC_BIN=/tmp/frp-setup/frpc
[ -s "$TOKEN_FILE" ] || { echo "!! 缺 token 文件 $TOKEN_FILE(应由 setup-frp-remote.sh 生成)"; exit 1; }
[ -s "$FRPC_BIN" ] || { echo "!! 缺 frpc 二进制 $FRPC_BIN(应由 setup-frp-remote.sh 上传)"; exit 1; }
read -r TOKEN < "$TOKEN_FILE"
echo "==> 1/6 写 frpc.toml + docker-compose.ymlsudo"
sudo mkdir -p "$FRP_DIR"
sudo tee "$FRP_DIR/frpc.toml" > /dev/null <<EOF
serverAddr = "182.92.213.171"
serverPort = 7000
auth.method = "token"
auth.token = "$TOKEN"
transport.tls.enable = true
[[proxies]]
name = "git-ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 2222
remotePort = 2222
[[proxies]]
name = "git-web"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3000
remotePort = 3000
[[proxies]]
name = "dsm"
type = "tcp"
localIP = "127.0.0.1"
localPort = 5001
remotePort = 5001
[[proxies]]
name = "nas-ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 10022
[[proxies]]
name = "win-rdp"
type = "tcp"
localIP = "192.168.3.88"
localPort = 3389
remotePort = 3389
[[proxies]]
name = "win-ssh"
type = "tcp"
localIP = "192.168.3.88"
localPort = 22
remotePort = 10023
EOF
sudo chmod 600 "$FRP_DIR/frpc.toml"
echo "==> 2/6 安装 frpc 二进制 + systemd 常驻"
sudo install -m 755 "$FRPC_BIN" /usr/local/bin/frpc
sudo tee /etc/systemd/system/frpc.service > /dev/null <<'EOF'
[Unit]
Description=frp client (home reverse tunnel to ali frps)
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/frpc -c /volume1/docker/frp/frpc.toml
Restart=always
RestartSec=5
LimitNOFILE=65536
MemoryLimit=64M
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable frpc >/dev/null 2>&1 || true
sudo systemctl restart frpc
echo "==> 3/6 mihomohosts 覆盖 + fake-ip-filter + use-hosts(幂等)"
if [ ! -f "$CFG" ]; then
echo " !! mihomo 配置不存在($CFG)——NAS 上 mihomo 已不在运行,跳过 3/4/5 步。"
echo " !! 家内 DNS 覆盖需另行方案(群晖 DNS Server 套件),见 docs/remote-access-frp.html。"
SKIP_MIHOMO=1
fi
if [ -z "${SKIP_MIHOMO:-}" ]; then
cp "$CFG" "$CFG.bak.frp"
echo " 备份: $CFG.bak.frp"
python3 - "$CFG" <<'PY'
import re, sys
p = sys.argv[1]
text = open(p).read()
orig = text
HOSTS = {
"nas.yanmeiai.com": "192.168.3.200",
"git.yanmeiai.com": "192.168.3.200",
"win.yanmeiai.com": "192.168.3.88",
"git.51yanmei.com": "192.168.3.200", # 兼容既有 git remote
}
lines = text.splitlines(True)
# ---- ① fake-ip-filter 追加域名(防 fake-ip 吞掉 hosts 真实值)----
missing = [d for d in HOSTS if ("'" + d + "'") not in text and ('"' + d + '"') not in text and ("- " + d) not in text]
out = []
inserted_filter = False
for i, ln in enumerate(lines):
out.append(ln)
if (not inserted_filter) and re.match(r"\s*fake-ip-filter:\s*$", ln):
# 探测下一行列表项缩进
indent = " "
for nxt in lines[i+1:]:
m = re.match(r"(\s*)- ", nxt)
if m:
indent = m.group(1)
break
for d in missing:
out.append(indent + "- '" + d + "'\n")
inserted_filter = True
if missing and not inserted_filter:
print(" !! 没找到 fake-ip-filter: 段,请人工检查", file=sys.stderr)
sys.exit(1)
lines = out
# ---- ② hosts 段(家内答案:域名 → 内网 IP)----
text = "".join(lines)
have_hosts = re.search(r"^hosts:\s*$", text, re.M)
need = {d: ip for d, ip in HOSTS.items() if not re.search(r"^\s+" + re.escape(d) + ":", text, re.M)}
if need:
if have_hosts:
out = []
done = False
for ln in text.splitlines(True):
out.append(ln)
if (not done) and re.match(r"^hosts:\s*$", ln):
for d, ip in need.items():
out.append(" " + d + ": " + ip + "\n")
done = True
text = "".join(out)
else:
block = "\nhosts:\n"
for d, ip in need.items():
block += " " + d + ": " + ip + "\n"
text += block
# ---- ③ dns.use-hosts: truemihomo 默认 false,不开 hosts 对 DNS 响应不生效)----
if re.search(r"^\s*use-hosts:", text, re.M):
text = re.sub(r"(^\s*use-hosts:\s*)false", r"\1true", text, flags=re.M)
else:
out = []
done = False
for ln in text.splitlines(True):
out.append(ln)
if (not done) and re.match(r"^dns:\s*$", ln):
out.append(" use-hosts: true\n")
done = True
if not done:
print(" !! 没找到 dns: 段,请人工检查", file=sys.stderr)
sys.exit(1)
text = "".join(out)
if text != orig:
open(p, "w").write(text)
print(" 已写入(hosts %d 条新增 / fake-ip-filter %d 条新增)" % (len(need), len(missing)))
else:
print(" 无需改动(已是目标状态)")
PY
echo "==> 4/6 热重载 mihomo"
curl -s -X PUT 'http://127.0.0.1:9090/configs?force=true' \
-H 'Content-Type: application/json' \
-d '{"path":"/root/.config/mihomo/config.yaml"}'
echo " reload 已请求"
echo "==> 5/6 验证家内解析(期望 192.168.3.200"
sleep 1
nslookup git.yanmeiai.com 127.0.0.1 2>&1 | tail -3
fi # SKIP_MIHOMO
echo "==> 6/6 验证 frpc 隧道"
sleep 3
sudo systemctl is-active frpc
sudo journalctl -u frpc --no-pager -n 20 2>/dev/null || sudo systemctl status frpc --no-pager | tail -20
rm -f "$TOKEN_FILE" "$FRPC_BIN"
echo ""
echo "完成。检查上方日志:应有 'login to server success',且 git-ssh/git-web/dsm/nas-ssh/win-rdp/win-ssh 六个 proxy 'start proxy success'。"
echo "若 login 失败:token 不对或 pangolin1:7000 不通;若个别 proxy 失败:对应本地端口没起。"