Linuxシステムにおけるキー認証に基づくSSHサービスのプロセス

Linuxシステムにおけるキー認証に基づくSSHサービスのプロセス

ご存知のとおり、SSH は現在、リモート ログイン セッションやその他のネットワーク サービスにセキュリティを提供するために設計された最も信頼性の高いプロトコルです。デフォルトでは TCP ポート 22 で動作します。具体的な実装ソフトウェアには、OpenSSH (CentOS にデフォルトでインストール) と DropBear があります。 SSH プロトコルには現在、v1 と v2 の 2 つのバージョンがあります。v1 は MAC 用の CRC-32 に基づいており、安全ではありません。 v2 では、キー交換に DH アルゴリズムを使用し、ID 認証に RSA または DSA を使用します。したがって、現在人気のある Linux バージョンのほとんどはバージョン V2 を使用しています。

SSH について簡単に理解した後、2 つのユーザー ログイン認証方法について説明しましょう。1 つ目は、ユーザー名とパスワードに基づく認証方法です。この認証方法は誰もが知っているはずです。リモート Linux システムにログインする場合は、対応するユーザー名とパスワードを入力してリモート Linux システムにログインする必要があります。この方法は対話型ログインです。 2 つ目は、今日お話しするキーベースの認証方法です。

まず、SSH暗号化通信のプロセスを理解しましょう

上の図からわかるように、クライアントにはキー ペアが存在する必要があります。キーはペアで表示され、A の公開キーで暗号化されたものを復号化できるのは A の秘密キーのみであることは誰もが知っています。非対称暗号化のこの機能があるからこそ、SSH 通信でもデータのセキュリティを確保するためにこの機能が使用されていることは理解しやすいのです。サーバー側にも公開鍵と秘密鍵のペアがあり、その目的もデータの暗号化と復号化です。 SSH 暗号化通信のプロセスは、おおよそ次のようになります。クライアントがサーバーとの通信を暗号化する場合、クライアントはまずサーバーの公開鍵を取得する必要があります。サーバーの公開鍵を取得したら、サーバーの公開鍵を使用して送信データを暗号化し、サーバーに送信します。サーバーは暗号文データを受信すると、独自の秘密鍵を使用してそれを復号化し、クライアントからサーバーへのデータ暗号化を実現します。同様に、サーバーがクライアントにデータを送信するプロセスも同じです。サーバーはクライアントの公開鍵を取得し、クライアントの公開鍵でデータを暗号化してクライアントに送信します。クライアントは自分の秘密鍵でデータを復号化することで、あなたと私の間で暗号化された通信を実現します。

考えてみましょう。サーバーとクライアントは通信時に互いの公開鍵を使用してデータを暗号化しますが、クライアントはどのようにしてサーバーの公開鍵を取得するのでしょうか?サーバーはどのようにしてクライアントの公開鍵を取得するのでしょうか?

サーバーとクライアントが初めて接続するときの公開鍵交換プロセスを見てみましょう。

まず、クライアントは ssh 接続要求をサーバーに送信します。要求を受け取った後、サーバーは公開鍵とセッション ID をクライアントに送信します。クライアントはサーバーから公開鍵を受け取った後、自身の公開鍵とサーバーから送信されたセッション ID を XOR し、その結果をサーバーの公開鍵で暗号化してから、暗号化された暗号文をネットワーク経由でサーバーに送信します。サーバーはクライアントから送信された暗号文を受け取った後、自身の秘密鍵で復号化し、その結果を以前のセッション ID と XOR して、最終的にクライアントの公開鍵を取得します。このようなプロセスを経て、クライアントはサーバーの公開鍵を取得し、サーバーもクライアントの公開鍵を取得します。お互いの公開鍵を取得した後、後で相手の公開鍵を使用してデータを暗号化できます。

Linux を使用したことがある人なら誰でも、サーバーとの SSH リモート接続を初めて確立するときに、接続を続行するかどうかの確認を求められることを知っているでしょう。yes と入力した後でのみ、パスワードを入力できます。なぜこれを行うのでしょうか?実際、サーバーが自身の公開鍵をクライアントに送信する場合、クライアントは受信した公開鍵が他のサーバーから送信されたものであるかどうかを確認する方法がないため、受信した公開鍵に対して md5 と sha256 を実行し、公開鍵のフィンガープリントを抽出して、「md5 が xxx である公開鍵を受信しました。この公開鍵を確認しますか?」というプロンプトを表示します。確認すると、この公開鍵がサーバーから送信されたと信じていることになります。この方法では、次の操作を実行できます。独自の公開鍵とセッション ID を XOR し、その結果を受信した公開鍵で暗号化します。公開鍵がサーバーからではなくハッカーから送信され、それが確認された場合、ハッカーは後続の暗号文を入手した後、自分の秘密鍵を使用してそれを復号化し、クライアントの公開鍵とデータを取得すると考えられます。その後、実際のデータを入手した後、ハッカーはそれを自由に変更し、サーバーの公開鍵で暗号化してサーバーに送信できます。このように、サーバーが取得したデータは、ハッカーによって変更されたデータであり、クライアントから送信された実際のデータではありません。これは中間者攻撃と呼ばれ、自分の公開鍵を使用してサーバーとクライアントの役割を偽装します。

SSH 暗号化通信とキー交換のプロセスを理解したので、ユーザー名、パスワード、キーに基づく SSH ログイン検証のプロセスを見てみましょう。

ユーザー名とパスワードに基づくログインのプロセスは次のとおりです。まず、クライアントが SSH 接続要求を開始し、サーバーは公開鍵をクライアントに送信します。クライアントはサーバーの公開鍵を受け取った後、サーバーの公開鍵でパスワードを暗号化し、サーバーに送信します。サーバーは暗号化されたパスワードを受け取り、独自の秘密鍵で復号化して、クライアントから送信されたパスワードを取得します。次に、このパスワードを検証に使用し、検証結果をクライアントの公開鍵で暗号化してクライアントに送信します。結果を受け取った後、クライアントは独自の秘密鍵で復号化して、検証プロセスを完了します。検証に合格すると、クライアントは正常にログインしますが、そうでない場合はクライアントのログインは失敗します。

キーベースのログイン検証のプロセスは次のとおりです。クライアントはキーペアを生成する必要があります(このキーペアは、ホストの公開キーではなくユーザー向けです。上記のものは公開キーであり、ホストの公開キーです)。クライアントがSSH接続要求を開始すると、そのユーザーのホームディレクトリの承認型ファイルがありますサーバーは、クライアントから送信されたランダムな文字を受信します。これは、以前に送信されたランダム文字と同じ場合、サーバーはパスワードのないログインを許可します。

上記の紹介から、キー検証に基づいてログインする場合、クライアントでユーザー キー ペアを生成し、生成されたユーザー公開キーをサーバー上のユーザーのホーム ディレクトリにある .ssh/authorized_keys ファイルに配置する必要があることが簡単にわかります。このユーザーは、将来サーバーにログインするためのキー検証に使用するユーザーです。次に、いくつか実験してみましょう。

1. クライアント上でユーザーキーペアを生成する

[qiuhom@docker ~]$ssh-keygen -t rsa
公開/秘密 RSA キー ペアを生成しています。
キーを保存するファイル (/home/qiuhom/.ssh/id_rsa) を入力します。
パスフレーズを入力してください (パスフレーズがない場合は空白):
同じパスフレーズをもう一度入力してください:
あなたの識別情報は /home/qiuhom/.ssh/id_rsa に保存されました。
公開鍵は /home/qiuhom/.ssh/id_rsa.pub に保存されました。
キーのフィンガープリントは次のとおりです。
SHA256:CbICoBfN3670ucEBjhDR/ltyYoe/jJMIWCkCK5Lt5eA qiuhom@docker
キーのランダムアート画像は次のとおりです。
+---[RSA 2048]----+
|. += |
|+ o+ |
|++oo..o. |
|ボ=.o=.o..|
|+*.+o..oS |
|. E.. B.=. |
| . + %o. |
| . =o+. |
| ..+o |
+----[SHA256]-----+
[qiuhom@docker ~]$ll .ssh/
総投与量 8
-rw------- 1 qiuhom qiuhom 1675 11月 2日 16:54 id_rsa
-rw-r--r-- 1 qiuhom qiuhom 395 11月2日 16:54 id_rsa.pub
[qiuhom@docker ~]$

注: Linux では、ssh-keygen コマンドを使用してユーザー キー ペアを生成します。-t オプションは、キーの生成に使用される暗号化アルゴリズムを示します。生成されたキー ペアは、デフォルトでは現在のユーザーのホーム ディレクトリの .ssh/ ディレクトリに配置されます。それぞれ id_rsa と id_rsa.pub と呼ばれます。名前から、id_rsa が秘密キーで、id_rsa.pub が公開キーであることがわかります。注意深く見れば、ssh-keygen を使用してキーを生成するときに、キー ファイルを保存する場所を尋ねられることに気付いたはずです。デフォルトは、現在のユーザーのホーム ディレクトリの下の .ssh ディレクトリです。もちろん、-f オプションを使用して保存場所を指定することもできます。また、パスワードの入力も求められます。ここでのパスワードは、秘密鍵を暗号化するためのパスワードを表します。相手の秘密鍵を入手するのは非常に危険であることは誰もが知っているので、デフォルトではシステムがプロンプトを表示します。Enter キーを押すと、生成された秘密鍵は暗号化されていないことを意味します。もちろん、-P (大文字) オプションを使用して、秘密鍵を暗号化するためのパスワードを指定することもできます。

2. ユーザーが生成した公開鍵を、サーバー上のユーザーのホームディレクトリにある .ssh/authorized_keys に配置します。 scp コマンドを使用してサーバーに配置するか、USB フラッシュドライブ経由でコピーすることもできますが、これは面倒です。ここでは、特別なツール ssh-copy-id を使用して、ユーザーの公開鍵ファイル情報をサーバー上の対応するユーザー ホーム ディレクトリにコピーします。

[qiuhom@docker ~]$ssh-copy-id -i .ssh/id_rsa.pub [email protected]
/usr/bin/ssh-copy-id: INFO: インストールされるキーのソース: ".ssh/id_rsa.pub"
ホスト '192.168.0.151 (192.168.0.151)' の信頼性を確立できません。
RSA キーのフィンガープリントは SHA256:GuKvtBmWnYyxogf1nyNvp02ccon/doAKhVdF7Qy7PvA です。
RSA キーのフィンガープリントは MD5:88:cf:f9:df:37:16:d7:e2:c4:99:a4:97:ab:49:f0:8e です。
本当に接続を続行しますか (はい/いいえ)? はい
/usr/bin/ssh-copy-id: INFO: すでにインストールされているキーを除外するために、新しいキーでログインしようとしています
/usr/bin/ssh-copy-id: INFO: インストールするキーが 1 つ残っています -- ここでプロンプトが表示された場合は、新しいキーをインストールしてください
[email protected]のパスワード:
 
追加されたキーの数: 1
 
ここで、「ssh '[email protected]'」を使用してマシンにログインしてみます。
必要なキーだけが追加されたことを確認します。
 
[qiuhom@docker ~]$

注: -i オプションは、公開鍵ファイルの保存場所を指定します。デフォルトは、現在のユーザーのホーム ディレクトリ内の .ssh/公開鍵ファイル名です。 公開鍵をコピーする前はサーバーにクライアント ユーザーの公開鍵がないため、ユーザーの公開鍵をコピーするときに確認用のパスワードを入力する必要があります。ここで注意すべき点は、私たちの実験のサーバー側の sshd サービスは、デフォルトでポート 22 で動作することです。デフォルトのポートで動作しない場合は、-p (小文字) オプションを使用してポートを指定する必要があります。

この時点で、SSH キーベースのパスワード不要のログイン認証が完了しました。

上で述べたキーの生成と発行はすべて手動で行われるため、サーバーが 1 台または 2 台であれば問題ありませんが、サーバーがさらに多い場合はどうなるでしょうか。多数のサーバーを管理する必要がある場合は、スクリプトを記述して完了する必要があります。以下は私が記述したスクリプトです。実装する機能は、キーを自動的に生成し、指定されたホストに自動的に送信することです。

[qiuhom@docker ~]$cat ssh_keygen.sh
#!/bin/bash
 
リモートホストIP=$1
リモートホストユーザー=$2
リモートホストポート=$3
リモートホストパスワード=$4
ローカル rsa ファイル = ~/.ssh/id_rsa
local_rsa_pub_file=~/.ssh/id_rsa.pub
 
[ $# -ne 4 ] && echo "使用法: sh $0 RemotehostIp RemotehostUser RemotehostPort RemotehostPasswd" && exit 5
 
[ ! -e ${local_rsa_file} ] && ssh-keygen -t rsa -P '' -f ${local_rsa_file} >/dev/null 2>&1
 
<< EOF を期待する
タイムアウトを10に設定
ssh-copy-id -i ${local_rsa_pub_file} $remote_host_user@$remote_host_ip -p $remote_host_port を生成します。
期待する {
 「(はい/いいえ)?」{「はい\n」を送信;exp_continue}
 "パスワード: " {"$remote_host_passwd\n" を送信}
}
EOFを期待する
終了

注: このスクリプトでは、リモート サーバーの IP、リモート ホスト ユーザー、リモート ホストの SSH ポート、およびパスワードを渡す必要があります。このスクリプトは、キーを自動的に生成し、指定されたサーバーに送信します。キーをさらに多くのサーバーに送信する必要がある場合は、このスクリプトを呼び出す別のスクリプトを作成して、キー ファイルのバッチ作成と配布の機能を実現できます。

テスト:

スクリプトを使用してキーファイルを生成し、指定されたサーバーに送信します。

[qiuhom@docker ~]$ll .ssh/
合計使用量 0
[qiuhom@docker ~]$ssh [email protected]
ホスト '192.168.0.151 (192.168.0.151)' の信頼性を確立できません。
RSA キーのフィンガープリントは SHA256:GuKvtBmWnYyxogf1nyNvp02ccon/doAKhVdF7Qy7PvA です。
RSA キーのフィンガープリントは MD5:88:cf:f9:df:37:16:d7:e2:c4:99:a4:97:ab:49:f0:8e です。
本当に接続を続行しますか (はい/いいえ)? はい
警告: '192.168.0.151' (RSA) が既知のホストのリストに永続的に追加されました。
[email protected]のパスワード:
[root@test ~]#ll .ssh/
総投与量 4
-rw------- 1 root root 0 11月2日 17:43 authorized_keys
-rw-r--r-- 1 ルート ルート 1202 10月 31日 21:25 known_hosts
[root@test ~]#rm -rf .ssh/*
[root@test ~]#ll .ssh/
合計使用量 0
[root@test ~]#終了
ログアウト
192.168.0.151 への接続が閉じられました。
[qiuhom@docker ~]$rm -rf .ssh/*
[qiuhom@docker ~]$sh ssh_keygen.sh 192.168.0.151 ルート 22 管理者
ssh-copy-id -i /home/qiuhom/.ssh/id_rsa.pub [email protected] -p 22 を生成します。
/usr/bin/ssh-copy-id: INFO: インストールされるキーのソース: "/home/qiuhom/.ssh/id_rsa.pub"
ホスト '192.168.0.151 (192.168.0.151)' の信頼性を確立できません。
RSA キーのフィンガープリントは SHA256:GuKvtBmWnYyxogf1nyNvp02ccon/doAKhVdF7Qy7PvA です。
RSA キーのフィンガープリントは MD5:88:cf:f9:df:37:16:d7:e2:c4:99:a4:97:ab:49:f0:8e です。
本当に接続を続行しますか (はい/いいえ)? はい
/usr/bin/ssh-copy-id: INFO: すでにインストールされているキーを除外するために、新しいキーでログインしようとしています
/usr/bin/ssh-copy-id: INFO: インストールするキーが 1 つ残っています -- ここでプロンプトが表示された場合は、新しいキーをインストールしてください
[email protected]のパスワード:
 
追加されたキーの数: 1
 
ここで、「ssh -p '22' '[email protected]'」を使用してマシンにログインしてみます。
必要なキーだけが追加されたことを確認します。
 
[qiuhom@docker ~]$ll .ssh/
総投与量 12
-rw------- 1 qiuhom qiuhom 1675 11月 2日 17:53 id_rsa
-rw-r--r-- 1 qiuhom qiuhom 395 11月2日 17:53 id_rsa.pub
-rw-r--r-- 1 qiuhom qiuhom 395 11月2日 17:53 known_hosts
[qiuhom@docker ~]$ssh [email protected]
[root@test ~]#ll .ssh/
総投与量 4
-rw------ 1 ルート ルート 395 11月 2日 17:53 authorized_keys
[root@test ~]#cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6yfNtYfGtwyZLKuffYgFoMZfEnKhpsp1pH3Mky1UGBsUNRGHIhNZzbtVNERWkAV/NndasfHss/vEnDSHVOXRScRfH7pPCNdVdy887WlSgshG6U5UIsQnlxlkUxf0ciVlc9VEw/IIg8eXrlOmcuezadxGc32yHB7o+zkEcg7UBYClDtjp5xqzrHyLDMd5OhGqMPJO+d+OFKqhOOYAUYsUi00aM1qNbf+KHFhYbQQj96UbWRTNQYFnqIJltvDPxqq7W5GGVl0xma6PSgGYMFNwIy9PhJJ8Lxaiaw3FjC8iCWrjzRONbnaqMPqrS8wQXs95vRDi2M0egKUuRlzFjGAGB qiuhom@docker
[root@test ~]#終了
ログアウト
192.168.0.151 への接続が閉じられました。
[qiuhom@docker ~]$cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6yfNtYfGtwyZLKuffYgFoMZfEnKhpsp1pH3Mky1UGBsUNRGHIhNZzbtVNERWkAV/NndasfHss/vEnDSHVOXRScRfH7pPCNdVdy887WlSgshG6U5UIsQnlxlkUxf0ciVlc9VEw/IIg8eXrlOmcuezadxGc32yHB7o+zkEcg7UBYClDtjp5xqzrHyLDMd5OhGqMPJO+d+OFKqhOOYAUYsUi00aM1qNbf+KHFhYbQQj96UbWRTNQYFnqIJltvDPxqq7W5GGVl0xma6PSgGYMFNwIy9PhJJ8Lxaiaw3FjC8iCWrjzRONbnaqMPqrS8wQXs95vRDi2M0egKUuRlzFjGAGB qiuhom@docker
[qiuhom@docker ~]$

注: スクリプトを実行する前に、サーバーにログインするためのパスワードを手動で入力する必要があることがわかります。スクリプトを実行すると、ユーザー キー ファイルが作成され、ユーザー公開キー ファイルが対応するサーバーに送信されます。

要約: SSHキーベースの認証には次のような利点があります

1. より安全で便利。面倒なユーザーパスワードを覚える必要はなく、パスワード漏洩を心配する必要もありません。 (sshd サービスを設定して、KEY 認証に基づくログインのみを許可することができます)

2. キー検証に基づくパスワードフリーのログインにより、サーバーのリモートバッチ操作を実現できます。これはスクリプトの作成に便利で、リモート操作コマンド(scp、sshなど)を実行するときに、ローカルでコマンドを実行するのと同じくらい簡単です。

3. ブルートフォースパスワード推測の脅威を効果的に防止します。

要約する

以上が、編集者が紹介した Linux システムでの SSH サービスのキー認証実践のプロセスです。皆様のお役に立てれば幸いです。

以下もご興味があるかもしれません:
  • Linux ssh サービス情報と実行ステータスを表示する方法
  • Python の Paramiko モジュールは、Linux サーバーにログインするための SSH 接続を実装します。
  • Windows で winscp とバッチ処理を使用して、SSH ポート経由で Linux サーバーにファイルをアップロードする
  • PHPでLinuxコマンドを実行し、SSHサービスを開始する例
  • Linux 構成 SSH パスワードフリーログイン「ssh-keygen」の基本的な使い方
  • Linux の SSH 使用状況の詳細な分析 (主要なログイン詳細)

<<:  MySQLで一意のサーバーIDを生成する方法

>>:  Vue バックグラウンドでステータス ラベルをエレガントに記述する例

推薦する

MySQL データベースの型変換のための CAST 関数と CONVERT 関数の説明

MySQL のCAST()およびCONVERT()関数を使用すると、ある型の値を取得し、別の型の値を...

HTMLの水平線注釈とコードコメントの使い方をマスターするだけです

水平線<hr /> タグを使用して、現在の位置に水平の分割線を描画します。例: XML/...

HTMLページ作成に関する私の経験の簡単な要約

Word of Mouth に入社して 3 ~ 4 か月が経ちました。仕事の中で一番の収穫は、ビジュ...

LinuxにNginxをインストールする正しい手順

序文私のように、Java バックエンドに勤勉な人であれば、多数のプロジェクト機能を実装することに加え...

ウェブサイトのユーザビリティを向上させる10のヒント

企業の Web サイト、個人のブログ、ショッピング Web サイト、ゲーム Web サイトなど、どの...

MySQL 分離レベル操作プロセスの詳細説明 (cmd)

コミットされていない読み取りの例の操作プロセス - コミットされていない読み取り1. 2 つの My...

HTML で選択ドロップダウン ボックスのコンテンツが不完全に表示され、部分的にカバーされる問題の解決策

今日、問題が発生しました。クエリ バーのドロップダウン ボックスの内容が長すぎて、一部が隠れてしまっ...

Vueフィルターとカスタム命令の使用

目次フィルター01.とは02. やり方(1)フィルターを定義する(2)使用方法(3)フィルタパラメー...

Centos7でのパーティションのフォーマットとマウントの実装

Linux では、ハードディスクの追加やパーティションの再マウントといった状況に頻繁に遭遇します。こ...

Angularコンポーネントライフサイクルの詳細説明(I)

目次概要1. フックの呼び出し順序2. onChangesフック3. 変更検出メカニズムとDoChe...

HTML ドラッグ アンド ドロップ機能の実装コード

Vueベースこの機能の核となるアイデアは、JavaScript コードを通じてページ上のノードの左余...

MySQL に絵文字表現を挿入できない問題の解決方法

序文最近この問題に遭遇するまで、私は UTF-8 が文字セットの問題に対する普遍的な解決策だと考えて...

MySQL トランザクションの概念と使用法の詳細な説明

目次情事の概念取引の状態取引の役割取引の特徴トランザクション構文トランザクション対応ストレージエンジ...

MySQL パスワードに特殊文字が含まれている場合とコマンドラインからログインする場合

サーバーでは、データベースにすばやくログインするために、通常は mysql -hhost -uuse...