SSH 概述#
SSH はプロトコルです#
- Secure Shell(セキュアシェル、略称 SSH)は、暗号化されたネットワーク転送プロトコルです。
- SSH は、ネットワーク内に安全なトンネルを作成することによって、SSHクライアントとサーバーの間の_接続_を実現します。
- SSH の最も一般的な用途はリモートシステムへのログインであり、人々は通常 SSH を利用してコマンドラインインターフェースを転送し、リモートでコマンドを実行します。
OpenSSH オープンソース版#
OpenSSH は、セキュアシェル(SSH)ツールのオープンソース版であり、Linux やその他の非 Windows システムの管理者がこのようなツールを使用してクロスプラットフォームでリモートシステムを管理します。
一般的な SSH ツール#
名称 | 説明 | サポートプラットフォーム | 推奨 |
---|---|---|---|
PuTTY(Free Windows) | 無料のオープンソース SSH ターミナルツール | Windows | ⭐⭐⭐ |
WinSCP | SCP プロトコルのファイル転送ツール | Windows | ⭐⭐⭐⭐⭐ |
FileZilla | マルチプロトコルファイル転送ツール | Windows Linux MacOS | ⭐⭐⭐⭐ |
MobaXterm | 無料のオープンソース SSH ターミナルツール | Windows | ⭐⭐⭐⭐ |
Termius | 全プラットフォームの SSH ターミナルツール | Windows Linux MacOS Android IOS | ⭐⭐⭐⭐⭐ |
SSH プロトコルの動作原理#
SSH プロトコルフレームワーク内の 3 つのサブプロトコル#
-
転送層プロトコル SSH-TRANS
サーバーの認証、完全性、機密性機能を提供し、従来の TCP/IP プロトコルの上に構築されています。
-
認証プロトコル SSH-USERAUT
サーバーに対してクライアントユーザーを認証し、ユーザー名とパスワードおよび公開鍵の 2 つの認証方式に基づいて、転送層プロトコル SSH-TRANS の上に構築されています。
-
接続プロトコル SSH-CONNECT
暗号化トンネルを複数の論理チャネルとして再利用します。これは認証プロトコルの上に構築されています。
SSH ワークフロー#
Wireshark を使用して各段階を分析#
TCP 三者間ハンドシェイク#
SSH サーバーは 22 ポートでクライアントの接続要求をリッスンし、クライアントの接続確立要求を受信すると、クライアントと三者間ハンドシェイクを行い、TCP 接続を確立します。その後のすべてのメッセージのやり取りはこの TCP 接続上で行われます。
バージョン交渉#
サーバーとクライアントはそれぞれ自分がサポートするバージョン番号を相手に送信します。サーバーとクライアントは相手から送信されたバージョンを受信した後、自分のバージョン番号と比較し、双方がサポートする最高のバージョン番号が交渉されたバージョン番号となります。
アルゴリズム交渉#
- クライアントとサーバーはそれぞれ自分がサポートするアルゴリズムのリストを相手に送信します;
- 双方はそれぞれのアルゴリズム(鍵交換アルゴリズム、暗号アルゴリズムなど)を交渉します。各アルゴリズムの交渉プロセスは、クライアントのアルゴリズムリストから最初のアルゴリズムを取り出し、サーバーのリストで対応するアルゴリズムを探します。もし同じアルゴリズムが一致すれば、そのアルゴリズムは交渉成功となります;そうでなければ、クライアントのアルゴリズムリストから次のアルゴリズムを取り出し、サーバーのアルゴリズムリストで一致するまで続けます。もしクライアントがサポートするアルゴリズムがすべて一致しなければ、そのアルゴリズムの交渉は失敗します。
- あるアルゴリズムが交渉成功した後、上記の方法で他のアルゴリズムの交渉を続け、すべてのアルゴリズムが交渉成功するまで続けます;もしあるアルゴリズムの交渉が失敗した場合、クライアントとサーバー間のアルゴリズム交渉は失敗し、サーバーはクライアントとの接続を切断します。
algorithms
には交渉が必要なすべてのアルゴリズムが含まれています。
NO. | 説明 | 説明 |
---|---|---|
1 | kex_algorithms | 鍵交換アルゴリズム Key Exchange、D-H アルゴリズムを含み、セッション鍵を生成するために使用されます |
2 | server_host_key_algorithms | サーバーホスト鍵アルゴリズム Host Key、鍵ペアを生成するために使用されます |
3 | encryption_algorithms_client_to_server | 対称暗号アルゴリズム、一般的にはaes128-cbc,3des-cbc が使用されます |
4 | mac_algorithms_client_to_server | Mac アルゴリズム、データの完全性を保証するために主に使用されます |
5 | compression_algorithms_client_to_server | 圧縮アルゴリズム |
鍵交換#
クライアントは一時的な鍵 ephemera-public key を生成し、サーバーに送信します **【??】**
サーバーとクライアントは Diffie-Hellman アルゴリズムを使用してセッション鍵 Session key を生成します。
このパッケージ内で、サーバーはホスト鍵 Host Key、セッション鍵 Session key、署名などを一緒にクライアントに送信します。
クライアントは新しい鍵 New Key を返信し、その後暗号化通信に入ります。
その後のセッションプロセスはすべて暗号化され、パケットキャプチャからはもはや明文情報は見えなくなります。
ユーザー認証#
- クライアントはサーバーに認証要求メッセージを送信し、その中に認証方式として「none」を含めます。
- サーバーは none 方式の認証要求を受け取り、認証チャレンジメッセージを返信し、その中にサーバーがサポートする、かつそのユーザーが完了する必要がある認証方式のリストを含めます。
- クライアントはサーバーから送信された認証方式のリストからある認証方式を選択し、サーバーに認証要求を発起します。認証要求にはユーザー名、認証方法、その認証方法に関連する内容が含まれます:
- パスワード認証方式では、内容はユーザーのパスワードです;
- 公開鍵認証方式では、内容はユーザーのローカル鍵ペアの公開鍵部分(公開鍵検証段階)またはデジタル署名(デジタル署名検証段階)です。
- サーバーはクライアントの認証要求を受け取り、クライアントの認証情報を検証します:
- パスワード認証方式:サーバーはクライアントが送信したユーザー名とパスワード情報を、デバイス上またはリモート認証サーバー上に保存されているユーザー名とパスワードと比較し、認証が成功したか失敗したかを判断します。
- 公開鍵認証方式:サーバーは公開鍵の合法性をチェックし、不合法であれば認証は失敗します;そうでなければ、サーバーはデジタル署名を使用してクライアントを認証し、認証が成功したか失敗したかを判断します。
- サーバーは自端末上のそのユーザーの設定およびユーザー認証の完了状況に基づいて、クライアントが引き続き認証を行う必要があるかどうかを決定します。以下のような状況に分かれます:
- その認証方式が成功し、そのユーザーが他の認証を続ける必要がない場合、サーバーは認証成功メッセージを返信し、認証プロセスは順調に完了します。
- その認証方式が成功したが、そのユーザーが他の認証を続ける必要がある場合、認証失敗メッセージを返信し、クライアントに対して引き続き認証チャレンジを発出し、そのメッセージにはサーバーがクライアントに引き続き完了させる必要がある認証方式のリストを含めます;
- その認証方式が失敗し、ユーザーの認証回数がまだ最大値に達していない場合、サーバーはクライアントに対して引き続き認証チャレンジを送信します;
- その認証方式が失敗し、ユーザーの認証回数が最大値に達した場合、ユーザーの認証は失敗し、サーバーはクライアントとの接続を切断します。
サービス要求#
SSH プロトコルは多様なアプリケーションサービスをサポートしています。ユーザーが認証を成功させた後、SSH クライアントはサーバーに対してサービス要求を行い、サーバーに特定のアプリケーションを提供するよう求めます。
サービス要求のプロセスは次のとおりです:
- クライアントは
SSH_MSG_CHANNEL_OPEN
メッセージを送信し、サーバーとのセッションチャネルを確立するよう要求します; - サーバーは
SSH_MSG_CHANNEL_OPEN
メッセージを受信した後、そのチャネルタイプをサポートしている場合、SSH_MSG_CHANNEL_OPEN_CONFIRMATION
メッセージを返信し、セッションチャネルを確立します; - セッションチャネルが確立された後、クライアントはチャネル上でシェルまたはサブシステムタイプのセッションを要求できます。これはそれぞれ SSH および SFTP の 2 種類のサービスに対応します。
SSH プロトコルのセキュリティメカニズム#
暗号化トンネル#
暗号化トンネルとは、送信者がデータを送信する前に、暗号化鍵を使用してデータを暗号化し、その後データを相手に送信することを指します。受信者はデータを受信した後、復号化鍵を使用して暗号文から平文を取得します。
暗号化アルゴリズムは 2 種類に分かれます:
- 対称鍵アルゴリズム:データの暗号化と復号化に同じ鍵と同じアルゴリズムを使用します。
- 非対称鍵アルゴリズム:データの暗号化と復号化に異なる鍵を使用します。一つは公開鍵で、もう一つはユーザーが秘密に保持する秘密鍵です。
非対称鍵アルゴリズムは時間がかかるため、一般的にはデジタル署名や身分証明に使用されます。SSH 暗号化トンネル上のデータの暗号化と復号化には対称鍵アルゴリズムが使用され、現在主にサポートされているアルゴリズムには DES、3DES、AES などがあります。これらのアルゴリズムは、相互データが盗聴されるのを効果的に防止でき、初期化ベクトル保護を採用しているため、パスワードストリームの再利用などの暗号分析ツールの攻撃を防ぐことができます。
鍵交換アルゴリズム#
対称鍵アルゴリズムは、復号化鍵と暗号化鍵が完全に一致する必要があり、そうでなければ暗号文から平文を正常に復号化できません。したがって、暗号化トンネルを確立するには、通信の両方の当事者が一致した暗号化・復号化鍵を展開する必要があります。鍵の展開方法には手動設定や第三者機関による配布などがあります。手動設定の方法は拡張性が低く、小規模なローカルネットワークにしか適していません;第三者機関による鍵の配布方法は、追加の第三者サーバーが必要であり、鍵がネットワーク上で送信されると盗聴される可能性があります。
SSH プロトコルは通信の両方の当事者間で鍵を展開するための安全な方法を使用します:鍵交換アルゴリズム。鍵交換アルゴリズムを利用することで、通信の両方の当事者が動的に鍵を生成できます。この鍵は通信の両方の当事者のみが取得でき、第三者は盗聴できないため、暗号化・復号化に使用する鍵の安全性が源泉から保証され、鍵の配布問題がうまく解決されます。
鍵交換アルゴリズムの基本原理#
- クライアントはランダムにプライベートキー を選択し、 を計算し、計算された をサーバーに送信します。ここで、 は非常に大きな素数で、 は の素根です。 と は双方が共有する一対のパラメータであり、プロトコルは双方が協議して同じ と パラメータを取得できることを許可します。
- サーバーもランダムにプライベートキー を生成し、 を計算し、計算された をクライアントに送信します。
- サーバーはクライアントから送信された を受信し、次の式に従って鍵を計算します:
- クライアントはサーバーから送信された を受信し、同様に次の式に従って鍵を計算します:
上記の方法により、クライアントとサーバーは同じ鍵を取得できます。
上記の分析から、鍵交換アルゴリズムの安全性は離散対数の計算の難しさに基づいています。式中で、からを計算するのは容易ですが、からを計算するのは非常に困難です。鍵交換アルゴリズムでは、公開されるのは 、、 および のみであり、プライベートキー と は秘密にされており、他のユーザーが 、、 および を取得しても、プライベートキー と を推測するのは非常に困難であり、鍵の安全性が保証されます。
鍵交換アルゴリズムには以下の利点があります:
- 拡張性が高く、ネットワーク管理者の余分な設定が不要;
- 交換された鍵はメモリに保存され、読み取りや改ざんが難しい;
- 各接続ごとに動的に新しい鍵が生成され、安全性が高い。
ユーザー認証メカニズム#
パスワードに基づく安全認証#
自動生成された公開鍵 - 秘密鍵ペアを使用してネットワーク接続を簡単に暗号化し、その後パスワード認証を使用してログインします。具体的なプロセスは次のとおりです:
- クライアントはログイン要求を送信します、
ssh user@hostname
- サーバーは要求を受け入れ、サーバーの公開鍵 server_rsa.pub をクライアントに送信します
- クライアントはパスワードを入力し、パスワードは server_rsa.pub で暗号化されてサーバーに送信されます(敏感情報の安全な転送)
- サーバーは暗号化されたパスワードを受け取り、サーバーの秘密鍵 server_rsa を使用して復号化し、認証パスワードが合法かどうかを確認します
これで、身分証明が完了し、次にセッション鍵(対称暗号化)を交換します。
- クライアントはセッションデータを暗号化するための session_key を生成し、server_rsa.pub で暗号化してサーバーに送信します(セッション鍵)
- サーバーは受け取った後、server_rsa を使用して復号化し、session_key を取得します
セッション鍵を使用して、その後のデータを暗号化します。注:対称暗号化を使用すると効率が高いです。
- クライアントとサーバーは session_key を使用してセッションデータを安全に転送します
ただし、この認証方式では中間者攻撃を回避できず、他のサーバーが本物のサーバーを偽装する可能性があります。
公開鍵認証#
クライアントは公開鍵と秘密鍵のペアを生成し、自分の公開鍵をサーバーにコピーします。クライアントがログインを要求すると、サーバーはランダムに生成された文字列をクライアントの公開鍵で暗号化し、クライアントはそれを受け取った後、自分の秘密鍵で復号化し、再度サーバーに送信します。サーバーは受け取った後、比較を行い、成功すればユーザーが信頼できることを証明し、直接ログインを許可し、パスワードを要求しなくなります。これにより、中間者攻撃を回避します。具体的なプロセスは次のとおりです:
鍵に基づく安全認証は、図に示されているように簡単に説明できます。しかし、実際の転送プロセスでは、すべてのデータが暗号化されて安全なデータ転送を保証する必要があります。つまり、同様にセッション鍵が生成され、セッション鍵で転送データを暗号化するプロセスが必要です。詳細なプロセスは次のとおりです:
- クライアントはログイン要求を送信します、
ssh user@hostname
- サーバーは要求を受け入れ、サーバーの公開鍵をクライアントに送信します
- サーバーはセッション ID(session id)を生成し、とし、クライアントに送信します。
- クライアントはセッション鍵(session key)を生成し、とし、を計算します
- クライアントはをで暗号化し、結果をサーバーに送信します
- サーバーはサーバーの秘密鍵を使用して復号化し、を取得します
- サーバーはの計算を行い、を取得します
これで、サーバーとクライアントはセッション鍵を知っており、その後の転送データはで暗号化されます。
- クライアントはクライアントの秘密鍵でを復号化し、を取得します
- クライアントはの md5 値を計算し、は前のステップで得られたセッション鍵です
- クライアントはをサーバーに送信します
- サーバーはの md5 値を計算します
- サーバーはとを比較し、両者が同じであれば認証成功となります
これで、サーバーとクライアントの認証が完了し、セッション鍵を使用して暗号化と復号化を行うことができます。
- クライアントとサーバーはを使用してセッションデータを安全に転送します。
SSH 鍵#
SSH 鍵は SSH プロトコルで使用されるアクセス資格情報であり、パスワードに似ています。SSH 鍵はユーザーに企業のコアデバイスへの自動リモートアクセス権を付与します。
ホスト鍵 Host Key#
各ホスト(コンピュータ)にはユニークなホスト鍵があります。
- Linux では
/etc/sshssh_host_<rsa/dsa/ecdsa/ed25519>_key
に保存されます - Windows では
C:\ProgramData\ssh
に保存されます
SSH を介してリモートホストに初めて接続すると、通常は次のようなプロンプトが表示されます:
$ ssh user@ip-address
ホスト 'ip-address (ip-address)' の真正性を確認できません。
ECDSA鍵フィンガープリントはSHA256:hjn60Ix3hjduyfhjHLJKOdJSDDX6beXpfp0ypeqTOPQ+f0tUです。
接続を続けてもよろしいですか(yes/no/[fingerprint])?
yes
と入力してEnterを押すと、次のようなプロンプトが表示されます:
警告: 'ip-address' (ECDSA)が既知のホストのリストに永久に追加されました。
user@ip-addressのパスワード:
このようにして、既知のホスト鍵リストに追加されます。
ip-address ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEvRRBRoCJSuJuEaXK3i3k/4Cd+uriN5cKPGbbl/Q5f5DhjduyfhjHLQXDZPVDw0reLJKmIcGcZh2qQHX5qjMLQ=
既知のホスト鍵リスト: SSH クライアントが以前に接続したホストのホスト鍵を保存するために使用します
- Linux では
/etc/ssh/known_hosts.ssh/known_hosts
に保存されます- Windows では
C:\Users\User\.ssh\known_host
に保存されます
認証鍵 Authorized Key#
SSH の認証鍵は、ユーザーにログインアクセス権を付与するための公開鍵です。認証メカニズムは公開鍵認証と呼ばれます。OpenSSH ではssh-keygen
ツールを使用して生成でき、通常は一対の鍵(秘密鍵 - 公開鍵)が生成されます。
サーバー側の authorized_keys ファイル#
authorized_keys ファイルには、各ユーザーの認証鍵が個別に設定されます。
- Linux では
~/.ssh/authorized_keys
に保存されます - Windows では
C:\Users\user\.ssh\authorized_keys
に保存されます
SSH サーバーの設定ファイルで保存パスを変更できます。
認証鍵の内容は次のようになります:
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBN+Mh3U/3We4VYtV1QmWUFIzFLTUeegl1Ao5/QGtCRGAZn8bxX9KlCrrWISIjSYAwCajIEGSPEZwPNMBoK8XD8Q= user@host-name
アイデンティティ鍵 Identity Key #
アイデンティティ鍵は、SSH 公開鍵認証でサーバーへのアクセス権を付与するために使用される秘密鍵です。OpenSSH ではssh-keygen
ツールを使用して生成でき、通常は一対の鍵(秘密鍵 - 公開鍵)が生成されます。
セッション鍵 Session Key#
SSH プロトコルは、Key Exchange アルゴリズムを利用して各セッションまたは接続に対して一意の鍵を派生させます。この鍵はセッション鍵 Session Key と呼ばれ、一般的な Key Exchange アルゴリズムにはDiffie-HellmanとElliptic-curve Diffie–Hellmanがあります。
セッション鍵はセッション接続の両方の当事者間で共有され、これは中間者攻撃に対して容易に脆弱です。
前方秘匿性:セッション鍵を使用しているため、長期鍵(ホスト鍵)が漏洩しても、侵入者は以前のセッション内容を復号化することができません。
鍵に関する基本知識#
公開鍵 Public Key#
公開鍵は、秘密鍵アルゴリズムと一緒に使用される鍵ペアの非秘密の一部です。公開鍵は通常、セッション鍵の暗号化、デジタル署名の検証、または対応する秘密鍵で復号化できるデータの暗号化に使用されます。公開鍵と秘密鍵は、あるアルゴリズムによって得られる鍵ペア(すなわち、1 つの公開鍵と 1 つの秘密鍵)であり、そのうちの 1 つは外部に公開され、公開鍵と呼ばれます;もう 1 つは自分が保持し、秘密鍵と呼ばれます。このアルゴリズムによって得られる鍵ペアは、世界中で一意であることが保証されます。この鍵ペアを使用する際、もし 1 つの鍵でデータを暗号化した場合、必ずもう 1 つの鍵で復号化しなければなりません。たとえば、公開鍵でデータを暗号化した場合は秘密鍵で復号化しなければならず、秘密鍵で暗号化した場合も公開鍵で復号化しなければなりません。そうでなければ、復号化は成功しません。
SSH では、公開鍵暗号化がコンピュータとユーザーの認証に使用されます。ホスト鍵はホストの認証に使用されます。認証鍵とアイデンティティ鍵はユーザーの認証に使用されます。
秘密鍵 Private Key#
公開鍵暗号システムにおいて、秘密鍵は文書にデジタル署名を行うための鍵です。特定の暗号システムでは、公開鍵で暗号化されたデータを復号化するためにも使用されます。各秘密鍵には対応する公開鍵があります。通常、公開鍵は秘密鍵から容易に派生できますが、公開鍵から秘密鍵を派生することは計算上不可能です。
SSH では、秘密鍵はコンピュータとユーザーの認証に使用されます。ホスト鍵はサーバーの認証に使用され、アイデンティティ鍵はユーザーの認証資格情報として使用されます。
SSH 設定ファイル#
OpenSSH クライアント設定ファイル#
設定ファイルの保存場所:
- Linux
~/.ssh/config/etc/ssh/ssh_config
- Windows
C:\Users\user\.ssh\config
通常、設定ファイルは存在しないため、手動で作成できます。
- Linux
touch ~/.ssh/config&&chmod 600 ~/.ssh/config
- Windows では
C:\Users\user\.ssh\
パスに手動でテキストファイルを作成し、.txt
拡張子を削除します。
設定ファイルの構造#
Host hostname1
SSH_OPTION value
SSH_OPTION value
Host hostname2
SSH_OPTION value
Host *
SSH_OPTION value
- config の構造は上記のように、ブロックごとに分かれています。
- インデントは必須ではありませんが、インデントがあると視認性が向上します。
- 各ブロックは Host ディレクティブで開始され、各 Host ブロックは 1 つまたは複数の一致する内容(複数はスペースで区切る)に対して設定できます。また、以下の特殊識別子を使用することもできます:
*
は 0 または任意の文字を一致させます。たとえば、Host *
はすべてのホストに一致し、192.168.0.*
は192.168.0.0/24
のサブネット内の IP に一致します。?
は 1 文字に一致します。たとえば、10.10.0.?
は10.10.0.[0-9]
に一致します。!
は否定を意味します。たとえば、Host 10.10.0.* !10.10.0.5
は10.10.0.0/24
サブネットに一致しますが、10.10.0.5
は除外されます。
一致ルール:SSH クライアントは上から下に一致を確認するため、複数の Host が一致した場合、最初に定義された設定パラメータが有効になります。たとえば、最初の一致設定グループに User 設定があり、最後の一致設定グループにも User 設定がある場合、最初に一致した User が実際に使用されます。したがって、比較的具体的な一致を上部に配置し、一般的なものを下部に配置することをお勧めします(たとえば、特定の IP 範囲に対するものを上部に配置し、すべてのものを最後に配置します)。
設定ファイルの詳細#
Host host-name
は設定ブロックを指定する必須項目ですuser username
はログインユーザーを指定する必須項目ですhostname 10.0.0.1
はサーバーアドレスを指定し、通常は IP アドレスを使用する必須項目ですport 22
は認証秘密鍵ファイルを指定する必須項目ですIdentityfile ~/.ssh/id_rsa
はローカル認証秘密鍵のアドレスを指定しますIdentityFile ~/.ssh/id_rsa.pub
は認証秘密鍵ファイルを指定しますForwardAgent yes
は ssh-agent の転送を許可しますForwardX11 yes
は X11 転送を許可しますForwardX11Trusted yes
はリモート X11 クライアントが元の X11 ディスプレイに完全にアクセスできるようにします。DynamicForward 2000
は安全なトンネルを介して転送されるローカルポートを指定しますRemoteForward 3000
はリモートホスト上の TCP ポートを安全なトンネルを介して指定されたホストとポートに転送します。最初のパラメータは[bind_address:]port
であり、2 番目のパラメータはhost:port
でなければなりません。SSH トンネルLocalForward
はローカルマシン上の TCP ポートを安全なトンネルを介してリモートマシン上の指定されたホストとポートに転送します。最初のパラメータは\[bind\_address:]port
であり、2 番目のパラメータはhost:port
でなければなりません。ExitOnForwardFailure yes
は動的、トンネル、ローカルおよびリモートポート転送の設定が失敗した場合に接続を終了するかどうかを指定します。ClearAllForwardings
は設定ファイルまたはコマンドラインで指定されたすべてのlocal
、remote
およびdynamic
ポートの転送をクリアすることを指定します。GatewayPorts 2001
はリモートホストがローカルポートに接続できるかどうかを指定します。IdentitiesOnly no
は ssh が設定ファイルまたはコマンドラインで指定された秘密鍵ファイルのみを使用して認証するかどうかを指定します。値はyes
またはno
であり、デフォルトはno
です。この状況は、ssh-agent が多くの認証ファイルを提供している場合に使用されます。StrictHostKeyChecking ask
ask
:デフォルト値で、初めて未知のサーバーに接続する際に追加するかどうかを確認し、リモートサーバーの公開鍵が変更された場合は接続を拒否します;yes
:サーバーの公開鍵を~/.ssh/known_hosts
に自動的に追加せず、リモートサーバーの公開鍵が変更された場合は接続を拒否します;no
:新しいホスト鍵を~/.ssh/known_hosts
に自動的に追加します。
BindAddress 10.0.0.1
はローカルコンピュータ上の指定されたアドレスを接続のソースアドレスとして使用することを指定します。Protoco- 2
は優先順位順にプロトコルバージョンを指定します。複数のバージョンはカンマで区切る必要があります。Cipher <char>
は SSH v1 で使用する暗号のパスワードを設定します。Ciphers <char>
- SSH v2 で許可される暗号を優先順位順に指定します。
- 複数の暗号はカンマで区切る必要があります。
- コマンド
ssh -Q cipher
を使用してサポートされている暗号を照会できます。
HostKeyAlgorithms ssh-ed25519
はクライアントが使用する SSH v2 のホスト鍵アルゴリズムを優先順位順に指定します。HostKeyAlias username
は、鍵データベースファイル内でホスト鍵を検索または保存する際に、実際のホスト名ではなくこのエイリアスを使用することを指定します。GlobalKnownHostsFile <path>
#グローバルホスト鍵データベースに使用するファイルを指定し、/etc/ssh/sh_known_hosts
ではなく指定します。HashKnownHosts yes
はホスト名とアドレスを~/.ssh/known_hosts
に追加する際にハッシュ処理を行うかどうかを指定します。Compression no
は圧縮を使用するかどうかを指定します。CompressionLeve- 1
は圧縮を有効にした場合に使用する圧縮レベルを指定します。EscapeChar ~
はエスケープキーを設定します。ConnectionAttempts 10
は終了前に行う試行回数を指定します。ConnectTimeout 10
は SSH サーバーへの接続時に使用するタイムアウト(秒単位)を指定し、デフォルトのシステム TCP タイムアウトを使用しません。ControlMaster 3
は単一のネットワーク接続を介して複数のセッションを共有することを許可します。ControlPath <path>
#接続共有のための制御ソケットのパスを指定するか、接続共有を無効にするためにnone
を指定します。RhostsAuthentication no
は rhosts ベースのセキュリティ認証を使用するかどうかを設定します。RhostsRSAAuthentication no
は RSA アルゴリズムを使用した rhosts ベースのセキュリティ認証を使用するかどうかを設定します。HostbasedAuthentication yes
は、ユーザーのホームディレクトリ内の.rhosts
または.shosts
ファイル、およびグローバル設定内の/etc/hosts.equiv
と/etc/shosts.equiv
を使用して、rhosts ベースの認証と公開鍵認証を試みるかどうかを指定します。RSAAuthentication yes
は RSA アルゴリズムを使用してセキュリティ認証を行うかどうかを設定します。PasswordAuthentication yes
はパスワード認証を使用するかどうかを設定します。FallBackToRsh no
は ssh 接続にエラーが発生した場合に自動的に rsh を使用するかどうかを設定します。UseRsh no
はこのコンピュータで rlogin/rsh を使用するかどうかを設定します。BatchMode no
はyes
に設定すると、passphrase/password(対話式入力のパスワード)のプロンプトが禁止されます。対話式でパスワードを入力できない場合、このオプションはスクリプトファイルやバッチ処理タスクに非常に便利です。CheckHostIP yes
は ssh がサーバーに接続するホストの IP アドレスを確認して DNS スプーフィングを防ぐかどうかを設定します。yes
に設定することをお勧めします。StrictHostKeyChecking no
はyes
に設定すると、ssh は自動的にコンピュータの鍵を$HOME/.ssh/known_hosts
ファイルに追加せず、コンピュータの鍵が変更された場合は接続を拒否します。KbdInteractiveAuthentication yes
はキーボードインタラクティブ認証を使用するかどうかを指定します。これはパスワード認証、一時パスワード、および多要素認証の一般的な方法です。KbdInteractiveDevices
LocalCommand ipconfig
はサーバーに接続した後にローカルコンピュータで実行するコマンドを指定します。LogLeve- ERROR
は ssh からのログ情報の粗さを指定します。値は QUIET、FATAL、ERROR、INFO、VERBOSE、DEBUG、DEBUG1、DEBUG2、DEBUG3 です。Macs hmac-sha1
は優先順位順に Mac(メッセージ認証コード)アルゴリズムを指定します。コマンドssh -Q mac
を使用してサポートされている Mac アルゴリズムを照会できます。NoHostAuthenticationForLocalhost yes
は、ホームディレクトリがマシン間で共有されている場合にこのオプションを使用できます。この場合、localhost は各マシンの異なるマシンを指し、ユーザーはホスト鍵の変更に関する多くの警告を受け取ります。PreferredAuthentications
はクライアントが SSH v2 認証メソッドを試みる順序を指定します。ProxyCommand
はサーバーへの接続に使用するコマンドを指定します。SSH クライアントはその標準入力と標準出力をプロキシコマンドと通信し、プロキシコマンドは通信を SSH サーバーに渡す必要があります。PubkeyAuthentication yes
は SSH 鍵を使用して公開鍵認証を試みるかどうかを指定します。SendEnv
はサーバーに送信する環境変数を指定します。ServerAliveCountMax 10
はクライアントが送信するkeepalive
の数を設定し、クライアントがサーバーからの情報フィードバックを受け取らなかった場合に、閾値に達したときにクライアントがセッションを終了します。ServerAliveInterva- 5
はサーバーにkeepalive
情報を送信する時間間隔を指定します。これらの情報は暗号化されたチャネルを介して送信され、サーバーがクラッシュしたかネットワークが中断されたかを検出するために使用されます。TCPKeepAlive yes
は相手に TCP keepalives を送信するかどうかを指定します。これは TCP プロトコルレベルでの操作です。Tunne- yes
はクライアントとサーバー間でデバイス転送を要求します。これは SSH を介して VPN を実現するために使用されます。TunnelDevice remote_tun
は tun デバイスを開くために、local_tun または remote_tun を指定します。UsePrivilegedPort no
は外向き接続に特権ポートを使用するかどうかを指定します。UserKnownHostsFile <path>
はユーザーの既知のホスト鍵データベースのファイルを指定し、デフォルトの~/.ssh/known_hosts
ではなく指定します。VerifyHostKeyDNS yes
はリモート鍵を検証するために DNS と SSHFP リソースレコードを使用するかどうかを指定します。VisualHostKey yes
はログイン時または未知のホスト鍵に対して、16 進数のフィンガープリント文字列に加えて、リモートホスト鍵フィンガープリントの ASCII アートを印刷するかどうかを指定します。
OpenSSH サーバー側設定ファイル#
OpenSSH サーバーは起動時に設定ファイルを読み込み、通常の設定ファイルの保存場所は次のとおりです:
- Linux
/etc/ssh/sshd_config
- Windows
C:\ProgramData\ssh\sshd_config
設定ファイルの関係#
設定の詳細#
- SSH サーバーの全体設定、使用するポートやパスワード演算方式を含みます。
Port 22
SSH はデフォルトで 22 ポートを使用しますProtoco- 2,1
選択された SSH プロトコルバージョンで、1 または 2 を指定できます。両方を同時にサポートする場合は、2,1 を使用する必要があります。ListenAddress 10.0.0.1
SSH 接続を 10.0.0.1 からのみリッスンします。(仮に 2 つの IP が 10.0.0.1 と 10.0.0.2 であるとします)PidFile /var/run/sshd.pid
SSHD の PID ファイルを配置できます。左側はデフォルト値です。LoginGraceTime 600
接続待機時間(秒単位)Compression yes
圧縮コマンドを使用できるかどうか
- ホストのプライベートキーの配置ファイルを説明し、デフォルトでは次のファイルを使用します。
HostKey /etc/ssh/ssh_host_key
SSH v1 で使用する秘密鍵HostKey /etc/ssh/ssh_host_rsa_key
SSH v2 で使用する RSA 秘密鍵HostKey /etc/ssh/ssh_host_dsa_key
SSH v2 で使用する DSA 秘密鍵KeyRegenerationInterva- 3600
ホスト鍵を再生成する時間間隔ServerKeyBits 768
サーバー鍵の長さ
- ログインファイルの情報データの配置とデーモンの名前
SyslogFacility AUTH
誰かが SSH でシステムにログインすると、SSH は情報をデーモン名の下に記録します。デフォルトは AUTH に設定されており、/var/log/secure
に記録されます。他の利用可能なデーモン名は:DAEMON、USER、AUTH、LOCAL0、LOCAL1、LOCAL2、LOCAL3、LOCAL4、LOCAL5、LogLeve- INFO
ログイン記録のレベル
- ログイン設定部分
PermitRootLogin no
root ログインを許可するかどうか。デフォルトは許可されていますが、no に設定することをお勧めします。UserLogin no
SSH の下では login プログラムのログインを受け付けません。StrictModes yes
ユーザーのホスト鍵が変更された場合、サーバーは新しい SSH 接続を受け付けません。RSAAuthentication yes
RSA 認証を完全に使用するかどうか。これは SSH v1 にのみ適用されます。PubkeyAuthentication yes
公開鍵を使用するかどうか。これは SSH v2 にのみ適用されます。AuthorizedKeysFile .ssh/authorized_keys
鍵認証の鍵パス。
- 認証部分
RhostsAuthentication no
.rhosts を使用するかどうか。安全でないため、通常は無効にします。IgnoreRhosts yes
~/.ssh/.rhosts
の使用を無効にするかどうか。RhostsRSAAuthentication no
/etc/hosts.equiv
の rhosts を RSA アルゴリズムと組み合わせて認証に使用するかどうか。これは SSH v1 にのみ適用されます。HostbasedAuthentication no
これは上記の項目と似ており、SSH v2 にのみ適用されます。IgnoreUserKnownHosts no
/home/.ssh/known_hosts
に記録されたホスト内容を無視するかどうか。PasswordAuthentication yes
パスワード認証を有効にするかどうか。PermitEmptyPasswords no
空のパスワードでログインを許可するかどうか。ChallengeResponseAuthentication yes
すべてのパスワード認証を挑戦し、login.conf で指定された認証方式を適用します!PAMAuthenticationViaKbdInt yes
他の PAM モジュールを有効にするかどうか!有効にすると、PasswordAuthentication の設定が無効になります。
- Kerberos に関連するパラメータ設定
KerberosAuthentication no
KerberosOrLocalPasswd yes
KerberosTicketCleanup yes
KerberosTgtPassing no
- X-Window で使用される関連設定
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost yes
- ログイン後の項目
PrintMotd no
ログイン後に情報を表示するかどうか。たとえば、前回のログイン時間、場所など。デフォルトは yes です。PrintLastLog yes
前回のログイン情報を表示するかどうか。デフォルトは yes です。KeepAlive yes
keepalive を有効にするかどうか。UsePrivilegeSeparation yes
ユーザーの権限設定項目です。MaxStartups 10
同時にログインしていない接続セッションの数(SSH に接続しているが、まだパスワードを入力していない場合、すなわち接続セッション)。
- 接続拒否の設定項目
DenyUsers test
ログインを拒否するユーザー名を設定します。DenyGroups test
ログインを拒否するユーザーグループを設定します。
- SFTP サービスの設定項目
Subsystem sftp /usr/lib/ssh/sftp-server
known_hosts#
known_hosts には認証されたリモートホストのホスト鍵が保存されており、各 SSH サーバーには秘密のユニーク ID、すなわちホスト鍵があります。
known_hosts の保存パス:
- Linux:
~/.ssh/known_hosts
- Windows:
C:\Users\uesr\.ssh\known_hosts
SSH を介してリモートホストに初めてログインすると、クライアント側に次のようなプロンプトが表示されます:
既知のホストのリストからホスト鍵が見つかりません。
接続を続けてもよろしいですか(yes/no)?
この時、yes を選択すると、そのホスト鍵がクライアントの known_hosts に追加され、形式は次のようになります:
# ドメイン名+暗号化アルゴリズム+ホスト鍵
example.hostname.com ssh-rsa AAAAB4NzaC1yc2EAAAABIwAAAQEA。。。
なぜ known_hosts が必要なのか?このファイルは、クライアントとサーバーの双方向認証を通じて中間者攻撃を回避するために使用されます。クライアントがサーバーに接続を開始する際、サーバーはクライアントの合法性を確認するだけでなく、クライアントもサーバーの身元を確認する必要があります。SSH クライアントは known_hosts 内のホスト鍵を使用してサーバーの身元を確認します。
実用チュートリアル#
SSH クライアントとサーバーのインストール#
Linux でのインストール確認#
ほとんどの Linux システムにはデフォルトでインストールされています。次のコマンドを使用して確認できます。
- バージョン番号が正常に表示され、OpenSSH がインストールされていることを証明します。
- サービスの状態が緑色の点で表示され、SSH サービスが実行中であることを証明します。
#sshバージョンの確認
$ ssh -V
OpenSSH_8.2p1 Ubuntu-4ubuntu0.4, OpenSSL 1.1.1f 31 Mar 2020
#SSHサービスの状態を確認
$ systemctl status sshd.service
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; ena>
Active: active (running) since Sun 2022-02-27 19:28:>
Docs: man:sshd(8)
man:sshd_config(5)
Process: 796 ExecStartPre=/usr/sbin/sshd -t (code=exi>
Main PID: 824 (sshd)
Tasks: 1 (limit: 4491)
Memory: 4.0M
CGroup: /system.slice/ssh.service
└─824 sshd: /usr/sbin/sshd -D [listener] 0 o>
مار 03 00:44:39 zac-ubuntu sshd[21852]: pam_unix(sshd:ses>
مار 03 00:44:39 zac-ubuntu sshd[21852]: pam_unix(sshd:ses>
مار 03 00:44:54 zac-ubuntu sshd[21917]: Accepted password>
مار 03 00:44:54 zac-ubuntu sshd[21917]: pam_unix(sshd:ses>
مار 03 00:45:02 zac-ubuntu sshd[21985]: Accepted password>
مار 03 00:45:02 zac-ubuntu sshd[21985]: pam_unix(sshd:ses>
مار 03 19:56:27 zac-ubuntu sshd[26728]: Accepted password>
مار 03 19:56:27 zac-ubuntu sshd[26728]: pam_unix(sshd:ses>
مار 03 21:28:46 zac-ubuntu sshd[28737]: Accepted password>
مار 03 21:28:46 zac-ubuntu sshd[28737]: pam_unix(sshd:ses>
lines 1-22/22 (END)
Linux での SSH 手動インストール#
インストールコマンド:
# arch
pacman -S openssh
# ubuntu
apt-get install openssh
# RHEL
yum install openssh
サービスを起動:
# SSHデーモンを起動
systemctl start sshd
# 自動起動を設定
systemctl enable sshd
Windows での SSH 手動インストール#
Windows 10(バージョン 1809 以降)は OpenSSH をサポートしています。OpenSSH コンポーネントをインストールするには:
- 「設定」を開き、「アプリ」>「アプリと機能」を選択し、「オプション機能」を選択します。
- リストをスキャンして OpenSSH がインストールされているか確認します。インストールされていない場合は、ページの上部で「機能を追加」を選択し、次に:
- 「OpenSSH クライアント」を探してクリックしてインストールします。
- 「OpenSSH サーバー」を探してクリックしてインストールします。設定が完了したら、「アプリ」>「アプリと機能」と「オプション機能」に戻ると、OpenSSH がリストに表示されます。
ステップバイステップのチュートリアルは《Windows-SSH サーバーのインストール》を参照してください。
Windows 10(バージョン 1809 以前)および Windows 7 での OpenSSH 手動インストール
- 対応するシステムバージョンのインストールファイルをダウンロードします;GitHub ダウンロードリンク
- ダウンロードしたインストール
.zip
ファイルを解凍します; - 解凍したフォルダー全体を
C:/Program Files/
パスにコピーします。もちろん、コンピュータ上の任意の好きなパスに置くことができます; - コンピュータ(Windows 7)またはこの PC(Windows 10)で右クリック --> プロパティ --> 詳細システム設定 --> 環境変数 -- システム変数で、
Path
を見つけて編集します;
- Windows 7 システムでは、編集時にテキスト形式で行われるため、最後に「;」英語のセミコロンを追加し、インストールパス
C:\Program Files\OpenSSH-Win64
を貼り付けます。Windows 10 システムでは、Path に入って新規作成をクリックして直接貼り付けることができます;
詳細なチュートリアルは《Windows で OpenSSH をインストールして SSH をサポートする》を参照してください。
Windows でのインストールを確認するには、cmd
またはpowershell
を開きます。
$ ssh -V
OpenSSH_for_Windows_8.1p1, LibreSSL 3.0.2
SSH サービスを自動起動に設定します。
SSH ポート番号#
デフォルトでは、ssh は tcp 22 ポートで動作しています。
SSH の C/S モードでは、SSH サーバーは 22 ポートをリッスンし、SSH クライアントはランダムなポート番号(1024〜65535)を使用して SSH サーバーと接続を確立します。
SSH サーバーのデフォルトポートを変更する方法#
SSH の設定ファイルを見つけます:
- Linux では:
/etc/ssh/sshd_config
- Windows では:
C:\ProgramData\ssh\sshd_config
#Port 22
前のコメント#
を解除し、22
を SSH が動作するポートに変更します(他のポートと衝突しないようにしてください)。
指定ポート番号を使用して SSH に接続する#
ssh -p <port-number> user@ip-address
sftp -P <port-number> user@ip-address #注意:Pは大文字を使用
SFTP は SSH プロトコルを使用してデータを転送するため、ポート番号を共用します。
鍵生成ツールssh-keygen
#
ssh-keygen
は新しい鍵ペアを作成するためのツールです。すなわち、上記の章で言及された認証鍵とアイデンティティ鍵で構成される鍵ペアです。
以下は操作の例です:
$ ssh-keygen
公開/秘密のrsa鍵ペアを生成しています。
鍵を保存するファイルを入力してください(/home/user/.ssh/id_rsa): #このステップで鍵の保存パスを指定できます
パスフレーズを入力してください(パスフレーズなしの場合は空にしてください): #このステップで鍵を保護するためのパスワード(passphrase)を指定できます
同じパスフレーズを再度入力してください: #前のステップのパスワード(passphrase)を再確認します
あなたの識別情報は/home/user/.ssh/id_rsaに保存されました。 #あなたの秘密鍵の保存パスを示します
あなたの公開鍵は/home/user/.ssh/id_rsa.pubに保存されました。 #あなたの公開鍵の保存パスを示します
鍵のフィンガープリントは:SHA256:Up6KjbnEV4Hgfo75YM393QdQsK3Z0aTNBz0DoirrW+c user@host
鍵のランダムアート画像は:
+---[RSA 2048]----+
| . ..oo..|
| . . . . .o.X.|
| . . o. ..+ B|
| . o.o .+ ..|
| ..o.S o.. |
| . %o= . |
| @.B... . |
| o.=. o. . . .|
| .oo E. . .. |
+----[SHA256]-----+
host (11:40) ~>
上記のすべてのステップは空白のままにしておくことができます。
アルゴリズムと鍵サイズの選択#
上記の「鍵のランダムアート画像は」の下に、RSA 2048
が表示されます。RSA
は鍵アルゴリズムであり、2048
は鍵サイズです。
ssh-keygen -t <arithmetic> -b <size> #-tの後にアルゴリズム名を指定し、-bの後に鍵サイズを指定します
SSH はさまざまな鍵アルゴリズムをサポートしています:
rsa
は最も古い公開鍵暗号システムの 1 つであり、安全なデータ転送に広く使用されています。その安全性は整数分解に依存しているため、安全な RNG(乱数生成器)は必要ありません。DSA と比較して、RSA の署名検証速度は速いですが、生成速度は遅いです。鍵サイズは少なくとも 2048 ビットを推奨します。4096 ビットがより良いです。dsa
は古いアメリカ政府のデジタル署名アルゴリズムです。離散対数の計算の難しさに基づいており、RSA と比較して DSA の署名生成速度は速いですが、検証速度は遅いです。通常、鍵サイズは 1024 です。ecdsa
は DSA(デジタル署名アルゴリズム)の楕円曲線実装です。楕円曲線暗号は、比較的小さな鍵で RSA と同等の安全レベルを提供できます。また、DSA が不良 RNG に敏感であるという欠点もあります。サポートされる鍵サイズは 256、384、および 521 ビットで、521 ビットが推奨されます。ed25519
は EdDSA 署名スキームですが、SHA-512/256 と Curve25519 を使用しています;これは安全な楕円曲線であり、DSA、ECDSA、EdDSA よりも優れた安全性を提供し、パフォーマンスも優れています。これは OpenSSH に追加された新しいアルゴリズムであり、クライアントのサポートは限られています。
- 数学的特性に基づいて、これらの 4 種類は 2 つの大きなクラスに分けられます。dsa/rsa は 1 つのクラスであり、ecdsa/ed25519 はもう 1 つのクラスであり、後者のアルゴリズムはより進んでいます。
- dsa は安全性の問題から、もはや使用されていません。
- ecdsa は政治的および技術的理由からも推奨されていません。
- rsa は現在、互換性が最も良く、最も広く使用されている鍵タイプであり、ssh-keygen ツールで鍵を生成する際にもデフォルトでこのタイプが使用されます。ただし、鍵サイズが小さすぎる場合は安全性の問題があります。推奨される鍵サイズは 3072 ビット以上です。
- ed25519 は現在、最も安全で暗号化速度が最も速い鍵タイプであり、その数学的特性により、鍵の長さは rsa よりもはるかに小さく、優先的に使用されることが推奨されます。現在のところ、古いバージョンの ssh ツールセットで使用できないという唯一の問題がありますが、私のテストではそのような問題は見つかりませんでした。 -- 抜粋自《RSA、DSA、ECDSA、EdDSA と Ed25519 の違い》
ssh-keygen
を使用してホスト鍵を作成する#
このツールはホスト鍵を作成するためにも使用されます。ホスト鍵は通常の SSH 鍵ペアです。上記で言及された 4 種類のアルゴリズムに対して、各ホストはそれぞれのアルゴリズムに基づいて鍵ペアを生成できます。Linux での例は次のとおりです:
- /etc/ssh/ssh_host_dsa_key
- /etc/ssh/ssh_host_dsa_key.pub
- /etc/ssh/ssh_host_ecdsa_key
- /etc/ssh/ssh_host_ecdsa_key.pub
- /etc/ssh/ssh_host_ed25519_key
- /etc/ssh/ssh_host_ed25519_key.pub
- /etc/ssh/ssh_host_rsa_key
- /etc/ssh/ssh_host_rsa_key.pub
ホスト鍵は通常、SSH サービスをインストールする際に自動的に生成されます。また、いつでも再生成できます。ホスト鍵が変更された場合、クライアントは変更された鍵に関する警告を発する可能性があります。
鍵をサーバーにコピーするツールssh-copy-id
#
クライアントのid-rsa.pub
から認証鍵を手動でサーバーの authorized_keys にコピーする以外に、ssh-copy-id
ツールを使用してコマンドラインでこの操作を完了することもできます。
まず、クライアントで一対の鍵(公開鍵 - 秘密鍵)を生成したことを確認します。以下はコピーコマンドです:
ssh-copy-id -i <pub_key path> user@serverhost #<pub_key path>:公開鍵のファイルパス
成功すると、クライアントの認証鍵がサーバーの authorized_keys に表示されます。
Windows では
ssh-copy-id
コマンドはありません。詳細は《Windows で ssh-copy-id を使用できない問題の解決方法》を参照してください。
SSH のパスワードなしログインの実現(公開鍵認証)#
準備条件#
- SSH クライアントとサーバーが正常にインストールされていること。
サーバー側の簡単な設定#
- ログインするユーザー user のために
~/.ssh
ディレクトリと~/.ssh/authorized_keys
ファイルを作成します。正しい権限を設定します(そうでないと SSH は接続を拒否します):
# 現在のユーザーを確認
whoami
# .sshディレクトリを作成
mkdir ~/.ssh
chmod 700 ~/.