AD Connector の前提条件 - AWS Directory Service

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

AD Connector の前提条件

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

VPC

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

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

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

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

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

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

  • 10.0.1.0/24 & 10.0.2.0/24

  • 192.168.1.0/24 & 192.168.2.0/24

私たちは、最初のオクテットをチェックすることによって、競合を回避しますETH1CIDR 10 で始まる場合は、192.168.1.0/24 と 192.168.2.0/24 のサブネットを持つ 192.168.0.0/16 VPC を選択します。最初のオクテットが 10 以外の場合、10.0.1.0/24 および 10.0.2.0/24 のサブネットを持つ 10.0.0.0/16 VPC を選択します。

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

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

AWS Direct Connector の詳細については、」AWS Direct Connect ユーザーガイド

既存の Active Directory

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

注記

AD Connector は、サポートしていません単一ラベルドメイン

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

注記

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

サービスアカウント

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

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

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

  • コンピュータオブジェクトの作成-シームレスなドメイン結合と 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 レコードの詳細については、Microsoft TechNet の「SRV リソースレコード」を参照してください。

サブネット用のポート

AD Connector で既存の Active Directory ドメインコントローラーにディレクトリリクエストをリダイレクトするには、既存のネットワークのファイアウォールで Amazon VPC の両方のサブネットの CIDR に対して次のポートが開かれている必要があります。

  • TCP/UDP 53 - DNS

  • TCP/UDP 88 - Kerberos 認証

  • TCP/UDP 389 - LDAP

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

注記

既存の Active Directory ドメインの DNS サーバーまたはドメインコントローラーサーバーが VPC 内にある場合、これらのサーバーに関連付けられたセキュリティグループでは、VPC の両方のサブネットで、CIDR に対して上記のポートが開かれている必要があります。

追加のポート要件については、Microsoft TechNet の AD and AD DS Port Requirements を参照してください。

Kerberos 事前認証

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

暗号化タイプ

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

  • AES-256-HMAC

  • AES-128-HMAC

  • RC4-HMAC

AWS Single Sign-On の前提条件

AD Connector で AWS Single Sign-On (AWS SSO) を使用する予定がある場合は、次の条件が満たされていることを確認する必要があります。

  • AD Connector は AWS Organization の管理アカウントに設定されています。

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

詳細については、「」を参照してください。AWS SSO の前提条件AWS Single Sign-On ユーザーガイドの「」を参照してください。

多要素認証の前提条件

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の MFA 認証の有効化

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

既存のディレクトリに接続するには、特定の権限が委任されている、既存のディレクトリの 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] をクリックします。

    フィールド 値/選択
    グループ名 Connectors
    Group scope グローバル
    Group type セキュリティ
  4. [Active Directory User and Computers] ナビゲーションツリーで、ドメインルートを選択します。メニューで [Action] を選択し、[Delegate Control] を選択します。AD Connector が AWS マネージド 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] を選択します。続いて、[Next] を選択します。

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

    注記

    シームレスなドメイン結合または WorkSpaces を使用する場合は、書き込みアクセス許可を設定して、AWS が管理する Microsoft AD がコンピューターオブジェクトを作成できるようにします。

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

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

AD Connector をテストする

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

接続をテストするには

  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; } } }