开始使用 AD Connector - Amazon Directory Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

开始使用 AD Connector

使用 AD Connecto Amazon Directory Service r,您可以连接到现有的企业活动目录。连接到现有目录后,所有目录数据仍保留在域控制器上。 Amazon Directory Service 不会复制您的任何目录数据。

AD Connector 先决条件

要使用 AD Connector 连接到您的现有目录,您需要:

VPC

对 VPC 进行如下设置:

  • 至少两个子网。每个子网必须位于不同的可用区。

  • 必须通过虚拟专用网络 (VPN) 连接或 Amazon Direct Connect将 VPC 连接到您的现有网络。

  • VPC 必须具有默认硬件租户。

Amazon Directory Service 使用双 VPC 结构。构成您目录的 EC2 实例在您的 Amazon 账户之外运行,由管理 Amazon。其有 ETH0ETH1 两个网络适配器。ETH0 是管理适配器,存在于您的账户之外。ETH1 在您的账户内创建。

目录的 ETH0 网络的管理 IP 范围以编程方式选择,以确保其不会与部署目录的 VPC 发生冲突。此 IP 范围可以是以下任一对(因为目录在两个子网中运行):

  • 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 用户指南 中的以下主题:

有关的更多信息 Amazon Direct Connect,请参阅《Amazon Direct Connect 用户指南》

现有 Active Directory

您将需要连接到具有 Active Directory 域的现有网络。

注意

AD Connector 不支持单个标签域

此 Active Directory 域的功能级别必须等于Windows Server 2003或更高。AD Connector 还支持连接到 Amazon EC2 实例上托管的域。

注意

与 Amazon EC2 域加入功能结合使用时,AD Connector 不支持只读域控制器(RODC)。

服务账户

您必须拥有现有目录中被委派了以下权限的服务账户的凭证:

  • 读取用户和组 – 必需

  • 将计算机加入域-仅在使用无缝域加入时才需要 WorkSpaces

  • 创建计算机对象-仅在使用无缝域加入时才需要 WorkSpaces

有关更多信息,请参阅向您的服务账户委派权限

注意

AD Connector 使用 Kerberos 对 Amazon 应用程序进行身份验证和授权。LDAP 仅用于用户和组对象查找(读取操作)。对于 LDAP 事务,所有都不可变,凭证也不以明文形式传递。身份验证由 Amazon 内部服务处理,该服务使用 Kerberos 票证以用户身份执行 LDAP 操作。

用户权限

所有 Active Directory 用户必须有权读取自己的属性。具体而言,包括以下属性:

  • GivenName

  • SurName

  • 邮件

  • SamAccountName

  • UserPrincipalName

  • UserAccountControl

  • MemberOf

默认情况下,Active Directory 用户确实有权读取这些属性。但是,管理员可以随时修改这些权限,因此,您可能希望在首次设置 AD Connector 之前,验证用户是否具有这些读取权限。

IP 地址

获取您现有目录域中两个 DNS 服务器或域控制器的 IP 地址。

AD Connector 在连接到您的目录时将从这些服务器获取 _ldap._tcp.<DnsDomainName>_kerberos._tcp.<DnsDomainName> SRV 记录,因此这些服务器必须包含这些 SRV 记录。AD Connector 尝试查找将同时提供 LDAP 和 Kerberos 服务的公用域控制器,因此这些 SRV 记录必须至少包含一个公用域控制器。有关 SRV 记录的更多信息,请访问 Microsoft 上的 SRV 资源记录。 TechNet

子网的端口

为了使 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 上的 AD 和 AD DS 端口要求 TechNet。

Kerberos 预身份验证

用户账户必须启用 Kerberos 预身份验证。有关如何启用此设置的详细说明,请参阅确保已启用 Kerberos 预身份验证。有关此设置的一般信息,请转到 Microsoft TechNet 上的预身份验证

加密类型

当通过 Kerberos 对您的 Active Directory 域控制器进行身份验证时,AD Connector 支持以下加密类型:

  • AES-256-HMAC

  • AES-128-HMAC

  • RC4-HMAC

Amazon IAM Identity Center 先决条件

如果计划将 IAM Identity Center 与 AD Connector 结合使用,则需要确保满足以下条件:

  • 您的 AD Connector 是在您 Amazon 组织的管理账户中设置的。

  • 您的 IAM Identity Center 实例位于您在其中设置 AD Connector 的同一区域中。

有关更多信息,请参阅 Amazon IAM Identity Center 用户指南中的 IAM 身份中心先决条件

多重身份验证先决条件

为了使用您的 AD Connector 目录支持多重身份验证,您需要以下内容:

  • 现有网络中具有两个客户端终端节点的远程身份验证拨入用户服务 (RADIUS) 服务器。RADIUS 客户端终端节点具有以下要求:

    • 要创建终端节点,您需要 Amazon Directory Service 服务器的 IP 地址。这些 IP 地址可以从目录详细信息的 Directory IP Address 字段中获取。

    • 两个 RADIUS 终端节点必须使用相同的共享密码。

  • 您的现有网络必须允许服务器通过默认 RADIUS 服务器端口 (1812) 的 Amazon Directory Service 入站流量。

  • 您的 RADIUS 服务器与您的现有目录的用户名必须相同。

有关通过 MFA 使用 AD Connector 的更多信息,请参阅 为 AD Connector 启用多重身份验证

向您的服务账户委派权限

要连接到您的现有目录,必须在现有目录中拥有被委托了某些权限的 AD Connector 服务账户的凭证。尽管 Domain Admins 组的成员有足够的权限连接到目录,但是作为最佳实践,您应使用仅具有连接到目录所需的最小权限的服务账户。以下过程演示如何创建名为的新组Connectors,委派连接到该组所需的必要权限,然后 Amazon 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 Global
    Group type 安全性
  4. Active Directory User and Computers 导航树中,选择您的域根。在菜单中,选择 Action,然后选择 Delegate Control。如果您的 AD Connector 已连接到 Amazon 托管 Microsoft AD,则您将无法访问域根级别的委托控制。在这种情况下,要委托控制权,请在您的目录 OU 下选择将在其中创建计算机对象的 OU。

  5. Delegation of Control Wizard 页面上,单击 Next,然后单击 Add

  6. Select Users, Computers, or Groups 对话框中,输入 Connectors,然后单击 OK。如果找到多个对象,请选择上面创建的 Connectors 组。单击下一步

  7. Tasks to Delegate 页面上,选择 Create a custom task to delegate,然后选择 Next

  8. 选择 Only the following objects in the folder,然后选择 Computer objectsUser objects

  9. 选择 Create selected objects in this folder,然后选择 Delete selected objects in this folder。然后选择下一步

    
                            控制向导的委托-仅选择文件夹中的以下对象、用户对象、在此文件夹中创建选定对象以及删除此文件夹中的选定对象选项。
  10. 选择 Read,然后选择 Next

    注意

    如果您要使用无缝域加入或 WorkSpaces,则还必须启用写入权限,这样 Active Directory 才能创建计算机对象。

    
                            控制权委托向导-在 “显示这些权限” 下,选择 “常规”、“特定于属性” 和 “读取”。
  11. Completing the Delegation of Control Wizard 页面上验证信息,然后单击 Finish

  12. 使用强密码创建一个用户账户,并将该用户添加到 Connectors 组。此用户将被称为您的 AD Connector 服务帐户,由于它现在是该Connectors组的成员,因此现在它具有足够的权限 Amazon Directory Service 来连接到该目录。

测试 AD Connector

为使 AD Connector 能够连接您的现有目录,现有网络的防火墙必须向 VPC 中的两个子网的 CIDR 开放特定的端口。要测试是否满足这些条件,请执行以下步骤:

测试 连接
  1. 在 VPC 中启动一个 Windows 实例并通过 RDP 连接它。实例必须是您现有域的成员。在该 VPC 实例上执行剩余步骤。

  2. 下载并解压缩DirectoryServicePortTest测试应用程序。其中包含源代码及 Visual Studio 项目文件,您可以根据需要修改该测试应用程序。

    注意

    Windows Server 2003 及更低版本的操作系统不支持此脚本。

  3. 在 Windows 命令提示符下,使用以下选项运行 DirectoryServicePortTest 测试应用程序:

    注意

    只有将域和林功能级别设置为 Windows Server 2012 R2 及更低版本时,才能使用 DirectoryServicePortTest 测试应用程序。

    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 应用程序的源代码。

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

创建 AD Connector

要使用 AD Connector 连接到现有目录,请执行以下步骤。在开始此过程之前,请确保您已满足了AD Connector 先决条件中确定的先决条件。

注意

您无法使用 Cloud Formation 模板创建 AD Connector。

使用 AD Connector 连接
  1. Amazon Directory Service 控制台导航窗格中,选择目录,然后选择设置目录

  2. 选择目录类型页面上,选择 AD Connector,然后选择下一步

  3. Enter AD Connector information (输入 AD Connector 信息) 页面上,提供以下信息:

    目录大小

    小型大型大小选项中进行选择。有关大小的更多信息,请参阅AD Connector

    目录描述

    目录的可选描述。

  4. Choose VPC and subnets (选择 VPC 和子网) 页面上,提供以下信息,然后选择 Next (下一步)

    VPC

    目录的 VPC。

    子网

    为域控制器选择子网。两个子网必须位于不同的可用区。

  5. Connect to AD (连接到 AD) 页面上,提供以下信息:

    目录 DNS 名称

    现有目录的完全限定名称,例如 corp.example.com

    目录 NetBIOS 名称

    现有目录的短名称,例如 CORP

    DNS IP 地址

    现有目录中至少一个 DNS 服务器的 IP 地址。这些服务器必须可从步骤 4 中指定的每个子网访问。只要指定的子网和 DNS 服务器 IP 地址之间存在网络连接,这些服务器就可以位于外部。 Amazon

    服务账户用户名

    现有目录中用户的用户名称。有关该账户的更多信息,请参阅AD Connector 先决条件

    服务账户密码

    现有用户账户的密码。此密码区分大小写,且长度必须介于 8 到 128 个字符之间。至少,它还必须包含下列四种类别中三种类别的一个字符:

    • 小写字母 (a-z)

    • 大写字母 (A-Z)

    • 数字 (0-9)

    • 非字母数字字符 (~!@#$%^&*_-+=`|\(){}[]:;"'<>,.?/)

    确认密码

    重新键入现有用户账户的密码。

  6. Review & create (检查并创建) 页面上,检查目录信息并进行任何必要的更改。如果信息正确,请选择 Create directory (创建目录)。目录创建需要几分钟时间。创建后,Status 值将更改为 Active

使用 AD Connector 创建了什么

创建 AD 连接器时, Amazon Directory Service 会自动创建弹性网络接口 (ENI) 并将其与每个 AD 连接器实例关联。这些 ENI 中的每一个 ENI 对于您的 VPC 和 Amazon Directory Service AD Connector 之间的连接都至关重要,因此切勿将其删除。您可以 Amazon Directory Service 通过描述来标识所有保留供使用的网络接口:“为目录目录 IDAmazon 创建的网络接口”。有关更多信息,请参阅《Amazon EC2 Windows 实例用户指南》中的弹性网络接口

注意

默认情况下,AD Connector 实例部署在一个区域的两个可用区中,并连接到您的 Amazon Virtual Private Cloud(VPC)。失败的 AD Connector 实例将在同一可用区中使用相同的 IP 地址自动替换。

当您登录任何与 AD Connector(Amazon IAM Identity Center 包括在内)集成的 Amazon 应用程序或服务时,应用程序或服务会将您的身份验证请求转发给 AD Connector,AD Connector 随后会将请求转发到您自行管理的 Active Directory 中的域控制器进行身份验证。如果您成功通过自我管理的 Active Directory 的身份验证,AD Connector 会向应用程序或服务返回身份验证令牌(类似于 Kerberos 令牌)。此时,您现在可以访问该 Amazon 应用程序或服务。