Linux / コマンド / sftp - SSHで安全にファイルを転送

sftpは、SSH(Secure Shell)接続上でファイルを転送し、リモートファイルを管理するプログラムです。基本接続形式はsftp ユーザー@ホストであり、SSHホストキーの検証や公開鍵認証をそのまま利用できます。

sftp user@example.com

SFTPは名前が似ているFTPやFTPSとは異なるプロトコルです。サーバーでSSHのSFTPサブシステムが有効になっている必要があり、通常はSSHと同じTCPポートを使用します。

SFTPの特徴と接続前の確認事項

OpenSSHのsftpは、ファイル転送を暗号化されたSSH接続で実行し、公開鍵認証、SSH設定ファイル、ジャンプホストなどのSSH機能を使用できます。全オプションと対話型コマンドはOpenSSH sftp公式マニュアルで確認できます。

  • サーバーアドレスとSSHポート
  • ログインするユーザーアカウント
  • パスワードまたはSSH秘密鍵
  • サーバーホストキーのフィンガープリントを確認する信頼できる経路
  • リモートディレクトリに対する読み取り・書き込み権限

初めて接続するときに表示されるホストキーのフィンガープリントは、サーバー管理者や信頼できる管理画面から受け取った値と比較してください。確認せずに承認すると、中間者攻撃や誤ったサーバー接続を見逃す可能性があります。

サーバーへの接続方法

基本接続

sftp user@example.com

接続されると sftp> プロンプトが表示され、対話形式のコマンドを入力できます。このプロンプトは説明のためのもので、以下のコード例にはコマンド自体のみが表示されています。

別のSSHポートを使用する

sftp -P 2222 user@example.com

SFTPのポートオプションは大文字の -P です。小文字の -p は、転送ファイルの修正時刻、アクセス時刻および権限を保持するよう要求する別のオプションであり、混同しないでください。

秘密鍵の指定

sftp -i ~/.ssh/id_ed25519 user@example.com

秘密鍵のファイルは他のユーザーが読めないように権限を制限し、可能であればパスフレーズを設定してSSHエージェントと一緒に使用してください。秘密鍵を接続先サーバーや共有ディレクトリにコピーしないでください。Ubuntu で鍵を準備する具体的な手順は、SSH 公開鍵認証の設定と接続確認で説明しています。

ローカルパスとリモートパスを区別する

SFTPの対話モードでは、リモートサーバーで実行されるコマンドとローカルコンピュータで実行されるコマンドが別々にあります。

コマンド 対象 説明
pwd リモート リモートサーバーの現在のディレクトリを表示します。
lpwd ローカル SFTPを実行したコンピュータの現在のディレクトリを表示します。
cd パス リモート リモートディレクトリを変更します。
lcd パス ローカル ローカルディレクトリを変更します。
ls リモート リモートファイルの一覧を表示します。
lls ローカル ローカルファイルの一覧を表示します。
mkdir リモート リモートディレクトリを作成します。
lmkdir ローカル ローカルディレクトリを作成します。

ファイルを間違った場所に転送しないように、作業前にpwdとlpwdを確認する習慣をつけると良いです。

ファイルをダウンロード

以下のアカウント名・ホスト名・ファイル名は例です。自分が利用できる接続先と実在するファイルに置き換え、保存先の download や uploads ディレクトリは事前に作成し、必要な権限を確認してください。既存ファイルに転送すると上書きされることがあるため、最初は専用のテスト用ディレクトリで試します。

ファイルを1つダウンロードする

get reports/daily.csv

ローカル保存パスを第2引数として指定できます。

get reports/daily.csv ./download/daily.csv

複数のファイルとディレクトリをダウンロードする

get reports/*.csv
get -R reports

ワイルドカードはリモートのファイル名に一致させることができます。ディレクトリを再帰的にダウンロードする際、SFTPはツリー内のシンボリックリンクをたどらず、サーバーとクライアントのバージョンによってサポートするオプションが異なる場合があります。

中断されたダウンロードを再開する

reget archive.tar.zst

または get -a で部分転送を再開できます。ローカルの部分ファイルがリモートファイルの先頭部分と正確に同じであることが前提なので、リモートファイルが変更されている場合は結果が破損する可能性があります。重要なファイルは転送後にチェックサムを比較してください。

ファイルをアップロードする

ファイルを1つアップロードする

put ./release.tar.zst

リモート保存パスまたは名前を第2引数として指定できます。

put ./release.tar.zst uploads/release.tar.zst

ディレクトリを再帰的にアップロードする

put -R ./assets uploads/assets

既存のファイルを上書きできるため、まずリモートパスを確認してください。複数のユーザーが同時にディレクトリを展開する場合は、一時的な名前でアップロードし、サーバーがサポートする原子的な名前変更手順を使用する方が安全です。

中断されたアップロードを再開する

reput ./large-image.img

put -aも部分アップロードの再開を試みます。リモートの部分ファイルがローカルファイルの先頭部分と一致しない場合、破損したファイルが作成される可能性があるため、変更の有無を確認し、完了後にハッシュを検証してください。

パス、空白とファイル名の扱い

空白があるパスは引用符で囲みます。

get "Monthly Reports/September Report.csv"
put "./Release Files/app package.tar.zst" uploads/

SFTPの対話型コマンドの解釈は通常のシェルと完全に同じではありません。ワイルドカードやバックスラッシュを含むファイル名は、まずリストで正確な名前を確認し、自動化では単純で予測可能なファイル名を使用する方が安全です。

SSH設定ファイルで接続情報を管理する

繰り返しオプションを Host 項目にまとめる

~/.ssh/config にエイリアス、ユーザー、ポートとキーのパスを記入すると、短く接続できます。

Host fileserver
    HostName sftp.example.com
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
sftp fileserver

設定ファイルにはパスワードや秘密鍵の内容自体を入れません。ファイル権限を制限し、システム全体の設定とユーザー設定の優先順位を確認してください。

ジャンプホストを通じて接続する

sftp -J bastion.example.com user@internal.example.com

-J は SSH の ProxyJump 機能を使用します。ジャンプホストと対象サーバー両方のホストキーをそれぞれ検証し、エージェント転送は必要な場合にだけ使用してください。

バッチモードで自動転送する

バッチファイルを作成する

たとえば upload.sftp に以下のような SFTP コマンドを保存します。

cd incoming
lcd ./exports
put report.csv report.tmp
rename report.tmp report.csv
bye

一時的な名前でアップロードした後に名前を変更すると、他のプロセスが送信中のファイルを完成版として読み取るリスクを減らすことができます。原子性は、サーバーの実装とファイルシステムに依存します。既存の report.csv を置き換えられるかもサーバーの拡張対応などで異なるため、運用前に確認してください。

バッチファイルを実行する

sftp -b upload.sftp fileserver

バッチモードは、ユーザーにパスワードを尋ねる対話に依存してはいけません。限定された専用アカウントと公開鍵認証を使用し、鍵の権限・接続元・許可されたパスをサーバーポリシーで制限してください。スクリプトやコマンドラインにパスワードを入れないでください。

失敗処理を理解する

バッチモードでは、get、put、renameなどの主要コマンドが失敗すると、通常は中断されます。コマンド前に-を付けることで失敗を無視することは可能ですが、必要なファイルが欠落したまま作業が成功したように見える可能性があるため、選択的に使用してください。

自動化では、SFTPプロセスの終了状態、送信されたファイルのサイズ、可能であればチェックサムまで確認し、失敗した場合の通知および再試行ポリシーを用意する必要があります。

セキュリティと運用チェックリスト

  • ホストキー: 初回接続時およびキー変更時には、信頼できる経路でフィンガープリントを検証します。
  • 認証: 自動化にはパスワードの代わりに、範囲が制限された公開鍵と専用アカウントを使用します。
  • 秘密鍵: 読み取り権限を最小限にし、リポジトリ、バックアップ共有フォルダやサーバーにアップロードしません。
  • パス権限: アップロードアカウントのアクセス先を必要なディレクトリに限定します。
  • 上書き: 対象パスと既存ファイルを確認し、一時名とバージョン保持ポリシーを使用します。
  • 完全性: 重要な転送は双方で信頼できるチェックサムを生成して比較します。
  • ログ: 転送の成功・失敗および対象を記録しますが、パスワード、秘密鍵、機密ファイルの内容は残しません。

SFTP、SCP、rsync 比較

ツール 適した状況 特徴
sftp 対話型ファイル管理と標準化された転送 リモートリスト、ディレクトリ移動、再開とバッチコマンドを提供します。
scp 簡単なファイルコピー コマンド1行でコピーしやすいですが、対話型リモート管理機能は制限されています。
rsync 繰り返し同期と大規模ディレクトリ 変更分の転送、除外ルールと削除同期などを提供しますが、サーバー側の対応環境も必要です。

どんなツールでもSSHを使うからといって、アカウント権限や展開手順が自動的に安全になるわけではありません。転送目的と障害復旧方式に合わせて選択してください。

よくある質問

SFTPはFTPにTLSを適用したものですか?

いいえ。SFTPはSSHファイル転送プロトコルで、SSH接続の上で動作します。FTPSはFTPにTLSを適用した別の方式であり、サーバー設定やポート構成が異なります。

Connection refused エラーが発生する理由は何ですか?

アドレスやポートが間違っているか、SSH サービスが受信していないか、またはファイアウォールが接続を拒否している可能性があります。サーバーアドレス、大文字 -P ポート、SSH サービスの状態、およびネットワークポリシーを確認してください。

Permission denied が出た場合はどうしますか?

認証自体が失敗したのか、ログイン後のファイル権限が不足しているのかを区別する必要があります。sftp -v user@example.com で接続して診断情報を確認してください。ただし、公開ログにユーザー名、パス、およびサーバー情報をそのまま共有しないでください。

アップロードが完了したかどうかはどうやって検証しますか?

終了状態とリモートファイルのサイズを確認し、重要なファイルはローカルとリモートで SHA-256 などのチェックサムを計算して比較してください。SFTP サーバーが任意のコマンド実行を許可しない制限アカウントの場合は、別の検証 API やサーバー側の処理手順が必要になることがあります。

まとめ

sftp ユーザー@ホスト に接続した後、get はダウンロード、put はアップロードに使用します。pwd と lpwd、cd と lcd を区別すると、リモートとローカルパスのミスを減らすことができます。

運用自動化では、公開鍵認証、ホスト鍵の検証、バッチ終了状態とファイルの完全性確認が重要です。パスワードをスクリプトに保存せず、専用アカウントと最小権限で送信範囲を制限してください。