AuthorEthan
Type折腾🐦
CreatedApr 19, 2026, 19:33:52
UpdatedApr 19, 2026, 20:31:38
Views —
Words1,999
BLOG
由于持有的公网云配置太低,而 Clash CPU占用过高,故用较高配置的校园网服务器当跳板机。
开始配置中转机,会遇到一个很现实的矛盾:
一方面,我们希望利用 Clash 之类的代理服务提升远程环境的可用性;另一方面,如果直接把 7890 这类端口暴露出来,就很容易被扫描器探测到,留下不必要的安全风险。
这篇文章分享我自己的做法:利用 Tailscale + UFW 做一层物理隔离,只允许来自 Tailscale 内网的设备访问代理端口,而把公网流量彻底挡在外面。
如果你也有“想用代理,但不想把代理端口暴露给全世界”的需求,这套方案基本够用,而且配置成本很低。
这套方案的关键点只有一句话:
先给 Tailscale 虚拟网卡开一个小窗,再把公网大门焊死。
UFW 会按规则顺序自上而下匹配,因此我们可以:
tailscale0 的流量访问 78907890这样一来:
大多数情况下,Tailscale 的网卡名称都是 tailscale0,但最好还是先确认一下:
ip addr show
你会看到类似下面的网卡:
tailscale0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> ...
如果你的环境里名字不是 tailscale0,下面命令里的网卡名记得一起替换。
这里最关键的是 insert 1。
它会把规则直接插到最顶端,确保 Tailscale 内网访问优先于后面的拦截规则。
sudo ufw insert 1 allow in on tailscale0 to any port 7890 proto tcp
这条命令的含义是:
只要流量是从 tailscale0 这个虚拟网卡进入,并且目标端口是 7890/tcp,就允许通过。
接下来,把这个端口对其他来源全部封住:
sudo ufw deny 7890/tcp
由于上一条规则已经通过 insert 1 放到了最顶部,所以这里的 deny 会排在它后面。
最终效果就是:
allowdeny 拦住配置完成后执行:
sudo ufw status numbered
预期输出类似这样:
[ 1] 7890/tcp on tailscale0 ALLOW IN Anywhere
[ 2] 7890/tcp DENY IN Anywhere
如果 ALLOW IN on tailscale0 没有排在 DENY 前面,那这套方案就不会按预期工作,需要调整规则顺序。
配置好之后,你不需要再使用跳板机 IP 来连代理。
只要你的电脑或手机已经登录同一个 Tailscale 网络,直接在代理客户端里填写:
跳板机的 Tailscale IP:7890
例如:
100.x.y.z:7890
这样代理只会在 Tailnet 内部可达,不会暴露给公网。
这里有一个很容易踩坑的点:
容器访问宿主机 7890 时,流量走的通常不是 tailscale0,而是 Docker 网桥,比如 docker0。
也就是说,如果你只写了:
sudo ufw insert 1 allow in on tailscale0 to any port 7890 proto tcp
sudo ufw deny 7890/tcp
那么容器里的程序即使和宿主机在同一台机器上,也可能还是连不上,因为它的请求不会命中 tailscale0 那条规则。
如果你只用默认 Docker bridge,那补一条 docker0 规则就够了:
sudo ufw insert 2 allow in on docker0 to any port 7890 proto tcp
这样规则顺序就变成:
[ 1] 7890/tcp on tailscale0 ALLOW IN Anywhere
[ 2] 7890/tcp on docker0 ALLOW IN Anywhere
[ 3] 7890/tcp DENY IN Anywhere
但这条规则只覆盖默认的 docker0,不等于跳板机上所有 Docker 网络都放行。
如果你还创建了自定义 bridge 网络,宿主机上通常会出现额外的 br-xxxx 网卡。更省事的做法是直接把当前所有 Docker bridge 网卡都放行:
#!/usr/bin/env bash
set -euo pipefail
PORT="${1:-7890}"
# 1. 自动获取所有 Docker 相关网桥的名称
mapfile -t DOCKER_INTERFACES < <(
ip -o link show \
| awk -F': ' '{print $2}' \
| grep -E '^(docker0|br-[a-f0-9]+)$' \
|| true
)
if [ "${#DOCKER_INTERFACES[@]}" -eq 0 ]; then
echo "未检测到任何 Docker bridge 网卡。"
exit 1
fi
echo "正在为端口 ${PORT} 配置精准子网放行..."
# 2. 遍历网卡并提取子网
for IFACE in "${DOCKER_INTERFACES[@]}"; do
# 提取该网卡的子网段,例如 172.18.0.1/16
SUBNET=$(ip -o -f inet addr show "$IFACE" | awk '{print $4}' | head -n 1)
if [ -z "$SUBNET" ]; then
echo "警告: 无法获取网卡 ${IFACE} 的子网信息,跳过。"
continue
fi
# 检查规则是否已存在,防止重复添加
if sudo ufw status | grep -Fq "${PORT}/tcp" | grep -Fq "$SUBNET"; then
echo "已存在规则: 允许来自子网 ${SUBNET} 的流量访问端口 ${PORT}"
continue
fi
echo "正在添加规则: 允许子网 ${SUBNET} -> 端口 ${PORT}"
# 插入到第 1 条规则位置,确保优先级最高
sudo ufw insert 1 allow from "$SUBNET" to any port "$PORT" proto tcp
done
# 3. 补充:始终确保本机回环地址被放行(防止本机 App 失败)
if ! sudo ufw status | grep -Fq "${PORT}/tcp" | grep -Fq "127.0.0.1"; then
echo "正在添加规则: 允许本机回环 (127.0.0.1) -> 端口 ${PORT}"
sudo ufw insert 1 allow from 127.0.0.1 to any port "$PORT" proto tcp
fi
echo "-----------------------------------"
sudo ufw status numbered
例如保存成 allow-docker-proxy.sh 后执行:
chmod +x allow-docker-proxy.sh
./allow-docker-proxy.sh 7890
这个脚本会自动扫描:
docker0br-xxxx如果后面又新建了 Docker 网络,需要再运行一次脚本,把新出现的 bridge 网卡补进 UFW 规则。
另外,network_mode: host 的容器不走 bridge,这种模式本来就不在这个脚本的覆盖范围内。
在服务器运维里,下面几个端口比较常见,可以按需开放:
| 端口 | 服务 | 建议 |
|---|---|---|
7890 | Clash HTTP 代理 | 仅对 Tailscale 开放 |
7891 / 7892 | Clash SOCKS / Mixed | 若使用,同样仅对 Tailscale 开放 |
22 | SSH 远程登录 | 可公网开放,但建议配合密钥登录 |
80 / 443 | HTTP / HTTPS | 有网站业务时再开放 |
40315 | 自定义 SSH 或其他管理口 | 仅在你明确需要时开放 |
如果你还开放了 9090 之类的 Dashboard 端口,也建议照着同样思路处理,不要直接裸露在公网。
最直接的收益就是:公网扫描器打不到你的代理端口。
即使代理程序本身在监听 0.0.0.0:7890,真正起决定作用的还是防火墙规则。没有经过 Tailscale 虚拟网卡的流量,根本过不来。
你不需要记公网 IP,也不需要每次折腾端口转发。
只要设备已经加入 Tailscale 网络,就能直接通过内网地址访问代理,手机、笔记本、平板都一样。
敏感服务不对公网开放,本质上就是一种“默认不信任”的设计。
哪怕你的代理软件没有额外做认证,这层网络访问控制本身也已经帮你挡掉了绝大多数无关访问。
如果你准备把这套配置长期使用,建议顺手再检查下面几项:
sudo ss -lntp | grep 7890
sudo ufw status
从一台 已加入 Tailscale 的设备测试连接
再从公网环境测试一下服务器公网 IP 的 7890,确认无法访问
如果你本机已经启用了 ufw default deny incoming,那很多情况下即使不额外写 deny 7890/tcp 也能挡住公网访问;但我仍然更推荐显式写出来,因为规则更直观,后续排查时也更容易看懂。
安全从来不是一次性动作,而是持续贯彻“最小暴露面”和“最小权限原则”。
对代理端口来说,Tailscale + UFW 这套组合的好处就在于:既保留了远程使用体验,又避免了把服务直接摊在公网面前。
如果你的服务器上还有面板、数据库、管理接口之类的敏感服务,也完全可以照着这个思路继续加固。