Como limitar as portas de tunelamento SSH reverso?

9

Temos um servidor público que aceita conexões SSH de vários clientes atrás de firewalls.

Cada um desses clientes cria um túnel SSH reverso usando o ssh -Rcomando de seus servidores da web na porta 80 para o servidor público.

A porta de destino (no lado do cliente) do túnel SSH reverso é 80 e a porta de origem (no lado do servidor público) depende do usuário. Estamos planejando manter um mapa de endereços de portas para cada usuário.

Por exemplo, o cliente A encapsularia seu servidor da web na porta 80 para a porta 8000; cliente B de 80 a 8001; cliente C de 80 a 8002.

Client A: ssh -R 8000:internal.webserver:80 clienta@publicserver

Client B: ssh -R 8001:internal.webserver:80 clientb@publicserver

Client C: ssh -R 8002:internal.webserver:80 clientc@publicserver

Basicamente, o que estamos tentando fazer é vincular cada usuário a uma porta e não permitir que eles façam túnel para outras portas.

Se estivéssemos usando o recurso de encapsulamento direto do SSH ssh -L, poderíamos permitir que porta fosse encapsulada usando a permitopen=host:portconfiguração. No entanto, não há equivalente para o túnel SSH reverso.

Existe uma maneira de restringir as portas de encapsulamento reverso por usuário?

Utku Zihnioglu
fonte
1
Somente por políticas em todo o sistema, como SELinux ou IPTABLES.
Andrew Smith

Respostas:

6

Como você não permitiu negrito, suponho que você queira algum tipo de rejeição em tempo de execução no lado do cliente SSH que impeça a ligação da porta. Então, eu tive uma escavação do código fonte para você:

serverloop.c:

/* check permissions */
if (!options.allow_tcp_forwarding ||
    no_port_forwarding_flag ||
    (!want_reply && listen_port == 0)
#ifndef NO_IPPORT_RESERVED_CONCEPT
    || (listen_port != 0 && listen_port < IPPORT_RESERVED &&
    pw->pw_uid != 0)
#endif
    ) {
        success = 0;
        packet_send_debug("Server has disabled port forwarding.");
} else {
        /* Start listening on the port */
        success = channel_setup_remote_fwd_listener(
            listen_address, listen_port,
            &allocated_listen_port, options.gateway_ports);
}

Infelizmente, como você pode ver, não existem muitas condições que impedem o encaminhamento de portas além das padrão.

Eu estava prestes a recomendar a mesma sugestão para uso mod_ownerinterno iptables, mas Jeff me superou.

Sua solução mais limpa seria apenas modificar esse arquivo (por exemplo, você pode usar pw->pw_uidpara conectar o usuário e mapeá-lo para a porta correta) e recompilar seu servidor SSH, mas isso dependeria de como você se sinta confortável com isso. .

Jay
fonte
Isto é muito bom. Na verdade, eu posso copiar a mesma sintaxe da opção -L (tunelamento) e fazê-la funcionar. Obrigado.
Utku Zihnioglu
3

Minha sugestão é usar o SELinux para isso. Você precisará configurar perfis de usuário que permitam que portas sejam abertas. O sshdprocesso bifurca e cai para os privilégios do usuário antes de abrir uma porta para encaminhar, para que qualquer coisa aplicada aos processos do usuário seja aplicada sshd. Lembre-se de que você precisará restringir a todos os processos do usuário, pois uma vez pode ser usado netcatpara encaminhar outra porta. Tentarei resolver a sintaxe adequada para você mais tarde (ou qualquer outro usuário poderá editá-la para mim).

Como alternativa, você pode tentar usar iptables.

iptables -m owner --add-owner $user -p tcp --sport 8000 -j ACCEPT
iptables -m owner --add-owner $user -p tcp --tcp-flags SYN,ACK SYN,ACK -j REJECT

Isso não os impedirá de abrir a porta e negar outro usuário, no entanto.

Jeff Ferland
fonte
Obrigado pela ótima resposta. Vou tentar a configuração de perfis SELinux / User. Parece a solução para minha pergunta.
Utku Zihnioglu