Linux主机间实现带WOL唤醒的Web请求端口转发方案咨询
你这个需求其实就是反向代理+WOL触发的组合方案,思路完全没问题,我给你拆解下具体怎么实现,都是内网环境下的操作,很容易落地:
第一步:先确保Box B能正常唤醒Server A
首先得把WOL的基础打通,不然后面的转发都是白搭:
- 先拿到Server A的网卡MAC地址:可以在Server A上执行
ip link show查看,或者直接登录路由器后台找设备列表里的MAC - 在Box B上安装WOL工具:Debian/Ubuntu系用
apt install etherwake,RHEL/CentOS系用yum install etherwake,也可以用wakeonlan包,功能差不多 - 测试唤醒:在Box B上执行
etherwake xx:xx:xx:xx:xx:xx(把xx替换成Server A的MAC),确认Server A能从待机状态启动
另外要注意:Server A的BIOS/UEFI要开启WOL功能,网卡也要启用WOL——可以在Server A上用ethtool eth0(替换成你的网卡名)查看,看Wake-on字段是不是g(代表支持魔术包唤醒),如果不是,执行ethtool -s eth0 wol g设置,然后把这个命令加到开机启动脚本里(比如/etc/rc.local或者netplan配置),避免重启后失效。
第二步:用Nginx做反向代理+触发WOL脚本
Nginx是轻量高效的反向代理工具,配合简单的脚本就能实现“请求到来时先唤醒,再转发”的逻辑:
1. 写一个唤醒脚本
在Box B上创建/usr/local/bin/wake_server_a.sh,内容如下:
#!/bin/bash # 用arping检查Server A是否在线(比ping更可靠,内网下不会被防火墙拦截) arping -c 1 -W 2 192.168.x.x > /dev/null # 替换成Server A的IP if [ $? -ne 0 ]; then # 发送WOL魔术包唤醒 etherwake xx:xx:xx:xx:xx:xx # 等待Server A启动服务,根据你的机器启动速度调整时长,比如10秒 sleep 10 fi
给脚本加执行权限:chmod +x /usr/local/bin/wake_server_a.sh
2. 配置Nginx反向代理
首先确保Nginx安装了ngx_http_lua_module模块——Debian/Ubuntu可以直接装nginx-extras包(自带Lua模块),源码编译的话需要额外加这个模块的编译参数。
然后修改Nginx的配置文件(比如/etc/nginx/sites-available/default),添加以下server块:
server { listen 80; server_name box_B; # 可以是Box B的IP或者内网主机名 # 匹配/site_1,转发到Server A的8080端口 location /site_1 { # 先执行唤醒脚本 rewrite_by_lua_block { os.execute("/usr/local/bin/wake_server_a.sh") } # 转发到目标地址 proxy_pass http://192.168.x.x:8080; # 替换成Server A的IP和端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 匹配/site_2,转发到Server A的9000端口 location /site_2 { rewrite_by_lua_block { os.execute("/usr/local/bin/wake_server_a.sh") } proxy_pass http://192.168.x.x:9000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
配置完后重启Nginx:systemctl restart nginx
第三步:测试验证
现在你在浏览器或者其他客户端访问http://box_B/site_1,Box B会先检查Server A是否在线,如果不在线就发送WOL包唤醒,等服务启动后再把请求转发到Server A的8080端口;访问http://box_B/site_2同理转发到9000端口。
替代方案:如果不用Nginx
如果你更熟悉Apache,也可以用Apache的mod_proxy模块配合自定义CGI脚本实现类似逻辑,但Nginx的性能和配置简洁度更适合这种场景。
优化小技巧
- 可以把脚本里的sleep时长调整得更灵活,比如用循环检测Server A的目标端口是否开放,直到开放再转发,避免固定sleep的误差
- 可以给脚本加日志,方便排查问题,比如在脚本里加
echo "$(date) - 尝试唤醒Server A" >> /var/log/wol_server_a.log
备注:内容来源于stack exchange,提问作者vzografos

