在Mac OS X Yosemite上卷曲本地主机名


30

我刚刚从Mavericks升级到Yosemite,现在curl看不到回送主机名。

设置一个简单的http服务器进行测试:

$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

现在,我可以在Chrome中访问localhost:8000。我什至可以得到它。但是在卷曲中,会发生这种情况:

$ curl localhost:8000
curl: (7) Failed to connect to localhost port 8000: Connection refused

但是,这可行:

$ curl 127.0.0.1:8000

我阅读了有关wget代理设置的答案,但没有帮助,因为它可以正常工作:

$ wget --proxy=off localhost:8000

这确实令人沮丧,因为我的/etc/hosts文件中列出了一些不同的回送主机名,因此我可以在本地开发应用程序,并且习惯于使用curl调试它们。

我试过了osx附带的curl版本:

$ curl --version
curl 7.37.1 (x86_64-apple-darwin14.0) libcurl/7.37.1 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IPv6 Largefile NTLM NTLM_WB SSL libz

$ curl localhost:8000
curl: (7) Failed to connect to localhost port 8000: Connection refused

$ curl 127.0.0.1 # works

我尝试用brew编译curl:

$ /usr/local/Cellar/curl/7.38.0/bin/curl --version
curl 7.38.0 (x86_64-apple-darwin14.0.0) libcurl/7.38.0 SecureTransport zlib/1.2.5
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: IPv6 Largefile NTLM NTLM_WB SSL libz

$ /usr/local/Cellar/curl/7.38.0/bin/curl localhost:8000
curl: (7) Failed to connect to localhost port 8000: Connection refused

$ /usr/local/Cellar/curl/7.38.0/bin/curl 127.0.0.1:8000 # works

我在测试node.js应用程序时遇到了类似的问题。我看到该节点的调试表明它绑定到0.0.0.0,并尝试了“ curl -4 localhost ...”,并且可以正常工作,但是如果没有-4,它将失败。看来IPv6地址是在IPv4地址之前从/ etc / hosts中解析出来的。
内斯2014年

我遇到了与您描述尼克相同的问题。
nerdburn

Answers:


36

我只是通过从我的/ etc / hosts文件中注释掉IPv6回送行之一来使其工作:

#fe80::1%lo0    localhost

现在,我所有的回送主机名都可以使用,而不仅仅是本地主机。我不知道这是怎么回事?


我有它,它也对我有帮助。我不知道那条线是怎么回事。看来我的系统早于优胜美地就拥有它。
mislav

非常感谢。我不知道为什么,为什么从根本上讲,它比IPv4更偏爱于环回设备的IPv6。这才开始在优胜美地发生。
lukecampbell 2015年

24

替代方法(不需要sudo或Modifying /etc/hosts -始终使用ipv4直到curl变得更聪明。

$ echo '--ipv4' >> ~/.curlrc

(然后一切都会按需运行)


谢谢-这个问题使我发疯,但是您的解决方案效果很好。
凯尔·福克斯

2

首先,0.0.0.0是一个特殊的地址,表示“任何IPv4地址”。

套接字可以绑定到IPv4或IPv6协议。如果套接字绑定到0.0.0.0,则意味着它将侦听任何尝试与其连接的IPv4,并将其表示为:

$ nc -l 0.0.0.0 8085
$ lsof -i4 -Pnl | grep 8085
  nc        23994 [xxx]    3u  IPv4 [xxx]      0t0  TCP *:8085 (LISTEN)

*标志等效0.0.0.0于IPv4上的标志。

对于IPv6:

$ nc -l :: 8085
$ lsof -i6 -Pnl | grep 8085
  nc        24145 [xxx]    3u  IPv6 [xxx]      0t0  TCP *:8085 (LISTEN)

正式规范中所示,该*标志与::IPv6 等效。

原因是curl尝试解析为中的随机localhost条目/etc/hosts,正如@NickRetallack提到的那样,该条目是在其默认模式下curl解析时选择的条目localhost(假定是IPv6或IPv4,无论先解析什么)。

迫使它在--ipv4模式,如@CharlesHebdough建议,将curl决心localhost127.0.0.1(假定没有其他的IPv4条目localhost/etc/hosts)。

每个实现都会localhost按他们希望的方式解决,因此为什么您使用不同的工具会取得间歇性的成功。

为了尽可能精确,请使用127.0.0.1而不是localhost,但这会将您绑定到IPv4。localhost使您可以灵活地同时使用IPv6和IPv4协议,但是在某些实现中,您可能会遇到麻烦,例如该版本的curl

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.