リモートサーバー管理・自動デプロイ・設定管理・インフラ監視はすべてセキュアシェルアクセスに依存しています。リモートホストで単一のコマンドを実行する場合でも、対話型ターミナルセッションを開く場合でも、ポートフォワーディングトンネルを設定する場合でも、SSH はそれを可能にするプロトコルです。
sgcIndy パッケージには TIdSSHClient が含まれています。これはコマンド実行・対話型シェル・疑似ターミナル割り当て・ポートフォワーディング・キープアライブ・最新の暗号アルゴリズムを完全サポートする SSH-2 プロトコルを実装したネイティブ Delphi SSH クライアントコンポーネントです。外部の SSH 実行ファイルや DLL ラッパーは不要で、イベント駆動 API を持つ純粋な Delphi コンポーネントアーキテクチャです。
本記事では主要な機能を解説し、最も一般的な SSH ユースケースの Delphi コードサンプルを提供します。
主な機能
|
コマンド実行 リモートコマンドを実行して stdout・stderr・終了コードをキャプチャします。ワンライン便利メソッドまたはチャンネルベースの完全な制御が可能です。 |
対話型シェル 疑似ターミナルサポートで対話型シェルセッションを開きます。コマンドの送信・非同期での出力受信・ターミナルリサイズの処理が可能です。 |
ポートフォワーディング 直接 TCP/IP トンネルとリバースフォワーディングを設定します。暗号化された SSH トンネルを通じてリモートサービスにアクセスします。 |
|
最新暗号 Curve25519・ECDH・AES-GCM・Ed25519 鍵。設定可能なアルゴリズムネゴシエーションと安全なデフォルト設定。 |
複数認証方式 パスワード・公開鍵(RSA・ECDSA・Ed25519)・キーボードインタラクティブ認証。イベントコールバックでホスト鍵検証。 |
マルチチャンネル 接続ごとに最大 10 の同時チャンネル。単一の SSH セッションで複数のコマンド・シェル・トンネルを同時に実行できます。 |
クイックスタート — リモートコマンドの実行
最もシンプルなユースケース:接続・コマンド実行・出力取得・切断をわずか数行で実現します。
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;
ワンライナー。Execute メソッドはチャンネルを開いてコマンドを実行し、結果を待って出力を文字列で返します。スクリプト自動化に最適です。
認証
3 つの認証方式がサポートされています。デフォルトで 3 つすべてが有効になっており、クライアントはサーバーと自動的にネゴシエーションします。
パスワード認証
oSSH.Authentication.Username := 'admin';
oSSH.Authentication.Password := 'secret';
公開鍵認証
oSSH.Authentication.Username := 'deploy';
oSSH.Authentication.PrivateKeyFile := 'C:\keys\id_ed25519';
oSSH.Authentication.PublicKeyFile := 'C:\keys\id_ed25519.pub';
oSSH.Authentication.Passphrase := 'keypassphrase';
キーボードインタラクティブ認証
多段階認証プロンプト(MFA・OTP・セキュリティ質問)を 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;
ホスト鍵検証
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;
コマンド実行
リモートコマンドの実行方法は 2 つあります:シンプルなケース向けの便利な Execute メソッド、または入力・出力・終了ステータスを完全に制御するチャンネルベース API です。
シンプル: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);
高度:チャンネルベースの実行
stdout/stderr を分けて処理し終了ステータスを追跡する非同期実行向けです。
// 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;
対話型シェルセッション
疑似ターミナルを開いてリモートシェルと対話します。SSH ターミナルエミュレーターの構築や対話型 CLI ワークフローの自動化に最適です。
// 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;
ターミナルリサイズとシグナル
// 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);
ポートフォワーディング(SSH トンネル)
暗号化されたトンネルを作成してリモートサービスにローカルのようにアクセスします。ファイアウォール背後のデータベース・管理パネル・内部 API に安全にアクセスするのに役立ちます。
直接 TCP/IP トンネリング(ローカルフォワード)
// 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;
リバースフォワーディング(リモートフォワード)
// 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);
キープアライブと接続オプション
組み込みのキープアライブメカニズムでアイドル接続がファイアウォールやロードバランサーに切断されるのを防ぎます。
// 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
暗号アルゴリズムの設定
デフォルトは安全かつ最新です。コンプライアンスポリシーやレガシーサーバーとの互換性が必要な場合はアルゴリズムネゴシエーションをカスタマイズできます。
| カテゴリ | サポートされるアルゴリズム |
|---|---|
| 鍵交換 | Curve25519, ECDH (P-256, P-384, P-521), DH Group14/16 |
| ホスト鍵 | Ed25519, ECDSA (P-256, P-384, P-521), RSA (SHA2-256, SHA2-512) |
| 暗号 | AES-256/192/128-CTR, AES-256/128-GCM |
| MAC | 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;
イベントリファレンス
コンポーネントは SSH ライフサイクルのすべての段階で詳細なイベントコールバックを提供します。
| イベント | 発火タイミング |
|---|---|
OnSSHConnect | SSH 接続が確立されたとき |
OnSSHDisconnect | SSH 接続がクローズされたとき(理由とコード付き) |
OnSSHError | SSH エラーが発生したとき |
OnSSHAuthSuccess / OnSSHAuthFailure | 認証が成功または失敗したとき |
OnSSHHostKey | ホスト鍵の検証が必要なとき(承認/拒否) |
OnSSHChannelData | チャンネルでデータ(stdout)を受信したとき |
OnSSHChannelExtendedData | チャンネルで拡張データ(stderr)を受信したとき |
OnSSHChannelExitStatus | リモートコマンドの終了コードを受信したとき |
OnSSHChannelExitSignal | リモートプロセスがシグナルで終了したとき(シグナル名付き) |
OnSSHKeyboardInteractive | サーバーがキーボードインタラクティブ応答を要求したとき |
OnSSHAuthBanner | サーバーが認証バナーメッセージを送信したとき |
完全なサンプル:自動デプロイスクリプト
鍵認証で接続してデプロイコマンドを実行し終了ステータスをキャプチャする完全設定済みの SSH クライアントです。
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;
