
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/application
para 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, ssh
solo se vinculará a puertos inferiores a 1024 para el root
usuario.
Este es un gran caso de uso socat
si 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 80
a 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
( -t
Es necesario en caso de que necesite una terminal interactiva para ingresar su sudo
contraseñ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, pw
es 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 DNAT
una regla a la OUTPUT
cadena de la nat
tabla:
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
nat
cadena:
iptables -t nat -A PREROUTING -d 10.0.0.200 -p tcp --dport 80 \
-j REDIRECT --to-port 8080
¿Dónde 10.0.0.200
está 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_config
y configurar GatewayPorts clientspecified
oGatewayPorts 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 -