AD Connector の前提条件 - AWS Directory Service

「翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。」

AD Connector の前提条件

AD Connector を使用して既存のディレクトリに接続するには、以下が必要です。

VPC

以下の手順での VPC の設定:

  • 少なくとも 2 つのサブネット。各サブネットはそれぞれ異なるアベイラビリティーゾーンにある必要があります。

  • VPC は、仮想プライベートネットワーク (VPN) 接続または AWS Direct Connect を通じて既存のネットワークに接続されている必要があります。

  • VPC にはデフォルトのハードウェアテナンシーが必要です。

AWS Directory Service は、2 つの VPC 構造を使用します。ディレクトリを構成する EC2 インスタンスは、AWS アカウントの外部で実行され、AWS によって管理されます。これらには、2 つのネットワークアダプタ (ETH0 および ETH1) があります。ETH0 は管理アダプタで、アカウント外部に存在します。ETH1 はアカウント内で作成されます。

ディレクトリのデプロイ先 VPC と競合しないよう、ディレクトリの ETH0 ネットワークの管理 IP 範囲がプログラムで選択されます。この IP 範囲は次のいずれかのペアとすることができます (ディレクトリは 2 つのサブネットで実行されるため)。

  • 10.0.1.0/24 および 10.0.2.0/24

  • 192.168.1.0/24 および 192.168.2.0/24

ETH1 CIDR の最初のオクテットを調べることで、競合が回避されます。オクテットが 10 で始まる場合、192.168.0.0/16 VPC と、192.168.1.0/24 および 192.168.2.0/24 サブネットが選択されます。最初のオクテットが 10 以外である場合は、10.0.0.0/16 VPC と、10.0.1.0/24 および 10.0.2.0/24 サブネットが選択されます。

この選択アルゴリズムには VPC 上のルートは含まれません。したがって、このシナリオでは IP ルーティングの競合が発生する可能性があります。

詳細については、Amazon VPC ユーザーガイド の以下のトピックを参照してください。

AWS Direct Connect の詳細については、『AWS Direct Connect ユーザーガイド』を参照してください。

既存の Active Directory

Active Directory ドメインを持つ既存のネットワークに接続する必要があります。

注記

AD Connector は、単一ラベルドメインによる信頼をサポートしていません。

このドメインの機能レベルは Windows Server 2003 以上である必要があります。AD Connector は Amazon EC2 インスタンスでホストされているドメインへの接続にも対応しています。

注記

AD Connector は、Amazon EC2 のドメイン結合機能と併用する場合の読み取り専用ドメインコントローラー (RODC) はサポートしていません。

サービスアカウント

次の権限が委任されている既存のディレクトリのサービスアカウントの認証情報が必要です。

  • ユーザーおよびグループの読み取り - 必須

  • ドメインへのコンピュータの参加 - シームレスなドメイン参加と Amazon WorkSpaces を使用する場合のみ必須

  • コンピュータオブジェクトの作成 - シームレスなドメイン参加と Amazon WorkSpaces を使用する場合にのみ必須。

詳細については、権限をサービスアカウントに委任する を参照してください。

ユーザーアクセス許可

すべての Active Directory ユーザーは、各ユーザー独自の属性を読み取るアクセス許可を持っている必要があります。具体的には次の属性があります。

  • GivenName

  • SurName

  • Mail

  • SamAccountName

  • UserPrincipalName

  • UserAccountControl

  • MemberOf

デフォルトでは、Active Directory ユーザーには、これらの属性に対する読み取りアクセス許可があります。ただし、時間の経過に伴い管理者がこれらのアクセス許可を変更する可能性があるため、AD Connector を初めて設定する前に、ユーザーがこれらの読み取りアクセス権限を持っているかどうか確認することをお勧めします。

IP アドレス

既存のディレクトリの 2 つの DNS サーバーまたはドメインコントローラーの IP アドレスを取得します。

AD Connector は、ディレクトリに接続するときに _ldap._tcp.<DnsDomainName> および _kerberos._tcp.<DnsDomainName> SRV レコードをこれらのサーバーから取得します。そのため、これらのサーバーにこれらの SRV レコードが含まれている必要があります。AD Connector は、LDAP と Kerberos サービスの両方を提供する共通ドメインコントローラーを検索しようとします。そのため、これらの SRV レコードには、少なくとも 1 つの共通ドメインコントローラーが含まれている必要があります。SRVレコードの詳細については、 SRVリソースレコード Microsoft 上で TechNet.

サブネット用のポート

対象 AD Connector ディレクトリ要求を既存のActive Directoryドメイン コントローラにリダイレクトするには、既存のネットワークのファイアウォールで、 CIDRs 2つのサブネットを Amazon VPC.

  • TCP/UDP 53 - DNS

  • TCP/UDP 88 - Kerberos 認証

  • TCP/UDP 389 - LDAP

これらは、AD Connector をディレクトリに接続する前に必要な最小限のポートです。固有の設定によっては、追加ポートが開かれていることが必要です。

注記

既存のActive DirectoryドメインのDNSサーバまたはドメイン コントローラ サーバがVPC内にある場合、それらのサーバに関連するセキュリティ グループは、 CIDRs VPC の両方のサブネットの です。

追加のポート要件については、以下を参照してください。 ADおよびAD DSポート要件 Microsoft 上で TechNet.

Kerberos 事前認証

ユーザーアカウントの Kerberos 事前認証を有効にしておく必要があります。この設定を有効にする方法の詳細については、「Kerberos の事前認証が有効に設定されていることを確認する」を参照してください。この設定に関する一般的な情報については、 事前認証 Microsoft 上で TechNet.

暗号化タイプ

AD Connector は、Active Directory ドメインコントローラーへの Kerberos を介した認証時に、以下のタイプの暗号化をサポートしています。

  • AES-256-HMAC

  • AES-128-HMAC

  • RC4-HMAC

AWS シングルサインオン の前提条件

AWS シングルサインオン (AWS SSO) を AD Connector で使用する場合は、次の条件が満たされていることを確認する必要があります。

  • あなたの AD Connector は、 AWS 組織 管理アカウント.

  • AWS SSO のインスタンスが AD Connector の設定先と同じリージョンにある。

詳細については、AWS シングルサインオン ユーザーガイドの「AWS SSO の前提条件」を参照してください。

多要素認証の前提条件

AD Connector ディレクトリで多要素認証をサポートするには、以下が必要です。

  • 2 個のクライアントのエンドポイントを持つ、既存のネットワーク内の Remote Authentication Dial-In User Service (RADIUS) サーバー。RADIUS クライアントエンドポイントには次の要件があります。

    • エンドポイントを作成するには、AWS Directory Service サーバーの IP アドレスが必要です。これらの IP アドレスは、ディレクトリの詳細の [Directory IP Address] フィールドから取得できます。

    • 2 つの RADIUS エンドポイントが同じ共有シークレットコードを使用する必要があります。

  • 既存のネットワークでは、AWS Directory Service サーバーからのデフォルトの RADIUS サーバーポート (1812) を介した受信トラフィックが許可されている必要があります。

  • RADIUS サーバーと既存のディレクトリの間でユーザー名が同じである必要があります。

MFA で AD Connector を使用する場合の詳細については、「AD Connector の多要素認証を有効にするには」を参照してください。

権限をサービスアカウントに委任する

既存のディレクトリに接続するには、特定の権限が委任されている、既存のディレクトリの AD Connector サービスアカウントの認証情報が必要です。[Domain Admins (ドメインの管理者)] グループのメンバーにはディレクトリに接続するための十分な権限がありますが、ベストプラクティスとして、そのディレクトリへの接続に必要な最小限の権限を含むサービスアカウントを使用してください。以下の手順では、Connectors という名前の新しいグループを作成後、AWS Directory Service をこのグループに接続するために必要な権限を委任し、新しいサービスアカウントをこのグループに追加する方法を説明します。

この手順はディレクトリに結合され、[Active Directory User and Computers] MMC スナップインがインストールされたマシンで実行される必要があります。ドメイン管理者としてログインする必要があります。

権限をサービスアカウントに委任するには

  1. [Active Directory User and Computers] を開き、ナビゲーションツリーのドメインルートを選択します。

  2. 左のペインの一覧で、[Users] を右クリックし、[New] を選択して、[Group] を選択します。

  3. [New Object - Group] ダイアログボックスで次のように入力し、[OK] をクリックします。

    Field 値/選択
    グループ名 Connectors
    Group scope グローバル
    Group type Security
  4. [Active Directory User and Computers] ナビゲーションツリーで、ドメインルートを選択します。メニューで [Action] を選択し、[Delegate Control] を選択します。あなたの AD Connector は に接続されています AWS Managed Microsoft ADドメインのルートレベルで代理コントロールにアクセスすることはできません。この場合、制御を委任するには、コンピュータオブジェクトが作成されるディレクトリ OU の下の OU を選択します。

  5. [Delegation of Control Wizard] ページで [Next] をクリックし、[Add] をクリックします。

  6. [Select Users, Computers, or Groups] ダイアログボックスで Connectors と入力し [OK] をクリックします。複数のオブジェクトがある場合は、上記で作成した Connectors グループを選択します。[Next] をクリックします。

  7. [Tasks to Delegate] ページで、[Create a custom task to delegate]、[Next] の順に選択します。

  8. [Only the following objects in the folder] を選択し、[Computer objects]、[User objects] の順に選択します。

  9. [Create selected objects in this folder] を選択し、[Delete selected objects in this folder] を選択します。続いて、[次へ] を選択します。

    
                            オブジェクトタイプ
  10. [Read] を選択し、[Next] を選択します。

    注記

    シームレスドメイン結合または Amazon WorkSpaces を使用する場合は、AWS Managed Microsoft AD で コンピュータオブジェクトに書き込めるように [Write] のアクセス許可を有効にする必要があります。

    
                            オブジェクトタイプ
  11. [Completing the Delegation of Control Wizard] ページの情報を確認し、[Finish] をクリックします。

  12. ユーザーアカウントと強力なパスワードを作成し、そのユーザーを Connectors グループに追加します。このユーザーは、AD Connector サービスアカウントとして知られます。これで、Connectors グループのメンバーになり、AWS Directory Service をディレクトリに接続するために十分な権限が付与されました。

AD Connector をテストする

対象 AD Connector 既存のディレクトリに接続するには、既存のネットワークのファイアウォールで、 CIDRs VPC の両方のサブネットの です。これらの要件が満たされるかどうかをテストするには、以下の手順に従います。

接続をテストするには

  1. VPC で Windows インスタンスを起動し、RDP 経由でインスタンスに接続します。インスタンスは、既存のドメインのメンバーである必要があります。残りの手順は、この VPC インスタンスで実行します。

  2. ダウンロードして解凍します。 DirectoryServicePortTest テストアプリケーション。ソースコードと Visual Studio プロジェクトファイルが含まれており、必要に応じてテストアプリケーションを変更できます。

    注記

    このスクリプトは Windows Server 2003 以前のオペレーティングシステムではサポートされていません。

  3. Windows のコマンドプロンプトで、次のオプションを指定して DirectoryServicePortTest テストアプリケーションを実行します。

    注記

    [ DirectoryServicePortTest テスト アプリケーションは、ドメインおよびフォレストの機能レベルがWindows Server 2012 R2以下に設定されている場合のみ使用可能です。

    DirectoryServicePortTest.exe -d <domain_name> -ip <server_IP_address> -tcp "53,88,389" -udp "53,88,389"
    <domain_name>

    完全修飾ドメイン名。これは、フォレストとドメインの機能レベルをテストするために使用されます。ドメイン名を除外した場合、機能レベルはテストされません。

    <server_IP_address>

    既存のドメインのドメインコントローラーの IP アドレス。ポートはこの IP アドレスに対してテストされます。IP アドレスを除外した場合、ポートはテストされません。

    このテストアプリケーションは、VPC からドメインに必要なポートが開いているかどうかを判断し、最小のフォレストとドメインの機能レベルも検証します。

    出力は以下のようになります。

    Testing forest functional level. Forest Functional Level = Windows2008R2Forest : PASSED Testing domain functional level. Domain Functional Level = Windows2008R2Domain : PASSED Testing required TCP ports to <server_IP_address>: Checking TCP port 53: PASSED Checking TCP port 88: PASSED Checking TCP port 389: PASSED Testing required UDP ports to <server_IP_address>: Checking UDP port 53: PASSED Checking UDP port 88: PASSED Checking UDP port 389: PASSED

DirectoryServicePortTest アプリケーションのソースコードは次のとおりです。

/* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. This file is licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at http://aws.amazon.com/apache2.0/ This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.DirectoryServices.ActiveDirectory; using System.Threading; using System.DirectoryServices.AccountManagement; using System.DirectoryServices; using System.Security.Authentication; using System.Security.AccessControl; using System.Security.Principal; namespace DirectoryServicePortTest { class Program { private static List<int> _tcpPorts; private static List<int> _udpPorts; private static string _domain = ""; private static IPAddress _ipAddr = null; static void Main(string[] args) { if (ParseArgs(args)) { try { if (_domain.Length > 0) { try { TestForestFunctionalLevel(); TestDomainFunctionalLevel(); } catch (ActiveDirectoryObjectNotFoundException) { Console.WriteLine("The domain {0} could not be found.\n", _domain); } } if (null != _ipAddr) { if (_tcpPorts.Count > 0) { TestTcpPorts(_tcpPorts); } if (_udpPorts.Count > 0) { TestUdpPorts(_udpPorts); } } } catch (AuthenticationException ex) { Console.WriteLine(ex.Message); } } else { PrintUsage(); } Console.Write("Press <enter> to continue."); Console.ReadLine(); } static void PrintUsage() { string currentApp = Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location); Console.WriteLine("Usage: {0} \n-d <domain> \n-ip \"<server IP address>\" \n[-tcp \"<tcp_port1>,<tcp_port2>,etc\"] \n[-udp \"<udp_port1>,<udp_port2>,etc\"]", currentApp); } static bool ParseArgs(string[] args) { bool fReturn = false; string ipAddress = ""; try { _tcpPorts = new List<int>(); _udpPorts = new List<int>(); for (int i = 0; i < args.Length; i++) { string arg = args[i]; if ("-tcp" == arg | "/tcp" == arg) { i++; string portList = args[i]; _tcpPorts = ParsePortList(portList); } if ("-udp" == arg | "/udp" == arg) { i++; string portList = args[i]; _udpPorts = ParsePortList(portList); } if ("-d" == arg | "/d" == arg) { i++; _domain = args[i]; } if ("-ip" == arg | "/ip" == arg) { i++; ipAddress = args[i]; } } } catch (ArgumentOutOfRangeException) { return false; } if (_domain.Length > 0 || ipAddress.Length > 0) { fReturn = true; } if (ipAddress.Length > 0) { _ipAddr = IPAddress.Parse(ipAddress); } return fReturn; } static List<int> ParsePortList(string portList) { List<int> ports = new List<int>(); char[] separators = {',', ';', ':'}; string[] portStrings = portList.Split(separators); foreach (string portString in portStrings) { try { ports.Add(Convert.ToInt32(portString)); } catch (FormatException) { } } return ports; } static void TestForestFunctionalLevel() { Console.WriteLine("Testing forest functional level."); DirectoryContext dirContext = new DirectoryContext(DirectoryContextType.Forest, _domain, null, null); Forest forestContext = Forest.GetForest(dirContext); Console.Write("Forest Functional Level = {0} : ", forestContext.ForestMode); if (forestContext.ForestMode >= ForestMode.Windows2003Forest) { Console.WriteLine("PASSED"); } else { Console.WriteLine("FAILED"); } Console.WriteLine(); } static void TestDomainFunctionalLevel() { Console.WriteLine("Testing domain functional level."); DirectoryContext dirContext = new DirectoryContext(DirectoryContextType.Domain, _domain, null, null); Domain domainObject = Domain.GetDomain(dirContext); Console.Write("Domain Functional Level = {0} : ", domainObject.DomainMode); if (domainObject.DomainMode >= DomainMode.Windows2003Domain) { Console.WriteLine("PASSED"); } else { Console.WriteLine("FAILED"); } Console.WriteLine(); } static List<int> TestTcpPorts(List<int> portList) { Console.WriteLine("Testing TCP ports to {0}:", _ipAddr.ToString()); List<int> failedPorts = new List<int>(); foreach (int port in portList) { Console.Write("Checking TCP port {0}: ", port); TcpClient tcpClient = new TcpClient(); try { tcpClient.Connect(_ipAddr, port); tcpClient.Close(); Console.WriteLine("PASSED"); } catch (SocketException) { failedPorts.Add(port); Console.WriteLine("FAILED"); } } Console.WriteLine(); return failedPorts; } static List<int> TestUdpPorts(List<int> portList) { Console.WriteLine("Testing UDP ports to {0}:", _ipAddr.ToString()); List<int> failedPorts = new List<int>(); foreach (int port in portList) { Console.Write("Checking UDP port {0}: ", port); UdpClient udpClient = new UdpClient(); try { udpClient.Connect(_ipAddr, port); udpClient.Close(); Console.WriteLine("PASSED"); } catch (SocketException) { failedPorts.Add(port); Console.WriteLine("FAILED"); } } Console.WriteLine(); return failedPorts; } } }