同一安全组的 EC2 实例无法通过 SQL Server 连接进行通信

Posted

技术标签:

【中文标题】同一安全组的 EC2 实例无法通过 SQL Server 连接进行通信【英文标题】:EC2 instances of same security group cannot communicate through SQL Server connection 【发布时间】:2022-01-21 22:07:03 【问题描述】:

我有 2 个使用 Windows Server 操作系统的 EC2 实例,其中一个(我们称之为 S1)使用 IIS 托管我的 php 代码,另一个(我们称之为 S2)使用 SQL Server 托管数据库。它们属于同一个安全组。

相互ping通,但通过S1连接到S2的数据库给我一个超时错误。

这是我得到的错误:

(
    [0] => Array
        (
            [0] => 08001
            [SQLSTATE] => 08001
            [1] => 258
            [code] => 258
            [2] => [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: The wait operation timed out.

            [message] => [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: The wait operation timed out.

        )

    [1] => Array
        (
            [0] => HYT00
            [SQLSTATE] => HYT00
            [1] => 0
            [code] => 0
            [2] => [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired
            [message] => [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired
        )

    [2] => Array
        (
            [0] => 08001
            [SQLSTATE] => 08001
            [1] => 258
            [code] => 258
            [2] => [Microsoft][ODBC Driver 17 for SQL Server]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.
            [message] => [Microsoft][ODBC Driver 17 for SQL Server]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.
        )

)

我尝试过的一些事情:

连接代码绝对正确,因为它与我的其他一些可以很好地相互连接的服务器使用的代码相同。但以防万一,它是PHP代码,如下所示:
$conn = array(
   'UID' => USERNAME,
   'PWD' => PASSWORD,
   'Database' => DATABASE,
);
if (!$conn_id = sqlsrv_connect(HOSTNAME, $conn)) 
   // exit blah blah

请注意,这是一个多租户应用程序,最初连接到主数据库,然后连接到相应客户端的数据库。连接到主数据库工作正常(顺便说一句,它托管在不同安全组的服务器中)。只有这个特定的 S2 客户端的数据库给我一个超时错误。

我已经使用安全组中的私有和公共/弹性 IP 为他们两个设置了规则。我什至尝试打开所有 tcp 连接的流量,但它仍然不起作用。

我在两台服务器上都禁用了 Windows 防火墙。

SQL Server 身份验证已启用,端口 1433 已为 SQL Server 连接打开。

我已在 S2 中配置 SQL Server 以允许通过服务器属性 -> 连接进行远程连接。

我通过 CMD netsh http show iplisten 在它们两个中运行此命令。我注意到在 S1 中,返回的列表不是空的,这意味着只允许特定的 IPS。但是,我尝试清除列表或向其中添加 S2 的 IP。两者都不起作用。

我尝试做相反的事情,即通过 S2 连接到 S1 的 SQL Server DB,它也给我一个超时错误。

编辑:我上面没有提到的一件事是,S1 中无法连接到 S2 数据库的应用程序正在使用我设置的辅助 IP(此 IP 被其他应用程序使用,没有问题)。我在安全组中为此辅助 IP 及其关联的弹性 IP 设置了规则。不知道这是否重要,但我提到它以防万一。

【问题讨论】:

1.安装 telnet 并验证 sql server 端口是否打开。 2. 确保您的 SQL Server 中启用了 SQL Server 身份验证。 好的,刚刚使用 telnet 验证端口 1433 已打开。还验证了通过服务器属性 -> 安全启用了 SQL Server 身份验证。 你得到了什么确切的错误信息?您是否在 SQL Server 日志中看到登录尝试?禁用 Windows 防火墙听起来是个很糟糕的主意。这是默认实例还是命名实例?如果默认,你确定端口是正确的吗?如果是命名实例,您要么需要运行 SQL Server Browser 服务并且不使用固定静态端口,要么将静态端口 not 固定在 1433 上。netsh http show iplisten 不相关在这里,在 SQL Server 机器上尝试netstat -ano | findstr "1433" 端口绝对正确。该实例是默认实例 (MSSQLSERVER)。但是,以防万一,我打开了 SQL Server 浏览器,但它仍然无法正常工作。 netstat -ano | findstr "1433" 返回以下内容: TCP 0.0.0.0:1433 0.0.0.0:0 LISTENING 748 TCP [::]:1433 [::]:0 LISTENING 748 您的连接字符串是否包含HOSTNAME,1433tcp:HOSTNAME,1433?如果它使用像 HOSTNAME\MSSQLSERVER 这样的实例名称,那么您还需要允许 udp/1434 通过 SQL Browser 服务进行实例名称解析。 【参考方案1】:

仅仅因为两个 Amazon EC2 实例“属于同一个安全组”并不意味着它们可以相互通信。

安全组分别应用于每个资源。因此,如果两个实例与同一个安全组相关联并且您希望它们进行通信,则需要在安全组中设置一个允许来自安全组本身的入站连接的规则。

更好的配置方法是:

在应用服务器 (App-SG) 上放置一个安全组,允许您的 Web 服务器的入站连接,并且 在数据库服务器 (DB-SG) 上放置一个安全组,以允许来自端口 1433 上 App-SG 的入站连接

这样,DB-SG 允许来自与App-SG 关联的任何 EC2 实例的入站连接。

【讨论】:

嗨,约翰,感谢您的回复。我尝试在安全组中添加如下规则: - 类型:所有 TCP 协议:TCP 范围:0 - 65535 源:SG id 我仍然得到连接超时。我开始相信这不是安全组问题。

以上是关于同一安全组的 EC2 实例无法通过 SQL Server 连接进行通信的主要内容,如果未能解决你的问题,请参考以下文章

ssh 隧道/端口转发无法通过 EC2 实例工作到 VPC 中的 Elasticsearch 集群

AWS 安全组难题

无法通过私有 IP 从另一个实例访问 AWS EC2 实例

打开端口 80 EC2 亚马逊网络服务 [关闭]

AWS Lambda 无法访问同一 VPC 中的 EC2 端口

实例无法通信 - 相同的 VPC 和子网,不同的安全组