能書き
私的サーバー構築日誌:仕切り直しからの自宅サーバー構築の続きです。
以前も同じネタを記事にしましたが、今回はちょっと詳細を変えています。
目標
sshを、パスワードではなく公開鍵方式で接続するようにします。
その公開鍵は$HOME/.ssh
に保管するのではなく、一ファイルに格納して集中管理する方式を試みます。
参考文献
- 自宅サーバー構築譚:SSH 公開鍵認証・公開鍵を集中管理
- OpenSSH で全ユーザの公開鍵を1ファイルで管理する - meta's blog - The Power To Serve
- LDAPSEARCH - ユーザコマンド(セクション1) - OpenLDAP 2.3 MAN ページ
- OpenLDAP - SSH公開鍵を登録してログインするまでの手順 - Qiita
- LDAPによるSSH公開鍵認証を行いたい - teratail
- 2017年版 SSH公開鍵認証で使用する秘密鍵ペアの作り方 - Qiita
サーバーの準備
スナップショット
スナップショットだいじ。超だいじ。
sudo zfs snapshot tank/root/ubuntu@$(date +%Y%m%d_%H%M%S)_before_ssh_authkey
SSH サーバー設定
公開鍵の置き場所を決めます。公開される鍵ですし、どこでも良いんですが。今回は/opt/ssh/publickeys.list
としました。
sudo mkdir /opt/ssh
sudo touch /opt/ssh/publickeys.list
publickeys.list
の中身はタブ区切りのテキストファイルとします。下記2つの項目をタブ文字で区切って1行とします。
- ユーザー名
- 公開鍵
sshd が公開鍵を取得する為のシェルスクリプトを作成します。これは自作しました。
sudo mkdir /opt/ssh/bin
cat <<"___" | sudo tee /opt/ssh/bin/ssh_authorized_key.sh >/dev/null
#!/bin/bash
look -t $'\t' $1$'\t' /opt/ssh/publickeys.list | cut -f2
___
sudo chmod +x /opt/ssh/bin/ssh_authorized_key.sh
そして Linux の伝統に則り/usr/local/bin
にシンボリックリンクを張ります。
sudo ln -s /opt/ssh/bin/ssh_authorized_key.sh /usr/local/bin/ssh_authorized_key.sh
このシェルスクリプト実行専用のユーザーアカウントが必要との事。
sudo useradd -s /usr/sbin/nologin -M sshauthkey
設定ファイルを調整して、作成したシェルスクリプトを呼び出すようにします。
同時にパスワード認証を禁止しときます。
cat <<___ | sudo tee /etc/ssh/sshd_config.d/ssh_authorized_key.conf >/dev/null
AuthorizedKeysCommand /usr/local/bin/ssh_authorized_key.sh
AuthorizedKeysCommandUser sshauthkey
AuthorizedKeysFile none
PasswordAuthentication no
___
sshdを再起動します。
sudo systemctl restart sshd
SSH接続用の鍵
ここからは、クライアントマシンとサーバーマシンの操作が少し入り組んできます。
ユーザーの選定
当然ながら、接続するユーザーはログイン可能でなければなりません。
ここまで手順通りに操作しているなら、admin
ユーザーが使える対象になります。
秘密鍵と公開鍵を生成
SSH接続の為の鍵を生成します。暗号の種類は、昨今の情勢を鑑みて楕円曲線暗号Ed25519にします。
なおssh-keygen
コマンドはWindowsも持っています。このコマンドはWindowsでも、コマンドプロンプトでそのまま実行できます。良い時代になりましたな。
ssh-keygen -t ed25519 -P ""
鍵ペアは$HOME/.ssh
ディレクトリに作成されて、それに関して問合せがありますので、何も入力せずにEnterキーを押しましょう。
>ssh-keygen -t ed25519 -P ""
Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\admin/.ssh/id_ed25519):
Your identification has been saved in C:\Users\admin/.ssh/id_ed25519.
Your public key has been saved in C:\Users\admin/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:RoiCRkTvjynwV3bHno8QenQxoteawl3zjUDcbrV6vk4 admin@client
The key's randomart image is:
+--[ED25519 256]--+
|o+ |
|... . . . . |
|..... . o = . . |
|. .. o = + . . |
|. . + S O o . |
|.. ++ B O * + |
| ..o..+ * o + E |
| .. o . o + |
| . ..+. |
+----[SHA256]-----+
公開鍵をサーバーへ送付
前回確立した手順でもって、公開鍵をサーバーへ送付します。サーバー名をprimary.home、ユーザー名をadmin
とした場合、下記のように操作します。
Windowsはsftp
コマンドも持っています。ただ、cd
コマンドのオプションが異なりますので、そこは適宜修正して下さい。
cd ~/.ssh
cd %USERPROFILE%\.ssh
sftp transporter@primary.home
cd publickey
mkdir admin
cd admin
put id_ed25519.pub
exit
サーバーで公開鍵一覧表に追加
送付された公開鍵をサーバー側で受け取ります。具体的には、公開鍵一覧表に追加してから並べ替えます。
KEYOWNER=admin
cat <(echo -n $KEYOWNER$'\t') /srv/transport/publickey/$KEYOWNER/id_ed25519.pub | sudo tee -a /opt/ssh/publickeys.list >/dev/null
sudo sort -u /opt/ssh/publickeys.list -o /tmp/publickeys.list
sudo mv /tmp/publickeys.list /opt/ssh/publickeys.list
処理が済んだ印として、サーバー側の責任で公開鍵を削除しておきましょう。
sudo rm /srv/transport/publickey/$KEYOWNER/id_ed25519.pub
sudo rmdir /srv/transport/publickey/$KEYOWNER
動作確認
動作を確認します。ssh 接続時にパスワード入力要求が無ければ成功です。
ssh admin@primary.home
仕舞い
上手くいったら/etc
を Subversion コミットしておきます。
まずは今回の差分を確認。
sudo svn st /etc
今回はユーザー追加などもあったので、下記のようになりました。
$ sudo svn st /etc
M /etc/group
M /etc/gshadow
M /etc/passwd
M /etc/shadow
? /etc/ssh/sshd_config.d/ssh_authorized_key.conf
M /etc/subgid
M /etc/subuid
M /etc/zfs/zpool.cache
問題無いようなのでコミットします。
sudo svn st /etc | grep "^?" | cut -b9- | xargs -I{} sudo find {} -type f -or -type d -or -type l | xargs -t sudo svn add
sudo svn ci /etc -m"ssh: public key authentication, prohibit password"
これで、パスワード認証ではなくて公開鍵認証方式で ssh 接続できるようになりました。その鍵は一箇所で集中管理します。