SSH reverso para um dispositivo: listener loopback ou VPN roteada?
Uma única porta de gestão para um dispositivo que só consegue marcar para fora. Três condições decidem se um túnel reverso basta ou se precisa de um caminho roteado a sério.
O seu dispositivo está atrás do NAT de uma operadora, consegue abrir ligações de saída e corre um servidor SSH que ninguém alcança. O pedido que chega costuma ser formulado como "dê-lhe uma VPN", que é uma resposta entre várias. Antes de o aceitar, decida se precisa de uma única porta TCP administrativa ou de um caminho roteado para uma sub-rede inteira, porque são projetos diferentes com exposição diferente.
Um túnel reverso responde bem à versão estreita. O dispositivo liga ao seu hub, pede ao hub para escutar numa porta loopback e reencaminha essa porta para o seu próprio serviço SSH. Depois, os administradores chegam ao listener através do hub, não através da internet pública.
Três condições que decidem a escolha
Anote-as antes de qualquer configuração. São a fronteira entre uma entrada de gestão limitada e uma extensão de rede, e misturá-las é como um túnel de cinco linhas se torna uma rede plana sem dono.
| Condition | Reverse tunnel fits | Something else is needed |
|---|---|---|
| How many services must be reachable? | One, or a small fixed set on loopback | Anything that needs many ports or dynamic discovery |
| Who connects, and how are they authenticated? | Named administrators with their own hub accounts | Third parties, or anything needing per-flow audit you do not control |
| Does the device's own LAN need to be reachable? | No | Yes, so a routed VPN or a managed platform is the honest answer |
A terceira linha é a que as pessoas discutem. Um túnel para a porta SSH de um dispositivo não põe os seus vizinhos na sua rede, e não deve parecer que o faz através de uma cadeia de reencaminhamentos adicionais. Se o requisito é mesmo a LAN, diga-o e conceba essa em vez disso.
Lado do hub: uma conta de repetidor limitada
Dê a cada dispositivo a sua própria conta de repetidor com autenticação por chave pública e sem sessão interativa. Match bloco limitado a essa conta mantém a permissão pequena, e a chave privada fica no dispositivo onde pertence.
Match User relay-dev-7
AuthenticationMethods publickey
PubkeyAuthentication yes
AllowTcpForwarding remote
PermitListen 127.0.0.1:21022
GatewayPorts no
MaxSessions 0
PermitTTY no
X11Forwarding no
AllowAgentForwarding no
MaxSessions 0 é a linha interessante. Nega sessões de shell e de subsistemas enquanto continua a permitir o reencaminhamento de que o dispositivo precisa, por isso uma chave roubada não pode ser transformada num início de sessão interativo. PermitListen fixa o endereço e a porta do listener do lado do hub, e GatewayPorts no mantém-no em loopback em vez de o abrir à rede onde o hub está.
Teste a configuração efetiva antes de recarregar, e mantenha uma segunda sessão aberta enquanto o faz. Match bloco que se aplica acidentalmente a todos, ou um erro de escrita no nome de uma opção, é a forma clássica de se trancar fora da máquina que está a endurecer. Despeje a configuração em execução e releia as opções em vez de confiar no ficheiro que acabou de escrever. Note que o suporte de opções difere entre compilações, pelo que uma linha aceite num servidor mais recente pode ser simplesmente ignorada por um mais antigo.
Lado do dispositivo: reencaminhamento que falha ruidosamente
O dispositivo abre a ligação e pede o listener. Os dois endereços no argumento -R significam coisas diferentes, e lê-los da esquerda para a direita é a forma mais rápida de memorizar qual é qual.
ssh -NT \
-o ExitOnForwardFailure=yes \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-R 127.0.0.1:21022:127.0.0.1:22 \
[email protected]
O par esquerdo é onde o hub deve escutar. O par direito é aquilo a que o dispositivo se liga quando chega um pedido, resolvido do próprio lado do dispositivo. Trocá-los produz um túnel que sobe limpo e reencaminha para o local errado, o que é pior do que uma falha.
ExitOnForwardFailure=yes faz o comando sair quando o listener pedido não pode ser estabelecido, por isso um ciclo de reinício diz-lhe a verdade em vez de deixar uma sessão a meio funcionar. Não diz nada sobre se o serviço SSH local está saudável mais tarde, por isso combine-o com um gestor de processos e um teste de ligação real ocasional.
Nunca substitua o endereço de escuta loopback por um curinga para evitar um salto extra. Essa única alteração é a diferença entre um caminho de gestão e uma porta acessível publicamente, e normalmente acontece durante a depuração e depois fica. Se um colega não chega à porta através do hub, corrija a configuração do salto em vez de alargar o bind. O loopback é todo o argumento de segurança deste desenho.
Acesso de administrador através do hub
Um administrador com uma conta normal no hub pode saltar através dele até à porta reencaminhada. A conta de repetidor não é usada para isto, e é justamente esse o ponto de as manter separadas.
ssh -J [email protected] -o HostKeyAlias=device-7 \
-p 21022 [email protected]
Verifique a chave de anfitrião do dispositivo sob o alias que escolheu, porque essa chave identifica o dispositivo no fim da cadeia e o túnel é apenas transporte. O início de sessão de ponta a ponta continua a autenticar ambas as pontas; um túnel que termina num hub partilhado não o torna por si só um caminho de confiança.
Assuma o ciclo de vida
Execute o comando do dispositivo sob um gestor de processos com exatamente uma instância ativa e uma política de reinício que tenha escolhido deliberadamente. As opções de keepalive detetam um par morto; não ressuscitam um processo que saiu.
Depois escreva o procedimento de desativação. Cada dispositivo tem o seu próprio listener e a sua própria chave, por isso desativar significa revogar essa conta e remover essa chave, não rodar um segredo partilhado por toda a frota.
Por fim, lembre-se do que o loopback lhe dá. Limita a exposição de rede e não faz nada quanto a outros utilizadores locais num hub partilhado, por isso a política de acesso do próprio hub tem de continuar correta. Referência de sshd_config documenta cada uma das opções usadas acima, e vale a pena ler as secções de reencaminhamento por completo antes de alargar qualquer uma delas.