Os serviços de túnel que prometem um dispositivo por assinante raramente obtêm essa promessa do MaxSessions, e o primeiro teste costuma provar isso. O assinante abre um segundo processo ssh, a primeira sessão continua funcionando, e ambos os túneis carregam tráfego. Cada opção de configuração conta algo diferente, e nenhuma delas conta dispositivos. Nomear a promessa primeiro é o que torna óbvia a escolha entre elas.

O que cada opção conta realmente

O MaxSessions limita o número de sessões abertas transportadas por uma conexão de rede autenticada. Uma sessão aqui significa um shell, uma solicitação exec, um subsistema como SFTP ou um canal semelhante multiplexado dentro de um único transporte SSH. Uma segunda invocação de ssh abre um segundo transporte, autentica-se novamente e obtém a sua própria cota. O número de sessões da primeira conexão é irrelevante para ele.

O MaxStartups limita as conexões simultâneas que ainda não foram autenticadas, expressas como limiar inicial, taxa e limiar completo. Existe para que uma rajada de handshakes entreabertos não possa esgotar os recursos do daemon antes da autenticação. Quando um cliente se autentica, essa conexão deixa de contar contra o MaxStartups e passa a ser a sessão de alguém. Nunca foi uma cota por usuário, e aumentá-lo não permite ao assinante fazer mais.

Uma regra de registro de dispositivo não é, de modo algum, uma opção do sshd. Ela pertence a qualquer sistema que emita credenciais e rastreie qual dispositivo as detém, o que significa que precisa de registro, inventário e revogação em vez de um contador. Misturar esse requisito na configuração do sshd é onde a maioria desses projetos trava.

Onde o MaxSessions deixa de ser uma cota

Um bloco Match User altera quais valores de configuração se aplicam àquele usuário, por isso é o lugar natural para definir um MaxSessions mais rigoroso para uma conta de serviço. O que ele não consegue fazer é agregar entre conexões, porque a opção é avaliada por transporte. Dois transportes recebem cada um o seu próprio limite, e o usuário acaba com o dobro do que o bloco permite.

O encaminhamento é uma surpresa à parte. O encaminhamento TCP não precisa de um canal de sessão, então MaxSessions 0 pode proibir shells e subsistemas enquanto ainda permite túneis -L e -R. Um serviço que apenas encaminha e trata o número de sessões como a sua cota de túnel não mede nada. Esse comportamento está documentado na referência de configuração do servidor OpenSSH, e vale a pena lê-la antes de projetar em torno de um nome de opção.

Despeje a configuração efetiva em vez do arquivo que você acha que está carregado. Inclusões e diretórios drop-in muitas vezes significam que o valor em vigor não é o valor que você editou.

O MaxStartups protege o daemon, não o assinante

A forma de três partes do MaxStartups descreve quantas conexões não autenticadas podem existir antes de o daemon começar a descartar uma porcentagem das novas. A sua forma predefinida existe porque uma conexão SSH não autenticada é barata de abrir e cara de manter. É um controlo de proteção de recursos para o servidor, e aplica-se a todos ao mesmo tempo.

Aumentá-lo durante uma tempestade de logins troca proteção do daemon por admissão, o que às vezes é a troca certa e é sempre deliberada. Não faz nada pelo assinante que quer um segundo túnel, porque o primeiro túnel já está autenticado. Confundir os dois leva a uma alteração que corrige o sintoma errado e enfraquece o servidor ao mesmo tempo.

Quando os logins são recusados em rajadas, olhe no log do daemon para a mensagem pré-autenticação antes de tocar em qualquer uma das opções. A mensagem nomeia qual guarda disparou, e as guardas não são intercambiáveis.

Uma vaga por usuário exige estado partilhado

Uma política genuína de um único transporte ativo precisa de uma reserva guardada nalgum lugar fora do sshd. O passo de admissão tem de reivindicar atomicamente a vaga da conta, libertá-la quando a conexão fecha, deixá-la expirar quando um cliente desaparece sem fechar, e decidir se uma nova tentativa é recusada ou substitui a antiga. Essa última decisão é uma decisão de produto, não um detalhe técnico, porque substituir um túnel ativo desliga alguém.

A reserva também tem de ser partilhada por cada servidor que aceita a conta. Dois hosts com contadores locais independentes aplicam dois limites separados, e um assinante que se reconecta pela outra gateway obtém uma segunda vaga de graça. Aquilo que armazena o estado precisa do seu próprio comportamento de falha, já que um armazém inalcançável não deve bloquear todos os assinantes.

Para uma promessa de um dispositivo, emita uma credencial distinta por cada dispositivo registado e controle o registro e a revogação nessa camada. Uma chave privada copiada continua a autenticar-se de qualquer lugar, por isso emitir uma chave por usuário não é prova de quantas máquinas a possuem.

Verifique a política com duas conexões reais

Escreva os testes de aceitação como comandos antes de escrever a política. Os cinco casos são um segundo transporte aberto enquanto o primeiro está ativo, vários canais dentro de um transporte, um cliente que só encaminha portas, uma reconexão após a queda de um link, e a mesma conta a chegar a outra gateway.

Leia primeiro os limites efetivos e depois abra as conexões que a política deve recusar. Ambas as metades desse teste importam, e nenhuma substitui a outra.

sshd -T | grep -iE "maxsessions|maxstartups|allowtcpforwarding|permitopen"
ss -tn state established '( sport = :22 )' | head
ssh -N -L 8080:127.0.0.1:80 [email protected]

Execute o comando do túnel duas vezes em dois terminais e conte as conexões estabelecidas na porta 22. Se ambos carregarem tráfego enquanto a sua política afirma um só transporte ativo, a política é documentação e não aplicação. Corrija essa lacuna na camada de admissão, não baixando o MaxSessions e esperando que o segundo transporte repare nisso.

Artigos relacionados