家庭宽带搞不定微信公众号IP白名单?30元/月固定IP服务器中转方案完整实操

2次阅读

本文约 4500 字,阅读时间 12 分钟
适合:需要调用微信公众号 API、企业微信 API、或任何需要 IP 白名单的服务,但本地是家庭宽带动态 IP 的开发者

用一台 30 元 / 月的固定 IP 云服务器做 SSH 隧道 + Squid 正向代理,把所有调用微信 API 的请求从这台服务器出口,白名单精确到 /32(一个 IP),从此动态 IP 无忧。

你想用脚本自动发布微信公众号文章。微信公众号后台要求:调用 API 必须先把你的服务器 IP 加到白名单

打开后台一看,白名单输入框只接受 单个 IP(如 1.2.3.4),或者 带掩码的 IP 段(如 1.2.3.0/24)。

你查一下自己的出口 IP:

curl ifconfig.me

把这个 IP 加进去。第二天再发,提示:

{"errcode":40164,"errmsg":"invalid ip xxx.xxx.xxx.xxx, not in whitelist"}

家庭宽带 IP 一夜之间变了。

国内家庭宽带(电信、联通、移动)默认都是 动态 IP,通常每 24 小时或重启光猫时就会变化。运营商出口 IP 段非常大:

  • 广东电信:14.153.0.0/16183.23.0.0/16 等数十个段
  • 总共可能轮换数千个 IP
方案 问题
加整段 /16 白名单单条记录最大支持 /24,且把 6.5 万个 IP 全加进白名单 = 等于没有白名单
每天手动改白名单 你愿意每天爬起来改?而且微信白名单 24 小时只能修改 N 次
申请运营商固定 IP 家用宽带不给办,企业宽带 300+/ 月
VPN 回家 VPN 服务器也得有固定 IP,绕了一圈回到原点

既然家庭 IP 会变,那就 借一个永远不变的 IP当跳板:

┌──────────────┐    SSH 加密隧道     ┌─────────────────┐    HTTP 请求    ┌──────────────────┐
│  你的电脑     │ ──────────────────> │  固定 IP 云服务器 │ ──────────────> │  微信公众号 API   │
│ (动态 IP)     │   端口转发 3128      │  (Squid 代理)   │   出口 = 固定 IP    │  (白名单已加固定 IP)│
└──────────────┘                     └─────────────────┘                  └──────────────────┘
角色 比喻
你的电脑 游击队(住址经常变)
固定 IP 服务器 固定联络站(永远在同一个门牌号)
微信公众号 API 大门守卫(只认联络站的门牌号)

游击队想进大门?先到联络站集合,由联络站统一带进去。

组件 作用 替代方案
SSH 隧道 把本地端口安全加密转发到服务器 WireGuard、frp、ngrok
Squid 在服务器上充当 HTTP/HTTPS 正向代理 tinyproxy、nginx forward proxy

选 SSH + Squid 的理由

  1. 零运维:SSH 是系统自带,Squid 一条命令装好
  2. 零成本:除了服务器,没有任何软件费用
  3. 强加密:SSH 全链路 AES 加密
  4. 可观测:Squid 有详细访问日志

推荐配置

服务商 配置 价格 推荐度
阿里云轻量 2 核 2G/3M 带宽 / 华东 ¥24/ 月 ⭐⭐⭐⭐⭐
腾讯云轻量 2 核 2G/4M 带宽 / 上海 ¥28/ 月 ⭐⭐⭐⭐⭐
华为云 2 核 2G/1M 带宽 ¥35/ 月 ⭐⭐⭐

关键要求

  • ✅ 必须是 固定公网 IP(轻量应用服务器默认就是固定 IP)
  • ✅ 系统选 Ubuntu 22.04Debian 12
  • ✅ 地域选国内(华东 / 华南),访问微信 API 延迟最低

购买后记下

服务器 IP:xxx.xxx.xxx.xxx
登录密码:xxxxxxxx
SSH 端口:22

💡 避坑:不要买 ECS 包年包月(贵),轻量应用服务器(Lighthouse)就够了。也可以蹲首年活动,阿里云常有 ¥99/ 年(合 ¥8/ 月)。

2.1 本地生成 SSH 密钥(已有的可跳过):

ssh-keygen -t ed25519 -C "wechat-proxy" -f ~/.ssh/wechat_proxy

一路回车,不设密码(方便自动化重连)。

2.2 上传公钥到服务器

ssh-copy-id -i ~/.ssh/wechat_proxy.pub root@你的服务器 IP

2.3 配置本地 SSH 别名,编辑 ~/.ssh/config

Host wechat-proxy
    HostName 你的服务器 IP
    User root
    IdentityFile ~/.ssh/wechat_proxy
    ServerAliveInterval 60
    ServerAliveCountMax 3

ServerAliveInterval 60 是关键:每 60 秒发一个心跳包,防止运营商 NAT 超时断连。

2.4 测试连接

ssh wechat-proxy

能免密直接登录就成功。

登录服务器后执行:

apt update && apt install -y squid

cp /etc/squid/squid.conf /etc/squid/squid.conf.bak

cat > /etc/squid/squid.conf << 'EOF'
http_port 127.0.0.1:3128

acl localnet src 127.0.0.1/32
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443
acl CONNECT method CONNECT

http_access allow localnet
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny all

forwarded_for delete
via off
request_header_access X-Forwarded-For deny all

access_log /var/log/squid/access.log
coredump_dir /var/spool/squid
EOF

systemctl restart squid
systemctl enable squid

ss -tlnp | grep 3128

关键安全设置说明

  • http_port 127.0.0.1:3128:只在 localhost 监听,外网根本碰不到这个端口
  • acl localnet src 127.0.0.1/32:只允许本地访问
  • forwarded_for delete:删掉 X-Forwarded-For 头,微信看不出你在用代理

4.1 手动测试

ssh -N -L 3128:127.0.0.1:3128 wechat-proxy &

这条命令的含义:把 本地 3128 端口 → 通过 SSH 加密 → 转发到 服务器的 127.0.0.1:3128(也就是 Squid)。

4.2 验证代理是否生效

curl https://api.ipify.org

curl -x http://127.0.0.1:3128 https://api.ipify.org

第二条返回云服务器 IP,说明 ✅ 链路打通。

4.3 设置开机自启(推荐用 systemd 用户服务,断了自动重连):

创建 ~/.config/systemd/user/wechat-tunnel.service

[Unit]
Description=WeChat API SSH Tunnel
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/ssh -N -L 3128:127.0.0.1:3128 wechat-proxy
Restart=always
RestartSec=10

[Install]
WantedBy=default.target

启用:

systemctl --user daemon-reload
systemctl --user enable --now wechat-tunnel
systemctl --user status wechat-tunnel

如果想让服务在用户未登录时也跑:

sudo loginctl enable-linger $USER

5.1 在微信公众号后台加白名单

  • 登录 mp.weixin.qq.com
  • 设置与开发 → 基本配置 → IP 白名单
  • 添加 你的云服务器 IP(单个 IP,/32 精度)

5.2 修改脚本走代理

如果是 Node.js / Bunfetch

import {ProxyAgent, setGlobalDispatcher} from 'undici'

const proxyAgent = new ProxyAgent('http://127.0.0.1:3128')
setGlobalDispatcher(proxyAgent)

// 后续所有 fetch 自动走代理
const res = await fetch('https://api.weixin.qq.com/cgi-bin/token?...')

如果是 Pythonrequests

import requests

proxies = {
    'http': 'http://127.0.0.1:3128',
    'https': 'http://127.0.0.1:3128',
}

r = requests.get('https://api.weixin.qq.com/cgi-bin/token', proxies=proxies)

如果是 shell 脚本

export https_proxy=http://127.0.0.1:3128
export http_proxy=http://127.0.0.1:3128
curl https://api.weixin.qq.com/cgi-bin/token?...

5.3 测试发布一篇文章

调一下获取 access_token 的接口,能正常返回就 ✅ 全链路通了。

逐项打勾,全部通过即上线就绪:

  • [] 云服务器已购买,固定 IP 已记录
  • [] SSH 免密登录成功(ssh wechat-proxy 不需要输密码)
  • [] Squid 在服务器 127.0.0.1:3128 监听
  • [] 本地 SSH 隧道开机自启(systemctl status 显示 active)
  • [] curl -x http://127.0.0.1:3128 https://api.ipify.org 返回服务器 IP
  • [] 微信公众号后台已加白名单
  • [] 脚本走代理成功调用微信 API

症状:跑半天后 curl 报 Connection refused

原因:运营商 NAT 超时回收连接。

解决

  1. ~/.ssh/configServerAliveInterval 60
  2. systemd 服务设 Restart=always,断了自动拉起

症状systemctl status squid 显示 failed。

排查

journalctl -u squid --no-pager | tail -50

squid -k parse

症状curl -x 卡住没响应。

排查

tail -f /var/log/squid/access.log

如果 Squid 收到请求但转发慢,是云服务器到微信 API 的网络问题,换地域。

症状:服务器 CPU 飙升,看日志全是暴力破解 SSH。

解决

vi /etc/ssh/sshd_config

apt install -y fail2ban
systemctl enable --now fail2ban

记得云厂商安全组同步开放新端口、关闭 22。

症状:除了微信,企业微信、飞书、钉钉也需要白名单。

方案

  • 方案 A(推荐):所有项目共用这一台代理服务器,把这一个 IP 加到每个平台的白名单
  • 方案 B:每个平台开一条独立 SSH 隧道(不同本地端口)
月成本 年成本
阿里云轻量 2 核 2G ¥24 ¥288(活动价 ¥99)
Squid + SSH 软件 ¥0 ¥0
维护时间 几乎为 0 几乎为 0
合计 ¥24 ¥99 ~ ¥288

相比每月手动改白名单浪费的时间,这点钱真不算什么。

这套架构搭好后还能干很多事:

  1. 作为爬虫出口:固定 IP 反爬虫友好,不容易被封
  2. 作为公司统一出口:团队多人共用同一出口 IP
  3. 作为 GitHub/Docker 镜像加速:服务器拉取国外资源更快
  4. 作为反向跳板:通过这台服务器 SSH 到内网机器
  • ❌ 不要用 Squid 做出墙代理(违规)
  • ❌ 不要在 Squid 上开公网认证(容易被扫破)
  • ❌ 不要把服务器密码写进脚本(一定用 SSH 密钥)

这套方案的本质是:用一个 ” 位置固定 ” 的中间人,解决 ” 位置漂移 ” 的问题

类似的思路在很多场景都能用:

  • 家庭宽带反向暴露服务 → frp 内网穿透(同样原理)
  • 多云多地域统一出口 → 全球加速 / SD-WAN(企业级版本)
  • AI Agent 调用海外 API → 海外 VPS 中转(同样架构)

INTP 风格的原则:用一次性的工程投入(搭建中转),消除每天重复的运维负担(手动改白名单)。30 元 / 月,换一辈子省心。

本文方案已在生产环境稳定运行。如果你也被 IP 白名单折腾过,欢迎评论区交流踩过的坑。

相关阅读

正文完