RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

SSHは公開鍵・秘密鍵を使って楽にする

こんにちは、インフラエンジニアのfro-rivです。

業務や趣味で多くのサーバにSSH接続する機会がある方は、サーバごとにパスワードを入力するのが面倒ですよね。

また、セキュリティ面の問題でSSH接続時にパスワードログインを禁止しており
公開鍵を登録する場面があったりと何かと公開鍵認証設定をする機会は多いのではないでしょうか。

今回は、公開鍵認証の設定方法だけでなく、
鍵認証設定時によく見かけるエラーについてもまとめましたので、よろしければご覧ください。

公開鍵認証とは

SSH接続やsshを使用したrsync, scpコマンドを使う際に公開鍵・秘密鍵のペアを使って
接続元のサーバが安全なものかを担保する認証方法
です。

ここでは難しい説明は省略しますが、「鍵」を持っていないと認証が成り立たないため、
パスワードログインよりも比較的安全な認証方法として知られています。

公開鍵認証設定で何が楽になるのか

SSH接続を行う際、公開鍵認証をすることでパスワード入力を行うことなくSSH接続ができます。
(公開鍵・秘密鍵を作成する際にパスフレーズを設定しないことが前提ですが...)

公開鍵認証と合わせて、~/.ssh/configファイルにサーバ情報を記載することで、更に便利になります。
~/.ssh/configファイルについては過去に記事にしていますので興味がある方はご覧ください。

過去記事:~/.ssh/configを使ってSSH接続を楽にする

公開鍵認証設定をしてみよう

使用するサーバ

今回、検証で使用するサーバの情報です。(CentOSを使用しています)

  • SSH接続を行うクライアント: client.local
  • SSH接続先として使うサーバ: server.local

公開鍵・秘密鍵ペアの作成

公開鍵・秘密鍵ペアの作成はssh-keygenコマンドを使用します。

よく使うオプション

オプション 説明
-t 暗号化形式
rsa, dsa, ecdsa, ed25519
(デフォルト: rsa)
-b ビット長
rsaの場合、4096bitくらいあった方が良い
(rsaのデフォルト: 2048bit) ​
-f 秘密鍵・公開鍵の場所を指定
秘密鍵パスの指定で、同階層に公開鍵も作成される
(デフォルト: ~/.ssh/配下)
-N パスフレーズを指定 ​

クライアントでの設定

ssh-keygenコマンドを実行し、ファイルパスやパスフレーズを対話形式で指定します。
ファイルパスの指定や、パスフレーズが必要ない場合はEnterキーを押すだけでOK
※ノンパスでログインする場合、パスフレーズは設定しないでください。

[root@client ~]# #公開鍵・秘密鍵のペアを作成する
[root@client ~]# ssh-keygen -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):                 ←←f オプションでも指定可能
Enter passphrase (empty for no passphrase):                              ←←Nオプションでも指定可能
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:9MTYgMkqHt0t0ZLL/BLW9uy4J/m+PE3Hd0TZ6HkXXXX root@client.local
The key's randomart image is:
+---[RSA 4096]----+
|     . =.     .oo|
|      B .=    ooo|
|   . = *o + ...+ |
|  o o XXXo . oo o|
| . o . =So. E..o |
|  .   . . o . o o|
|       . + o . ..|
|        +.+ .    |
|        .*=o     |
+----[SHA256]-----+
[root@client ~]# 

上記の様に問題なく公開鍵・秘密鍵ペアが作成出来たら鍵の確認をします。

ls -l ${鍵を保存しているディレクトリ}

[root@client ~]# ls -l ~/.ssh/
-rw------- 1 root root 3247  7月 15 17:17 /root/.ssh/id_rsa
-rw-r--r-- 1 root root  743  7月 15 17:17 /root/.ssh/id_rsa.pub

これで、公開鍵・秘密鍵の作成は完了です。

公開鍵の配置

次にSSH接続を行う対象のサーバにクライアントの公開鍵を設置します。

クライアントサーバ(root@client.local)の公開鍵をSSH接続先のサーバ(root@server.local)の~/.ssh/authorized_keysに登録します。
クライアントサーバ(root@client.local)で、以下を実行します。

ssh-copy-id ${ユーザ名}@${サーバ名}

[root@client ~]# ssh-copy-id root@server.local
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@server.local's password:             ←←パスワード入力だけ行えば自動で登録してくれる

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@server.local'"
and check to make sure that only the key(s) you wanted were added.

[root@client ~]# 

ssh-copy-idコマンドを使わない場合は、公開鍵(id_rsa.pub)をコピーしてSSH接続先サーバの~/.ssh/authorized_keysに張り付けましょう。

注意
.sshディレクトリ、authorized_keysファイルのパーミッションには注意してください。
.sshディレクトリは700, authorized_keysファイルは600(644でも問題なし)です。
違っていた場合はchmod ${パーミッション} ${ファイルorディレクトリ}で変更可能です。

動作確認

設定が完了したら、client.local→server.localへパスワード入力なしでSSH接続できるかを確認します。

ssh ${ユーザ名}@${サーバ名} -i ${秘密鍵のパス}
秘密鍵のパスは、デフォルト~/.ssh/id_rsaの場合省略可能。(ユーザも同じ場合は省略可)

[root@client ~]# ssh server.local
 ___
/ __| ___ _ ___ _____ _ _
\__ \/ -_) '_\ V / -_) '_|
|___/\___|_|  \_/\___|_|

Last login: Fri Jul 16 18:17:57 2021 from XXX.XXX.XXX.XXX
[root@server 18:19:04 ~]# 

できました!!!設定はこれにて完了です。

鍵認証用の公開鍵・秘密鍵を作る→SSH接続先のサーバ~/.ssh/authorized_keysに登録するだけなので案外簡単にできると思います。

よくあるエラー

次に、公開鍵認証でSSH接続しようとするときに頻発する(した)エラーをご紹介しようと思います。
これは私の経験による独断と偏見ですので当てはまらないかもしれませんが...

鍵ファイルのパーミッション(秘密鍵)

クライアント側の公開鍵ファイル(id_rsa.pub)は644秘密鍵ファイル(id_rsa)は600となっているはずですが、
秘密鍵ファイルが何らかの拍子にパーミッションが変更された場合は、chmodコマンドなどで修正しましょう。

↓↓↓ こんなエラーが出ます。

### 秘密鍵のパーミッションが644の場合
[root@client ~]# ssh server.local
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/root/.ssh/id_rsa' are too open.           ←←パーミッションが開けすぎている旨のエラーが出る
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/root/.ssh/id_rsa": bad permissions
root@server.local's password: 

authorized_keysファイルのパーミッション

SSH接続接続先サーバに設置している~/.ssh/authorized_keysファイルのパーミッションは、600にしてください。
644でも認証できますが、ほかのサーバの公開鍵が格納されていますので好ましくありません。

権限が間違っていた場合、エラーは出ませんが公開鍵認証ができないためパスワード入力が必要になります。

~/.ssh/ディレクトリのパーミッション

SSH接続先のサーバの.sshディレクトリは700パーミッションにしてください。
グループユーザ・他ユーザに書き込み権限などがあると、特にエラーは起きませんが、authorized_keysと同様に公開鍵認証できずパスワード入力を求められます。
(デフォルトではグループユーザ・他ユーザに書き込み権限は付かないのでこのエラーの頻度は少ないかもです。)

### 700(正常な場合)
[root@client ~]# ssh server.local
 ___                                                         ←←パスワード入力不要
/ __| ___ _ ___ _____ _ _
\__ \/ -_) '_\ V / -_) '_|
|___/\___|_|  \_/\___|_|

Last login: Mon Jul 19 14:38:53 2021 from XXX.XXX.XXX.XXX
[root@server 14:39:30 ~]# ls -al ./ | grep ".ssh"
drwx------.  2 root root        80  7月 15 18:39 .ssh
[root@server 14:39:46 ~]# 

### 722(書き込み権限がある場合)
[root@client ~]# ssh server.local
root@server.local's password:                                ←←パスワード入力必要
 ___
/ __| ___ _ ___ _____ _ _
\__ \/ -_) '_\ V / -_) '_|
|___/\___|_|  \_/\___|_|

Last login: Mon Jul 19 14:39:30 2021 from XXX.XXX.XXX.XXX
[root@server 14:42:08 ~]# ls -al ./ | grep ".ssh"
drwx-w--w-.  2 root root        80  7月 15 18:39 .ssh
[root@server 14:42:10 ~]# 

最後に

今回は、SSH接続の際に公開鍵認証を行う方法について紹介しました。
公開鍵認証の他にSSH接続をパスワード入力なしで行う場合は、sshpassコマンドを使用する方法などもありますが、
コンソールログにパスワードがそのまま残ってしまったり、スクリプト内でパスワードを平文で書く必要があったりとあまり好ましくありません。

設定自体は簡単ですし、sshだけでなくrsyncやscpコマンドを使用する時にもパスワードが不要になり、
非常に便利だなと思いました。

公開鍵認証設定を行った上で、~/.ssh/configへの設定も追加で行うと更に開発環境が快適になるのではないかと思います。
前回は、.ssh/configファイルについての記事を書いているのでよければご覧ください。
というわけで、SSH公開鍵認証設定方法の紹介でした。

tech-blog.rakus.co.jp

参考文献


◆TECH PLAY
techplay.jp

◆connpass
rakus.connpass.com

Copyright © RAKUS Co., Ltd. All rights reserved.