.NET で SFTP の送受信を実行する
環境
- Visual Studio
-
- Visual Studio Community 2017
- Visual Studio Community 2019
- .NET Core
-
- 3.1
- .NET Framework
-
- 4
- 4.8
- SSH.NET
-
- 2016.1.0
※他のバージョンでも動作しますが未確認です
はじめに
.NET Framework (.NET Core) で SFTP によるファイルの送受信を行うためのクライアントプログラムを作成します。 SFTP 関連のプログラムは .NET には標準搭載されていないため、 ここではサードパーティーのライブラリ「SSH.NET」を使用します。
SSH.NET は最近更新されていませんが、比較的簡単にプログラムを実装でき .NET Standard にも対応しているため、利用することによるデメリットはあまりないと思います。
今回は .NET Core コンソールプロジェクトで SFTP によるファイルの送受信を行います。 SSH.NET は対応しているフレームワークが多いのでコンソール以外のプロジェクトでも実装可能です。
事前準備
- Visual Studio がインストール済みであること
- SFTP の動作を確認するための SFTP サーバーがあること
- SFTP で接続できるアカウントを用意しておくこと
- パスワード認証を行う場合は SFTP サーバーでパスワード認証を有効にすること
- 公開鍵認証を行う場合は SFTP サーバーに公開鍵を配置し、クライアントに読み込む秘密鍵(OpenSSH 形式)を用意しておくこと
SSH.NET のインストール
Visual Studio で .NET Core コンソールプロジェクトを作成します。プロジェクト名は「SshNetBasic」としておきます。
「SSH.NET」を NuGet から取得します。
パッケージが追加されました。
パスワード認証
パスワード認証の場合は「PasswordAuthenticationMethod」クラスを使用してユーザー名とパスワードを設定します。
「ConnectionInfo」クラスにホスト名 (sorceryforce.net や 192.168.0.1 など) と先ほど生成した AuthenticationMethod を設定し、 「SftpClient」クラスに渡します。
「SftpClient.Connect」メソッドで実際に接続を行い、成功すれば次の処理へ、失敗の場合は例外が投げられます。 Disconnect メソッドで接続を切ります。
// 必要な情報を設定する
var host = "";
var userName = "";
var password = "";
// 認証メソッドを作成
var authMethod = new Renci.SshNet.PasswordAuthenticationMethod(userName, password);
// 接続情報を作成
var connectionInfo = new Renci.SshNet.ConnectionInfo(host, userName, authMethod);
// SFTP クライアントを作成
var client = new Renci.SshNet.SftpClient(connectionInfo);
// 接続。失敗した場合は例外が発生
client.Connect();
// 切断
client.Disconnect();
公開鍵認証
クライアントの任意のフォルダに秘密鍵を配置します。 セットアップの Tips にも記載しましたが、秘密鍵を他のアカウントにもアクセスできるフォルダに配置していると SFTP 処理が失敗する場合があります。 必ず実行するアカウント、または Administrators 以外にアクセスできないようになっているか確認してください。
パスワード認証と違う点は認証メソッドが「PrivateKeyAuthenticationMethod」に変わったところです。
第二引数に「PrivateKeyFile」を指定し、秘密鍵を配置しているファイルパスとパスフレーズ(設定している場合)を指定します。
// 必要な情報を設定する
var host = "";
var userName = "";
var passPhrase = "";
var keyFilePath = @"C:\xxxxxxxxxx\id_rsa";
// 認証メソッドを作成
var authMethod = new Renci.SshNet.PrivateKeyAuthenticationMethod(userName,
new Renci.SshNet.PrivateKeyFile(keyFilePath, passPhrase));
// 接続情報を作成
var connectionInfo = new Renci.SshNet.ConnectionInfo(host, userName, authMethod);
// SFTP クライアントを作成
var client = new Renci.SshNet.SftpClient(connectionInfo);
// 接続。失敗した場合は例外が発生
client.Connect();
// 切断
client.Disconnect();
SFTP によるファイルの送受信
ファイルの送受信は「SftpClient.Connect」メソッドでサーバーに接続した後に送受信のコードを記述して実行します。 やっていることは「ローカルのファイルを読み込み SFTP サーバーに送信」「SFTP サーバーからファイルをダウンロードしてローカルに保存」となっており 特に難しい処理を書くことなく実装できます。
日本語のファイル名でも問題なく送受信できます。
/* ---------------- 中略 ------------------- */
var sendFilePath = @"C:\xxxxxxxxxxxx\テスト.txt";
var reseiveFilePath = @"C:\xxxxxxxxxxxx\テスト2.txt";
/* ---------------- 中略 ------------------- */
// 接続。失敗した場合は例外が発生
client.Connect();
// ファイルのアップロード(上書き)
using var sendStream = File.OpenRead(sendFilePath);
client.UploadFile(sendStream, Path.GetFileName(sendFilePath), true);
// ファイルのダウンロード(上書き)
using var reseiveStream = File.OpenWrite(reseiveFilePath);
client.DownloadFile(Path.GetFileName(sendFilePath), reseiveStream);
// 切断
client.Disconnect();
まとめ
SSH.NET を使用することにより簡単に SFTP の送受信ができるようになりました。 プログラムを実装するよりもテスト環境を整える方が時間がかかるかもしれません。
SFTP による処理は基本的に FTP とほぼ同じであり、SSH.NET でも大抵の処理は実装されていますので SFTP をプログラムで使いたい場合にはお勧めのライブラリです。