SFTP クライアント sgcIndy Delphi コンポーネント

· コンポーネント

セキュアなファイル転送はエンタープライズ統合の基盤です。銀行パートナーとのデータ交換、リモートサーバーとのファイル同期、デプロイパイプラインの自動化など、さまざまなシナリオで SFTP (SSH File Transfer Protocol) は信頼されていないネットワーク上でのファイルの安全な転送における業界標準です。

sgcIndy パッケージには TIdSFTPClient が含まれています。これは外部コマンドラインツールやサードパーティの実行ファイルを必要とせず、SSH 上でネイティブに動作する Delphi SFTP クライアントコンポーネントです。ファイルのアップロード・ダウンロード、ディレクトリ管理、シンボリックリンク、ファイル属性、進捗トラッキング、最新の暗号アルゴリズムをすべてクリーンなイベント駆動 API で提供します。

この記事では、完全な機能セットと最も一般的な SFTP 操作に対応した Delphi コードをご紹介します。

主な機能

ファイル転送
バッファサイズを設定可能なファイルのアップロード・ダウンロードとリアルタイムの進捗イベントをサポートします。ファイルパスまたは TStream オブジェクトから直接転送できます。
ディレクトリ操作
完全なメタデータを含むディレクトリ一覧の取得、ディレクトリの作成・削除、シンボリックリンクを含むパスの解決をサポートします。
最新の暗号化
Curve25519、ECDH、AES-GCM、Ed25519 キー、HMAC-SHA2 をサポートします。コンプライアンス要件に応じてアルゴリズムネゴシエーションを設定できます。
複数の認証方式
パスワード、公開鍵 (RSA、ECDSA、Ed25519)、キーボードインタラクティブ認証をサポートします。フィンガープリントコールバックによるホストキーの検証も可能です。
ファイル属性とアクセス権
ファイルのアクセス権、所有者、タイムスタンプ、サイズの読み取りと変更をサポートします。Unix スタイルのモードビットとシンボリックリンクを完全サポートします。
進捗とイベント
転送バイト数と合計サイズで転送進捗をトラッキングできます。転送のキャンセルも可能です。エラー、接続、切断イベントを提供します。

クイックスタート — 接続してファイルをダウンロードする

リモートサーバーに接続し、ファイルをダウンロードして切断するシンプルなサンプルです。

var
  oSFTP: TIdSFTPClient;
begin
  oSFTP := TIdSFTPClient.Create(nil);
  Try
    oSFTP.Host := 'sftp.example.com';
    oSFTP.Port := 22;
    oSFTP.Authentication.Username := 'deploy';
    oSFTP.Authentication.Password := 'secret';
    oSFTP.Connect;
    // Download a file
    oSFTP.Get('/data/report.csv', 'C:\local\report.csv');
    oSFTP.Disconnect;
  Finally
    oSFTP.Free;
  End;
end;

認証

このコンポーネントは 3 つの認証方式をサポートしています。すべてデフォルトで有効になっており、クライアントとサーバーが最適な方式を自動的にネゴシエートします。

パスワード認証

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

公開鍵認証

oSFTP.Authentication.Username := 'deploy';
oSFTP.Authentication.PrivateKeyFile := 'C:\keys\id_rsa';
oSFTP.Authentication.PublicKeyFile := 'C:\keys\id_rsa.pub';
oSFTP.Authentication.Passphrase := 'keypassphrase';

ホストキーの検証

サーバーの本人確認は OnSSHHostKey イベントでホストキーフィンガープリントを検査することで行います。

oSFTP.OnSSHHostKey := OnHostKey;
procedure TForm1.OnHostKey(Sender: TObject;
  const aHostKeyType, aFingerprint: string;
  var aAction: TIdSSHHostKeyVerification);
begin
  // Verify fingerprint against known hosts
  if aFingerprint = 'SHA256:xyzABC123...' then
    aAction := sshHostKeyAccept
  else
    aAction := sshHostKeyReject;
end;

ファイル操作

アップロードとダウンロード

// Upload a file
oSFTP.Put('C:\local\data.zip', '/uploads/data.zip');
// Download a file
oSFTP.Get('/reports/monthly.pdf', 'C:\local\monthly.pdf');
// Upload from a stream
oSFTP.Put(oMemoryStream, '/uploads/stream-data.bin');
// Download to a stream
oSFTP.Get('/data/export.csv', oFileStream);

文字列の便利メソッド

// Read a remote file into a string
vContent := oSFTP.GetFileAsString('/config/settings.json');
// Write a string to a remote file
oSFTP.PutFileFromString('{"key":"value"}', '/config/settings.json');

削除、リネーム、シンボリックリンク

// Delete a remote file
oSFTP.Delete('/tmp/old-file.log');
// Rename / move a file
oSFTP.Rename('/data/temp.csv', '/data/final.csv');
// Create a symbolic link
oSFTP.Symlink('/data/final.csv', '/data/latest.csv');

ディレクトリ操作

// List directory contents with full metadata
var
  oItems: TIdSFTPDirectoryItems;
  i: Integer;
begin
  oItems := oSFTP.ListDirectory('/data');
  for i := 0 to Length(oItems) - 1 do
    WriteLn(oItems[i].Filename + ' - ' +
      IntToStr(oItems[i].Attrs.Size) + ' bytes');
end;
// Create and remove directories
oSFTP.MakeDirectory('/data/archive/2026');
oSFTP.RemoveDirectory('/data/temp');
// Get current working directory
vPath := oSFTP.GetCurrentDirectory;
// Resolve a path (follows symlinks, resolves . and ..)
vRealPath := oSFTP.RealPath('../data/../data/./file.txt');

ファイル属性と情報

// Check existence
if oSFTP.FileExists('/data/report.csv') then
  WriteLn('File found');
if oSFTP.DirectoryExists('/data/archive') then
  WriteLn('Directory exists');
// Get file size
vSize := oSFTP.FileSize('/data/report.csv');
// Get full attributes (size, permissions, timestamps, UID/GID)
var
  oAttrs: TIdSFTPFileAttributes;
begin
  oAttrs := oSFTP.Stat('/data/report.csv');
  WriteLn('Size: ' + IntToStr(oAttrs.Size));
  WriteLn('Permissions: ' + IntToStr(oAttrs.Permissions));
end;

転送進捗とキャンセル

OnSFTPProgress イベントはファイル転送中に毎回発火し、転送中のキャンセル機能を含むリアルタイムのトラッキングを提供します。

oSFTP.OnSFTPProgress := OnProgress;
procedure TForm1.OnProgress(Sender: TObject;
  const aFilename: string;
  aTransferred, aTotal: Int64;
  var Cancel: Boolean);
begin
  ProgressBar1.Max := aTotal;
  ProgressBar1.Position := aTransferred;
  Label1.Caption := Format('%s: %d / %d bytes',
    [aFilename, aTransferred, aTotal]);
  // Set Cancel := True to abort the transfer
  Cancel := FUserCancelled;
end;

暗号アルゴリズムの設定

このコンポーネントは最新の暗号標準をサポートしています。デフォルト設定は安全ですが、コンプライアンスや相互運用性の要件に応じてアルゴリズムネゴシエーションをカスタマイズできます。

カテゴリ サポートされているアルゴリズム
鍵交換 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
// Restrict to only the strongest algorithms
oSFTP.Algorithms.Ciphers := 'aes256-gcm@openssh.com'
		,aes256-ctr';
oSFTP.Algorithms.KexAlgorithms := 'curve25519-sha256';
oSFTP.Algorithms.MACs := 'hmac-sha2-256,hmac-sha2-512';

完全なサンプル

公開鍵認証で接続し、ディレクトリを一覧表示し、進捗トラッキング付きでファイルをダウンロードし、エラーを処理する本番対応のサンプルです。

uses
  IdSFTPClient, IdSSHClasses;
var
  oSFTP: TIdSFTPClient;
  oItems: TIdSFTPDirectoryItems;
  i: Integer;
begin
  oSFTP := TIdSFTPClient.Create(nil);
  Try
    // Connection
    oSFTP.Host := 'sftp.example.com';
    oSFTP.Port := 22;
    // Public key authentication
    oSFTP.Authentication.Username := 'deploy';
    oSFTP.Authentication.PrivateKeyFile := 'C:\keys\id_ed25519';
    // Events
    oSFTP.OnSFTPProgress := OnProgress;
    oSFTP.OnSFTPError := OnError;
    oSFTP.OnSSHHostKey := OnHostKey;
    // Connect
    oSFTP.Connect;
    // List remote directory
    oItems := oSFTP.ListDirectory('/data');
    for i := 0 to Length(oItems) - 1 do
      WriteLn(oItems[i].Filename);
    // Download file with progress
    oSFTP.Get('/data/backup.tar.gz', 'C:\backups\backup.tar.gz');
    // Disconnect
    oSFTP.Disconnect;
  Finally
    oSFTP.Free;
  End;
end;

メソッドリファレンス

メソッド 説明
Getローカルパスまたは TStream へファイルをダウンロードします
Putローカルパスまたは TStream からファイルをアップロードします
Deleteリモートファイルを削除します
Renameリモートファイルをリネームまたは移動します
ListDirectoryメタデータを含むディレクトリの内容を一覧表示します
MakeDirectoryリモートディレクトリを作成します
Stat / LStatファイル属性を取得します(シンボリックリンクの解決あり/なし)
FileExists / DirectoryExistsファイルまたはディレクトリが存在するか確認します
Symlink / ReadLinkシンボリックリンクを作成または読み取ります
GetFileAsString / PutFileFromString文字列ベースの便利メソッドです