Túnel SSH inverso: ¿cómo puedo enviar mi número de puerto al servidor?


12

Tengo dos máquinas, Cliente y Servidor.

El cliente (que está detrás de un firewall corporativo) abre un túnel SSH inverso al Servidor, que tiene una dirección IP de acceso público, usando este comando:

ssh -nNT -R0: localhost: 2222 insecure@server.example.com

En OpenSSH 5.3+, lo que 0ocurre justo después de los -Rmedios "elige un puerto disponible" en lugar de llamarlo explícitamente. La razón por la que hago esto es porque no quiero elegir un puerto que ya esté en uso. En verdad, en realidad hay muchos clientes que necesitan establecer túneles similares.

El problema en este punto es que el servidor no sabe qué Cliente es cuál. Si queremos volver a conectarnos con uno de estos Clientes (a través de localhost), ¿cómo sabemos qué puerto se refiere a qué cliente?

Soy consciente de que ssh informa el número de puerto a la línea de comando cuando se usa de la manera anterior. Sin embargo, también me gustaría usar autossh para mantener vivas las sesiones. autossh ejecuta su proceso hijo a través de fork / exec, presumiblemente, para que la salida del comando ssh real se pierda en el éter.

Además, no se me ocurre otra forma de obtener el puerto remoto del Cliente. Por lo tanto, me pregunto si hay una manera de determinar este puerto en el servidor.

Una idea que tengo es usar de alguna manera / etc / sshrc, que supuestamente es un script que se ejecuta para cada conexión. Sin embargo, no sé cómo se obtendría la información pertinente aquí (¿tal vez el PID del proceso sshd particular que maneja esa conexión?) Me encantaría algunos consejos.

¡Gracias!


2
¿No sería una VPN más apropiada? OpenVPN es muy simple de configurar.
Ben Lessani - Sonassi

Suena interesante. No sé mucho sobre VPN. ¿Es esto algo que podría funcionar incluso si la máquina del Cliente está configurada para usar DHCP?
Tom

1
Sí, se ejecuta en otra interfaz TUN / TAP, por lo que otras interfaces son irrelevantes.
Ben Lessani - Sonassi

@sonassi, parece que esta cosa de VPN hará el truco. Gracias por la info.
Tom

He agregado una respuesta a continuación que lo guía específicamente a través del proceso de VPN con OpenVPN (basado en Debian / Ubuntu)
Ben Lessani - Sonassi

Respuestas:


4

¿No sería una VPN más apropiada? OpenVPN es muy simple de configurar. Aquí hay una configuración de muestra y algunos enlaces para guiarlo a través del proceso de creación del certificado:

apt-get install openvpn
mkdir /etc/openvpn/easy-rsa
mkdir -p /etc/openvpn/ccd/client_server
touch /etc/openvpn/ipp.txt
cp -a /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
source ./vars
./clean-all
./build-ca 
./build-dh
./build-key-server server
cd /etc/openvpn/easy-rsa/keys
openssl pkcs12 -export -out server.p12 -inkey server.key -in server.crt -certfile ca.crt

Luego cree un nuevo archivo /etc/openvpn/client_server.confy coloque lo siguiente en él, cambiando el archivo SERVER_IP_ADDRESSsegún corresponda

local SERVER_IP_ADDRESS
port 8443
proto udp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
pkcs12 /etc/openvpn/easy-rsa/keys/server.p12
dh /etc/openvpn/easy-rsa/keys/dh1024.pem
ifconfig-pool-persist /etc/openvpn/ipp.txt
server 192.168.100.0 255.255.255.0
client-config-dir /etc/openvpn/ccd/client_server
ccd-exclusive
keepalive 10 120
comp-lzo
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3
reneg-sec 0

Luego, cree una clave por usuario que se va a conectar y cree el archivo de configuración en el directorio ccd

./build-key-pkcs12 user1@domain.com
echo "ifconfig-push 192.168.100.2 255.255.255.0" > /etc/openvpn/ccd/client_server/user1@domain.com

La dirección IP DEBE ser adecuada para una subred / 30 (consulte http://www.subnet-calculator.com/cidr.php ), ya que solo hay 2 direcciones disponibles (servidor y cliente) por conexión. Entonces su próxima IP de cliente disponible sería 192.168.100.6 y así sucesivamente.

Entonces ahora tiene IP estáticas por usuario conectado.

Luego suministre el the user1@domain.com.p12archivo al usuario final y use el siguiente archivo de configuración

client
dev tun
proto udp
remote SERVER_IP_ADDRESS 8443
pkcs12 user1@domain.com.p12
resolv-retry infinite
nobind
ns-cert-type server
comp-lzo
verb 3
reneg-sec 0

Gracias por la respuesta completa! Sin embargo, tengo dos preguntas sobre esto. A) Especificar 255.255.255.0 para la línea ifconfig-push del cliente no parece funcionar, pero funciona si especifico una segunda dirección IP. ¿Por qué es esto? Y B) ¿este enfoque significa que se usan 4 direcciones IP por conexión?
Tom

En algunos sistemas Linux, la sintaxis de la línea ifconfig-push es diferente. P.ej. ifconfig-push 192.168.100.2 192.168.100.3- No tengo idea de por qué difiere en las plataformas. Y sí, significa que se usan 4 IP por cliente (desperdicio, pero la naturaleza de la bestia).
Ben Lessani - Sonassi

3

Si los clientes tienen nombres de usuario diferentes, puede usar netstatpara averiguar en qué puerto sshdestá escuchando el proceso de ese usuario . Por ejemplo:

% sudo netstat -tlpn | grep 'sshd: mgorven@'
tcp        0      0 127.0.0.1:22220         0.0.0.0:*               LISTEN      5293/sshd: mgorven@
tcp        0      0 127.0.0.1:5120          0.0.0.0:*               LISTEN      5293/sshd: mgorven@

3

Puede alterar el rango de puertos efímero ( /proc/sys/net/ipv4/ip_local_port_rangepara Linux) y luego usar puertos asignados estáticamente fuera de ese rango.


No es necesario cambiar el rango efímero para eso. Por defecto, el rango efímero termina en 61000, por lo que hay miles de números de puerto disponibles por encima de eso. A menudo solía echo $[61002+RANDOM%4532]elegir un número de puerto en ese rango.
kasperd 01 de

2

Quiero la misma configuración que tú, aumenté el nivel de registro del servidor SSH a DEPURAR, y mostró en los registros cuál era el puerto local del cliente

por ejemplo:

comando del cliente: ssh -N -R0:127.0.0.1:5522 connector@example.com

registro del servidor:

Jun 30 11:28:59 debsid sshd[27577]: debug1: Local forwarding listening on 127.0.0.1 port 35391

ahí ves el número de puerto


0

Debería poder extraer la información relevante de la salida de:

lsof -i tcp

Ejecutar como root.


0

Ejecute este script en el servidor:

sudo lsof -i -n | grep "sshd" | grep "(LISTEN)" | awk '{print $2}' | while read line; do sudo lsof -i -n | egrep $line | sed 3~3d | sed 's/.*->//' | sed 's/:......*(ESTABLISHED)//' | sed 's/.*://' | sed 's/(.*//' | sed 'N;s/\n/:/' 2>&1 ;done

Puede que necesite o no los dos sudo's. Eliminar si no lo hace.

PD: esta es una versión modificada de una solución que encontré en otro lugar hace un tiempo. Creo que puede provenir de StackOverflow, pero no puedo encontrar la referencia original.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.