cartesi / rollups

Cartesi Rollups
30 stars 12 forks source link

Redis clients should support tls #13

Closed gligneul closed 1 year ago

gligneul commented 1 year ago

📚 Context

We might need to support TLS when connecting to a hosted Redis service (e.g. AWS MemoryDB).

✔️ Solution

When connecting using redis-cli, it is possible to connect to Redis using the option --tls. We should do something similar for our clients.

📈 Subtasks

torives commented 1 year ago

I’ve been researching to find the best way to add TLS support and this is what I have found so far:

We’re using the aptly named redis crate to connect to Redis (I’ll call it redis-rs to avoid confusion). It supports TLS by enabling features related to the rustls or native-tls crates. Configuring a connection using custom certificates seemed the best approach, so I searched for a way to do just that. The problem is that redis-rs doesn’t offer this customizability in its high-level API, hiding the functionality present in the TLS crates it uses internally.

There’s an open issue regarding this topic with a proposed workaround. Unfortunately, it doesn’t seem to work with ConnectionManager, which we are currently using.

Some possible paths forward:

  1. Add the client/ca certificate to the certificate store on the host, as both rustls and native-tls load all certificates from the host’s store by default. This has some security implications and would make testing harder, but theoretically, it should work.
  2. Validate if the workaround actually works. This would be costly, as I would have to dig deep into the crate’s code to learn how to do it and would have no guarantees of success.
  3. Discuss with the maintainers the best approach and open a PR to their repo with a solution.

@endersonmaia I wanted to hear from you if path 1 would be a good (enough) fit for our needs or if it presents more issues that I'm aware of.

endersonmaia commented 1 year ago

Configuring a connection using custom certificates seemed the best approach, so I searched for a way to do just that.

When I also control/manage the redis-server, it's the way to go. There's the need to generate the root CA and generate server and client certificates, and a way to define this configuration.

For redis cloud providers that support TLS, they usually use valid certificates supported by every OS, and public domains.


We could wait (watch) this to be solved upstream, and make our own workaround using stunnel, this should be enough to connect to AWS Managed Redis TLS.

And we could focus on #12, to make use of the cluster features from AWS Managed Redis.

torives commented 1 year ago

This is the solution I came up with in the end:

I've decided to use the native-tls crate as I find it provides a richer API (even though we won't interact directly with it). The certificates are loaded "automagically", so there are not many code changes besides the Redis server's URL schema (which becomes rediss).

To test it out, we've created a Docker image containing a Redis server adequately configured with the TLS certificates and a test binary. When executed the binary tries to connect to the server to generate and retrieve an event. The test itself consists of executing said binary inside the container and asserting it finishes with a valid exit code.

Client certificate authentication was disabled in the server as we considered it unnecessary for now.