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

Posted

技术标签:

【中文标题】ssh 隧道/端口转发无法通过 EC2 实例工作到 VPC 中的 Elasticsearch 集群【英文标题】:ssh tunneling/port forwarding not working through EC2 instance to an Elasticsearch cluster in a VPC 【发布时间】:2021-06-30 18:47:03 【问题描述】:

我在 VPC 中有我的 Elasticsearch 集群,我想从我的本地 Macbook 访问这个 EC 集群。 我已经设置了一个使用相同 VPC 和相同安全组的堡垒主机,并且我能够从我的 Macbook SSH 到这个堡垒主机。

但不知何故,我的代码无法通过这个堡垒主机连接到我的 ES 集群,这是我运行端口转发的命令:

ssh -i ~/Downloads/keypairs/20210402-02.pem ubuntu@ec2-123-456.us-west-2.compute.amazonaws.com -N -L 9200:vpc-es-domain-20210331-abc123def.us-west-2.es.amazonaws.com:443

这是我在 VPC 中访问 ES 集群时的超时异常:

java.net.ConnectException: Timeout connecting to [vpc-es-domain-20210331-abc123def.us-west-2.es.amazonaws.com/10.0.47.182:443]
    at org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:823) ~[elasticsearch-rest-client-7.6.1.jar:7.6.1]
    at org.elasticsearch.client.RestClient.performRequest(RestClient.java:248) ~[elasticsearch-rest-client-7.6.1.jar:7.6.1]
    at org.elasticsearch.client.RestClient.performRequest(RestClient.java:235) ~[elasticsearch-rest-client-7.6.1.jar:7.6.1]
    at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1514) ~[elasticsearch-rest-high-level-client-7.6.1.jar:7.6.1]
    at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1484) ~[elasticsearch-rest-high-level-client-7.6.1.jar:7.6.1]
    at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1454) ~[elasticsearch-rest-high-level-client-7.6.1.jar:7.6.1]
    at org.elasticsearch.client.RestHighLevelClient.bulk(RestHighLevelClient.java:497) ~[elasticsearch-rest-high-level-client-7.6.1.jar:7.6.1]

这是我的SG的规则:

入站:

All TCP TCP 0 - 65535   0.0.0.0/0
All traffic All All sg-abc123 / default
SSH TCP 22  0.0.0.0/0

出站:

All traffic All All 0.0.0.0/0

当我通过 ssh 进入我的堡垒主机并运行 curl vpc-es-domain-20210331-abc123def.us-west-2.es.amazonaws.com 后,我得到了以下响应:


  "name" : "abc123",
  "cluster_name" : "abc123097:es-domain-beta-20210331",
  "cluster_uuid" : "abc123def",
  "version" : 
    "number" : "7.8.0",
    "build_flavor" : "oss",
    "build_type" : "tar",
    "build_hash" : "unknown",
    "build_date" : "2021-01-15T06:15:47.944536Z",
    "build_snapshot" : false,
    "lucene_version" : "8.5.1",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  ,
  "tagline" : "You Know, for Search"

我怀疑我的端口转发命令不正确?但经过研究,这对我来说似乎是最合法的选择。 任何见解将不胜感激!

【问题讨论】:

可能你没有在 ElasticDomain 安全组中授权你的堡垒安全组 感谢您的评论,但实际上我使用与我的 ES 相同的 SG 启动了我的堡垒主机,也更新了我的 OP。还有其他见解吗? 您是否授权从同一个安全组访问 443 端口? 例如添加一个端口为 443 的规则并作为源:[此安全组 ID] 好的,我已将此 All TCP TCP 0 - 65535 0.0.0.0/0 作为新的入站规则添加到与此堡垒主机关联的我的 SG。还是没有运气。 【参考方案1】:

在您的本地计算机上运行的代码正在尝试不通过 SSH 隧道直接连接到 Elasticsearch 服务器。 SSH 命令正在打开从本地端口9200 到远程服务器的隧道。尝试连接到 Elasticsearch 的本地软件应该连接到 localhost:9200 而不是 vpc-es-domain-20210331-abc123def.us-west-2.es.amazonaws.com/10.0.47.182:443


端点vpc-es-domain-20210331-abc123def.us-west-2.es.amazonaws.com/10.0.47.182:443 无论如何看起来都无效。它有一个主机名和一个 IP 地址。


您在 cmets 中提到:

“我实际上使用与我的 ES 相同的 SG 启动了我的堡垒主机”

但是,仅将两个资源放在同一个安全组中没有任何作用,除非该安全组还具有专门允许其中资源之间的流量的规则。默认情况下,安全组没有此规则,但在您首次创建 AWS 账户时自动创建的默认 VPC 中的默认安全组除外。

所以请确保安全组有一个规则,允许堡垒主机通过端口443 连接到 Elasticsearch 服务器。

【讨论】:

谢谢马克。我刚刚添加了一个入站规则,我已经在 OP 中进行了更新,请告诉我这对您来说是否正确? 那么,如何让我的本地代码通过 SSH 隧道而不是直接连接到 ES 服务器? @FisherCoder 根据所有 cmets 和聊天,您会收到“地址已在使用中”,因为您已经运行过该命令一次。您已经设置了 ssh 隧道。当您从堡垒主机 curl 时,您还会收到来自 Elasticsearch 的响应,因此安全组配置正确。正如我在回答中所说,您需要做的就是更改本地计算机上运行的代码以连接到https://localhost:9200 您能否列出从我的 Mac 访问 ES 集群所需执行的所有步骤?到目前为止,我可以通过我的代码通过 HTTP 而不是 HTTPS 访问我的 localhost ES 服务。但是我想要实现的是访问 VPC 中的 ES,正如我在我的 OP 中所说的那样。谢谢 Nvm,我也通过设置解决了这个错误:httpClientBuilder.setSSLHostnameVerifier((s, sslSession) -> true);,非常感谢你们!

以上是关于ssh 隧道/端口转发无法通过 EC2 实例工作到 VPC 中的 Elasticsearch 集群的主要内容,如果未能解决你的问题,请参考以下文章

SSH.Net 隧道

ssh隧道 学习总结

通过 AWS SSM 代理命令设置 SSH 隧道

通过 SSH 端口转发连接到 AWS

无法从我的 linux shell 打开 ssh 隧道(EC2 暴露 RDS db)

通过 Ubuntu 堡垒到私有子网中的 EC2 实例的 SSH 隧道