Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SSL support to JedisCluster #1550

Merged
merged 12 commits into from Aug 1, 2018
Merged

Add SSL support to JedisCluster #1550

merged 12 commits into from Aug 1, 2018

Conversation

joroda
Copy link

@joroda joroda commented Jul 18, 2017

These changes add SSL support to JedisCluster. Tests have also been added. I've tried to solve issue of not being able to get SSL ports from a Redis server by introducing a configuration setting where users can specify a mapping between the ports reported by Redis and the actual SSL ports that should be used. This approach seemed the most flexible.

@marcosnils
Copy link
Contributor

marcosnils commented Jul 18, 2017

hey @joroda this is really amazing. I'll try to review whenever I have some time. Would love if @xetorthio @HeartSaVioR or @damiri-ts could also take a look.

@damiri-ts
Copy link

@joroda I've been looking at the code to try to understand it. I will outline my analysis of the code here just to make sure I understand it correctly.

  • The client maintains a local map of standard ports to TLS ports for each node in the cluster
  • When the client connects to a single node in the cluster, the node returns the hosts and standard ports of all nodes in the cluster to the client
  • The client uses the information from the server and it local map of ports to determine the TLS port to use when connecting to the other nodes in the cluster.

It seems that one limitation of this solution, is that the client needs to know all hosts, ports, and TLS ports in the cluster ahead of time. This means that if another node is added to the cluster, the client will not be immediately aware of this.

Did I understand this correctly?

@joroda
Copy link
Author

joroda commented Jul 24, 2017

@damiri-ts Your understanding is correct. I'm not sure that there is a way to avoid the client needing to know about all ports/TLS ports ahead of time. However, instead of using a map for these ports, it may be more flexible for the user to provide a Function<int, int> that does the mapping between normal and TLS ports.

In the case that the relationship between port and TLS port was easily predictable, the user could provide something like (int p) -> p + 1000 to adapt to nodes being added without having to change code.

Please let me know what you think about this.

Edit: I've realized that defining anonymous function is something that was only added in Java 8, so that may not be the best option. Alternatively, the client could have the user provide either a Map of the ports or just a integer representing the offset between a port and its TLS port.

@damiri-ts
Copy link

@joroda Providing a port mapping function is a clever idea. I believe that this would be the best solution, short of modifications to the server, because it would allow clients to have immediate knowledge of additional nodes on the cluster, provided some convention for calculating TLS ports from non-TLS ports.

Thank you for your contribution.

@joroda
Copy link
Author

joroda commented Jul 25, 2017

@damiri-ts Sounds great. I've just pushed a change to implement this. In order to do this in a way supported by Java 7, I've added the JedisClusterPortMap inteface instead of using Java 8's lambda function feature. Here is the interface:

public interface JedisClusterPortMap {
  int getSSLPort(int port);
}

Users will have to provide an implementation of the interface which could look something like this:

JedisClusterPortMap portMap = new JedisClusterPortMap() {
    public int getSSLPort(int port) {
      return port + 1000;
    }
};

Please let me know what you think of this.

@damiri-ts
Copy link

@joroda It looks good to me. I think it's the most flexible and practical solution without server-side changes.

@joroda
Copy link
Author

joroda commented Aug 7, 2017

@damiri-ts @marcosnils Let me know if this needs anything else before it can be merged.

@HeartSaVioR
Copy link
Contributor

I'll have a look when I have some time to catch up. Sorry to visit too late.

@joroda
Copy link
Author

joroda commented Oct 12, 2017

@HeartSaVioR Just wanted to check in to see if you've had the chance to take a look at this.

Copy link
Contributor

@HeartSaVioR HeartSaVioR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@HeartSaVioR
Copy link
Contributor

@marcosnils @sazzad16 Please review this. Thanks in advance.

@mp911de
Copy link
Contributor

mp911de commented Dec 8, 2017

Looks pretty decent, it would also make sense to provide an address mapper if the IP address is different than the one reported by CLUSTER INFO/CLUSTER SLOTS (e.g. running the SSL tunnel on a different machine).

sazzad16 added a commit to sazzad16/jedis that referenced this pull request Dec 9, 2017
There are no usage of these methods. From redis#1550, it is evident that these are not handy even for ssl operations.
…isting one to fix backwards compatibility issue
# Conflicts:
#	src/main/java/redis/clients/jedis/JedisCluster.java
#	src/main/java/redis/clients/jedis/JedisClusterConnectionHandler.java
#	src/main/java/redis/clients/jedis/JedisClusterInfoCache.java
#	src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java
@joroda
Copy link
Author

joroda commented Jan 18, 2018

@sazzad16 I've added the requested changes and attempted to resolve merge conflicts.

src/main/java/redis/clients/jedis/JedisCluster.java Outdated Show resolved Hide resolved
Assert.assertEquals(CertificateException.class, e.getCause().getCause().getCause().getClass());
}

if (jc != null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If jc != null, execution will not reach this point because of previous Assert.fail(). Put this block in finally and remove following Assert.fail(). Also, if this is only fail testing, try to hint that in method name (e.g. WithWrongSSLParameters).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to go with connectByIpAddressFailsWithSSLParameters since in this case, there is not really a right SSLParameters that will work.

// hostname validation. When closing this Jedis object, the RedisOutputStream in the underlying
// Connection object is null and causes this exception
}
if (jc2 != null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If jc2 != null, execution will not reach this point because of previous Assert.fail(). Put this block in finally and remove following Assert.fail().

InvalidAlgorithmParameterException.class, e.getCause().getCause().getCause().getCause().getClass());
}

if (jc != null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If jc != null, execution will not reach this point because of previous Assert.fail(). Put this block in finally and remove following Assert.fail().

@sgopan
Copy link

sgopan commented Jul 5, 2018

Any idea when these changes will be will merged. We badly need these changes.

@akhiljain1986
Copy link

Is there any ETA to merge these changes ?

@johnynek
Copy link

Maintainers: is there any update? We are considering running our own build of jedis to get this feature. Of course, a release would be easier for us.

Is there anything blocking? It has a "ready to merge" tag, so maybe everything is ready to go?

@sazzad16
Copy link
Collaborator

@johnynek There isn't any approximate date of release. So please use your own build for the time being. Thanks!

@marcosnils marcosnils merged commit ba33d0f into redis:master Aug 1, 2018
marcosnils pushed a commit that referenced this pull request Aug 1, 2018
* Add SSL support to JedisCluster

* Remove unused imports from SSLJedisClusterTest

* Add JedisClusterPortMap interface for mapping between plaintext and SSL ports.

* Fix casing in JedisClusterPortMap

* Add new constructor for JedisClusterInfoCache instead of modifying existing one to fix backwards compatibility issue

* Undo unintended formatting changes.

* Improve name of test case in SSLJedisClusterTest

* Fix logic for closing JedisCluster objects in SSLJedisClusterTest

* Add option to specify mapping between redis and ssl hostnames

* Remove unneeded public access modifiers
marcosnils pushed a commit that referenced this pull request Aug 1, 2018
* Add SSL support to JedisCluster

* Remove unused imports from SSLJedisClusterTest

* Add JedisClusterPortMap interface for mapping between plaintext and SSL ports.

* Fix casing in JedisClusterPortMap

* Add new constructor for JedisClusterInfoCache instead of modifying existing one to fix backwards compatibility issue

* Undo unintended formatting changes.

* Improve name of test case in SSLJedisClusterTest

* Fix logic for closing JedisCluster objects in SSLJedisClusterTest

* Add option to specify mapping between redis and ssl hostnames

* Remove unneeded public access modifiers
@marcosnils
Copy link
Contributor

Downmerged

@sazzad16
Copy link
Collaborator

sazzad16 commented Aug 1, 2018

@marcosnils Thank you for merging these PRs 👍 . I was planning to do this weekend :)

@marcosnils
Copy link
Contributor

Np. Trying to understand why tests do not pass in travis but they do in my local machine 😕

@sazzad16
Copy link
Collaborator

sazzad16 commented Aug 1, 2018

Hmm, that's odd. Because it did pass during merge request.

@sazzad16
Copy link
Collaborator

sazzad16 commented Aug 1, 2018

@marcosnils Please revert this from 2.9.

@marcosnils
Copy link
Contributor

Done.

@marcosnils
Copy link
Contributor

marcosnils commented Aug 11, 2018

I'll revert this PR because of two reasons:

  1. Tests don't pass
  2. There are some things in the design which I don't like and I'd like to change.

@joroda can you please open the PR again?

@wangxu0 wangxu0 mentioned this pull request Aug 13, 2018
@joroda
Copy link
Author

joroda commented Aug 13, 2018

The tests were passing after my latest change to this PR, but that was a while ago so I wonder if other changes to the master branch since then have broken something. I'm not sure I'll have time to make additional changes, but please build off of my contribution if it is helpful. Otherwise, I will probably have time to work on this in a few months.

@marcosnils
Copy link
Contributor

@joroda Apologize for the inconveniences and we really appreciate your effort. Would you mind re-opening the PR as-is so we can have a fresh start?. Thx!.

marcosnils pushed a commit that referenced this pull request Aug 14, 2018
* Add SSL support to JedisCluster (#1550)

* Add SSL support to JedisCluster

* Remove unused imports from SSLJedisClusterTest

* Add JedisClusterPortMap interface for mapping between plaintext and SSL ports.

* Fix casing in JedisClusterPortMap

* Add new constructor for JedisClusterInfoCache instead of modifying existing one to fix backwards compatibility issue

* Undo unintended formatting changes.

* Improve name of test case in SSLJedisClusterTest

* Fix logic for closing JedisCluster objects in SSLJedisClusterTest

* Add option to specify mapping between redis and ssl hostnames

* Remove unneeded public access modifiers

* Support for geo RO commands.

* Support for geo RO commands.

* Support for geo RO commands.

* Change _ro to Readonly for better understanding.

* Change _ro to Readonly for better understanding

Update as per comments

* Change _ro to Readonly for better understanding

Update as per comments

* Minor update. Update commands.

https://redis.io/commands/georadius

* Update as per comments.

* Revert "Add SSL support to JedisCluster (#1550)"

This reverts commit 17901ba.
marcosnils pushed a commit that referenced this pull request Aug 14, 2018
* Add SSL support to JedisCluster (#1550)

* Add SSL support to JedisCluster

* Remove unused imports from SSLJedisClusterTest

* Add JedisClusterPortMap interface for mapping between plaintext and SSL ports.

* Fix casing in JedisClusterPortMap

* Add new constructor for JedisClusterInfoCache instead of modifying existing one to fix backwards compatibility issue

* Undo unintended formatting changes.

* Improve name of test case in SSLJedisClusterTest

* Fix logic for closing JedisCluster objects in SSLJedisClusterTest

* Add option to specify mapping between redis and ssl hostnames

* Remove unneeded public access modifiers

* Support for geo RO commands.

* Support for geo RO commands.

* Support for geo RO commands.

* Change _ro to Readonly for better understanding.

* Change _ro to Readonly for better understanding

Update as per comments

* Change _ro to Readonly for better understanding

Update as per comments

* Minor update. Update commands.

https://redis.io/commands/georadius

* Update as per comments.

* Revert "Add SSL support to JedisCluster (#1550)"

This reverts commit 17901ba.
@joquijada
Copy link

joquijada commented Oct 24, 2018

Is this solution already part of a Maven release of the jedis artifact? I see here it still lists 2.9.0, which is what I'm currently using and also facing the SSL issue while connecting to AWS Redis Cluster, which is using in-transit encryption, i.e. SSL enabled client required.

@marcosnils
Copy link
Contributor

Nope 2.10.0 hasn't been released yet.

@analytically
Copy link

Doesn't seem part of 2.10.0 or 3.0.0.

joyang1 pushed a commit to joyang1/jedis that referenced this pull request Dec 27, 2018
…1841)

* Add SSL support to JedisCluster (redis#1550)

* Add SSL support to JedisCluster

* Remove unused imports from SSLJedisClusterTest

* Add JedisClusterPortMap interface for mapping between plaintext and SSL ports.

* Fix casing in JedisClusterPortMap

* Add new constructor for JedisClusterInfoCache instead of modifying existing one to fix backwards compatibility issue

* Undo unintended formatting changes.

* Improve name of test case in SSLJedisClusterTest

* Fix logic for closing JedisCluster objects in SSLJedisClusterTest

* Add option to specify mapping between redis and ssl hostnames

* Remove unneeded public access modifiers

* Support for geo RO commands.

* Support for geo RO commands.

* Support for geo RO commands.

* Change _ro to Readonly for better understanding.

* Change _ro to Readonly for better understanding

Update as per comments

* Change _ro to Readonly for better understanding

Update as per comments

* Minor update. Update commands.

https://redis.io/commands/georadius

* Update as per comments.

* Revert "Add SSL support to JedisCluster (redis#1550)"

This reverts commit 17901ba.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet