Enrollar nombres de host locales en Mac OS X Yosemite

30

Acabo de actualizar de Mavericks a Yosemite, y ahora curlno puedo ver los nombres de host de bucle invertido.

Configure un servidor http simple para probar:

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

Ahora puedo golpear localhost: 8000 en cromo. Incluso puedo olvidarlo. Pero en curl, esto sucede:

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

Sin embargo, esto funciona:

$ curl 127.0.0.1:8000

Leí esta respuesta sobre la configuración del proxy wget , pero no ayudó, porque esto funciona:

$ wget --proxy=off localhost:8000

Esto es realmente frustrante, porque tengo algunos nombres de host de bucle invertido diferentes enumerados en mi /etc/hostsarchivo para poder desarrollar aplicaciones localmente, y estoy acostumbrado a depurarlos con curl.

He intentado con la versión de curl que se incluye con 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

Y he intentado compilar curl con brew:

$ /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
fuente
Me encontré con un problema similar al probar una aplicación node.js. Vi que la depuración del nodo decía que era vinculante para 0.0.0.0, e intenté 'curl -4 localhost ...' y funcionó, pero sin el -4 falló. Parece que la dirección IPv6 se está resolviendo fuera de / etc / hosts antes que la IPv4.
Neth
Tengo el mismo problema que describiste a Nick.
nerdburn

Respuestas:

36

Acabo de hacerlo funcionar comentando una de las líneas de bucle invertido IPv6 de mi archivo / etc / hosts:

#fe80::1%lo0    localhost

Ahora todos mis nombres de host de bucle invertido funcionan, no solo localhost. Me pregunto qué pasa con esto.

Nick Retallack
fuente
Tenía eso y me ayudó también. No sé cuál es el problema con esa línea; Parece que mi sistema lo tenía antes de Yosemite.
mislav el
Muchas gracias. Sin embargo, me pregunto por qué en el núcleo favorece el IPv6 para el dispositivo de bucle invertido sobre el IPv4. Esto solo comenzó a sucederme en Yosemite.
lukecampbell
24

Alternativa (no requiere sudo o modificación /etc/hosts) : use siempre ipv4 hasta que curl se vuelva más inteligente.

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

(entonces todo funcionará como se desee)

Charles Hebdough
fuente
Gracias, este problema me estaba volviendo loco, pero su solución funcionó perfectamente.
Kyle Fox
2

En primer lugar, 0.0.0.0es una dirección especial que significa "cualquier dirección IPv4".

Un socket puede estar vinculado al protocolo IPv4 o IPv6. Si un socket está vinculado 0.0.0.0, eso significa que escuchará cualquier IPv4 que intente conectarse a él, y se representará de la siguiente manera:

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

El *signo es equivalente a 0.0.0.0en IPv4.

Para IPv6:

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

El *signo es equivalente a ::en IPv6, como en la especificación oficial .

La razón es que curlintenta resolver una localhostentrada aleatoria /etc/hosts, y como @NickRetallack mencionó, esa entrada es la elegida curlcuando se resuelve localhosten su modo predeterminado (supuestamente IPv6 o IPv4, lo que se resuelva primero).

Forzándolo en --ipv4el modo, como se sugiere @CharlesHebdough, hará que curlla determinación localhostde 127.0.0.1(asumiendo que no hay otras entradas IPv4 para localhosten /etc/hosts).

Cada implementación se resolverá localhostcomo lo deseen, de ahí que haya tenido éxito intermitente con diferentes herramientas.

Para ser lo más preciso posible, use en 127.0.0.1lugar de localhost, pero lo vinculará a IPv4. localhostle brinda la flexibilidad de trabajar en los protocolos IPv6 e IPv4, sin embargo, en algunas implementaciones puede tener problemas, como en esa versión específica de curl.

Jose Alban
fuente