PowerShell リモーティング(PSRemoting)の説明:究極のガイド

PowerShellリモート(PSRemoting)は、PowerShell全体で最も使用される機能の1つです。なぜなら、非常に便利だからです!1つのコマンドを使用するだけで、リモートコンピューターの1台または数千台にシームレスに接続し、コマンドを実行することができます。

この究極のガイドでは、PSRemotingについて詳しく説明します。PSRemotingとは何か、どのように動作し、PSRemotingが機能するためのさまざまな技術について学びます。このガイドでは、PSRemotingの使用方法については説明しません。その代わり、多くのハウツーガイドへの参照がたくさんあります。

PSRemotingの動作原理

要するに、PSRemotingを使用すると、前に座っているかのようにリモートコンピューター上でコマンドを実行できます。PSRemotingは、ユーザーを接続し認証し、リモートコマンドを実行し、そのコマンドの出力をローカルコンピューターに返す一連の機能を提供します。

PSRemotingは、telnetやSSH、さらにはpsexecのようなものと考えてください。PowerShell内でコンピューター上でコマンドを実行するための方法です。

PSRemotingは、セッションと呼ばれる概念に大きく依存しています。セッションとは、内部でコマンドを実行するリモートシェルを表す用語です。これらのセッションを作成するプロセスは、多くのステップを経てバックグラウンドで行われます。

PSRemotingセッションを開始すると、以下の大まかなステップが実行されます:

  • クライアントはWinRMリスナー(WinRmリスナーについての詳細は後述)に接続しようとします。WinRMリスナーは、宛先サーバー上で実行される小さなWebサービスです。 WinRMは、Microsoftが作成した標準であるWSManの実装です。WSManは、Dell、Intel、Sun Microsystemsなどの他の多くの大手テクノロジー企業と共同で作成されたオープンな標準です。
  • クライアントがHTTPまたはHTTPSプロトコルを介してリスナーに接続すると、認証プロセスが開始されます。認証の各方法の詳細は後で説明しますが、今のところ、クライアントはいかなる方法であれサーバーに資格情報を渡す必要があることを知っておいてください。
  • クライアントがサーバーに接続し、認証された後、PSRemotingはセッションを作成します。
  • PSRemotingがセッションを作成すると、それはビジネスに開かれた状態になります。この時点で、クライアントはサーバーに情報を送信し、サーバーは必要な出力を返すことができます。この通信は通常、暗号化されます。
Creating a PSSession with PSRemoting

WinRMリスナー:接続可能なリスナー

A client needs somewhere to connect to when coming in from over the network. The client needs to “talk” to something that’s “listening” on the other side; that “listening” is the role of the WinRM listener.

以下のwinrmコマンドを使用することで、任意のWindowsコンピューター上で実行されているすべてのWinRmリスナーを確認できます。

winrm e winrm/config/listener
WinRm listeners

WinRmリスナーにはいくつか重要なコンポーネントがあります。それらは次のとおりです:

  • A listening address – The listening address is the IP address that they bind to. This is the IP address that a client connects to.
  • 輸送のタイプ – すべてのWinRMリスナーは、HTTPまたはHTTPSを使用して通信するための輸送方法が必要です。
  • オプションの証明書のサムプリント – WinRMリスナーが輸送にHTTPSを使用する場合、クライアントの認証に使用するプライベートキーを知る必要があります。このキーは証明書のサムプリントを使用して見つけることができます。

可能な場合は、HTTPSリスナーを使用してください。HTTPSトランスポートを設定することで、サーバーの正当性を確保し、認証および輸送トラフィックの両方を暗号化してセキュリティを向上させることができます。証明書を発行する際には、自己署名証明書ではなく、信頼できる認証機関からの証明書を使用してください。

信頼できるホスト:サーバーの検証

WinRMを介したPSRemoting認証の仕組み

上記のように、PSRemotingが最初に行う手順の1つは認証です。認証は、PSRemotingの中で最も複雑でありながらも最も重要な部分の1つです。

PSRemotingが最初に導入されたとき、Windows Remote Management(WinRM)の認証メカニズムしかありませんでしたが、現在ではSSHを使用して認証することもできます(後で説明します)。

WinRMは、ユーザー名とパスワードまたはユーザー名/パスワードの組み合わせのさまざまなタイプの証明書を使用して、2つの異なるタイプの認証をサポートしています。

基本認証

最も簡単でありながらもセキュリティの低い認証のタイプは、Basic認証です。この認証のタイプは、HTTPプロトコルに組み込まれています。Basic認証では、クライアントからリスナーへのHTTPヘッダーに、ユーザー名とパスワードをベース64でエンコードしたものが送信されます。

Basic認証はユーザー名とパスワードをエンコードするだけで暗号化は行わないため、ネットワーク上で簡単に認証情報を傍受される可能性があります。

必要な場合を除き、Basic認証は使用しないでください。WinRMはより安全な認証方法がたくさんあります!

Kerberos認証

クライアントとサーバーがActive Directory環境にある場合、おそらく既にネットワークサービスの多くでKerberos認証が使用されています。

WinRMクライアントがKerberosを使用してWinRMリスナーに接続しようとすると、

  • サーバーは最初にドメインコントローラーからクライアントのセッションキーまたはチケット発行チケットを取得しようとします。
  • ドメインコントローラーはクライアントとサーバーを検索し、両方が有効で信頼できる場合、トークンを発行します。
  • サーバーはその後、ユーザー名とパスワードではなく、信頼されたトークンを使用してクライアントの接続を検証します。

Kerberos認証中、ドメインコントローラーはチケット取得の段階でクライアントとサーバーの両方を検証し、悪意のある第三者がサーバーをなりすますことを防止します。

Kerberosは、クライアントとサーバーがActive Directoryドメインのメンバーである場合にデフォルトの認証方式として使用される、堅牢で安全な認証方法です。ただし、クライアントとサーバーは同じActive Directoryフォレストに参加しているか、またはフォレスト間で信頼関係が設定されている必要があります。

Negotiate認証

WinRmはKerberosを使用しようと試み、利用できない場合はNT Lan Manager(NTLM)と呼ばれる認証プロトコルを使用しようとします。

NTLMを使用する場合:

  • サーバーはクライアントに文字列を送信します。
  • クライアントはその文字列をユーザーのパスワードのハッシュで暗号化します。
  • 暗号化された文字列は、サーバーに送り返され、サーバーはユーザー名、元の文字列、暗号化された文字列をドメインコントローラーに送信します。
  • ドメインコントローラーはそのユーザーのパスワードハッシュを参照し、同じ暗号化プロセスを文字列に対して繰り返し行い、一致するかどうかを確認します。

NTLMはクライアントの検証には適していますが、Kerberosとは異なりサーバの検証は行いません。そのため、サーバが攻撃者によってなりすまされる可能性があり、複数の攻撃手法が開かれます。

サーバ認証証明書を使用してサーバも検証し、HTTPS WinRMリスナーに割り当てることで、NTLMのセキュリティを向上させることができます。この設定では、クライアントはドメインコントローラに対してNTLMで認証され、サーバは信頼された証明書で認証されます。この設定により、クライアントとサーバの両方の認証が提供されますが、NLTMプロトコルは古い暗号化方式と古いキーサイズを使用しています。

これらの理由から、NLTMはサーバを信頼されたホストリストに追加するか、HTTPSリスナーを使用する場合にのみ使用可能です。

ダイジェスト認証

WinRMで使用する最も一般的でない認証方法の1つはダイジェスト認証です。NTLMとダイジェストは似たような認証方法です。NTLMと同様に、ダイジェストはユーザのパスワードのハッシュで暗号化された一意の文字列を生成します。そのため、パスワードをサーバに送信する必要はありません。

ダイジェストはMD5ハッシュアルゴリズムを使用してパスワードを暗号化します。このアルゴリズムの選択により、ダイジェストは一般的には時代遅れであり、使用すべきではありません。MD5にはさまざまな既知の脆弱性があり、暗号化には適していません。

Credential Security Support Provider(CredSSP)

CredSSPについて詳しく説明することは必要ありません。なぜなら、PSRemotingとWinRMにおいて、CredSSPは通常「セカンドホップ問題」と呼ばれる理由で実装されるからです。以下で詳しく説明します。

CredSSP認証が構成されている場合、WinRMクライアントとサーバーは両方ともユーザーとクライアントの両方を認証するためにネゴシエート認証を使用します。しかし、認証が完了すると、ユーザーのパスワードがサーバーに送信されます。

パスワードは認証プロセスの完了後に送信されるため、現在は暗号化されています。CredSSPはまた、パスワードをTLSセッションキー で暗号化するため、暗号化された文字列はセッションごとに一意になります。

CredSSPは、認証後にサーバーがあなたの代わりに他の何かに接続できるため便利です。ただし、これが起こると、接続したサーバーに対してユーザーパスワードを完全に信頼することになります。

証明書ベースの認証

PSRemotingで使用する最も安全な認証方法は、証明書ベースの認証です。この認証方法では、クライアントとサーバーで典型的な鍵交換が行われ、証明書の検証が行われます。

WinRMは、WinRm内のサーバー上のユーザーをマッピングすることによってユーザーを認証します。認証プロセスで渡されるのは公開鍵だけなので、非常に安全な認証方法です。

一番安全な認証方法ではありますが、設定には手間がかかるため、あまり一般的ではありません。なぜなら、次の手順が必要だからです。

  • 証明書機関を作成する
  • ユーザー認証証明書を作成する
  • 公開鍵を共有する
  • 適切な権限を持つローカルユーザーアカウントを使用する(おそらくAdministratorsグループ)
  • HTTPSリスナーを設定する
  • …その他の手順

ドメインユーザーは、クライアントとサーバーがActive Directoryの一部であっても、証明書で認証することはできません。

Windows OSのデフォルト認証設定

これまでにさまざまな認証オプションが利用可能であることがわかりましたが、どの認証方法がデフォルトで利用可能かを知る方法はありますか?以下の表は、WinRMクライアントがデフォルトで有効化されているか、およびその特定の認証タイプがデフォルトで有効化されているかを示す2列の表です。

上記のすべての認証タイプは設定可能ですが、以下の表を使用すると、自分で設定する必要がある内容がわかります。

Method Client Service
Basic Enabled Disabled
Kerberos Enabled Enabled
Negotiate Enabled Enabled
CredSSP Disabled Disabled
Digest Enabled Disabled
Certificate Enabled Disabled
Windows OS Authentication Defaults

セカンドホップまたはダブルホップ問題

PSRemotingの最大の問題の一つは、「セカンドホップ問題」または「ダブルホップ」として知られています。これは、PSRemotingを介してリモートシステムに接続し、その後別のリモートコンピュータに接続する必要がある場合に発生します。

この状況は問題です。なぜなら、WinRmクライアントが最初のリモートコンピュータに認証する際、サーバーはパスワードを送信せずに元のクライアントのアイデンティティのみを検証するからです。最初の接続のサーバーから2番目のコンピュータに接続しようとすると、最終的なサーバーはユーザーのアイデンティティを検証する方法を持っていません。

ダブルホップ問題は、CredSSPまたはKerberos委任を使用していくつかの異なる方法で解決することができます。

CredSSPの使用

ダブルホップ問題を回避する最も一般的な方法は、CredSSPを使用することです。 CredSSP認証は、最初のリモートサーバーにユーザーの資格情報を保存し、サーバーがクライアントに変わった際に2番目のリモートサーバーに渡すことで、この状況を回避します。

ただし、CredSSPを使用する場合には注意が必要です。最初のリモートサーバーに保存されているユーザーの資格情報は、平文で保存されるため、明らかなセキュリティ上の懸念が生じます。新しいオペレーティングシステムでは、パスワードのハッシュとKerberosのチケット発行チケット(TGT)が使用されます。これらは、平文のパスワードと同様にネットワーク上のどこでもユーザーとして認証するために使用できますが、リスクを少し低くすることができます。

Negotiateを使用すると、クライアントとサーバーは情報をやり取りして、自分たちが誰であるかを検証しますが、ユーザーのパスワードはアクセスできません。このセキュリティ機能により、1つ目のサーバーが2つ目のサーバーに接続したときにあなたを認証する方法はありません。

ケルベロス委任を使用する

前述のように、ケルベロスはPSRemotingを設定する一般的な方法です。普及しているActive Directoryの一部であり、デフォルトで設定されているため、非常に一般的です。ケルベロス自体はWinRMの認証には適していますが、ダブルホップの問題を解決することはできません。

ダブルホップのシナリオを回避するために、ケルベロス委任と呼ばれる第二の認証方法を使用できます。ケルベロス委任にはさまざまな種類がありますが、CredSSPの代替として使用できる唯一のセキュリティが十分な種類は、ケルベロス制約 委任、具体的にはリソースベースのケルベロス制約委任です。

リソースベースのケルベロス制約委任は、この場合、コンピューターなどのドメインリソースに基づいてケルベロス認証トークンを委任する形式ですが、特定のリストのケルベロス(Active Directory)オブジェクトに制約されます。

このKerberos委任を設定するには、チェーンの3番目のコンピューターのADComputerオブジェクトを編集する必要があります。たとえば、ClientAからServerBからServerCにリモート接続する場合、ServerCのADComputerオブジェクトを編集する必要がありますが、ServerBも知る必要があります。この例では、PowerShellで以下のコマンドを実行します:

リソースベースのKerberos委任は、リモート接続(例:…または…)では機能しますが、PSRemotingでは機能しません。PSRemotingを使用してWinRM経由でコンピューターに接続している場合、3番目のコンピューターに接続することはできません。

リソースベースのKerberos制約委任の設定は、Set-ADComputerコマンドレットを使用した1行のPowerShellコマンドです。たとえば、PSRemotingを介してServerBClientAから接続していて、ServerCに…で接続したい場合、以下のPowerShellコマンドを実行してください。

Set-ADComputer -Identity ServerC -PrincipalsAllowedToDelegateToAccount ServerB

WinRMは失敗した接続を15分間キャッシュします。この機能のため、リソースベースのKerberos制約委任を設定した後でも、3番目のコンピューターに接続できない場合があります。これを解消するには、待機するか、3番目のコンピューターでコマンドklist purge -LI 0x3e7を実行して失敗したKerberosトークンをクリアします。

SSH経由でのPSRemoting認証の動作方法

WinRm認証はPSRemotingにおける最も一般的な認証方法ですが、PowerShell v6以降では別の方法、SSHも使用できます。SSHを認証方法として使用することで、LinuxとPSRemotingを使用することができます。

WinRmとは異なり、SSHはクライアントとサーバーの両方で追加の設定が必要です。WindowsクライアントにSSHクライアントを設定するなどの手順が必要です。

SSHを使用して認証を処理する場合、SSHがサポートする認証の種類に制限があります。主な2つはパスワードベースと公開鍵ベースです。

SSHでサポートされる他の認証の種類もありますが、通常はパスワードと公開鍵ベースのオプションよりも安全性が低いと見なされるため、これらの2つに焦点を当てます。

パスワード認証

PSRemotingでのSSH認証の最も簡単な方法は、パスワードベースの認証です。パスワードベースの認証では、自分自身を確認するためにパスワードを提供することができます。

SSHの認証プロセスでは、SSH接続が確立された後にパスワードが交換され、パスワードは送信中に暗号化されます。KerberosのようなWinRMで使用される一部の認証方法とは異なり、この認証方法ではパスワード全体がサーバーに送信されます。

SSHのパスワード認証は、HTTPSリスナーを使用したWinRMのBasic認証方法に類似しています。パスワード自体はあまり意味のある方法で保護されていませんが、パスワードを含む接続全体が暗号化され、サーバーは証明書に基づいて検証されます。

証明書ベースの認証

パスワードベースの認証は簡単に設定でき、使い方も直感的ですが、2つの問題があります。

  1. まず、セキュアな自動認証方法が存在しないという点です。
  2. パスワード認証はパスワードをネットワーク上に送信します。パスワードはSSH接続内で暗号化されますが、サーバーはパスワード全体を受け取ります。サーバーが何らかの方法で侵害されると、セキュリティ上の問題になる可能性があります。

一方、証明書ベースの認証では、パスワードのような機密データをネットワーク上に送信しません。代わりに、サーバーは公開鍵のコピーを持ち、クライアントは秘密鍵のコピーを持っており、交渉はサーバー上で行われます。

A rough workflow goes as follows:

  1. クライアントが認証を試みると、公開鍵のIDまたはサムプリントをサーバーに送信します。
  2. サーバーが公開鍵を認可リストに登録している場合、公開鍵で暗号化された文字列で応答します。
  3. その後、クライアントは秘密鍵で文字列を復号化します。
  4. その後、プライベートキーはセッションIDとハッシュ化されます。
  5. セッションIDはサーバーに送信され、元の文字列とセッションIDを使用して生成されたハッシュと比較されます。
  6. クライアントからのセッションIDのハッシュとサーバー上のセッションIDが一致した場合、クライアントは認証され、接続が許可されます。

公開キーで暗号化されたものは関連するプライベートキーでのみ復号化できます。プライベートキーで暗号化されたものは公開キーでのみ復号化できます。セッションIDも含まれており、それによって提供されるものは完全な転送秘密(PFS)と呼ばれます。

PFSは、プライベートキーが危険にさらされた場合、攻撃者が行き来したすべてのメッセージを復号化することができないようにセキュリティを提供します。ユニークなセッションIDは、通信を暗号化するために使用される共有秘密が各セッションごとに異なることを意味します。

WinRmのようなSSHにおける証明書ベースの認証では、プライベート/公開キーペアの生成やリモートサーバーでの公開キーの承認など、追加の手順が必要です。

接続に必要なユーザー権限

デフォルトでは、2つのローカルユーザーグループがPSRemotingを使用してサーバーにリモートで接続できます。それは管理者リモート管理ユーザーです。

リモートサーバーには、ローカルのAdministratorsグループにユーザーアカウントを追加することができますが、常に最小限のアクセス権を提供する必要があります。ユーザーが単にリモートコンピュータにPSRemotingで接続する必要がある場合、ユーザーアカウントをRemote Management Usersグループに追加することができます。ただし、Administratorsではありません。

PSRemotingアクセスをさらに制御するために、Just Enough Administration(JEA)という機能も使用できます。JEAを使用すると、非管理者ユーザーはPowerShellの制約言語モードで管理者として特定のコマンドのみを実行できます。

暗黙のリモーティング vs 「明示的な」リモーティング

以前にPSRemotingを使用したことがある場合、Invoke-CommandNew-PSSessionEnter-PSSessionなどのコマンドにはなじみがあるかもしれません。これらのコマンドを実行すると、いかにリモートコンピュータに接続しているかが明確になります。PSRemotingを明示的に使用しています。

PSRemoting固有のコマンドを実行すると、そのコマンドを明示的に実行していますが、別の方法があることを知っていましたか?直接Invoke-Commandや他のコマンドレットを呼び出す代わりに、暗黙のPSRemotingを利用することができます。

暗黙のPSRemotingは、PowerShellセッション内でコマンドをローカルで実行しているように見えますが、実際にはリモートマシンで実行されています。これの良い例は、システムにインストールされていないモジュールを使用する場合です。ローカルにインストールする代わりに、PSSessionからコマンドをエクスポートして、それらをローカルにインストールされているかのように実行することができます。

以下のスクリーンショットでは、Test-PendingRebootコマンドが存在しないことがわかります。次に、リモートマシンに接続し、そのコマンドをエクスポートします。

Export-PSSession example

次に、そのモジュールがインポートされた場合、Test-PendingRebootコマンドを実行できます。以下に示されているように、出力のコンピュータ名がPowerShellが実行されているデバイスの名前ではなく、コマンドがインポートされたデバイスの名前であることに注意してください。

Implicit remoting in action

Source:
https://adamtheautomator.com/psremoting/