OpenSSHサーバでSFTP(公開鍵認証)

直前の投稿「OpenSSHサーバでSFTP」の続きです。
前回はパスワード認証だったので、今回は公開鍵認証でユーザ認証できるようにします。

環境について

※ 前回と同じ、サーバはUbuntu を使っています。

クライアントの環境構築

キーペアの生成

公開鍵認証で使うデジタル署名Ed25519のキーペアを生成

ssh-keygen -t ed25519
→ Your identification has been saved in /Users/xxx/.ssh/id_ed25519
   Your public key has been saved in /Users/xxx/.ssh/id_ed25519.pub
  • 任意のパスフレーズを設定します
  • 生成されるキーペアは、id_ed25519 が秘密鍵、id_ed25519.pub が公開鍵
  • キーペアのファイル名を指定したい場合は、-f オプションを使って指定します(今回は指定しなかったのでデフォルトの”id_ed25519″で作成されました)

公開鍵をサーバにアップロード

前回設定したSFTP(パスワード認証)を使ってアップロードします。
※ 公開鍵 id_ed25519.pub/var/sftp/sftpuser にアップロードします。

sftp sftpuser@<hostname またはipaddress>
→パスワードを入力してユーザ認証

cd sftpuser
put ~/.ssh/id_ed25519.pub
quit

OpenSSHサーバの環境構築

前回作成したユーザ「sftpuser」のユーザ認証の方式をパスワード認証から公開鍵認証に変更します。

公開鍵の設置

SSH接続できるユーザでサーバにSSH接続して、公開鍵を設置します。

su - sftpuser
mkdir ~/.ssh
chmod 700 ~/.ssh
cat /var/sftp/sftpuser/id_ed25519.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
exit

sudo rm /var/sftp/sftpuser/id_ed25519.pub

OpenSSHサーバの設定

設定ファイルの編集

sudo vi /etc/ssh/sshd_config

設定した内容(一部抜粋)

PubkeyAuthentication yes
AllowTcpForwarding no
X11Forwarding no
Subsystem sftp  internal-sftp

Match User sftpuser
    ChrootDirectory /var/sftp
    ForceCommand internal-sftp
    PasswordAuthentication no
    AuthorizedKeysFile /home/sftpuser/.ssh/authorized_keys
  • PasswordAuthentication no により、パスワード認証ができないようにする
  • AuthorizedKeysFile で公開鍵を指定する

設定の有効化

OpenSSH サーバを再起動

sudo systemctl restart sshd

接続確認(クライアントからサーバ)

SFTP接続の確認(成功)

Mac のターミナルを使ってネットワーク経由でSFTP接続の確認

echo "test" > testfile.txt

sftp -i ~/.ssh/id_ed25519 sftpuser@<hostname またはipaddress>
→パスフレーズを入力して公開鍵認証

cd sftpuser
put testfile.txt
ls
quit

SSHとSCP接続の確認(失敗)

SSHの接続を試してみると失敗します

ssh -i ~/.ssh/id_ed25519 sftpuser@<hostname またはipaddress>
→パスフレーズを入力して公開鍵認証
→ This service allows sftp connections only.

SCPの接続を試してみると失敗します

scp -i ~/.ssh/id_ed25519 testfile.txt sftpuser@<hostname またはipaddress>:
→パスフレーズを入力して公開鍵認証
→ This service allows sftp connections only.

あとがき

パスワード認証の場合、パスワードが漏洩すると第三者がログインできてしまいますが、公開鍵認証はクライアント上に保存した暗号鍵とパスフレーズの両方が第三者の手に渡らなければ第三者によるログインが成功しないので、より安全なユーザ認証の方式といえると思います。

設定がパスワード認証に比べると面倒かもしれませんが、なるべく公開鍵認証を使うようにした方がよいのでしょう。

OpenSSHサーバでSFTP

クライアント上のファイルをサーバにSFTPでアップロードできるようにします。
今回解説する手順は、SFTP専用のユーザを作成して、Chrootにより限定された場所にファイルをアップロードできるようにする手順となります。

環境について

サーバ側の環境

  • Ubuntu
  • OpenSSHサーバ ※インストール済み

クライアント側の環境

  • macOS Monterey

OpenSSHサーバの環境構築

SFTP専用ユーザーの作成

sudo adduser sftpuser

ユーザ認証はパスワード認証を使うので、任意のパスワードを設定します。
※ 公開鍵認証も可能ですが、SFTP中心の解説にしたいので省略します。

SFTP専用グループの作成

sudo groupadd sftponly

ユーザをグループに追加 ※セカンダリグループ

sudo adduser sftpuser sftponly

SFTP専用ディレクトリの作成

SFTP専用ディレクトリの作成 ※Chrootディレクトリ

sudo mkdir /var/sftp
sudo chown root:root /var/sftp

SFTP専用ユーザのディレクトリの作成 ※ここにアップロードする

sudo mkdir /var/sftp/sftpuser
sudo chown sftpuser:sftponly /var/sftp/sftpuser
sudo chmod 755 /var/sftp/sftpuser

OpenSSHサーバの設定

設定ファイルの編集

sudo vi /etc/ssh/sshd_config

/etc/ssh/ssh_config というファイルもあるけれども、設定するのは/etc/ssh/sshd_config

設定した内容(一部抜粋)※既存の設定の変更やコメントアウトなど

AllowTcpForwarding no
X11Forwarding no
Subsystem sftp  internal-sftp

設定した内容 ※末尾に追記

Match User sftpuser
    ChrootDirectory /var/sftp
    ForceCommand internal-sftp
    PasswordAuthentication yes
  • ChrootDirectory は、SFTP接続した際のルートディレクトリを/var/sftp に設定する
  • ForceCommand internal-sftp により、SFTP の利用に限定する(SSHとSCPが使えない)
  • ChrootDirectoryForceCommand internal-sftp の両方を設定することでChroot とSFTP 限定が有効になるようです

設定の有効化

OpenSSH サーバを再起動

sudo systemctl restart sshd

接続確認

サーバのローカル環境上でのSFTP接続の確認

sftp sftpuser@localhost

接続確認(クライアントからサーバ)

SFTP接続の確認(成功)

Mac のターミナルを使ってネットワーク経由でSFTP接続の確認

echo "test" > testfile.txt

sftp sftpuser@<hostname またはipaddress>
→パスワードを入力してユーザ認証

pwd
→ Remote working directory: /
put testfile.txt
→ remote open("/testfile.txt"): Permission denied
cd sftpuser
put testfile.txt
ls
quit
  • 接続した時点のカレントディレクトリは/var/sftp がルートディレクトリとなっていて、ディレクトリの所有者とグループがroot なのでput でファイルをアップロードしようとすると失敗します。
  • cd でカレントディレクトリを/var/sftp/sftpuser に変えてからput するとアップロードが成功します。

SSHとSCP接続の確認(失敗)

SSHの接続を試してみると失敗します

ssh sftpuser@<hostname またはipaddress>
→ This service allows sftp connections only.

SCPの接続を試してみると失敗します

scp testfile.txt sftpuser@<hostname またはipaddress>:
→ This service allows sftp connections only.

あとがき

ChrootDirectory/var/sftp としましたが、ユーザのホームディレクトリ/home/sftpuser を指定してもよさそうです。

SFTPでファイルのアップロード・ダウンロードをするのが専用のユーザなので、SSH接続できるユーザがそのファイルのコピー等をするのにどこが運用上望ましいかで判断する感じでしょうか。