Search code examples
amazon-web-serviceselasticsearchamazon-ec2portforwardingssh-tunnel

ssh tunneling/port forwarding not working through EC2 instance to an Elasticsearch cluster in a VPC


I have my Elasticsearch cluster in a VPC, I'd like to access this EC cluster from my local Macbook. I have set up a bastion host that uses the same VPC and the same security group, and I was able to ssh into this bastion host from my Macbook.

But somehow, my code just cannot connect to my ES cluster through this bastion host, here's my command to run port forwarding:

ssh -i ~/Downloads/keypairs/20210402-02.pem [email protected] -N -L 9200:vpc-es-domain-20210331-abc123def.us-west-2.es.amazonaws.com:443

Here's my timeout exception when accessing the ES cluster in the VPC:

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]

Here are the rules of my SG:

Inbound:

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

Outbound:

All traffic All All 0.0.0.0/0

When I've ssh'ed into my bastion host, and run curl vpc-es-domain-20210331-abc123def.us-west-2.es.amazonaws.com, I got this response:

{
  "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"
}

I'm suspecting my command to do port forwarding is not correct? But after research, this looks the most legit option to me. Any insight would be greatly appreciated!


Solution

  • The code running on your local computer is trying to connect directly to the Elasticsearch server without going through the SSH tunnel. The SSH command is opening a tunnel from your local port 9200 to the remote server. The local software trying to connect to Elasticsearch should be connecting to localhost:9200 not vpc-es-domain-20210331-abc123def.us-west-2.es.amazonaws.com/10.0.47.182:443.


    The endpoint vpc-es-domain-20210331-abc123def.us-west-2.es.amazonaws.com/10.0.47.182:443 doesn't look valid anyway. It has a hostname and an IP address in there.


    You mentioned in the comments:

    "I actually launched my bastion host using the same SG as my ES"

    However just placing two resources in the same security group does nothing unless that security group also has a rule specifically allowing traffic between the resources within it. Security groups do not have this rule by default, except for the default security group in the default VPC that is created automatically when you first create your AWS account.

    So please make sure that the security group has a rule that will allow the bastion host to connect to the Elasticsearch server over port 443.