「C Sharpとネットワーク - SFTP」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
 
(同じ利用者による、間の4版が非表示)
33行目: 33行目:
*: NuGet
*: NuGet
*: https://www.nuget.org/packages/SSH.NET
*: https://www.nuget.org/packages/SSH.NET
<br>
libSSH / libSSH2ライブラリを使用する場合は、C/C++で記述されているため、マーシャリングして使用する必要がある。<br>
ただし、これらの操作は煩雑であるため、SSH.NETライブラリを使用することを推奨する。<br>
<br><br>
<br><br>


71行目: 74行目:
       // 公開鍵にパスフレーズが存在する場合
       // 公開鍵にパスフレーズが存在する場合
       var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
       var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
                                                           new PrivateKeyFile(secretKeyPath, "finger_print"));
                                                           new PrivateKeyFile(secretKeyPath, "<パスフレーズ>"));
   
   
       // 公開鍵にパスフレーズが無い場合
       // 公開鍵にパスフレーズが無い場合
       //var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
       //var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
                                                            new PrivateKeyFile(secretKeyPath));
      //                                                    new PrivateKeyFile(secretKeyPath, ""));
   
   
       // パスワード認証の場合
       // パスワード認証の場合
       //var authMethod = new PasswordAuthenticationMethod("<リモートPCのユーザ名>",
       //var authMethod = new PasswordAuthenticationMethod("<リモートPCのユーザ名>",
                                                          "<リモートPCのユーザ名のパスワード>");
      //                                                  "<リモートPCのユーザ名のパスワード>");
   
   
       // 接続情報のインスタンス生成
       // 接続情報のインスタンス生成
133行目: 136行目:
<br>
<br>
  <syntaxhighlight lang="c#">
  <syntaxhighlight lang="c#">
  // ...略
  using System;
   
  using System.IO;
  client.Connect();
  using Renci.SshNet;
   
   
  var files = client.ListDirectory("/home/username/test").Where(x => x.Name != "." && x.Name != "..");
  class SftpDownloadMultipleFiles
foreach (var file in files)
  {
  {
     using (var fs = System.IO.File.OpenWrite(file.Name))
     static void Main(string[] args)
     {
     {
       client.DownloadFile(file.FullName, fs);
       // 公開鍵認証の場合
      // 例としてユーザディレクトリ配下の.sshディレクトリ内のsecret_key.pemを秘密鍵として使用
      string secretKeyPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".ssh", "secret_key.pem");
      var authMethod = new PrivateKeyAuthenticationMethod("username", new PrivateKeyFile(secretKeyPath, "finger_print"));
      // 公開鍵にパスフレーズが存在する場合
      var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
                                                          new PrivateKeyFile(secretKeyPath, "<パスフレーズ>"));
      // 公開鍵にパスフレーズが無い場合
      //var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
      //                                                    new PrivateKeyFile(secretKeyPath, ""));
      // パスワード認証の場合
      //var authMethod = new PasswordAuthenticationMethod("<リモートPCのユーザ名>",
      //                                                  "<リモートPCのユーザ名のパスワード>")
      // 接続情報のインスタンス生成
      var connectionInfo = new ConnectionInfo("<リモートPCのIPアドレス または ホスト名>",
                                              <ポート番号  例: 22>,
                                              "<リモートPCのユーザ名>",
                                              authMethod);
      using (var client = new SftpClient(connectionInfo))
      {
          // SSH接続を行う
          client.Connect();
          // リモートPCのユーザディレクトリに移動して、
          // 任意のディレクトリ (ここでは、/home/username/testディレクトリ) にある全てのファイルをダウンロードする
          var files = client.ListDirectory("/home/username/test").Where(x => x.Name != "." && x.Name != "..");
          foreach (var file in files)
          {
            // ファイル群を個別に書き込み専用で開く
            using (var fs = System.IO.File.OpenWrite(file.Name))
            {
                // ファイル群を個別にダウンロード
                client.DownloadFile(file.FullName, fs);
            }
          }
          // SSH接続を切断
          client.Disconnect();
      }
     }
     }
  }
  }
client.Disconnect();
// ...略
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
<br><br>
172行目: 213行目:
       // 公開鍵にパスフレーズが存在する場合
       // 公開鍵にパスフレーズが存在する場合
       var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
       var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
                                                           new PrivateKeyFile(secretKeyPath, "finger_print"));
                                                           new PrivateKeyFile(secretKeyPath, "<パスフレーズ>"));
   
   
       // 公開鍵にパスフレーズが無い場合
       // 公開鍵にパスフレーズが無い場合
       //var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
       //var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
                                                            new PrivateKeyFile(secretKeyPath));
      //                                                    new PrivateKeyFile(secretKeyPath, ""));
   
   
       // パスワード認証の場合
       // パスワード認証の場合
       //var authMethod = new PasswordAuthenticationMethod("<リモートPCのユーザ名>",
       //var authMethod = new PasswordAuthenticationMethod("<リモートPCのユーザ名>",
                                                          "<リモートPCのユーザ名のパスワード>")
      //                                                  "<リモートPCのユーザ名のパスワード>")
   
   
       // 接続情報のインスタンス生成
       // 接続情報のインスタンス生成

2024年7月28日 (日) 23:45時点における最新版

概要

SFTP(Secure File Transfer Protocol)は、SSH(Secure Shell)プロトコルを使用してファイルを安全に転送するためのプロトコルの一種である。

  • セキュアな通信
    SFTPは、データ転送の際にSSHを使用するため、通信は暗号化され、セキュアである。
    データの盗聴や改竄から保護されるため、非常に安全な転送方法とされている。

  • ポート番号
    SFTPは、SSHのポート番号を使用する。
    しかし、SFTP専用のポートを使用することもできる。

  • 利用方法
    SFTPは、コマンドラインインターフェースやGUIツールを通じて使用できる。
    一般的なSFTPクライアントには、FileZilla、WinSCP、Cyberduck等が存在する。

  • アクセス権の管理
    SFTPは、SSHの認証メカニズムを使用するため、ユーザは、ユーザ名、パスワード、鍵を使用してサーバに接続する。
    アクセス権はSSHの権限設定によって管理される。

  • バッチ処理
    SFTPはバッチ処理にも適している。
    スクリプトを使用して、定期的なファイル転送や自動化されたタスクを実行できる。


C#において使用できるSSHライブラリとして、SSH.NET等がある。


libSSH / libSSH2ライブラリを使用する場合は、C/C++で記述されているため、マーシャリングして使用する必要がある。
ただし、これらの操作は煩雑であるため、SSH.NETライブラリを使用することを推奨する。


処理の流れ

  1. 認証方法のインスタンスを生成する。
    公開鍵認証またはパスワード認証を選択する。
    公開鍵認証において、SSH.NETはppk形式の鍵ファイルをサポートしていない。 (例外が発生する)
    そのため、あらかじめ、ppk形式をOpenSSH形式に変換する必要があることに注意する。

  2. 接続情報のインスタンスを生成する。
    生成した認証方法のインスタンスをコンストラクタの引数で渡す。

  3. sftpClientのインスタンスを生成する。
    接続情報のインスタンスをコンストラクタの引数に渡す。

  4. 処理を記述する。
    (ダウンロード処理やアップロード処理)


以下に示すサンプルコードでは、公開鍵認証を用いてユーザディレクトリのパスを取得するメソッドSystem.Environment.GetFolderPathを使用しているが、
Linuxでも問題なくユーザディレクトリ配下のパスを取得できる。


単一のファイルのダウンロード / アップロード

 using System;
 using System.IO;
 using Renci.SshNet;
 
 class SFTP
 {
    static void Main(string[] args)
    {
       // 公開鍵認証の場合
       // 例としてユーザディレクトリ配下の.sshディレクトリ内のsecret_key.pemを秘密鍵として使用
       string secretKeyPath = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".ssh", 
                                          "secret_key.pem");
 
       // 公開鍵にパスフレーズが存在する場合
       var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
                                                           new PrivateKeyFile(secretKeyPath, "<パスフレーズ>"));
 
       // 公開鍵にパスフレーズが無い場合
       //var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
       //                                                    new PrivateKeyFile(secretKeyPath, ""));
 
       // パスワード認証の場合
       //var authMethod = new PasswordAuthenticationMethod("<リモートPCのユーザ名>",
       //                                                  "<リモートPCのユーザ名のパスワード>");
 
       // 接続情報のインスタンス生成
       var connectionInfo = new ConnectionInfo("<リモートPCのIPアドレス または ホスト名>",
                                               <ト番号>,
                                               "<リモートPCのユーザ名>",
                                               authMethod);
 
       using (var client = new SftpClient(connectionInfo))
       {
          // SSH接続を行う
          client.Connect();
 
          // ユーザディレクトリに移動
          client.ChangeDirectory("/home/username");
 
          // test.txtファイルを読み込み専用で開く
          using (var fs = System.IO.File.OpenRead("test.txt"))
          {
             // test.txtファイルをアップロード(trueを指定すると上書き可能となる)
             client.UploadFile(fs, "test.txt", true);
          }
 
          // SSH接続を切断
          client.Disconnect();

          // SSH接続を行う
          client.Connect();
 
          // ユーザディレクトリに移動
          client.ChangeDirectory("/home/username");
 
          // test.txtファイルを書き込み専用で開く
          using (var fs = System.IO.File.OpenWrite("test.txt"))
          {
                // test.txtファイルをダウンロード
                client.DownloadFile("test.txt", fs);
          }
 
          // SSH接続を切断
          client.Disconnect();
       }
    }
 }



複数のファイルのダウンロード

SSH.NETはディレクトリ単位でダウンロードできない。
そのため、ディレクトリ内の全てのファイルをダウンロードする場青は、サーバ上にあるディレクトリのパスを指定して、個別にダウンロードする必要がある。

以下の例では、リモートPC上にある/home/username/testディレクトリ内のファイルを全てダウンロードしている。

 using System;
 using System.IO;
 using Renci.SshNet;
 
 class SftpDownloadMultipleFiles
 {
    static void Main(string[] args)
    {
       // 公開鍵認証の場合
       // 例としてユーザディレクトリ配下の.sshディレクトリ内のsecret_key.pemを秘密鍵として使用
       string secretKeyPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".ssh", "secret_key.pem");
       var authMethod = new PrivateKeyAuthenticationMethod("username", new PrivateKeyFile(secretKeyPath, "finger_print"));
 
       // 公開鍵にパスフレーズが存在する場合
       var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
                                                           new PrivateKeyFile(secretKeyPath, "<パスフレーズ>"));
 
       // 公開鍵にパスフレーズが無い場合
       //var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
       //                                                    new PrivateKeyFile(secretKeyPath, ""));
 
       // パスワード認証の場合
       //var authMethod = new PasswordAuthenticationMethod("<リモートPCのユーザ名>",
       //                                                  "<リモートPCのユーザ名のパスワード>")
 
       // 接続情報のインスタンス生成
       var connectionInfo = new ConnectionInfo("<リモートPCのIPアドレス または ホスト名>",
                                               <ト番号  : 22>,
                                               "<リモートPCのユーザ名>",
                                               authMethod);
 
       using (var client = new SftpClient(connectionInfo))
       {
          // SSH接続を行う
          client.Connect();
 
          // リモートPCのユーザディレクトリに移動して、
          // 任意のディレクトリ (ここでは、/home/username/testディレクトリ) にある全てのファイルをダウンロードする
          var files = client.ListDirectory("/home/username/test").Where(x => x.Name != "." && x.Name != "..");
          foreach (var file in files)
          {
             // ファイル群を個別に書き込み専用で開く
             using (var fs = System.IO.File.OpenWrite(file.Name))
             {
                // ファイル群を個別にダウンロード
                client.DownloadFile(file.FullName, fs);
             }
          }
 
          // SSH接続を切断
          client.Disconnect();
       }
    }
 }



複数のファイルのアップロード

以下の例では、アップロードするファイルのパスを配列で指定して、複数のファイルをリモートPC上にある/home/usernameディレクトリアップロードしている。
ループ処理内において、1つずつファイルを読み込み、UploadFileメソッドを使用する。

 using System;
 using System.IO;
 using Renci.SshNet;
 
 class SftpUploadMultipleFiles
 {
    static void Main(string[] args)
    {
       // 公開鍵認証の場合
       // 例としてユーザディレクトリ配下の.sshディレクトリ内のsecret_key.pemを秘密鍵として使用
       string secretKeyPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".ssh", "secret_key.pem");
       var authMethod = new PrivateKeyAuthenticationMethod("username", new PrivateKeyFile(secretKeyPath, "finger_print"));
 
       // 公開鍵にパスフレーズが存在する場合
       var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
                                                           new PrivateKeyFile(secretKeyPath, "<パスフレーズ>"));
 
       // 公開鍵にパスフレーズが無い場合
       //var authMethod = new PrivateKeyAuthenticationMethod("<リモートPCのユーザ名>",
       //                                                    new PrivateKeyFile(secretKeyPath, ""));
 
       // パスワード認証の場合
       //var authMethod = new PasswordAuthenticationMethod("<リモートPCのユーザ名>",
       //                                                  "<リモートPCのユーザ名のパスワード>")
 
       // 接続情報のインスタンス生成
       var connectionInfo = new ConnectionInfo("<リモートPCのIPアドレス または ホスト名>",
                                               <ト番号  : 22>,
                                               "<リモートPCのユーザ名>",
                                               authMethod);
 
       using (var client = new SftpClient(connectionInfo))
       {
          // SSH接続を行う
          client.Connect();
 
          // リモートPCのユーザディレクトリに移動
          client.ChangeDirectory("/home/username");
 
          // アップロードするファイルのパスを配列で指定
          string[] filePaths = { "/path/to/file1.txt", "/path/to/file2.jpg", "/path/to/file3.png" };
 
          foreach (string filePath in filePaths)
          {
             // ファイルを読み込み専用で開く
             using (var fs = File.OpenRead(filePath))
             {
                // ファイル名を取得
                string fileName = Path.GetFileName(filePath);
 
                // ファイルをアップロード(trueを指定すると上書き可能となる)
                client.UploadFile(fs, fileName, true);
             }
          }
 
          // SSH接続を切断
          client.Disconnect();
       }
    }
 }