13

I'm trying to use a Ruby redis client and either one of two NodeJS clients (node_redis or ioredis) to connect to an Amazon ElastiCache cluster with in-transit encryption and auth enabled and am having issues. For all three clients, as soon as I connect I get an ECONNRESET error thrown immediately and over and over again when connection retries occur.

I have followed the AWS docs and am able to successfully connect via redis-cli using stunnel, but haven't been able to connect with any other client so far.

From looking at this SO answer, it appears there is no certificate required and we simply need to pass empty options to the TLS config (if applicable), but no matter what I enter I'm unsuccessful. I've also tried passing the default stunnel stunnel.pem private key as the cert in all clients just in case, and it obviously doesn't work either. Any assistance or expertise from others who have used ElastiCache would be helpful!

LeoMurillo
  • 6,048
  • 1
  • 19
  • 34
Lance Whatley
  • 2,395
  • 1
  • 13
  • 16

2 Answers2

22

For both clients the default TLS behavior is to verify the server certificate, which we needed to disable. The solution for both clients is as follows:

NodeJS client:

const redis = require('redis')
const client = redis.createClient({host: hostOrIp, port: 6379, auth_pass: 'thePassword', tls: { checkServerIdentity: () => undefined }})

Ruby client:

require "redis"
redis = Redis.new(url: connectionString, ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE })
Lance Whatley
  • 2,395
  • 1
  • 13
  • 16
  • THANK YOU. From my node client I was getting `Error: Redis connection to :6379 failed - read ECONNRESET` and could not figure this out. I was trying with only the `auth_pass` param in the client connection and adding the `tls` param did the trick – McLovin Sep 05 '18 at 02:31
  • Many thanks to Lance Whatley. You save my day. Hope this post can resolve the problem for who has trouble with connecting AWS Elasticache Redis with Node.js. Btw, thePassword in the code should be quoted like 'thePassword' – Frank Liu Oct 03 '18 at 20:50
  • Thanks @FrankLiu I just fixed it in the answer. – Lance Whatley Oct 03 '18 at 22:28
  • `password` is the documented param but `auth_pass` works. Thanks for this answer!! – ricka Oct 19 '18 at 23:12
  • @ricka `auth_pass` is documented as an alias – AlienWebguy Dec 11 '19 at 01:15
  • 1
    For Googlers, this is no longer needed, Elasticache Redis certificates now have correct hostnames set. – dz902 Feb 04 '21 at 06:54
  • @dz902 - Did you need to download the certs for Elasticache Redis in this case or provide it in the code. If so, how did you provide it? – Rajesh Chamarthi Aug 30 '22 at 23:12
9

I ran into a similar problem, but instead of ECONNRESET I was getting a timeout. For me, there were a few problems that had to be ironed out

  • The lambda needs VPC permissions.
  • The ElastiCache security group needs an inbound rule from the Lambda security group that allows communication on the Redis port. I thought they could just be in the same security group.
  • Because encryption in-transit was turned on, I needed to pass redis.RedisClient(... ssl=True). The redis-py page mentions that ssl_cert_reqs needs to be set to None for use with ElastiCache similar to what was answered, but that didn't seem to be true in my case. I think AWS has updated the ElastiCache certs to have the proper hostname. I did however need to pass ssl=True.

It makes sense that ssl=True needed to be set but the connection was just timing out so I went round and round trying to figure out what the problem with the permissions/VPC/SG setup was.

feus4177
  • 1,193
  • 1
  • 11
  • 15