redis.conf contains:

# If TLS/SSL clients are required to authenticate using a client side
# certificate, use this directive.
#
# Note: this applies to all incoming clients, including replicas.
#
# tls-auth-clients yes

which strongly suggests that the default is not this, when in fact this is the default behavior, and it is required to add:

tls-auth-clients no

to disable client auth.


There may or may not also be some interaction with tls-ca-cert-file/tls-ca-cert-dir - it isn't clear to me whether this should be required when not authenticating clients/peers, but: the server won't start without it being configured.

Comment From: antirez

Ping @yossigo

Comment From: yossigo

Thanks @mgravell, I've made some clarifications in #6839.

Regarding the CA certificates, obviously tls-auth-clients yes would interact with it but also cluster-bus. Theoretically we could relax the requirement to always specify it but then we'll need to prevent users from changing those parameters on the fly if a CA certificate was not configured. I think it's common practice today to always require explicit CA path/certificate so I'm quite comfortable leaving it as is.

Comment From: jain-abhishek

Even after setting tls-auth-clients to yes or keeping it commented, the client without passing its certificates is able to access the redis server. Is it the expected behavior ?

Comment From: yossigo

@jain-abhishek No, it's not expected. Can you provide more details on what you see, because I don't see this reproduce as part of the tests or even manually.

Comment From: jain-abhishek

Neither I have created any certificates of client nor included any. I used one way ssl only. I works. However when I set tls-auth-clients to yes (or even leaving it default), I am still able to insert into and fetch from redis.

Please find the code here: 1. redis.conf:

port 0
tls-port 6379
tls-cert-file redisServer.crt
tls-key-file redisServer.key
tls-ca-cert-file rootCA.crt
#tls-auth-clients no

I tried setting tls-auth-clients yes also.

  1. Created keystore by adding the certificates and private key:
openssl pkcs12 -export -in redisServer.crt -inkey redisServer.key -out redisServerKeystore.p12 -CAfile rootCA.crt 
  1. Created truststore:
keytool -import -alias redisServerCA -trustcacerts -file rootCA.crt -keystore cacerts
  1. java code:
import java.net.MalformedURLException;
import java.net.URI;

import org.redisson.Redisson;
import org.redisson.api.RBucket;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.redisson.config.TransportMode;

public class RedissonSSL {

    public static void main(String[] args) throws MalformedURLException {
        Config config = new Config();
        config.setTransportMode(TransportMode.NIO);
        SingleServerConfig ssconfig = config.useSingleServer();
        ssconfig.setAddress("rediss://3.143.214.20:6379");
        ssconfig.setSslKeystore(URI.create("file:/C:/workspace/RedisInAction/redisServerKeystore.p12").toURL());
        ssconfig.setSslKeystorePassword("passwd"); 
        ssconfig.setSslTruststore(URI.create("file:/C:/workspace/RedisInAction/cacerts").toURL());
        ssconfig.setSslTruststorePassword("changeit");
        ssconfig.setUsername("abhishek");
        ssconfig.setPassword("abhishek");

        RedissonClient client = Redisson.create(config);
        RBucket<String> bucket = client.getBucket("cfo:key");
        bucket.set("value");

        RList<String> list = client.getList("cfo:list");
        for(int i=0;i<50;i++)
            list.add("value"+i);

        for(int i=0;i<list.size();i++)
            System.out.println(list.get(i));

        System.out.println("exiting");
        client.shutdown();
    }
}

Comment From: yossigo

@jain-abhishek You're not creating a client cert but you're loading the server certificate - which is signed by the same CA - to the client. So this certificate is essentially used by the client to authenticate.

I'm not familiar with the specific Redisson implementation but I suppose that if you only leave the trusted store setup and drop these lines:

ssconfig.setSslKeystore(URI.create("file:/C:/workspace/RedisInAction/redisServerKeystore.p12").toURL());
ssconfig.setSslKeystorePassword("passwd"); 

you will be able to connect with tls-auth-clients no only.

Comment From: jain-abhishek

So basically, we should create a separate certificate for client and get it signed by the same CA (which signed server certificate also).

Comment From: yossigo

@jain-abhishek Yes, that should work and is one way of doing that. It really depends on what you're trying to achieve - using the same self signed certificate on both ends may also be a valid choice.

Comment From: Bec-k

Agree, tls-auth-clients should be no as default. Basically it is enabling two way tls communication if i'm not wrong. Performing handshake before allow to access data. For example, kubernetes nginx ingress lua redis doesn't have this feature yes, it is not released yet. So this is impossible to connect, because of this flag was set by default.

Comment From: Bec-k

Possibly rename it to enableTwoWaySSL or something like that, or requireSSLHandshake or any other name, which will be more meaningful.

Comment From: yossigo

@denissabramovs We use tls-auth-clients yes to follow the best practice of secure defaults.