8 min de leitura

Multiplexing de conexões SSH: riscos dos sockets de controle

O multiplexing de conexões SSH pode manter o acesso autenticado ativo depois que uma tarefa termina. Saiba como isolar sockets de controle, fechar sessões e preservar evidências.

Multiplexing de conexões SSH: riscos dos sockets de controle

O multiplexing de conexões SSH pode deixar aberta uma rota autenticada para um host depois que o comando que a criou termina. Esse comportamento é intencional. Também é fácil interpretá-lo mal quando uma tarefa automatizada, uma execução de agente ou um job de implantação informa que terminou.

Já vi equipes investigarem uma janela de manutenção que supostamente havia sido encerrada e descobrirem que um master local do ssh ainda mantinha um transporte ativo, que um socket ainda aceitava novos clientes e que um comando posterior o reutilizava sem outra autenticação interativa. Nada de extraordinário havia acontecido. A configuração fazia exatamente o que o OpenSSH documenta. A equipe havia tratado o fim de um comando de shell como o fim do acesso.

A distinção importante é entre um comando do cliente concluído e um transporte autenticado encerrado. O multiplexing separa esses dois eventos. Se você executa trabalho autônomo por SSH, a limpeza e as evidências precisam levar essa separação em conta.

Um socket de controle pode durar mais que o comando que o abriu

O multiplexing SSH usa uma conexão SSH de longa duração, chamada master, para transportar o trabalho de processos clientes SSH executados depois. Esses clientes posteriores costumam ser chamados de slaves na documentação do OpenSSH. Quando consegue entrar em contato com o master local pelo socket de controle, um slave não repete a configuração normal da conexão nem a autenticação do usuário.

Uma configuração típica parece inofensiva:

Host build-box
    HostName 192.0.2.44
    User deploy
    ControlMaster auto
    ControlPath ~/.ssh/cm/%C
    ControlPersist 20m

O primeiro ssh build-box cria uma conexão de rede e um socket de domínio Unix em ~/.ssh/cm/. Comandos posteriores, como ssh build-box 'uname -a', scp e sftp, podem usar esse socket. Com ControlPersist 20m, o master continua disponível por vinte minutos depois que sua última sessão é encerrada.

Isso torna normal a seguinte sequência:

  1. Uma tarefa executa ssh build-box 'apply-change' e termina com status zero.
  2. O master continua conectado porque ControlPersist determina que ele permaneça disponível.
  3. Dezenove minutos depois, outro processo local executa ssh build-box 'read-status'.
  4. Esse processo abre um canal pelo transporte já autenticado.

O comando posterior pode ser autorizado pelo sistema operacional local e pelas permissões do socket, mas não faz o host remoto receber uma nova autenticação SSH. Um revisor que examine apenas o registro do login inicial pode concluir facilmente que a atividade terminou muito antes do que realmente terminou.

O OpenSSH descreve ControlMaster no manual de ssh_config como um recurso que permite várias sessões por uma única conexão de rede, e descreve ControlPersist como a opção que mantém o master aberto em segundo plano. Leia as duas descrições em conjunto. ControlPersist não é apenas uma configuração de desempenho. Ele altera o período durante o qual um processo local pode solicitar novos canais em uma conexão autenticada.

Para uma pessoa trabalhando em uma única máquina, essa troca pode fazer sentido. Para automação limitada ao escopo de uma tarefa, ela precisa de um responsável explícito e de uma ação explícita de encerramento.

Um evento de autenticação não é um evento de comando

As equipes costumam misturar autenticação, conexão, canal e comando. No SSH, são coisas diferentes, e o multiplexing deixa essa diferença evidente.

O master inicial cria uma conexão TCP com o servidor, verifica o host, negocia a criptografia e autentica a conta. Depois de autenticado, ele pode abrir canais SSH. Um comando de shell, um shell interativo, uma transferência SFTP, uma solicitação de encaminhamento de porta local e uma solicitação de encaminhamento de porta remoto usam canais ou solicitações relacionadas a canais nesse transporte.

Quando uma nova invocação local de ssh encontra um socket de controle utilizável, ela envia uma solicitação por esse socket. O master decide se deve abrir o canal pedido. Ele não precisa da chave privada novamente. Não precisa de outra solicitação ao agente. O servidor não precisa receber outra tentativa de login.

Isso não significa que o OpenSSH armazene uma senha reutilizável no socket. Essa descrição é imprecisa e leva a análises ruins. O problema de segurança é um transporte já autenticado com uma interface local que pode pedir que ele atue. Um invasor que consiga usar o socket talvez nem precise da credencial original.

Essa distinção muda as perguntas feitas durante um incidente. «A chave continuou no disco?» é uma pergunta importante, mas não determina se o acesso continuou. Pergunte também:

  • Um processo master continuou conectado ao destino remoto?
  • Outro processo local conseguia alcançar o socket de controle?
  • O master aceitou sessões adicionais, transferências de arquivos ou solicitações de encaminhamento?
  • Quem podia executar processos como o proprietário do socket ou atravessar o diretório do socket?
  • Quando o master realmente terminou?

Um executor de tarefas que informa o código de saída de um comando não responde sozinho a nenhuma dessas perguntas. Esse código descreve apenas o processo filho que ele aguardou.

Sockets compartilhados transformam limites entre processos locais em limites de acesso

Um socket de controle é um socket de domínio Unix local. Sua localização no sistema de arquivos e suas permissões determinam quais processos locais podem tentar se comunicar com o master. Por isso, um ControlPath amplo pode unir trabalhos que não deveriam compartilhar nada, mesmo quando os aliases dos hosts remotos parecem organizados.

Considere uma conta de executor de CI com esta configuração:

Host *
    ControlMaster auto
    ControlPath /tmp/ssh-%r@%h:%p
    ControlPersist 1h

O job A conecta-se como deploy a app.internal. Ele cria um master e um socket em /tmp. Depois, o job A termina. O job B, executado pela mesma conta local, conecta-se ao mesmo destino. Ele pode reutilizar o transporte autenticado do job A se conseguir descobrir e acessar esse socket.

Essa configuração é popular porque acelera comandos repetidos com quase nenhuma alteração na aplicação. Ela está errada para jobs independentes porque o limite de reutilização se baseia no host, na porta e no usuário, e não no job que possui a autorização. Uma conta compartilhada no executor transforma esse erro em acesso rotineiro entre tarefas.

O diretório importa tanto quanto o arquivo do socket. Em sistemas Unix, um processo precisa de permissão de busca no diretório para alcançar um caminho. Um socket armazenado em um diretório privado, pertencente ao usuário e com modo 0700, oferece um limite muito mais claro do que um diretório temporário compartilhado. As permissões do próprio socket continuam importantes, mas não devem ser tratadas como o único controle.

Use um diretório criado para a tarefa e pertencente à conta que a executa. Um wrapper de shell pode fazer isso sem depender de uma configuração SSH global:

set -eu
run_id="release-4821"
cm_dir="$HOME/.ssh/task-control/$run_id"
mkdir -p "$cm_dir"
chmod 700 "$cm_dir"

socket="$cm_dir/%C"
ssh -o ControlMaster=auto \
    -o ControlPersist=5m \
    -o ControlPath="$socket" \
    build-box 'id \u0026\u0026 hostname'

O token %C evita um nome literal muito longo e reduz colisões entre conjuntos diferentes de parâmetros de conexão. O manual de ssh_config do OpenSSH o define como um hash sobre os detalhes da conexão. Ele é útil, mas não inclui o ticket da implantação, a sessão do agente nem o ID da tarefa. Neste exemplo, o diretório pai fornece esse limite que faltava.

Não coloque um socket de controle literal em um checkout de repositório, em um workspace com permissão ampla de escrita ou em /tmp apenas porque esses locais são convenientes. É assim que um socket local se transforma em uma capacidade compartilhada por acidente.

ControlPersist é uma política de retenção, não um plano de limpeza

ControlPersist determina que o SSH mantenha um master disponível depois que as sessões clientes forem encerradas. Ele aceita yes, que o mantém executando indefinidamente em segundo plano, ou um período como 10m. As duas opções são escolhas de retenção.

Um timeout ajuda quando um cliente falha antes de executar a limpeza. Ele não prova que a tarefa terminou ao mesmo tempo que o acesso. Durante o timeout, um processo com acesso ao socket pode solicitar trabalho novo. Uma hora é especialmente difícil de justificar quando uma tarefa de implantação durou dois minutos.

Há situações em que um timeout curto é razoável. Um processo de automação controlado pode executar vários comandos em sequência e se beneficiar de uma conexão já aquecida. Nesse caso, torne o timeout menor que o intervalo ocioso esperado, isole o socket nessa execução e encerre o master pelo caminho de sucesso. Assim, o timeout funciona como fallback para falhas, não como mecanismo normal de encerramento.

A configuração ControlPersist yes precisa de um responsável com uma razão duradoura para manter o acesso. Uma estação de trabalho interativa de administrador pode ter essa razão. Uma tarefa descartável não tem.

Outro erro comum é presumir que uma falha de comando fecha o master. Um shell pode retornar cedo depois de um comando remoto falhar enquanto o master em segundo plano continua ativo. Uma tarefa cancelada pode fazer o mesmo. A limpeza precisa ser executada depois de sucesso, falha e interrupção, e deve registrar se o encerramento funcionou.

Se a automação usa um trap, mantenha a limpeza restrita e verifique o alvo. Não remova cegamente primeiro o caminho do socket. Remover o caminho pode dificultar a investigação enquanto o processo master e a conexão continuam existindo.

cleanup() {
    ssh -S "$socket" -O exit build-box e/dev/null 2e261 || true
    rmdir "$cm_dir" 2e/dev/null || true
}
trap cleanup EXIT HUP INT TERM

Esse padrão pede que o master termine antes de tentar remover o diretório. Se ssh -O exit falhar, preserve o diretório e investigue, em vez de apagar as evidências. Em código de produção, registre no histórico da tarefa a falha, o ID do processo e o caminho do socket.

exit e stop têm significados operacionais diferentes

Aprove a execução do agente
Aprove um novo processo de agente uma vez, depois de verificar sua autoridade de assinatura de código.

O OpenSSH disponibiliza comandos de controle por meio de ssh -O. Os operadores costumam usar o comando errado porque os dois nomes parecem indicar limpeza.

ssh -O check host pergunta se há um master executando e informa seu ID de processo quando recebe uma resposta. ssh -O exit host pede que o master termine. Para uma tarefa concluída, exit normalmente é o comando correto, porque encerra o transporte reutilizável.

ssh -O stop host informa ao master que pare de aceitar novas sessões multiplexadas. As sessões existentes continuam. Isso pode ser útil quando um operador precisa drenar o trabalho ativo, mas não atende à afirmação de que todo o acesso SSH terminou quando a tarefa foi concluída. Um master ativo com canais ativos ainda possui uma conexão de rede ativa.

Use explicitamente o caminho do socket quando o diagnóstico não puder depender da configuração atual do usuário:

ssh -S "$socket" -O check build-box
# Master running (pid=41782)

ssh -S "$socket" -O exit build-box
# Exit request sent.

ssh -S "$socket" -O check build-box
# Control socket connect(...): No such file or directory

As palavras e o texto exato dos erros variam conforme a plataforma e a versão do OpenSSH. Por isso, capture a saída padrão e a saída de erro, em vez de interpretar uma única frase como um contrato. O formato das evidências importa: um check bem-sucedido identifica um master ativo, um exit bem-sucedido envia a solicitação de encerramento e um check posterior malsucedido apoia a afirmação de que nenhum socket de controle respondeu.

Há um caso incômodo que merece atenção. O socket pode permanecer depois de uma falha do master, e um PID pode desaparecer entre duas verificações. Um caminho antigo não prova que o acesso ainda existe. Por outro lado, uma verificação sem resposta não prova que a conexão remota terminou se você removeu o caminho antes de examiná-lo. Verifique a tabela de processos e os sockets Unix abertos antes de apagar qualquer coisa.

No macOS, lsof costuma ser a ferramenta local mais rápida para inspeção:

lsof -nP -U | grep '/.ssh/task-control/'
ps -p 41782 -o pid=,ppid=,lstart=,etime=,command=

Capture essa saída no registro da tarefa. O primeiro comando associa um socket Unix a um processo. O segundo fornece processo pai, horário de início, tempo decorrido e detalhes da invocação. Use grep como auxílio interativo, não como controle de auditoria. Um coletor real deve consultar e armazenar diretamente os registros relevantes.

O encaminhamento de portas torna um master ocioso mais importante

Um master que parece ocioso ainda pode transportar um estado de encaminhamento ou aceitar uma solicitação posterior de encaminhamento. Por isso, contar apenas comandos de shell produz uma visão incompleta.

O encaminhamento local expõe um listener local que envia tráfego pela conexão SSH. O encaminhamento remoto pede que o servidor escute e envie as conexões de volta pelo cliente. O encaminhamento dinâmico cria um proxy SOCKS. Cada um deles pode durar mais que o comando que o estabeleceu, dependendo de como a sessão e o master foram invocados.

Os manuais do OpenSSH documentam comandos de controle como forward e cancel para solicitações de encaminhamento quando o multiplexing está ativo. Isso é útil na operação. Também significa que um processo que alcance o socket pode solicitar caminhos de rede além de um comando de shell comum, sujeito à política do servidor e ao estado do master.

Para tarefas automatizadas, trate o encaminhamento como uma exceção explícita. Registre o endereço de bind, a porta local ou remota, o host e a porta de destino e o resultado da limpeza. Não permita que um wrapper SSH genérico herde silenciosamente diretivas LocalForward, RemoteForward ou DynamicForward da configuração ampla Host * de um usuário.

Inspecione as configurações resolvidas antes de confiar em um alias:

ssh -G build-box | grep -E '^(controlmaster|controlpath|controlpersist|localforward|remoteforward|dynamicforward) '

ssh -G imprime a configuração efetiva depois que o OpenSSH aplica a correspondência de hosts e os valores padrão. Essa verificação detecta uma falha surpreendentemente comum: uma tarefa usa um alias simples de host, mas um arquivo de configuração incluído ativa multiplexing ou encaminhamento longe da configuração da própria tarefa. O comando pode mostrar mais campos em versões diferentes. Armazene a saída completa de ssh -G, e não apenas as linhas esperadas.

Um sistema remoto pode registrar uma única conexão de origem enquanto várias conexões de aplicações encaminhadas passam por ela. A telemetria de rede, os logs SSH do servidor e os logs da tarefa respondem a partes diferentes dessa história. Nenhum deles substitui os outros.

Os logs do servidor, sozinhos, não reconstroem as decisões locais

Remova as chaves do contexto
Mantenha as chaves SSH em um cofre local criptografado, sem expô-las como material acessível ao agente.

O servidor SSH remoto vê o transporte e tudo que sua configuração de logs registrar sobre canais e comandos. Ele não consegue informar de maneira confiável por que um processo local recebeu permissão para usar um socket de controle, qual tarefa era proprietária daquele diretório ou se outro processo local o reutilizou depois que a tarefa original terminou.

Isso não é uma crítica aos logs do servidor. Eles operam em outro ponto do sistema. sshd pode registrar eventos de autenticação e conexão. Um wrapper de comando forçado ou um subsistema de auditoria pode registrar comandos remotos. Esses registros continuam úteis. Por padrão, eles não identificam todos os clientes locais de multiplexing, porque o servidor pode enxergar todos os canais como parte de um único transporte já autenticado.

Mantenha evidências dos dois lados desse limite. Um registro útil da tarefa inclui:

  • a configuração completa do cliente, resolvida por ssh -G, sem incluir segredos;
  • o hostname remoto, o endereço, a conta, o resultado da verificação da impressão digital do host e o PID do master inicial;
  • o caminho do socket de controle, o diretório pai privado e os horários observados de criação e encerramento;
  • cada comando remoto, transferência ou operação de encaminhamento solicitada, com seu status de saída;
  • o resultado de check antes da limpeza, o resultado de exit e a inspeção posterior do processo e do socket.

Adicione um identificador de tarefa ao nome do diretório e ao registro, não a um caminho de socket global compartilhado por todas as tarefas. O identificador conecta os eventos locais, mas não deve ser tratado sozinho como um limite de segurança.

Fazer hash ou assinar o registro depois da coleta ajuda a detectar alterações posteriores, mas não corrige eventos que não foram registrados. Colete os eventos do ciclo de vida enquanto acontecem. Um registro montado a partir do histórico do shell depois de um incidente é uma evidência fraca, especialmente quando entram em cena masters em segundo plano e novas tentativas.

Para trabalhos conduzidos por agentes, diferencie a intenção do agente da ação SSH executada. «Implantar a versão X» é uma intenção. ssh build-box 'sudo systemctl restart api' é uma ação. O registro de reutilização do socket mostra se essa ação obteve um transporte novo ou usou um transporte existente. São fatos de auditoria diferentes.

Sockets limitados à tarefa dão um responsável à limpeza

O padrão mais seguro para trabalhos automatizados curtos é simples: use um diretório exclusivo de socket de controle por tarefa, permita reutilização apenas dentro dessa tarefa e envie uma solicitação explícita de exit antes que a tarefa informe que terminou.

Um wrapper prático precisa de um ciclo de vida claro. Ele deve criar o diretório com permissões restritivas, gravar um registro antes da primeira conexão, executar os comandos com o mesmo ControlPath explícito, desligar o master, verificar o resultado e só então remover o diretório vazio. Uma tarefa que não consegue verificar a limpeza deve informar falha de limpeza, mesmo que o comando remoto tenha sido bem-sucedido.

Este exemplo usa mktemp para evitar a necessidade de adivinhar um nome de diretório exclusivo:

set -eu
base="$HOME/.ssh/task-control"
mkdir -p "$base"
chmod 700 "$base"
cm_dir=$(mktemp -d "$base/run.XXXXXX")
chmod 700 "$cm_dir"
socket="$cm_dir/%C"

finish() {
    status=$?
    ssh -S "$socket" -O exit build-box ee"$cm_dir/cleanup.log" 2e261 || \
        printf '%s\n' 'master exit request failed' ee"$cm_dir/cleanup.log"
    ssh -S "$socket" -O check build-box ee"$cm_dir/cleanup.log" 2e261 || true
    exit "$status"
}
trap finish EXIT HUP INT TERM

ssh -o ControlMaster=auto \
    -o ControlPersist=2m \
    -o ControlPath="$socket" \
    build-box 'deployctl apply release-4821'

A configuração curta de ControlPersist cobre o caso em que um processo morre antes de executar seu trap. Ela não deve ser interpretada como permissão para outra tarefa reutilizar o master. O diretório aleatório impede essa reutilização porque a segunda tarefa não conhece nem herda o caminho da primeira.

Há uma correção a fazer antes de adotar este exemplo exatamente assim. Não registre argumentos de comandos sensíveis, valores de ambiente ou dados privados copiados em cleanup.log. Registros de auditoria precisam de detalhes suficientes para estabelecer quem fez o quê, mas não podem se transformar em um novo repositório de segredos. Redija os argumentos no limite do wrapper, enquanto ainda conhece seu significado.

O Sallyport encaminha as ações SSH pelo seu helper stateless sp-ssh, mantendo as chaves SSH no cofre criptografado em vez de expô-las ao agente. Isso elimina uma falha comum no tratamento de credenciais, mas as equipes ainda precisam definir o limite da ação e manter registros que mostrem quando a execução terminou.

Configurações globais de conveniência anulam os limites das tarefas

Veja qual agente foi executado
Registre as execuções dos agentes no diário de sessões, com uma opção direta para revogar uma sessão em andamento.

Uma seção global Host * costuma ativar o multiplexing para todo shell humano, script, repositório e processo filho de automação executado por uma conta. Isso é amplo demais quando a mesma conta executa tarefas com aprovações ou responsáveis diferentes.

A configuração pode vir de arquivos Include, de ferramentas de gerenciamento de configuração, dos dotfiles pessoais de um desenvolvedor ou de uma imagem de build. A linha de comando também pode substituí-la. Nunca deduza o comportamento ativo a partir de um único arquivo de configuração visível. Use ssh -G com o alias exato do host e o contexto de usuário que a tarefa usará.

Se o ambiente de automação não puder garantir um caminho de controle privado, desative o multiplexing para essa ação:

ssh -o ControlMaster=no \
    -o ControlPath=none \
    build-box 'maintenancectl status'

Isso exige uma nova conexão e uma nova autenticação em cada invocação. É um custo adequado para ações de alto impacto, acesso emergencial raro ou trabalho que atravesse limites de tarefa e confiança. A autenticação repetida fornece um evento de autorização mais claro e torna o raciocínio sobre o ciclo de vida muito menos ambíguo.

Não confunda ControlMaster=auto com uma garantia de que um processo só reutilizará sua própria conexão. auto significa que o cliente tentará encontrar um master no caminho configurado e criará um se não encontrar. O caminho configurado determina qual conexão ele pode encontrar.

Algumas equipes afirmam que um socket compartilhado não é problema porque todos os jobs executam sob uma única conta de serviço. Esse argumento só vale se todo job com essa identidade Unix tiver a mesma autoridade para alcançar todos os destinos por meio da conta e se a equipe aceitar que um job possa herdar o transporte ativo de outro. A maioria dos ambientes maduros não quer isso de fato.

Um encerramento limpo da tarefa precisa provar que o transporte foi fechado

Não declare uma tarefa SSH concluída quando o último comando remoto retornar. Declare-a concluída quando a tarefa tiver fechado o master e registrado a prova, ou informado que não conseguiu fazer isso.

O registro final deve dizer ao investigador se um comando posterior tinha algum caminho para reutilizar a conexão. Ele precisa conter a identidade da tarefa, a configuração SSH resolvida, o caminho do socket, os detalhes do processo master, os registros de atividade, os resultados explícitos dos comandos de controle e a observação posterior à limpeza. Também precisa de evidências remotas para alterações que continuaram de forma independente do SSH, como uma reinicialização de serviço ou um processo destacado.

Estabeleça um procedimento que os operadores consigam executar sob pressão: isole o socket, inspecione-o antes da limpeza, solicite exit, verifique que nenhum master responde e preserve o resultado. Esse procedimento é mais útil do que um timeout padrão longo porque transforma uma suposição sobre o acesso em um fato verificável.

Quando o trabalho for sensível a ponto de um transporte autenticado deixado para trás ser inaceitável, não o otimize com um master compartilhado. Abra uma conexão nova, execute a ação, feche-a e mantenha o registro. Os segundos extras custam menos do que explicar por que um caminho de acesso sobreviveu depois que a tarefa deveria ter terminado.

FAQ

O SSH ControlMaster pode manter uma conexão autenticada ativa depois que meu comando termina?

Sim. Uma conexão ControlMaster faz a autenticação uma vez, e os clientes SSH posteriores podem pedir ao master local que abra novos canais. Se o ControlPersist mantiver o master ativo, esses canais posteriores poderão ser abertos depois que o comando original e a tarefa que o iniciou já tiverem terminado.

Qual é a diferença entre uma conexão SSH master e uma slave?

O processo master é a conexão SSH original, que possui o transporte de rede e o socket de controle local. Um processo slave é um comando ssh executado depois, que entra em contato com esse socket e pede ao master que abra uma sessão, um encaminhamento ou outro canal.

Como fechar com segurança um socket de controle SSH compartilhado?

Use ssh -O exit alias-do-host quando sua configuração resolver o alias para o ControlPath pretendido. Se precisar indicar o socket diretamente, use ssh -S /path/to/socket -O exit host; verifique primeiro com -O check para não encerrar a conexão errada.

O multiplexing SSH é seguro para automação?

Ele reduz autenticações repetidas e torna muito mais rápidos vários comandos SSH curtos. O multiplexing não é seguro quando ninguém é responsável por seu ciclo de vida, quando tarefas independentes compartilham o mesmo diretório de sockets ou quando uma tarefa pode continuar abrindo canais depois que o limite de aprovação expirou.

Os logs do servidor SSH mostram todos os comandos enviados por multiplexing?

O servidor SSH remoto costuma registrar um único login de transporte e pode não identificar cada comando local posterior como um novo evento de autenticação. Se precisar de um registro confiável da atividade, reúna os registros de processos do cliente, a configuração de multiplexing, os eventos do ciclo de vida do socket de controle e os logs de comandos da tarefa.

Devo confiar no timeout do ControlPersist para limpar o SSH?

Um timeout é um limite máximo, não uma prova de que a conexão terminou junto com a tarefa. Use ssh -O exit na limpeza e confirme depois que o socket desapareceu e que ssh -O check falha. O timeout continua sendo um fallback útil para clientes que travaram.

Onde os sockets de controle SSH devem ser armazenados?

Trate os sockets de controle como credenciais locais. Coloque-os em um diretório privado, pertencente à conta que executa a tarefa, use um caminho exclusivo por tarefa, evite diretórios temporários compartilhados e só remova caminhos antigos depois de verificar se ainda pertencem a um processo master.

O que significa %C em SSH ControlPath?

O ControlPath define o caminho do socket Unix. %C se expande para um hash derivado dos atributos da conexão e evita muitos problemas de tamanho e colisões de nomes, mas não cria sozinho uma identidade separada para cada tarefa.

Fechar o master SSH desfaz o trabalho que já começou no host remoto?

Não. Fechar um transporte multiplexado encerra a conexão autenticada do lado do cliente, mas não desfaz arquivos alterados remotamente, não termina um processo remoto destacado nem revoga credenciais que outra sessão ainda possa usar. A limpeza do trabalho remoto precisa ser tratada separadamente.

Que evidências devemos guardar depois que uma tarefa SSH automatizada termina?

Comece com um registro reproduzível: a configuração SSH totalmente resolvida, o ID do processo master, o caminho do socket, o destino remoto, os horários de início e encerramento e o resultado de um comando explícito de desligamento. Mantenha esse registro junto da transcrição de comandos da tarefa e dos logs relevantes do host remoto.

Sallyport

O Sallyport executa chamadas de API e comandos SSH pelo seu agente de IA. As chaves ficam em um cofre local no seu Mac; você aprova cada execução e toda ação vai para um registro selado.

© 2026 Sallyport · Código aberto sob Apache-2.0 · Oleg Sotnikov