Ubuntu20.04でOpenSSHクライアントを強化する方法
このチュートリアルの以前のバージョンは、 JamieScaifeによって作成されました。
序章
Linuxサーバーは、 OpenSSH サーバーに接続することにより、SSHを使用してリモートで管理されることがよくあります。これは、Ubuntu、Debian、CentOS、FreeBSD、およびその他のほとんどのLinux/BSDベースのシステムで使用されるデフォルトのSSHサーバーソフトウェアです。 SSHはサーバーへのエントリとして機能するため、SSHのサーバー側の側面を保護するために多大な努力が払われています。
ただし、OpenSSHクライアントなどのクライアント側のセキュリティを考慮することも重要です。
OpenSSHクライアントは、SSHの「クライアント」側であり、ssh
コマンドとも呼ばれます。 SSHクライアントサーバーモデルの詳細については、 SSH Essentials:SSHサーバー、クライアント、およびキーの操作を参照してください。
サーバー側でSSHを強化する場合の主な目的は、悪意のある攻撃者がサーバーにアクセスしにくくすることです。 ただし、クライアント側での強化は大きく異なります。代わりに、SSH接続とクライアントを次のようなさまざまな脅威から防御および保護するために取り組んでいます。
- 「Person-in-the-Middle」攻撃として知られるネットワーク上の攻撃者。
- 不正な形式のデータパケット、不正な制御シーケンス、または大量のデータを送信してクライアントに過負荷をかける、侵害されたサーバーまたは悪意のあるサーバー。
- サーバーアドレスや構成値の入力ミスなどの人為的エラー。
このチュートリアルでは、Ubuntu 20.04 OpenSSHクライアントを強化して、発信SSH接続が可能な限り安全であることを確認します。
前提条件
このチュートリアルを完了するには、次のものが必要です。
-
SSHクライアントとして使用するデバイス。例:
- あなたのパソコン
- SSH「ジャンプホスト」または「要塞ホスト」
- Ubuntu 20.04を使用した初期サーバーセットアップに従ってセットアップされたUbuntu20.04サーバー(sudo非rootユーザーを含む)
-
接続するSSHサーバー。例:
これらの準備ができたら、root以外のユーザーとしてSSHクライアントデバイスにログインして開始します。
ステップ1—一般的な硬化
この最初のステップでは、SSHクライアントの全体的なセキュリティを向上させるために、いくつかの初期強化構成を実装します。
クライアントに最適な正確な強化構成は、独自の脅威モデルとリスクしきい値に大きく依存します。 ただし、この手順で説明する構成は、大多数のユーザーに適した、一般的なオールラウンドの安全な構成です。
OpenSSHクライアントの強化構成の多くは、/etc/ssh/ssh_config
にあるグローバルOpenSSHクライアント構成ファイルを使用して実装されます。 このファイルに加えて、一部の構成は、~/.ssh/config
にあるユーザーのローカルSSH構成ファイルを使用して設定することもできます。
このチュートリアルで強化オプションの大部分を設定します。 続行する前に、既存の構成ファイルのバックアップを作成して、万が一問題が発生した場合に復元できるようにすることをお勧めします。
次のcp
コマンドを使用して、ファイルのバックアップを作成します。
- sudo cp /etc/ssh/ssh_config /etc/ssh/ssh_config.bak
- cp ~/.ssh/config ~/.ssh/config.bak
これらのコマンドは、ファイルのバックアップコピーをデフォルトの場所に保存しますが、.bak
拡張子が追加されています。
ローカルSSH構成ファイル(~/.ssh/config
)は、過去に使用したことがない場合は存在しない可能性があることに注意してください。 この場合、今のところ無視しても問題ありません。
これで、nano
またはお気に入りのテキストエディタを使用してグローバル構成ファイルを開き、初期の強化対策の実装を開始できます。
- sudo nano /etc/ssh/ssh_config
注: OpenSSHクライアント構成ファイルには、多くのデフォルトのオプションと構成が含まれています。 既存のクライアント設定によっては、推奨される強化オプションのいくつかがすでに設定されている場合があります。
構成ファイルを編集する場合、一部のオプションは、行の先頭に単一のハッシュ文字(#
)を使用してデフォルトでコメント化される場合があります。 これらのオプションを編集する、またはオプションを有効にするには、ハッシュを削除してコメントを解除する必要があります。
まず、X11ディスプレイ転送を使用していない場合は、次のオプションを設定して無効にします。
ForwardX11 no
ForwardX11Trusted no
X11転送では、SSH接続を介したリモートグラフィカルアプリケーションの表示が可能ですが、これが実際に使用されることはめったにありません。 これを無効にすることで、悪意のあるサーバーや侵害された可能性のあるサーバーがX11セッションをクライアントに転送しようとするのを防ぐことができます。これにより、ファイルシステムのアクセス許可がバイパスされたり、ローカルキーストロークが監視されたりする場合があります。
次に、SSHトンネリングを無効にすることを検討してください。 SSHトンネリングは非常に広く使用されているため、有効にしておく必要がある場合があります。 あなたは一般的にあなたがそれを使用しているかどうかを知るでしょう。 特定のセットアップに必要ない場合は、さらに強化する手段として安全に無効にすることができます。
Tunnel no
サーバーがローカルSSHエージェントを使用して以降のSSH接続を認証することを要求しないようにするために、SSHエージェント転送が不要な場合は無効にすることも検討する必要があります。
ForwardAgent no
ほとんどの場合、SSHクライアントは、サーバーに接続するときにパスワード認証または公開鍵認証を使用するように構成されます。 ただし、OpenSSHクライアントは他の認証方法もサポートしており、その一部はデフォルトで有効になっています。 これらが不要な場合は、無効にして、クライアントの潜在的な攻撃対象領域をさらに減らすことができます。
GSSAPIAuthentication no
HostbasedAuthentication no
SSH内で利用可能な追加の認証方法のいくつかについて詳しく知りたい場合は、次のリソースを確認することをお勧めします。
OpenSSHクライアントを使用すると、サーバーに接続するときにカスタム環境変数を自動的に渡すことができます。たとえば、言語設定を設定したり、端末設定を構成したりできます。 ただし、これがセットアップで必要ない場合は、SendEnv
オプションがコメント化されているか、完全に削除されていることを確認することで、変数が送信されないようにすることができます。
# SendEnv
最後に、厳密なホストキーチェックが有効になっていることを確認し、リモートサーバーのホストキー/フィンガープリントが変更されたとき、または新しいサーバーに初めて接続したときに適切に警告されるようにする必要があります。
StrictHostKeyChecking ask
これにより、既知のホストキーが変更されたときにサーバーに接続できなくなります。これは、サーバーが再構築またはアップグレードされたことを意味するか、中間者攻撃が進行中であることを示している可能性があります。
新しいサーバーに初めて接続するとき、SSHクライアントは、ホストキーを受け入れて~/.ssh/known_hosts
ファイルに保存するかどうかを尋ねてきます。 ホストキーを受け入れる前に確認することが重要です。これには通常、サーバー管理者に問い合わせるか、サービスのドキュメントを参照する必要があります(GitHub / GitLabおよび他の同様のサービスの場合)。
ファイルを保存して終了します。
初期構成ファイルの強化が完了したので、SSHをテストモードで実行して、新しい構成の構文を検証する必要があります。
- ssh -G .
.
を任意のホスト名に置き換えて、Match
またはHost
ブロックに含まれる設定をテスト/シミュレーションできます。
構成ファイルに有効な構文がある場合、その特定の接続に適用されるオプションが出力されます。 構文エラーが発生した場合は、問題を説明する出力が表示されます。
新しい設定を有効にするためにシステムサービスを再起動する必要はありませんが、新しい設定を継承する場合は、既存のSSHセッションを再確立する必要があります。
このステップでは、OpenSSHクライアント構成ファイルの一般的な強化を完了しました。 次に、SSH接続で使用できる暗号を制限します。
ステップ2—使用可能な暗号を制限する
OpenSSHは、接続を介してデータを暗号化するために、さまざまな暗号化アルゴリズムをサポートしています。 このステップでは、SSHクライアント内の非推奨またはレガシー暗号スイートを無効にします。
nano
またはお好みのテキストエディタでグローバル設定ファイルを開くことから始めます:
- sudo nano /etc/ssh/ssh_config
既存のCiphers
構成行の前に単一のハッシュ(#
)を付けて、コメントアウトされていることを確認します。
次に、ファイルの先頭に以下を追加します。
Ciphers -arcfour*,-*cbc
これにより、従来の Arcfour暗号と、 Cipher Block Chaining(CBC)を使用するすべての暗号が無効になります。これらの暗号の使用は推奨されなくなりました。
これらのレガシー暗号のみをサポートするシステムに接続する必要がある場合は、Match
ブロックを使用して、特定のホストに必要な暗号を明示的に再度有効にすることができます。 たとえば、特定のレガシーホストに対して3des-cbc
暗号を有効にするには、次の構成を使用できます。
Match host legacy-server.your-domain
Ciphers +3des-cbc
編集が完了したら、ファイルを保存して終了します。 nano
を使用している場合は、CTRL+O
、ENTER
の順に押してファイルを保存し、CTRL+X
を押して終了します。
最後に、手順1と同様に、SSHクライアント構成をテストして、潜在的なエラーがないかどうかを確認します。
- ssh -G .
Match
ブロックを追加して特定のホストのレガシー暗号を有効にしている場合は、関連するホストアドレスを指定することで、テスト中にその構成を具体的にターゲットにすることもできます。
- ssh -G legacy-server.your-domain
SSHクライアントで使用可能な暗号を保護しました。 次に、SSHクライアントで使用されるファイルのアクセス許可を確認します。
ステップ3—構成ファイルと秘密鍵のアクセス許可を保護する
この手順では、SSHクライアント構成ファイルと秘密鍵のアクセス許可をロックダウンして、偶発的または悪意のある変更、または秘密鍵の開示を防止します。 これは、複数のユーザー間で共有クライアントデバイスを使用する場合に特に便利です。
デフォルトでは、Ubuntuの新規インストールでは、OpenSSHクライアント構成ファイルは、各ユーザーが自分のローカル構成ファイル(~/.ssh/config
)のみを編集できるように構成されており、編集するにはsudo/administrativeアクセスが必要です。システム全体の構成(/etc/ssh/ssh_config
)。
ただし、場合によっては、特に長期間存在しているシステムでは、これらの構成ファイルのアクセス許可が誤って変更または調整された可能性があるため、構成が安全であることを確認するためにリセットすることをお勧めします。
stat
コマンドを使用して、システム全体のOpenSSHクライアント構成ファイルの現在のアクセス許可値を確認することから始めることができます。このコマンドを使用して、ステータスまたはファイルやファイルシステムオブジェクトを表示できます。
- stat -c "%a %A %U:%G" /etc/ssh/ssh_config
-c
引数を使用して、カスタム出力形式を指定します。
注:macOSなどの一部のオペレーティングシステムでは、-c
ではなく、-f
オプションを使用してカスタム形式を指定する必要があります。
この場合、%A %a %U:%G
オプションは、ファイルのアクセス許可を8進数で人間が読める形式で印刷し、ファイルを所有するユーザー/グループも印刷します。
これにより、次のようなものが出力されます。
Output644 -rw-r--r-- root:root
この場合、権限は正しく、 root がファイルを完全に所有し、rootのみがファイルへの書き込み/変更の権限を持っています。
注:続行する前にLinuxのアクセス許可に関する知識を更新したい場合は、Linuxのアクセス許可の概要を確認してください。
ただし、独自の出力が異なる場合は、次のコマンドを使用してアクセス許可をデフォルトにリセットする必要があります。
- sudo chown root:root /etc/ssh/ssh_config
- sudo chmod 644 /etc/ssh/ssh_config
この手順の前半からstat
コマンドを繰り返すと、システム全体の構成ファイルの正しい値を受け取るようになります。
次に、ローカルSSHクライアント構成ファイルがある場合は、それに対して同じチェックを実行できます。
- stat -c "%a %A %U:%G" ~/.ssh/config
これで、stat
コマンドは次のように出力するはずです。
Output644 -rw--r--r-- user:user
独自のクライアント構成ファイルのアクセス許可のアクセス許可が異なる場合は、前の手順と同様に、次のコマンドを使用してそれらをリセットする必要があります。
- chown user:user ~/.ssh/config
- chmod 644 ~/.ssh/config
次に、~/.ssh
ディレクトリ内にある各SSH秘密鍵のアクセス許可を確認できます。これらのファイルには自分だけがアクセスでき、システム上の他のユーザーはアクセスできないためです。
まず、各秘密鍵の現在のアクセス許可と所有権の値を出力します。
- stat -c "%a %A %U:%G" ~/.ssh/id_rsa
これにより、次のようなものが出力されます。
Output600 -rw------- user:user
秘密鍵ファイルのアクセス許可を適切にロックダウンすることは非常に重要です。ロックダウンしないと、デバイスの他のユーザーがそれらを盗み、関連するサーバーまたはリモートユーザーアカウントにアクセスする可能性があります。
権限が適切に構成されていない場合は、各秘密鍵ファイルで次のコマンドを使用して、それらを安全なデフォルトにリセットします。
- chown user:user ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
この手順では、SSHクライアント構成ファイルと秘密鍵のファイル権限を評価してロックダウンしました。 次に、アウトバウンド許可リストを実装して、クライアントが接続できるサーバーを制限します。
ステップ4—ホスト許可リストを使用して発信接続を制限する
この最後のステップでは、SSHクライアントが接続できるホストを制限するために、送信許可リストを実装します。 これは、SSHジャンプホストまたは要塞ホストだけでなく、共有/マルチユーザーシステムで特に役立ちます。
このセキュリティ制御は、サーバーアドレスやホスト名の入力ミスなど、人為的なエラーや間違いから保護するために特別に設計されています。 これは、ユーザーがローカル構成ファイルを編集することで簡単に回避できるため、悪意のあるユーザー/アクターに対する防御として機能するようには設計されていません。
ネットワークレベルでアウトバウンド接続を制限する場合、これを行う正しい方法はファイアウォールルールを使用することです。 これはこのチュートリアルの範囲を超えていますが、 UFW Essentials:Common Firewall RulesandCommandsを確認できます。
ただし、フェイルセーフを追加する場合は、このセキュリティ制御が役立つ場合があります。
これは、SSHクライアント構成ファイル内のワイルドカードルールを使用して、特定のアドレスまたはホスト名への接続を除くすべてのアウトバウンド接続を nullrouteすることで機能します。 つまり、誤ってサーバーアドレスを誤って入力したり、想定外のサーバーに接続しようとしたりした場合、リクエストはすぐに停止され、間違いを認識して修正措置を講じることができます。
これは、システムレベル(/etc/ssh/ssh_config
)またはローカルユーザー構成ファイル(~/.ssh/config
)のいずれかで適用できます。 この例では、ローカルユーザー構成ファイルを使用します。
nano
を使用してファイルを開き、まだ存在しない場合はファイルを作成することから始めます。
- nano ~/.ssh/config
ファイルの最後に、許可されたIPアドレスとホスト名の独自のリストに置き換えて、次のコンテンツを追加します。
Match host !203.0.113.1,!192.0.2.1,!server1.your-domain,!github.com,*
Hostname localhost
この構成は、SSHクライアントに、リストに含まれていないのホストまたはIPの場合、接続を試みる前に、代わりにlocalhost
という名前に置き換える必要があることを通知します。 Match
行の末尾に感嘆符オプションが付いていないワイルドカード(*
)オプションにより、リストに含まれていないホストはデフォルトでnullルーティングされます。
IPアドレスまたはホスト名の前に感嘆符(!
)を付ける必要があります。これは、SSHにホスト名またはIPアドレスにヌルルーティングを適用しない
マシン上でもSSHサーバーを実行している場合は、localhost
以外のホスト名値を使用することをお勧めします。これにより、ヌルルーティングされた接続が独自のローカルSSHサーバーに送信される可能性があります。逆効果または混乱する。 null
、do-not-use
、disallowed-server
など、任意のnullroutedホスト名を使用できます。
変更を加えたら、ファイルを保存して閉じます。
これで、SSHクライアントを使用して許可されていない宛先に接続を試みることにより、構成が機能していることをテストできます。 例えば:
- ssh disallowed.your-domain
構成が正しく機能している場合は、次のようなエラーがすぐに表示されます。
OutputCannot connect to localhost: connection refused
ただし、許可された宛先に接続しようとすると、接続は通常どおり成功します。
この最後のステップでは、SSHクライアントを使用する際の人為的エラーやミスから保護するために、いくつかの追加のフェイルセーフを実装しました。
結論
この記事では、OpenSSHクライアントの構成を確認し、さまざまな強化策を実装しました。
これにより、発信SSH接続のセキュリティが向上し、ローカル構成ファイルが他のユーザーによって誤ってまたは悪意を持って変更されないようにすることができます。
OpenSSHクライアントとそれに関連する構成ファイルのマニュアルページを確認して、さらに微調整する可能性のあるものを特定することをお勧めします。
最後に、サーバー側でもOpenSSHを強化したい場合は、 Ubuntu20.04でOpenSSHを強化する方法を確認してください。