OpenVPN AF_INET 警告:无害的回退,还是创建套接字失败?
把 AF_INET 回退与之后的套接字创建失败区分开:先读准那一行,再检查监听器和下一条错误。
两条 OpenVPN 日志以相同的词开头,但只有一条报告了问题。Could not determine IPv4/IPv6 protocol. Using AF_INET 是回退提示:配置文件没有指定地址族,于是守护进程自行选择了一个并继续运行。失败分支则报告没有创建套接字,并要求重启。共同前缀之后的内容才是区别所在,所以在动手修改前,请先读完后面的话。
回退提示说明了什么
OpenVPN 通过 proto udp4 或 proto udp6 接受明确的地址族;当地址族需要在启动时推导时,则接受 proto udp。在后一种情况下,守护进程会查看本地绑定信息并做出选择。
这种推导成功时,警告会说明它选定了哪个方向,进程继续创建套接字。在双栈主机上使用 proto udp 的服务器,常常就这样落到 IPv4。这条路径上没有任何错误,也不暗示攻击、缺少 Web 服务器或被拒绝的账户。这一行之所以有用,只是因为后续检查应当拿它所说的地址族来对照。
把它当作对一个问题的回答,而不是诊断。它只告诉你这个进程选了哪个地址族,完全没有说明客户端为什么连不上。
失败分支是什么样子
在同一段套接字代码的后面,还有一个根本不存在套接字的分支。它会记录较短的地址族消息并请求重启,因为已经没有可继续的东西了。开头几个词与回退提示相同,结果却不同。
靠后面跟着什么来区分。如果守护进程继续运行并报告监听器,那行就是信息。如果它退出或在循环中重启,讨论的就是绑定。
用 grep 搜到也不算识别分支。这句话会出现在轮转的摘要、折行的日志,以及人们二手转贴的摘录里,所以要读相邻的行和时间戳顺序,而不是只看看那一条匹配。
检查监听器,而不是警告
正在运行的服务器会直接回答地址族的问题,不需要从日志文本去推断。
ss -lunp | grep openvpn
ss -ltnp | grep openvpn把地址族、地址和端口与配置文件对照。0.0.0.0:1194 那一行只是 IPv4;而在双栈主机上,[::]:1194 那一行可能根据 bindv6only 设置同时接受两个地址族。如果配置文件写的是 udp,而套接字是 IPv4,那么解析器只返回 AAAA 记录的客户端就会 在隧道还没开始协商之前就失败。
然后从接近真实用户的客户端测试:同样的解析路径、同样的网络类型。从服务器本机连一下,几乎证明不了穿 NAT 设备或按另一个地址族写的防火墙规则的流量。
什么时候强制地址族是对的
固定 proto udp4 适合纯 IPv4 部署:只有 A 记录的 DNS 名、针对一个 v4 地址的防火墙规则、位于只分配 v4 地址的运营商之后的客户端。它消除了歧义,也让下一批日志行变得可预测。
同样的论证在 IPv6 优先的环境里正好反过来;在只有 A 记录的客户端群前面用 udp6,等于自己制造中断。只为让一条无害警告闭嘴就强制地址族,是这类错误的经典版本,因为你用更安静的日志换掉了谁能连接。
根据端点和必须访问它们的客户端来选择。OpenVPN 2.6 手册记录了各种传输形式,而那条消息是这个选择的输出,不是输入。
把记录写窄
记下那一行原文和时间戳、运行中配置的实际传输设置、内核报告的套接字,以及失败的下一个阶段。这四项几乎能回答这条消息引出的所有问题,而且没有一项需要去猜无关服务。它们也能经得起交接,而 grep 截图做不到。
伴随这条警告出现的软件包建议,在某个错误点名缺失的可执行文件之前,都与此无关。
如果 ifconfig 确实不存在,脚本调用时守护进程会直接点出它的名字,这值得单独调查。AF_INET 那一行和缺少某个工具是两种不同的失败,为了看警告会不会变而去安装东西,正是让干净主机变乱的路子。