¿Cómo puedo configurar un reenvío de puerto remoto en el puerto 80 a mi host local con la ayuda de setcap?

¿Cómo puedo configurar un reenvío de puerto remoto en el puerto 80 a mi host local con la ayuda de setcap?

Me gustaría aceptar conexiones brevemente para el desarrollo cuando tenga NAT, por lo que intento hacer esto:

$ ssh [email protected] -R 80:localhost:80

Lo cual falla porque intento vincular un puerto que está demasiado bajo:

Warning: remote port forwarding failed for listen port 80

Entonces descubrí que puedo hacer setcap 'cap_net_bind_service=+ep' /my/applicationpara permitirle escuchar puertos inferiores a 1024. Entonces tengo esto en mi crontab de suders:

@reboot setcap 'cap_net_bind_service=+ep' /usr/sbin/sshd

Pero todavía no me permite vincularme al puerto 80. ¿Qué estoy haciendo mal? Solo voy a usar nginx para hacer proxy a 8080 o iptables o algo así, pero todavía tengo curiosidad por saber por qué lo que estaba tratando de hacer no funcionó.

Respuesta1

Como se explica en @dwurfrespuesta aceptada, sshsolo se vinculará a puertos inferiores a 1024 para el rootusuario.

Este es un gran caso de uso socatsi no es así root.

Primero, realice un reenvío remoto al puerto 8080(o cualquier otro puerto permitido) de la máquina remota:

ssh [email protected] -R 8080:localhost:80

Luego, en la máquina remota, asigne un puerto 80a otro 8080:

sudo socat TCP-LISTEN:80,fork TCP:localhost:8080

Notas:

Como sugiere Dirk Hoffman, estos dos comandos se pueden combinar en una sola línea:

ssh -t [email protected] -R 8080:localhost:80 sudo socat TCP-LISTEN:80,fork TCP:localhost:8080

( -tEs necesario en caso de que necesite una terminal interactiva para ingresar su sudocontraseña).

Respuesta2

OpenSSH se negará rotundamente a vincularse a puertos privilegiados a menos que la identificación del usuario que inició sesión sea 0 (raíz). Las líneas de código relevantes son:

if (!options.allow_tcp_forwarding ||
    no_port_forwarding_flag ||
    (!want_reply && listen_port == 0) ||
    (listen_port != 0 && listen_port < IPPORT_RESERVED &&
    pw->pw_uid != 0)) {
        success = 0;
        packet_send_debug("Server has disabled port forwarding.");

Fuente:http://www.openssh.com/cgi-bin/cvsweb/src/usr.bin/ssh/serverloop.c?annotate=1.162líneas 1092-1098

Si tienes curiosidad, pwes de tipo struct passwd *y en Linux está definido en/usr/include/pwd.h

Respuesta3

Me encontré con un problema similar, por lo que la solución que terminé fue agregar DNATuna regla a la OUTPUTcadena de la nattabla:

iptables -t nat -A OUTPUT -d 127.0.0.0/8 -p tcp --dport 80 \
-j DNAT --to-destination :8080

Esta regla reemplaza efectivamente el puerto de destino 80 con 8080 para todos los paquetes tcp generados localmente.

Si desea permitir que también se reenvíen las conexiones entrantes, agregue una regla adicional a la PREROUTING natcadena:

iptables -t nat -A PREROUTING -d 10.0.0.200 -p tcp --dport 80 \
-j REDIRECT --to-port 8080

¿Dónde 10.0.0.200está la dirección IP de la interfaz que debería reenviar las conexiones entrantes a su servicio web?

Respuesta4

Desarrollando la propuesta de solución deBen Maresarriba,

a continuación se muestra una sola línea que:

abre dos puertos remotos hacia adelante:
1. puerto remoto 8888 al puerto local 80
2. puerto remoto 8443 al puerto local 443

en la máquina remota, socat conecta cualquier cosa
1. llega al puerto 80 para transmitirse al puerto 8888
   , que luego se canaliza al puerto 80 del host local
2. llega al puerto 443 para transmitirse al puerto 8443,
   que luego se canaliza al puerto 443 del host local

ssh -t -i ~/.ssh/id_rsa \
    -R 0.0.0.0:8888:0.0.0.0:80 \
    -R 0.0.0.0:8443:0.0.0.0:443 \
    remoteUser@remoteMachine \
    -- "(sudo socat TCP-LISTEN:80,fork TCP:localhost:8888) & \
        sudo socat TCP-LISTEN:443,fork TCP:localhost:8443"

entonces, si ejecuta el comando, debe proporcionar su contraseña de root de la máquina remota (para poder listar en los puertos 80/443) y luego (siempre que el túnel esté establecido) cualquier cosa que llegue al puerto 80 o 443. del host remoto, se conectará a los puertos 80 o 443 de su máquina local respectivamente...

¡¡recordar!!

para poder vincularse en todas las interfaces de red (0.0.0.0), debe editar sus máquinas remotas /etc/ssh/sshd_configy configurar GatewayPorts clientspecifiedoGatewayPorts yes

Puedes verificar esto en la máquina remota con netstat -tlpn | grep -E '8888|8443'lo que debería mostrar:

tcp        0      0 0.0.0.0:8888            0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN      -

y no

tcp        0      0 127.0.0.1:8888          0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:8443          0.0.0.0:*               LISTEN      -

información relacionada