前回は、パスフレーズを設定したSSH接続を rsyncと組み合わせてセキュアな同期を実現しました。これに対して、今回は、あえてパスフレーズを設定しないけど、安全性を高める方法をご紹介します。
実行コマンドの制約
実行コマンドの制約とは、パスフレーズを設定していないペア鍵に対して、特定のコマンドだけを実行するよう制約を設けることで、万が一鍵が盗まれたとしても、特定のコマンド以外は受け付けないようにするものです。
具体的には、rsync
コマンドをSSH接続で実行する場合、ローカル側でrsync
を実行すると、リモート側でもrsync
が実行され、2つのrsync
コマンドが通信することで同期がおこなわれます。この機能を利用して、特定のコマンドのみを実行するよう、公開鍵(authorized_keys
)に制約を設定して、安全性を高めます。
ここから先は、具体的な手順を紹介していきますが、今回の作業は、前回の記事にしたがって、既にパスフレーズを設定したSSH鍵を導入している前提で記事を書いているので、あしからず。また、環境変数の例も前回と同じです。
パスフレーズなしの公開鍵と秘密鍵をローカルに生成
前回生成したパスフレーズ付きの鍵とは別に、rsync
自動実行用にパスフレーズをしていない鍵ペアを作成します。デフォルトのファイル名ではなく、その利用用途が分かるようなファイル名にします。なお、ファイル名の指定には、-f
オプションを使います。
cd ~/.ssh
# -fオプションの後ろにファイル名を指定して鍵を生成
ssh-keygen -t ecdsa -b 384 -C "rsyncHomePC" -f id_ecdsa_for_rsync
# パスフレーズを空のまま鍵を作成
# 秘密鍵(id_ecdsa_for_rsync)と公開鍵(id_ecdsa_for_rsync.pub)の生成を確認
ls -l
-rw------- 1 yourId yourId 288 Jul 30 23:23 id_ecdsa_for_rsync
-rw-r--r-- 1 yourId yourId 216 Jul 30 23:23 id_ecdsa_for_rsync.pub
ちなみに、同じフォルダ内のknown_hosts
は、接続したことのあるサーバのSSHサーバ証明書が格納されているファイルです。
パスフレーズなしの公開鍵をサーバにアップロード
生成したパスフレーズなしの公開鍵(id_ecdsa_for_rsync.pub
)をscp
コマンドでアップロード。ここでは、authorized_keys
を上書きしないように、ファイル名は変更せずにアップロードします。
scp /home/yourId/.ssh/id_ecdsa_for_rsync.pub hogeId@hogehoge.sakura.ne.jp:/home/hogehoge/.ssh
# パスフレーズを入力してEnter
id_ecdsa_for_rsync.pub 100% 222 0.2KB/s 00:00
既存の公開鍵にパスフレーズなしの公開鍵を追加
既に設置している公開鍵(authorized_keys
)にパスフレーズなしの公開鍵(id_ecdsa_for_rsync.pub
)の内容を追加します。
# SSHでログイン
$ ssh hogeId@hogehoge.sakura.ne.jp
# パスフレーズを入力してEnter
Welcome to FreeBSD!
% # ログイン成功
# 公開鍵(authorized_keys)にパスフレーズなしの公開鍵(id_ecdsa_for_rsync.pub)の内容を追加
% cat ~/.ssh/id_ecdsa_for_rsync.pub >> ~/.ssh/authorized_keys
# ちゃんと追加されたか確認
% cat ~/.ssh/authorized_keys
ecdsa-sha2-nistp384 《省略》 HomePC
ecdsa-sha2-nistp384 《省略》 rsyncHomePC # <-- 追加されている
# id_ecdsa_for_rsync.pubを削除
% rm -f ~/.ssh/id_ecdsa_for_rsync.pub
# このまま次の作業へ
%
指定したコマンドが実行されるか確認
テスト用に ls コマンドを記述
指定したコマンドがちゃんと実行されるか確認するため、authorized_keys
に追加した鍵の前に command="ls"
を追記します。ここではリモートで書き換えてますが、ローカルで書き換えたものをアップロードしても大丈夫です。
# 前の作業の続き
# authorized_keysにテストコマンドを設定
% vi ~/.ssh/authorized_keys
# viで追加した鍵の手前にcommand="ls" を挿入して保存
ecdsa-sha2-nistp384 《省略》 HomePC
command="ls" ecdsa-sha2-nistp384 《省略》 rsyncHomePC # <-- 追加した行の先頭にcommandを挿入
~
~
~
# ログアウト
% exit
テストします
パスフレーズなしの秘密鍵(id_ecdsa_for_rsync
)を使って SSH接続して、ls
が実行されて、コネクションが切断されたら成功です。
ssh -i ~/.ssh/id_ecdsa_for_rsync hogeId@hogehoge.sakura.ne.jp
# lsが実行され、コネクションが切断されたら成功
Connection to hogehoge.sakura.ne.jp closed.
実際に使用する rysncコマンドを確認
リモート先で実行されるrysnc
のコマンドを確認するには、実行したいコマンドに -vv
オプションを追加したものを実行します。あと、パスフレーズなしの秘密鍵を使ってSSH接続するためのオプション(-e "ssh -i /home/yourId/.ssh/id_ecdsa_for_rsync"
)を付けるのも忘れずに。
# 通常のrsyncコマンドに -vv コマンドを追加して実行
$ rsync -vv -avz --update --delete --exclude='.htaccess' --chmod=D0755,F0644 -e "ssh -i /home/yourId/.ssh/id_ecdsa_for_rsync" /mnt/《自分なりのPath》/public/ hogeId@hogehoge.sakura.ne.jp:/home/hogeId/www/
# すると、このようにリモート先で実行されるコマンドが確認できます
opening connection using: ssh -i /home/yourId/.ssh/id_ecdsa_for_rsync -l hogeId hogehoge.sakura.ne.jp rsync --server -vvvulogDtprze.iLsfx --delete . /home/hogeId/www/ (12 args)protocol version mismatch -- is your shell clean?
(see the rsync man page for an explanation)
rsync error: protocol incompatibility (code 2) at compat.c(176) [sender=3.1.1]
[sender] _exit_cleanup(code=2, file=compat.c, line=176): about to call exit(2)
rsync --server
から /home/hogeId/www/
までの -vv
オプションを除いた部分がリモート先で実行されるコマンドになります。この部分をcommand=""
制約に入れることになります。(当然、本番のコマンドも -vv
オプションを外したものを実行します)
command="rsync --server -vulogDtprze.iLsfx --delete . /home/hogeId/www/"
実行コマンドの制約を記載
テストでcommand="ls"
と記述していた部分を先ほどのコマンド制約に書き換えて、設定したrsync
コマンドを実行します。問題なければ、パスフレーズなしで同期が完了するはずです。
これで、設定したrsync
コマンドで実行した場合はパスフレーズなしで同期がおこなわれ、その他のSSH接続時にはパスフレーズを入力してログインできるようになります。
その他の制約を追加
先の 実行コマンドの制約を含め、公開鍵(authorized_keys
)に対して使用できるオプションが man sshd
の AUTHORIZED_KEYS FILE FORMAT
に書かれています。その中から、今回は、下記のオプションを付けて、もう少し安全性を高めることにしました。
- 接続元ホストの指定(from="《接続元アドレス》")
- ポートフォワーディング禁止(no-port-forwarding)
- X11(画面)転送の禁止(no-X11-forwarding)
- 仮想端末の割り当てを禁止(no-pty)
- 認証エージェントの転送禁止(no-agent-forwarding)
先ほど追加したコマンド制約の前(後ろでも可)に追加のオプションを記述します。オプションが複数ある場合はカンマで区切り、各オプションの間には、二重引用符で囲まれた部分を除き、スペースを入れないようにします。
最終的な公開鍵(authorized_keys
)の内容がこちら。
ecdsa-sha2-nistp384 《省略》 HomePC # パスフレーズありの鍵
from="《接続元アドレス》",no-port-forwarding,no-X11-forwarding,no-pty,no-agent-forwarding,command="rsync --server -vulogDtprze.iLsfx --delete . /home/hogeId/www/" ecdsa-sha2-nistp384 《省略》 rsyncHomePC # パスフレーズなしの鍵
rsyncの実行
そして、最終的なrsync
コマンドの内容がこちら。
rsync -avz --update --delete --exclude='.htaccess' --chmod=D0755,F0644 -e "ssh -i /home/yourId/.ssh/id_ecdsa_for_rsync" ${HUGO_DIR}/public/ hogeId@hogehoge.sakura.ne.jp:/home/hogeId/www/
おしまい
コメント
コメントなどありましたら、GitHubのディスカッションへお願いします。(書き込みには、GitHubのアカウントが必要です)