🌊

【初心者向け】最低限知っておくべき「SFTP」の基本と仕組み

に公開

はじめに

「外部システムからCSVファイルを取得してDBに取り込む」
バックエンド開発をしていると、こういった要件で SFTP を使う場面によく遭遇します。

「FTPの親戚でしょ?ライブラリを使えば簡単につながるはず」
と思って実装を始めると、意外な接続エラーや認証周りでハマることがあります。
この記事では、難しい理論は抜きにして、
「開発者が最低限知っておくべきSFTPの仕組みと実装のポイント」
を解説します。

対象者

・エンジニア初学者
・これから初めてSFTP連携機能を実装する、学習する
に絞った記事を作成しています


1. そもそもSFTPとは?(FTPとの違い)

一言で言うと、
「SSH(Secure Shell)という安全なトンネルの中でファイルを送受信する仕組み」 です。

名前に「FTP」とついていますが、FTPとは全くの別物で、
ここではFTP、SFTPの違いについて触れておきましょう。

開発者が知るべき決定的な違い

  • FTP: 平文(暗号化なし)。パスワードもデータも丸見え。ポートを2つ以上使うため、セキュリティ設定が面倒。
  • SFTP: 全暗号化。SSHポート(通常 22番)1つだけで通信する。インフラ設定がとても楽。

ポイント:
「SFTPで接続したい」と言われたら、「SSHでサーバーにログインするのと同じ仕組みを使うんだな」とイメージしてください。


2. 認証の仕組み(パスワード vs 公開鍵)

プログラムから接続する際、大きく2つの認証方式があります。

A. パスワード認証

いつものログインIDとパスワードを使う方法です。

  • メリット: 実装が簡単。
  • デメリット: ソースコードや設定ファイルに生パスワードを保存する必要が出てくるため、セキュリティリスクがある。

B. 公開鍵認証(こちらが主流)

「鍵ペア」を使う方式です。
初学者が混乱しやすいポイントですが、物理的な鍵に例えるとシンプルです。

  1. 公開鍵(Public Key): 「南京錠」 です。
    これはサーバー側に置きます(登録します)。誰に見られても大丈夫です。
  2. 秘密鍵(Private Key): 「鍵本体」 です。
    これはクライアント(あなたのプログラム)が持ちます。
    絶対に使用する側以外に見せてはいけません。

プログラムは「この秘密鍵(鍵本体)」を使って、サーバーにある「公開鍵(南京錠)」を開けることで認証します。
「パスワードがネットワーク上を流れない」ため、非常に安全です。

鍵ファイル例

主な拡張子と意味

  • key: 秘密鍵ファイルを指すことが多い
  • pub: 公開鍵ファイル
  • pem: PEM形式と呼ばれる、鍵や証明書をBase64エンコードしたテキスト形式のファイル
  • ppk: PuTTYで使用する秘密鍵の形式で、特定のソフトウェアに依存する拡張子です。
    etc

3. 実装時の最大のハマりどころ:「ホスト鍵の検証」

いざプログラム(Python, Node.js, Go, Javaなど)で接続しようとすると、最初によく出るエラーがこれです。

"Host key verification failed""Unknown Host"

これは**「接続先のサーバーが、本当に目的のサーバーか?」**を疑っているエラーです。

何が起きているのか?

皆さんがターミナルで初めてSSH接続する時、以下のようなメッセージを見たことがありませんか?

The authenticity of host 'example.com' can't be established.
Are you sure you want to continue connecting (yes/no)?

人間なら yes と打てば済みますが、プログラムは勝手に yes を押せません。そのため、エラーになります。

どう解決するか?

実装のアプローチは2つあります。

  1. 厳格な方法(推奨):
    事前にサーバーの「指紋(ホスト鍵)」を教えておく方法です。(フィンガープリント)
    known_hosts」というファイルにサーバー情報を書いておきます。
    初回接続時にその指紋を登録されるかも確認されます。

初回接続例:

$ sftp user@example.com
The authenticity of host 'example.com (93.184.216.34)' can't be established.
ED25519 key fingerprint is SHA256:AbCdEfGh...
Are you sure you want to continue connecting (yes/no/[fingerprint])?

一致を確認してyesとすると、~/.ssh/known_hostsに登録されます。
既存の登録と異なる場合は警告が出ます。むやみにyesしないでください。

  1. 緩い方法(開発時のみ):
    プログラムの設定で「ホスト鍵のチェックをしない(Auto Add Policy)」にする方法です。楽ですが、セキュリティ的には「なりすまし」のリスクがあるため、本番環境での利用は慎重にする必要があります。

4. パフォーマンスの注意点

SFTPは安全性を高めるため、接続を開始する際の手続き(ハンドシェイク)が長いです。

  • TCP接続
  • 暗号化の相談
  • ユーザー認証
  • SFTPの準備
  • ...やっとファイル転送

これには数秒かかることもあります。

【悪い実装例】
100個のファイルをダウンロードするのに、「1ファイルごとに接続→切断」を繰り返す。
激重になります。

【良い実装例】
1回接続したら、その接続(セッション)を維持したまま100個のファイルを転送し、最後に切断する。


5. よくあるトラブルと原因

実装中に動かなくなった時は、以下確認しましょう。

「Permission denied (publickey)」

原因: 公開鍵認証が失敗している

チェックポイント:

  • 秘密鍵のパーミッションが600になっているか?
  • サーバーのauthorized_keysに公開鍵が正しく登録されているか?
  • サーバー ~/.ssh/authorized_keys ファイルのパーミッションも600644になっているか?

「Connection timed out」

原因: サーバーに到達できない

チェックポイント:

  • ファイアウォールでポート22が閉じていないか?
  • サーバーのIPアドレスは正しいか?
  • ネットワークの疎通はあるか?(ping、sftpコマンドで確認)

「Host key verification failed」

原因: サーバーのホスト鍵が変わった

対処:

  • サーバーを再構築した等、正当な理由があれば記録を削除
  • 身に覚えがない場合は要注意(なりすましの可能性)

まとめ

SFTPの実装に取り組むバックエンドエンジニアへのアドバイスまとめです。

  • SFTPは 「SSH上でファイルを運ぶ」 仕組み。
  • 認証は 「公開鍵認証」 が基本。秘密鍵の管理に注意。
  • 「ホスト鍵検証(Unknown Host)」 でエラーになることを予期しておく。
  • 接続確立のコストが高いので、「コネクションは使い回す」
  • 接続できない場合は、実装以外の問題についても確認

少しでもSFTP接続に関しての学びに役立てば幸いです。

※直近、実務でJavaライブラリで実装したサンプルコードについてや、実際の接続コマンドなどの解説についての記事も投稿予定。

Discussion