反向隧道保活的几个反直觉教训:判活命令最容易骗过自己
有台机器只能从内网访问,日常维护靠反向隧道:它主动向一台有公网地址的跳板机建一条隧道,把跳板机的某个端口转发回自己的 SSH 端口,人在跳板机上就能连进来。隧道本身不难搭,难的是让它长期活着——保活循环写不好,隧道死了没人知道,或者循环以为它还活着。
教训一:判活命令会把自己算进去
保活循环最常见的写法,是用进程名去查隧道进程在不在。问题是:检查者自己的命令行里往往也含有那个关键字,查询结果里就会出现检查者自己,循环误判“隧道还在”,永远不重建。
可靠的做法是精确匹配整条命令行,而不是子串匹配。凡是检查命令里会出现被查字面串的场景,都要先想一想“我这次查询会不会命中自己”。
教训二:端口被占着,不等于隧道还活着
有一次隧道长期不可用,查下来是远端端口被一个孤儿会话占着:旧隧道进程死了,但它在跳板机上留下的会话还在持有端口。新隧道因为端口绑定失败起不来,而保活循环只看“有没有隧道进程”,旧的僵尸进程还在,循环就一直以为一切正常。
排查时除了看本地进程,还要到跳板机一侧确认:持有端口的到底是不是当前会话。确认是孤儿残留后清掉它,保活循环下一周期就能重建。
教训三:别给常驻隧道套定时杀手
早期我给隧道进程外层包过一个定时器,本意是“卡住了就杀掉重连”,结果它把已经连通的健康隧道也定时杀掉,隧道从没活过几分钟。正确做法是分两段:先用短超时做一次链路探测,探测通了再起一条没有外层定时的常驻隧道,死连接靠心跳参数自己检测。
小结
反向隧道的坑基本都出在“以为活着”上:判活查到了自己、端口被孤儿占着、定时器杀了健康连接。保活逻辑写完后,先故意制造一次隧道死亡,看它能不能真的在下一周期自己爬起来——能爬起来,这套保活才算数。
(本文为个人运维实践记录。)
- 点赞
- 收藏
- 关注作者
评论(0)