反向代理 ASUS 路由器 WebUI 需要设置 Referer 与 Host 匹配
今天想给 subconverter 添加一个 webhook,来触发路由器中 Merlin Clash 应用的自动重新加载,这就涉及要把路由器的 API 暴露到互联网上。
我一开始的想法是绑定域名,然后从外面直接访问,因为我的环境只有 IPv6 可用,而 GitHub Action 它只支持 IPv4,所以这条路不行。
那另一条路就是在外部公共环境中放置一个反向代理,我尝试了 Cloudflare Tunnel 和自己腾讯云服务器上的 nginx 反向代理,他们都遇到了一个问题:可以打开登录页,但是无法进行登录,点击登录按钮会刷新网页。
正常来说,不论登录不论账号密码是正确还是错误,那它都会有一个提示。那现在点击登录就像是刷新了网页一样。
我一开始还怀疑是 Cloudflare Tunnel ,它动态 IP 导致每次都连接到一个新的 session,也检查了浏览器中的 cookie,但似乎并不是相关的。
此时我想起来之前,调用 API 的时候,给路由器 API 的请求中必须有一个 Referer 参数,这次让 GPT 验证了下确有其事,调用点在 asuswrt-merlin.ng/release/src/router/httpd/httpd.c
int check_noauth_referrer(char *referer, int fromapp_flag)
{
char *auth_referer = NULL;
if (fromapp_flag != 0)
return 0;
if (!referer || !strlen(host_name))
return NOREFERER;
auth_referer = get_referrer(referer);
if (!strcmp(host_name, auth_referer))
return 0;
return REFERERFAIL;
}逻辑上即是验证 Host 和 Referer 必须匹配,那就简单了,在 Caddy 反向代理处设置固定值即可
rt-ax86u.home.kokomi.site {
reverse_proxy RT-AX86U-CE58. {
header_up Host "RT-AX86U-CE58"
header_up Referer "http://RT-AX86U-CE58"
}
}这其实相当于公网暴露了,留下一个坑就是,任何人如果多输入错误几次,这个 WebUI 就会被锁,需要
service restart_httpd重新启动