每天进步一点点:curl 与IPv6的问题
好久以前使用he.net的DDNS服务配合路由器的NAT功能实现在任何地方访问家里的网络,用起来还算方便,好多年过去,一直没让我失望。
(图源 :pixabay)
解析失败
不过因为这大半年一直没有出门,所以有半年多时间没有用过这个功能了,昨天无意中测试一下,发现竟然无法连接到家里的网络了,提示是拒绝连接。
要排查的第一个问题就是看一下DDNS解析出来的IP是否正确,命令行ping一下域名的IP,再与在线显示IP工具中显示的IP对比一下,果然不是同一个IP。那么问题来了,是什么原因导致的IP不一致呢?
脚本出错
回头看一下DDNS更新IP的脚本:
*/5 * * * * curl "https://dyn.dns.he.net/nic/update" -d "hostname=xxx.xxxx.com" -d "password=XXXXXX" -k
非常简单的脚本,并且一直很好用,不应该出问题才对。那么我直接执行一下试试看:
curl "https://dyn.dns.he.net/nic/update" -d "hostname=xxx.xxxx.com" -d "password=XXXXXX" -k
结果竟然出现如下错误:
curl: (7) Failed to connect to dyn.dns.he.net port 443: No route to host
排查错误
这看起来貌似是DNS解析的问题,然而我使用wget
访问https://dyn.dns.he.net/nic/update
却可以正常解析。这就让我很晕了,为啥curl
找不到路由,而wget
却可以?
不过看wget的提示信息,我注意到上述域名多了个IPv6地址,那么会不会是IPv6地址导致的呢?毕竟我的机器没有配置IPv6信息:
于是测试了一下加-4
参数来强制使用IPv4地址访问,发现返回信息一切正常。
curl -4 "https://dyn.dns.he.net/nic/update" -d "hostname=xxx.xxxx.com" -d "password=XXXXXX" -k
关于-4
(--ipv4
),手册中解释如下:
If curl is capable of resolving an address to multiple IP versions (which it is if it is IPv6-capable), this option tells curl to resolve names to IPv4 addresses only.
除此之外,我在另外一台OS版本较新的主机上测试(不加-4
),提示信息为:noipv6
,这个返回信息就友好多了。
解决问题
既然知道是IPv6的问题我又不想/也不知道如何配置IPv6,那么就在脚本中加上-4
参数好了,问题就算是解决了。
至于为何之前脚本一直好用,我猜测可能是之前curl
版本低或者是dyn.dns.he.net
这个域名没有配置IPv6的缘故,也懒得去调查到底是谁的原因了。
略为遗憾的是,curl
竟然不能像wget
那样自动选择,导致我遇到这个问题,还浪费我大半天的时间。😡