Remote server administration, automated deployments, configuration management, et infrastructure monitoring — tous reposent tous sur un accès shell sécurisé. Que tu doives exécuter une seule commande sur un hôte distant, ouvrir une session terminal interactive, ou mettre en place un tunnel de redirection de port, SSH est le protocole qui rend cela possible.
Le sgcIndy package inclut TIdSSHClient — un composant Delphi natif de client SSH qui implémente le protocole SSH-2 avec une prise en charge complète de l'exécution de commandes, les shells interactifs, l'allocation de pseudo-terminal, la redirection de port, keep-alive, et les algorithmes cryptographiques modernes. Aucun exécutable SSH externe, aucun wrapper DLL — architecture de composant 100% Delphi avec une API basée sur les événements.
Cet article parcourt les fonctionnalités clés et et fournit des exemples de code Delphi pour les cas d'usage SSH les plus courants.
Fonctionnalités clés
|
Exécution de commandes Exécute des commandes distantes et capture stdout, stderr et les codes de sortie. Méthode de commodité en une ligne ou contrôle complet par canal. |
Shell interactif Ouvre des sessions shell interactives avec prise en charge du pseudo-terminal. Envoie des commandes, reçois la sortie de manière asynchrone, et gère le redimensionnement du terminal. |
Redirection de port Mets en place des tunnels TCP/IP directs et de la redirection inverse. Accède aux services distants via des tunnels SSH chiffrés. |
|
Cryptographie moderne Clés Curve25519, ECDH, AES-GCM, Ed25519. Négociation d'algorithme configurable avec des valeurs par défaut sécurisées. |
Méthodes d'authentification multiples Mot de passe, clé publique (RSA, ECDSA, Ed25519), et et authentification interactive au clavier. Vérification de clé d'hôte via callback d'événement. |
Multi-canal Jusqu'à 10 canaux concurrents par connexion. Exécute plusieurs commandes, shells ou tunnels simultanément sur une seule session SSH. |
Démarrage rapide — Exécuter une commande distante
Le cas d'usage le plus simple: connect, run a command, obtenir le output, et disconnect — tous dans un few lines.
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;
En une ligne. Le Execute méthode opens un canal, exécute la commande, attend le résultat, et et renvoie la sortie sous forme de chaîne — parfait pour l'automatisation par script.
Authentification
Trois méthodes d'authentification sont prises en charge. Les trois sont activées par défaut et le client négocie automatiquement avec le serveur.
Password
oSSH.Authentication.Username := 'admin';
oSSH.Authentication.Password := 'secret';
Clé publique
oSSH.Authentication.Username := 'deploy';
oSSH.Authentication.PrivateKeyFile := 'C:\keys\id_ed25519';
oSSH.Authentication.PublicKeyFile := 'C:\keys\id_ed25519.pub';
oSSH.Authentication.Passphrase := 'keypassphrase';
Interactif au clavier
Gère les prompts d'authentification multi-étapes (MFA, OTP, questions de sécurité) through le OnSSHKeyboardInteractive event.
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;
Vérification de clé d'hôte
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;
Exécution de commandes
Deux approches pour exécuter des commandes distantes: le convenience Execute méthode for simple cases, ou le canal-based API for full control over input, output, et exit status.
Simple: Execute Method
// 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);
Advanced: Channel-Based Execution
For asynchronous execution avec separate stdout/stderr gestion d'unnd exit status tracking.
// 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;
Shell interactif Sessions
Open a pseudo-terminal et interact avec un remote shell — ideal for building SSH terminal emulators ou automating interactive CLI workflows.
// 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;
Terminal Resize & Signals
// 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);
Redirection de port (SSH Tunnels)
Create encrypted tunnels to access remote services as si ils were local. Useful for securely accessing databases, admin panels, ou internal APIs behind firewalls.
Direct TCP/IP Tunneling (Local Forward)
// 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;
Reverse Forwarding (Remote Forward)
// 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 & Connection Options
Prevent idle connections depuis being dropped by firewalls ou load balancers avec le built-in keep-alive mechanism.
// 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
Cryptographic Algorithm Configuration
Le defaults are secure et modern. Customize algorithm negotiation lorsque compliance policies ou legacy server compatibility demand it.
| Category | Supported Algorithms |
|---|---|
| Key Exchange | 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) |
| Ciphers | 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;
Events Reference
Le component fournit granular événement callbacks for every stage de la SSH lifecycle.
| Event | Fired When |
|---|---|
OnSSHConnect | SSH connection established |
OnSSHDisconnect | SSH connection closes (with reason et code) |
OnSSHError | SSH erreur occurs |
OnSSHAuthSuccess / OnSSHAuthFailure | Authentification succeeds ou fails |
OnSSHHostKey | Host key needs verification (accept/reject) |
OnSSHChannelData | Data (stdout) received on un canal |
OnSSHChannelExtendedData | Extended data (stderr) received on un canal |
OnSSHChannelExitStatus | Remote command exit code received |
OnSSHChannelExitSignal | Remote process terminated by signal (with signal name) |
OnSSHKeyboardInteractive | Server requests keyboard-interactive responses |
OnSSHAuthBanner | Server sends an authentification banner message |
Complete Exemple : Automated Deployment Script
A fully configured client SSH que connects avec key authentification, runs deployment commands, et captures exit status.
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;
