7 minute read

服务器配置网络通

问题背景

在中国科学技术大学校园网环境下,使用服务器接入校园网默认会使用 DHCP 动态分配 IP 地址,如果需要 ssh 连接服务器动态的 IP 地址会带来诸多不便。解决方法有两种:

  1. 在网络信息中心申请固定公网 IP 地址,但需要额外费用且服务器 IP 暴露在公网上会带来额外安全风险与维护成本。
  2. 通过校园网的 WLT(无线认证系统)进行认证后,服务器即可获得校外网络访问权限,从而可以通过 VPN 工具(如 Tailscale)实现虚拟地址映射,获得一个固定的虚拟 IP 地址。

针对于第二种方法,在使用 Tailscale 等 VPN 工具时,必须先通过校园网的 WLT 系统进行认证登录,才能获得外网访问权限与 Tailscale 控制平面建立联系。手动登录过程繁琐且需要频繁输入密码,与自动化需求及如果 IP 变化无法连接服务器进行维护的需求产生冲突。

解决方案

目标与总体思路

实现服务器开机或重启后,自动通过 WLT 系统进行认证登录,并验证是否成功获得外网访问权限,从而确保 Tailscale 等 VPN 工具能够正常工作。

  1. 开机 / 重启后自动跑 wlt 校园网认证
  2. 不需要人工输入密码,并且保护密码安全
  3. 确认真的“拿到访问校外网络能力”(至少能连 Tailscale control plane: controlplane.tailscale.com)

WLT 的限制似乎不对 https 协议生效,故不能用 https://controlplane.tailscale.com 进行检测。

所以系统应该是:

systemd service → 周期性 / 启动时运行 → 尝试认证 → 验证外网(curl controlplane) → 成功就退出,失败就重试

wlt 自动登录脚本实现

  • root-only 配置文件保存用户与密码
  • 权限 600
  1. /etc/wlt.conf
WLT_USER=<username>
WLT_PASS=<password>
chmod 600 /etc/wlt.conf
  1. /usr/local/bin/wlt-login.sh
#!/bin/bash
set -euo pipefail

source /etc/wlt.conf

COOKIE=$(mktemp)

# 登录
curl -fsS -c "$COOKIE" \
  "http://wlt.ustc.edu.cn/cgi-bin/ip?cmd=login&name=${WLT_USER}&password=${WLT_PASS}" \
  > /dev/null

# 设置type(type=9)
curl -fsS -b "$COOKIE" \
  "http://wlt.ustc.edu.cn/cgi-bin/ip?cmd=set&type=9&exp=0" \
  > /dev/null

rm -f "$COOKIE"
chmod +x /usr/local/bin/wlt-login.sh

验证外网连接脚本实现

  1. 原理上是通过 curl 访问 controlplane.tailscale.com 来验证是否具备外网访问能力:
    curl -v -I controlplane.tailscale.com
    
  2. /usr/local/bin/wlt-online.sh
#!/bin/bash
set -euo pipefail

MAX_RETRY=10
SLEEP_SEC=10

for ((i=1; i<=MAX_RETRY; i++)); do
  echo "[wlt] attempt $i..."

  /usr/local/bin/wlt-login.sh || true

  if curl -fsS --connect-timeout 5 --max-time 8 \
       https://controlplane.tailscale.com > /dev/null; then
    echo "[wlt] external network OK"
    exit 0
  fi

  echo "[wlt] not online yet, retrying..."
  sleep "$SLEEP_SEC"
done

echo "[wlt] failed after $MAX_RETRY attempts"
exit 1

设置 systemd 服务

Service 文件

  1. /etc/systemd/system/wlt-online.service
[Unit]
Description=WLT campus network auto login
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/wlt-online.sh
RemainAfterExit=yes

# 安全加固
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=full
ProtectHome=yes

[Install]
WantedBy=multi-user.target
  1. 启用服务
systemctl daemon-reexec
systemctl daemon-reload
systemctl enable wlt-online.service
systemctl start wlt-online.service
  1. 查看日志:
journalctl -u wlt-online.service -f

Updated: