SSH Client sgcIndy Delphi Component

· Bileşenler

Uzak sunucu yönetimi, otomatik dağıtımlar, yapılandırma yönetimi ve altyapı izleme — bunların tümü güvenli kabuk (shell) erişimine dayanır. İster uzak bir ana bilgisayarda tek bir komut çalıştırmanız, ister etkileşimli bir terminal oturumu açmanız veya bir bağlantı noktası iletme (port-forwarding) tüneli kurmanız gereksin, bunu mümkün kılan protokol SSH'tir.

sgcIndy paketi, komut yürütme, etkileşimli kabuklar, sözde terminal (pseudo-terminal) tahsisi, bağlantı noktası iletme, keep-alive ve modern kriptografik algoritmalar için tam destekle SSH-2 protokolünü uygulayan yerel bir Delphi SSH istemci bileşeni olan TIdSSHClient'ı içerir. Harici SSH çalıştırılabilirleri yok, DLL sarmalayıcıları yok — olay güdümlü bir API'ye sahip saf Delphi bileşen mimarisi.

Bu makale, başlıca özellikleri adım adım anlatır ve en yaygın SSH kullanım durumları için Delphi kod örnekleri sağlar.

Başlıca Özellikler

Komut Yürütme
Uzak komutları çalıştırın ve stdout, stderr ve çıkış kodlarını yakalayın. Tek satırlık kolaylık metodu veya tam kanal tabanlı denetim.
Etkileşimli Kabuk
Sözde terminal desteğiyle etkileşimli kabuk oturumları açın. Komutlar gönderin, çıktıyı eşzamansız olarak alın ve terminal yeniden boyutlandırmasını ele alın.
Bağlantı Noktası İletme
Doğrudan TCP/IP tünelleri ve ters iletme kurun. Şifreli SSH tünelleri aracılığıyla uzak hizmetlere erişin.
Modern Kriptografi
Curve25519, ECDH, AES-GCM, Ed25519 anahtarları. Kutudan çıkar çıkmaz güvenli varsayılanlarla yapılandırılabilir algoritma görüşmesi.
Birden Fazla Kimlik Doğrulama Yöntemi
Parola, açık anahtar (RSA, ECDSA, Ed25519) ve keyboard-interactive kimlik doğrulama. Olay geri çağrısı aracılığıyla ana bilgisayar anahtarı doğrulama.
Çok Kanallı
Bağlantı başına en fazla 10 eşzamanlı kanal. Tek bir SSH oturumu üzerinden aynı anda birden fazla komut, kabuk veya tünel çalıştırın.

Hızlı Başlangıç — Uzak Bir Komut Çalıştırın

En basit kullanım durumu: bağlanın, bir komut çalıştırın, çıktıyı alın ve bağlantıyı kesin — tümü birkaç satırda.

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;

Tek satırlık. Execute metodu bir kanal açar, komutu çalıştırır, sonucu bekler ve çıktıyı bir dize olarak döndürür — betikli otomasyon için mükemmel.

Kimlik Doğrulama

Üç kimlik doğrulama yöntemi desteklenir. Üçü de varsayılan olarak etkindir ve istemci sunucuyla otomatik olarak görüşür.

Parola

oSSH.Authentication.Username := 'admin';
oSSH.Authentication.Password := 'secret';

Açık Anahtar

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

Çok adımlı kimlik doğrulama istemlerini (MFA, OTP, güvenlik soruları) OnSSHKeyboardInteractive olayı aracılığıyla ele alın.

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;

Ana Bilgisayar Anahtarı Doğrulama

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;

Komut Yürütme

Uzak komutları çalıştırmak için iki yaklaşım: basit durumlar için kolaylık Execute metodu veya girdi, çıktı ve çıkış durumu üzerinde tam denetim için kanal tabanlı API.

Basit: Execute Metodu

// 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);

Gelişmiş: Kanal Tabanlı Yürütme

Ayrı stdout/stderr ele alma ve çıkış durumu izlemeyle eşzamansız yürütme için.

// 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;

Etkileşimli Kabuk Oturumları

Bir sözde terminal açın ve uzak bir kabukla etkileşime girin — SSH terminal öykünücüleri oluşturmak veya etkileşimli CLI iş akışlarını otomatikleştirmek için idealdir.

// 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 Yeniden Boyutlandırma & Sinyaller

// 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);

Bağlantı Noktası İletme (SSH Tünelleri)

Uzak hizmetlere yerelmiş gibi erişmek için şifreli tüneller oluşturun. Güvenlik duvarları arkasındaki veritabanlarına, yönetici panellerine veya dahili API'lere güvenli bir şekilde erişmek için kullanışlıdır.

Doğrudan TCP/IP Tünelleme (Yerel İletme)

// 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;

Ters İletme (Uzak İletme)

// 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 & Bağlantı Seçenekleri

Yerleşik keep-alive mekanizmasıyla boştaki bağlantıların güvenlik duvarları veya yük dengeleyiciler tarafından düşürülmesini önleyin.

// 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

Kriptografik Algoritma Yapılandırması

Varsayılanlar güvenli ve moderndir. Uyumluluk politikaları veya eski sunucu uyumluluğu gerektirdiğinde algoritma görüşmesini özelleştirin.

Kategori Desteklenen Algoritmalar
Anahtar Değişimi Curve25519, ECDH (P-256, P-384, P-521), DH Group14/16
Ana Bilgisayar Anahtarları Ed25519, ECDSA (P-256, P-384, P-521), RSA (SHA2-256, SHA2-512)
Şifreler AES-256/192/128-CTR, AES-256/128-GCM
MAC'ler 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;

Olaylar Referansı

Bileşen, SSH yaşam döngüsünün her aşaması için ayrıntılı olay geri çağrıları sağlar.

Olay Tetiklenme Zamanı
OnSSHConnectSSH bağlantısı kuruldu
OnSSHDisconnectSSH bağlantısı kapanır (neden ve kodla)
OnSSHErrorSSH hatası oluşur
OnSSHAuthSuccess / OnSSHAuthFailureKimlik doğrulama başarılı olur veya başarısız olur
OnSSHHostKeyAna bilgisayar anahtarı doğrulama gerektirir (kabul/reddet)
OnSSHChannelDataBir kanalda veri (stdout) alındı
OnSSHChannelExtendedDataBir kanalda genişletilmiş veri (stderr) alındı
OnSSHChannelExitStatusUzak komut çıkış kodu alındı
OnSSHChannelExitSignalUzak işlem sinyalle sonlandırıldı (sinyal adıyla)
OnSSHKeyboardInteractiveSunucu keyboard-interactive yanıtları ister
OnSSHAuthBannerSunucu bir kimlik doğrulama başlık (banner) mesajı gönderir

Tam Örnek: Otomatik Dağıtım Betiği

Anahtar kimlik doğrulamasıyla bağlanan, dağıtım komutlarını çalıştıran ve çıkış durumunu yakalayan tam yapılandırılmış bir SSH istemcisi.

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;