2 votos

¿Por qué puedo abrir una conexión en el puerto 80 para 0.0.0.0 pero no otras formas?

Mi comprensión de los permisos de puerto de Linux/MacOS (creo que son iguales en este sentido) es que los puertos del 1 al 1024 solo están disponibles para root, pero por encima de eso, están disponibles para cualquiera.

Sin embargo, me he encontrado con un comportamiento inesperado al abrir puertos en MacOS 10.14.2. Estoy usando php -S (versión 7.3.0) para experimentar.

Cuando ejecuto el comando con los siguientes casos:

127.0.0.1:80
[::1]:80
miipv4local:80
miipv6local:80

devuelve Error al escuchar en ::1:80 (motivo: Permiso denegado) como se esperaba (donde se muestra la IP/puerto proporcionados).

Sin embargo, si lo ejecuto con 0.0.0.0:80, inicia la escucha correctamente, pero no puedo conectar con él con curl, ya sea usando 127.0.0.1 o la IP real de mi máquina.

Si ejecuto el servidor PHP con [::0]:80 inicia la escucha correctamente, y puedo curlarlo con curl [::1] y con mi dirección ipv6 local.

Esperaría que los últimos dos casos fallaran al inicio con permiso denegado. ¿Por qué no lo hacen?

0 votos

Si macOS y Linux son (supuestamente) lo mismo en ese sentido, es solo porque son sistemas operativos Unix. macOS en realidad está basado (originalmente) en una versión de BSD con un microkernel, por lo que asumir que macOS y Linux son lo mismo en cualquier aspecto podría no ser preciso. Verificaría eso en línea.

4voto

Jose Chavez Puntos 645

Desde las pruebas que he realizado, puedo ver que es posible para los usuarios de macOS de escritorio realizar bind() en números de puerto TCP por debajo de 1024 (los llamados puertos conocidos). Funciona tanto en IPv4 como en IPv6, y en las direcciones localhost/no especificadas.

El código fuente del núcleo de Darwin está disponible libremente: desde allí puedo ver que tiene la funcionalidad incorporada para verificar los procesos que intentan hacer bind/listen en puertos <1024 y denegarlo. Esto es similar a cómo funciona Linux. Sin embargo, es posible deshabilitar esta verificación al compilar el núcleo definiendo "IPNOPRIVPORTS". Supongo que esto es lo que se hizo con el kernel suministrado en Mojave.

En Linux solía ser el caso de que no era posible para usuarios no root hacer bind en números de puerto bajos, pero hoy en día tienes varias opciones que permiten a usuarios no root hacer bind en puertos numerados bajos. Como por ejemplo usando la capacidad NET_BIND_SERVICE.

En macOS también tienes varias opciones para restringir la unión de puertos de números bajos. Por ejemplo, a través de módulos de kernel que filtran sockets, u a través de otros medios. Quizás tienes software instalado, como por ejemplo Little Snitch, que te negó el permiso cuando estabas haciendo las pruebas.

Ten en cuenta que las diversas direcciones IP que has probado tienen significados completamente diferentes:

 127.0.0.1 = Dirección IPv4 que significa el "localhost" (es decir, tu propio ordenador básicamente) - no está disponible en la red
 [::1]     = el equivalente en IPv6 de 127.0.0.1

 0.0.0.0   = "dirección no especificada" en IPv4 - es decir, no es una dirección en sí misma, más bien es un valor especial que le das a bind() para informarle que no has especificado una dirección específica en la que quieres que el puerto se enlace. Básicamente esto significa que el puerto se enlazará en todas las direcciones IP que tienes.
 [::0]     = equivalente IPv6 de 0.0.0.0 (aunque generalmente escrito [::/128])

Esto puede explicar por qué algunas cosas fallaron y otras tuvieron éxito. Por ejemplo, es posible que no puedas hacer bind en 127.0.0.1, pero 0.0.0.0 funciona ya que intenta hacer bind en el puerto no solo en 127.0.0.1 sino también en otras direcciones IP que tengas.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X