Túnel SSH reverso: como posso enviar o número da minha porta para o servidor?


12

Eu tenho duas máquinas, cliente e servidor.

O cliente (que está protegido por um firewall corporativo) abre um túnel SSH reverso para o servidor, que possui um endereço IP acessível ao público, usando este comando:

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

No OpenSSH 5.3+, a 0ocorrência logo após os -Rmeios "escolhe uma porta disponível" em vez de pedir explicitamente uma. A razão pela qual estou fazendo isso é porque não quero escolher uma porta que já esteja em uso. Na verdade, existem muitos clientes por aí que precisam configurar túneis semelhantes.

O problema neste momento é que o servidor não sabe qual cliente é qual. Se queremos nos conectar novamente a um desses clientes (via host local), como sabemos qual porta se refere a qual cliente?

Estou ciente de que o ssh relata o número da porta para a linha de comando quando usado da maneira acima. No entanto, eu também gostaria de usar o autossh para manter as sessões vivas. O autossh executa seu processo filho via fork / exec, presumivelmente, para que a saída do comando ssh real seja perdida no éter.

Além disso, não consigo pensar em outra maneira de obter a porta remota do cliente. Assim, eu estou querendo saber se existe uma maneira de determinar esta porta no servidor.

Uma idéia que tenho é de alguma forma usar / etc / sshrc, que é supostamente um script que roda em todas as conexões. No entanto, não sei como obter as informações pertinentes aqui (talvez o PID do processo sshd específico que lida com essa conexão?) Adoraria alguns indicadores.

Obrigado!


2
Uma VPN não seria mais apropriada? O OpenVPN é super simples de configurar.
Ben Lessani - Sonassi

Soa interessante. Eu não sei muito sobre VPN. Isso é algo que poderia funcionar mesmo se a máquina cliente estiver configurada para usar DHCP?
Tom

1
Sim, ele executa outra interface TUN / TAP, portanto outras interfaces são irrelevantes.
Ben Lessani - Sonassi

@sonassi, parece que essa coisa de VPN fará o truque. Obrigado pela informação.
Tom

Eu adicionei uma resposta abaixo especificamente guiá-lo através do processo de VPN com o OpenVPN (baseado em Debian / Ubuntu)
Ben Lessani - Sonassi

Respostas:


4

Uma VPN não seria mais apropriada? O OpenVPN é super simples de configurar. Aqui está um exemplo de configuração e alguns links para guiá-lo através do processo de criação do 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

Em seguida, crie um novo arquivo /etc/openvpn/client_server.confe coloque o seguinte, alterando o SERVER_IP_ADDRESSconforme apropriado

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

Em seguida, crie uma chave por usuário que irá se conectar e crie o arquivo de configuração no diretório 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

O endereço IP DEVE ser adequado para uma sub-rede / 30 (consulte http://www.subnet-calculator.com/cidr.php ), pois há apenas 2 endereços disponíveis (servidor e cliente) por conexão. Portanto, seu próximo IP do cliente disponível seria 192.168.100.6 e assim por diante.

Agora você tem IPs estáticos por usuário conectado.

Em seguida, forneça o the user1@domain.com.p12arquivo ao usuário final e use o seguinte arquivo de configuração

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

Obrigado pela resposta completa! Eu tenho duas perguntas sobre isso, no entanto. A) A especificação de 255.255.255.0 para a linha ifconfig-push do cliente parece não funcionar, mas funciona se eu especificar um segundo endereço IP. Por que é isso? E B) essa abordagem significa que 4 endereços IP são usados ​​por conexão?
Tom

Em alguns sistemas Linux, a sintaxe da linha ifconfig-push é diferente. Por exemplo. ifconfig-push 192.168.100.2 192.168.100.3- Não faço ideia por que difere nas plataformas. E sim, significa que 4 IPs são usados ​​por cliente (desperdício, mas a natureza da besta).
Ben Lessani - Sonassi

3

Se os clientes tiverem nomes de usuário diferentes, você poderá usar netstatpara descobrir em qual porta o sshdprocesso do usuário está escutando. Por exemplo:

% 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

Você pode alterar o intervalo de portas efêmeras ( /proc/sys/net/ipv4/ip_local_port_rangepara Linux) e, em seguida, usar portas alocadas estaticamente fora desse intervalo.


Não há necessidade de alterar o alcance efêmero para isso. Por padrão, o intervalo efêmero termina em 61000, para que haja milhares de números de portas disponíveis acima disso. Eu costumava echo $[61002+RANDOM%4532]escolher um número de porta nesse intervalo.
kasperd

2

Quero a mesma configuração que você, aumentei o nível de log do servidor SSH para DEBUG e ele mostrou nos logs qual era a porta local do cliente

por exemplo:

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

log do servidor:

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

aí você vê o número da porta


0

Você deve conseguir extrair as informações relevantes da saída de:

lsof -i tcp

Execute como root.


0

Execute este script no 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

Você pode ou não precisar dos dois sudo's. Remova se não o fizer.

PS - Esta é uma versão modificada de uma solução que encontrei em outro lugar há algum tempo. Eu acho que pode ter vindo do StackOverflow, mas não consigo encontrar a referência original.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.