Administração remota de servidores, implantações automatizadas, gerenciamento de configuração e monitoramento de infraestrutura — tudo isso depende de acesso seguro via shell. Seja para executar um único comando em um host remoto, abrir uma sessão de terminal interativo ou configurar um túnel de port forwarding, o SSH é o protocolo que torna tudo isso possível.
O pacote sgcIndy inclui TIdSSHClient — um componente cliente SSH nativo para Delphi que implementa o protocolo SSH-2 com suporte completo a execução de comandos, shells interativos, alocação de pseudo-terminal, port forwarding, keep-alive e algoritmos criptográficos modernos. Sem executáveis SSH externos, sem wrappers de DLL — arquitetura de componente Delphi pura com uma API orientada a eventos.
Este artigo apresenta os principais recursos e fornece exemplos de código Delphi para os casos de uso SSH mais comuns.
Principais Recursos
|
Execução de Comandos Execute comandos remotos e capture stdout, stderr e códigos de saída. Método de conveniência em uma linha ou controle completo baseado em canal. |
Shell Interativo Abra sessões de shell interativo com suporte a pseudo-terminal. Envie comandos, receba saída de forma assíncrona e trate o redimensionamento do terminal. |
Port Forwarding Configure túneis TCP/IP diretos e forwarding reverso. Acesse serviços remotos através de túneis SSH criptografados. |
|
Criptografia Moderna Curve25519, ECDH, AES-GCM, chaves Ed25519. Negociação de algoritmos configurável com padrões seguros prontos para uso. |
Múltiplos Métodos de Autenticação Senha, chave pública (RSA, ECDSA, Ed25519) e autenticação keyboard-interactive. Verificação de host key via callback de evento. |
Multi-Canal Até 10 canais simultâneos por conexão. Execute múltiplos comandos, shells ou túneis ao mesmo tempo em uma única sessão SSH. |
Início Rápido — Executar um Comando Remoto
O caso de uso mais simples: conectar, executar um comando, obter a saída e desconectar — tudo em poucas linhas.
var
oSSH: TIdSSHClient;
vOutput: string;
begin
oSSH := TIdSSHClient.Create(nil);
Try
oSSH.Host := 'server.example.com';
oSSH.Port := 22;
oSSH.Authentication.Username := 'admin';
oSSH.Authentication.Password := 'secret';
oSSH.Connect;
// Execute a command and capture the output
vOutput := oSSH.Execute('df -h');
WriteLn(vOutput);
oSSH.Disconnect;
Finally
oSSH.Free;
End;
end;
Uma linha. O método Execute abre um canal, executa o comando, aguarda o resultado e retorna a saída como string — perfeito para automação via scripts.
Autenticação
Três métodos de autenticação são suportados. Os três estão habilitados por padrão e o cliente negocia automaticamente com o servidor.
Senha
oSSH.Authentication.Username := 'admin';
oSSH.Authentication.Password := 'secret';
Chave Pública
oSSH.Authentication.Username := 'deploy';
oSSH.Authentication.PrivateKeyFile := 'C:\keys\id_ed25519';
oSSH.Authentication.PublicKeyFile := 'C:\keys\id_ed25519.pub';
oSSH.Authentication.Passphrase := 'keypassphrase';
Keyboard-Interactive
Trate prompts de autenticação em múltiplas etapas (MFA, OTP, perguntas de segurança) através do evento OnSSHKeyboardInteractive.
oSSH.OnSSHKeyboardInteractive := OnKeyboardInteractive;
procedure TForm1.OnKeyboardInteractive(Sender: TObject;
const aName, aInstruction: string;
aPrompts: TStrings; aEchos: TList; aResponses: TStrings);
begin
// Respond to each prompt (e.g., "Password:", "OTP:")
if aPrompts.Count > 0 then
aResponses.Add('mypassword');
end;
Verificação de Host Key
oSSH.OnSSHHostKey := OnHostKey;
procedure TForm1.OnHostKey(Sender: TObject;
const aHostKeyType, aFingerprint: string;
var aAction: TIdSSHHostKeyVerification);
begin
// Accept or reject based on known fingerprint
aAction := sshHostKeyAccept;
end;
Execução de Comandos
Duas abordagens para executar comandos remotos: o método de conveniência Execute para casos simples, ou a API baseada em canal para controle total de entrada, saída e status de saída.
Simples: Método Execute
// Execute and get output (30-second timeout by default)
vOutput := oSSH.Execute('ls -la /var/log');
// Custom timeout (10 seconds)
vOutput := oSSH.Execute('cat /etc/hostname', 10000);
Avançado: Execução Baseada em Canal
Para execução assíncrona com tratamento separado de stdout/stderr e rastreamento de status de saída.
// Open a channel and execute a command
var
vChannelId: Cardinal;
begin
vChannelId := oSSH.OpenChannel;
oSSH.RequestExec(vChannelId, 'tar czf /tmp/backup.tar.gz /data');
// Output arrives via OnSSHChannelData event
// Exit status arrives via OnSSHChannelExitStatus event
end;
// Handle stdout
procedure TForm1.OnChannelData(Sender: TObject;
aChannelId: Cardinal; const aData: TIdBytes);
begin
Memo1.Lines.Add(BytesToString(aData));
end;
// Handle stderr
procedure TForm1.OnChannelExtendedData(Sender: TObject;
aChannelId: Cardinal; aDataType: Cardinal; const aData: TIdBytes);
begin
MemoErrors.Lines.Add(BytesToString(aData));
end;
// Handle exit status
procedure TForm1.OnExitStatus(Sender: TObject;
aChannelId: Cardinal; aExitStatus: Integer);
begin
WriteLn('Command exited with code: ' + IntToStr(aExitStatus));
end;
Sessões de Shell Interativo
Abra um pseudo-terminal e interaja com um shell remoto — ideal para criar emuladores de terminal SSH ou automatizar fluxos de trabalho CLI interativos.
// Open channel, request PTY, then request shell
var
vChannelId: Cardinal;
begin
vChannelId := oSSH.OpenChannel;
// Request a pseudo-terminal (xterm, 80x24)
oSSH.RequestPTY(vChannelId, 'xterm', 80, 24);
// Start the shell
oSSH.RequestShell(vChannelId);
// Send commands to the shell
oSSH.SendChannelData(vChannelId, 'cd /var/log' + #13#10);
oSSH.SendChannelData(vChannelId, 'tail -f syslog' + #13#10);
end;
Redimensionamento de Terminal & Sinais
// Notify the server of terminal resize
oSSH.SendWindowChange(vChannelId, 120, 40, 0, 0);
// Send Ctrl+C (interrupt signal)
oSSH.SendSignal(vChannelId, 'INT');
// Set an environment variable before running commands
oSSH.SetEnvironmentVariable(vChannelId, 'LANG', 'en_US.UTF-8');
// Signal end of input
oSSH.SendEOF(vChannelId);
Port Forwarding (Túneis SSH)
Crie túneis criptografados para acessar serviços remotos como se fossem locais. Útil para acessar de forma segura bancos de dados, painéis de administração ou APIs internas atrás de firewalls.
Tunelamento TCP/IP Direto (Forward Local)
// Tunnel to a remote database through SSH
var
vTunnelId: Cardinal;
begin
vTunnelId := oSSH.OpenDirectTCPIP(
'db-internal.example.com', // Remote host
5432, // Remote port (PostgreSQL)
'127.0.0.1', // Originator IP
0); // Originator port
// Send/receive data through the tunnel
oSSH.SendChannelData(vTunnelId, vDatabaseQuery);
end;
Forwarding Reverso (Forward Remoto)
// Ask the server to forward a remote port to us
oSSH.RequestForwarding('0.0.0.0', 8080);
// Cancel the forwarding
oSSH.CancelForwarding('0.0.0.0', 8080);
Keep-Alive & Opções de Conexão
Evite que conexões ociosas sejam derrubadas por firewalls ou load balancers com o mecanismo de keep-alive integrado.
// Send keep-alive every 30 seconds, disconnect after 3 failures
oSSH.KeepAlive.Enabled := True;
oSSH.KeepAlive.Interval := 30;
oSSH.KeepAlive.MaxCount := 3;
// Connection options
oSSH.SSHOptions.ConnectTimeout := 10000; // 10 seconds
oSSH.SSHOptions.ReadTimeout := 30000; // 30 seconds
oSSH.SSHOptions.MaxChannels := 10; // Concurrent channels
Configuração de Algoritmos Criptográficos
Os padrões são seguros e modernos. Personalize a negociação de algoritmos quando políticas de conformidade ou compatibilidade com servidores legados exigirem.
| Categoria | Algoritmos Suportados |
|---|---|
| Troca de Chaves | Curve25519, ECDH (P-256, P-384, P-521), DH Group14/16 |
| Host Keys | Ed25519, ECDSA (P-256, P-384, P-521), RSA (SHA2-256, SHA2-512) |
| Cifras | AES-256/192/128-CTR, AES-256/128-GCM |
| MACs | HMAC-SHA2-256, HMAC-SHA2-512, HMAC-SHA1 |
// Customize algorithm preferences
oSSH.Algorithms.KexAlgorithms := 'curve25519-sha256';
oSSH.Algorithms.Ciphers := 'aes256-gcm@openssh.com'
,aes256-ctr';
oSSH.Algorithms.HostKeyAlgorithms := 'ssh-ed25519,rsa-sha2-256';
oSSH.Algorithms.MACs := 'hmac-sha2-256';
// Force re-keying to refresh encryption
oSSH.Rekey;
Referência de Eventos
O componente fornece callbacks de evento granulares para cada etapa do ciclo de vida SSH.
| Evento | Disparado quando |
|---|---|
OnSSHConnect | Conexão SSH estabelecida |
OnSSHDisconnect | Conexão SSH encerrada (com motivo e código) |
OnSSHError | Erro SSH ocorre |
OnSSHAuthSuccess / OnSSHAuthFailure | Autenticação bem-sucedida ou falha |
OnSSHHostKey | Host key precisa de verificação (aceitar/rejeitar) |
OnSSHChannelData | Dados (stdout) recebidos em um canal |
OnSSHChannelExtendedData | Dados estendidos (stderr) recebidos em um canal |
OnSSHChannelExitStatus | Código de saída do comando remoto recebido |
OnSSHChannelExitSignal | Processo remoto encerrado por sinal (com nome do sinal) |
OnSSHKeyboardInteractive | Servidor solicita respostas keyboard-interactive |
OnSSHAuthBanner | Servidor envia uma mensagem de banner de autenticação |
Exemplo Completo: Script de Implantação Automatizada
Um cliente SSH totalmente configurado que conecta com autenticação por chave, executa comandos de implantação e captura o status de saída.
uses
IdSSHClient, IdSSHClasses;
var
oSSH: TIdSSHClient;
vOutput: string;
begin
oSSH := TIdSSHClient.Create(nil);
Try
// Connection
oSSH.Host := 'production.example.com';
oSSH.Port := 22;
// Key-based authentication
oSSH.Authentication.Username := 'deploy';
oSSH.Authentication.PrivateKeyFile := 'C:\keys\deploy_ed25519';
// Keep connection alive through firewalls
oSSH.KeepAlive.Enabled := True;
oSSH.KeepAlive.Interval := 30;
// Events
oSSH.OnSSHHostKey := OnHostKey;
oSSH.OnSSHError := OnError;
// Connect
oSSH.Connect;
// Run deployment commands
vOutput := oSSH.Execute('cd /opt/app && git pull origin main');
WriteLn(vOutput);
vOutput := oSSH.Execute('systemctl restart myapp');
WriteLn(vOutput);
vOutput := oSSH.Execute('systemctl status myapp');
WriteLn(vOutput);
// Disconnect
oSSH.Disconnect;
Finally
oSSH.Free;
End;
end;
