开始使用 AD Connector - AWS Directory Service

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

开始使用 AD Connector

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

AD Connector 先决条件

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

Amazon VPC

VPC使用以下内容设置:

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

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

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

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

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

  • 10.0.1.0/24 和 10.0.2.0/24

  • 169.254.0.0/16

  • 192.168.1.0/24 和 192.168.2.0/24

我们可以通过检查的第一个八位组来避免冲突。ETH1 CIDR如果它以 10 开头,那么我们选择一个带有 192.168.1.0/24 和 192.168.2.0/24 子网的 192.168.0.0/16 VPC。如果第一个八位组是 10 以外的任何其他八位组,我们选择一个 10.0.0.0/16,子网为 10.0.1.0/24,子网为 10.0.2.0/ VPC 24。

选择算法不包括您的路线VPC。因此,这种情况可能会导致 IP 路由冲突。

有关更多信息,请参阅 Amazon VPC 用户指南中的以下主题:

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

现有 Active Directory

您需要使用Active Directory域连接到现有网络。

注意

AD Connector 不支持单个标签域

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

注意

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

服务账户

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

  • 读取用户和组 – 必需

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

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

  • 服务账号密码应符合 AWS 密码要求。 AWS 密码应为:

    • 长度介于 8 到 128 个字符(含)之间。

    • 至少包含以下四个类别中的三个类别中的一个字符:

      • 小写字母 (a-z)

      • 大写字母 (A-Z)

      • 数字 (0-9)

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

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

注意

AD Connector 使用 Kerberos 对 AWS 应用程序进行身份验证和授权。LDAP仅用于用户和群组对象查找(读取操作)。在LDAP交易中,没有任何东西是可变的,凭据也不是以明文形式传递的。身份验证由 AWS 内部服务处理,该服务使用 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域控制器,您现有网络的防火墙必须CIDRs为 Amazon VPC 中的两个子网开放以下端口。

  • TCP/UDP53-DNS

  • TCP/UDP88-Kerberos 身份验证

  • TCP/UDP389-LDAP

这些是 AD Connector 能够连接到目录之前所需的最少端口。根据您的特定配置,您可能需要打开其他端口。

如果您想使用 AD Connector 和 Amazon WorkSpaces,则需要将域控制器的 D isableVLVSupport LDAP 属性设置为 0。这是域控制器的默认设置。如果启用 D isableVLVSupport LDAP 属性,AD Connector 将无法查询目录中的用户。这会阻止 AD Connector 使用 Amazon WorkSpaces。

注意

如果您现有域的DNS服务器或Active Directory域控制器服务器位于其中VPC,则与这些服务器关联的安全组必须CIDRs为中的两个子网开放上述端口。VPC

有关其他端口要求,请参阅Microsoft文档中的 AD 和 AD DS 端口要求

Kerberos 预身份验证

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

加密类型

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

  • AES-256-HMAC

  • AES-128-HMAC

  • RC4-HMAC

AWS IAM Identity Center 先决条件

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

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

  • 您的 Ident IAM ity Center 实例位于设置 AD Connector 的同一区域。

有关更多信息,请参阅《 AWS IAM Identity Center 用户指南》中的 “IAM身份中心先决条件”。

多重身份验证先决条件

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

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

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

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

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

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

有关将 AD Connector 与配合使用的更多信息MFA,请参阅为 AD Connector 启用多重身份验证

向您的服务账户委派权限

要连接到您的现有目录,必须在现有目录中拥有被委托了某些权限的 AD Connector 服务账户的凭证。尽管 Domain Admins 组的成员有足够的权限连接到目录,但是作为最佳实践,您应使用仅具有连接到目录所需的最小权限的服务账户。以下过程演示如何创建名为的新组Connectors,委派连接到该组所需的必要权限,然后 AWS Directory Service 向该组添加新的服务帐户。

此过程必须在已加入您的目录并安装了 Act ive Directory 用户和计算机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 用户和计算机导航树中,选择确定将在其中创建计算机帐户的组织单位 (OU)。在菜单中,选择 Action,然后选择 Delegate Control。当权限传播到子域时,您可以选择该域的父 OU。OUs如果您的 AD Connector 已连接到 AWS 托管 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组的成员,因此现在它具有足够的权限 AWS Directory Service 来连接到该目录。

测试 AD Connector

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

测试 连接
  1. 在中启动一个 Windows 实例,VPC然后通过它进行连接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. AWS Directory Service 控制台导航窗格中,选择目录,然后选择设置目录

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

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

    目录大小

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

    目录描述

    目录的可选描述。

  4. 选择VPC和子网页面上,提供以下信息,然后选择下一步

    VPC

    VPC对应于目录。

    子网

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

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

    目录DNS名

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

    目录网BIOS名

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

    DNSIP 地址

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

    服务账户用户名

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

    服务账户密码

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

    • 小写字母 (a-z)

    • 大写字母 (A-Z)

    • 数字 (0-9)

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

    确认密码

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

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

使用 AD Connector 创建了什么

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

注意

默认情况下,AD Connector 实例部署在一个地区的两个可用区中,并连接到您的亚马逊虚拟私有云 (VPC)。失败的 AD Connector 实例将在同一可用区中使用相同的 IP 地址自动替换。

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