Zwinąć nazwy lokalnych hostów w systemie Mac OS X Yosemite

30

Właśnie zaktualizowałem system z Mavericks do Yosemite i teraz curlnie widzę nazw hostów z pętlą zwrotną.

Skonfiguruj prosty serwer HTTP do testowania:

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

Teraz mogę trafić localhost: 8000 w chrome. Mogę nawet o tym zapomnieć. Ale w curl dzieje się tak:

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

Działa to jednak:

$ curl 127.0.0.1:8000

Przeczytałem tę odpowiedź o ustawieniach proxy wget , ale to nie pomogło, ponieważ to działa:

$ wget --proxy=off localhost:8000

To jest naprawdę frustrujące, ponieważ mam kilka różnych nazw hostów z pętlą zwrotną wymienionych w moim /etc/hostspliku, dzięki czemu mogę tworzyć aplikacje lokalnie i jestem przyzwyczajony do debugowania ich za pomocą curl.

Próbowałem z wersją curl, która jest dostarczana z osx:

$ 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

Próbowałem kompilować curl za pomocą naparu:

$ /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
Nick Retallack
źródło
Wystąpił podobny problem podczas testowania aplikacji node.js. Widziałem, że debugowanie tego węzła mówiło, że wiąże się z 0.0.0.0, i spróbowałem „curl -4 localhost ...” i zadziałało, ale bez -4 nie powiodło się. Wygląda na to, że adres IPv6 jest usuwany z / etc / hosts przed adresem IPv4.
Neth
Mam ten sam problem, który opisałeś Nick.
nerdburn

Odpowiedzi:

36

Właśnie uruchomiłem to, komentując jedną z linii sprzężenia zwrotnego IPv6 z mojego pliku / etc / hosts:

#fe80::1%lo0    localhost

Teraz działają wszystkie moje nazwy hostów z pętlą zwrotną, nie tylko localhost. Zastanawiam się, o co chodzi?

Nick Retallack
źródło
Miałem to i to też mi pomogło. Nie wiem, o co chodzi z tą linią; wygląda na to, że mój system miał go przed Yosemite.
mislav
Dziękuję bardzo. Zastanawiam się jednak, dlaczego w istocie faworyzuje IPv6 dla urządzenia z pętlą zwrotną nad IPv4. To zaczęło się dla mnie dopiero na Yosemite.
lukecampbell
24

Alternatywa (nie wymaga sudo ani modyfikacji /etc/hosts) - zawsze używaj ipv4, aż curl stanie się bardziej inteligentny.

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

(wtedy wszystko będzie działać zgodnie z oczekiwaniami)

Charles Hebdough
źródło
Dzięki - ten problem doprowadzał mnie do szału, ale twoje rozwiązanie działało idealnie.
Kyle Fox,
2

Przede wszystkim 0.0.0.0jest to specjalny adres oznaczający „dowolny adres IPv4”.

Gniazdo można powiązać z protokołem IPv4 lub IPv6. Jeśli gniazdo jest powiązane 0.0.0.0, oznacza to, że będzie nasłuchiwało dowolnego IPv4 próbującego się z nim połączyć i będzie reprezentowane w następujący sposób:

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

*Znak odpowiada 0.0.0.0na IPv4.

W przypadku IPv6:

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

*Znak odpowiada ::na IPv6, jak w oficjalnej specyfikacji .

Powodem jest to, że curlpróbuje rozwiązać losowy localhostwpis w /etc/hosts, a jak wspomniano @NickRetallack, ten wpis jest wybierany przez, curlgdy jest rozstrzygany localhostw trybie domyślnym (przypuszczalnie IPv6 lub IPv4, cokolwiek rozstrzygnie się najpierw).

Zmuszając go w --ipv4trybie, jak sugeruje @CharlesHebdough, uczyni curldeterminację localhostdo 127.0.0.1(zakładając, że nie istnieją żadne inne wpisy dla IPv4 localhostw /etc/hosts).

Każda implementacja zostanie rozwiązana localhostzgodnie z ich życzeniem, dlatego odniosłeś sporadyczny sukces dzięki różnym narzędziom.

Aby być jak najbardziej precyzyjnym, użyj 127.0.0.1zamiast localhost, ale będzie to wiązało cię z IPv4. localhostdaje elastyczność pracy zarówno w protokołach IPv6, jak i IPv4, jednak w niektórych implementacjach możesz mieć problemy, tak jak w tej konkretnej wersji curl.

Jose Alban
źródło