LuckPerms

LuckPerms

41.4k Downloads

[feature request] TLS support for redis messaging service

RalphORama opened this issue ยท 1 comments

commented

Description

Redis security guidelines state applications should use TLS where possible. I am currently using Luckperms on multiple servers that connect over the internet to my Redis server for messaging.

It would be nice to have the option to use client certificates in order to enable TLS connections to Redis. The Redis docs provide example Java code for connecting via TLS.

Proposed Behaviour

In config.yml, options could look something like this:

messaging-service: redis
# ...
redis:
  enabled: true
  address: redis.example.com
  username: ''
  password: ''
  tls:
    enabled: false
    ca-keystore: 'redis_ca.jks'
    ca-keystore-password: 'example'
    user-keystore: 'redis-user-keystore.p12'
    user-keystore-password: 'example'

When redis.tls.enabled is set to true, LuckPerms would use the CA/User keys specified to establish a TLS connection with the Redis server.

Extra Details

I'm not sure if a more concise approach could be used (i.e. one keystore/password for CA and user keys) but that is the general idea. The default values used here are taken from the Redis guide for using TLS with Java

commented

Additionally, LuckPerms currently cannot establish a connection to a Redis server with TLS enabled, even if tls-auth-clients optional is specified in redis.conf:

redis.conf snippet
# By default, clients (including replica servers) on a TLS port are required
# to authenticate using valid client side certificates.
#
# If "no" is specified, client certificates are not required and not accepted.
# If "optional" is specified, client certificates are accepted and must be
# valid if provided, but are not required.
#
# tls-auth-clients no
tls-auth-clients optional
LuckPerms error message
[01:04:52 INFO]: [LuckPerms] Redis pubsub connection re-established
[01:04:54 WARN]: [LuckPerms] Redis pubsub connection dropped, trying to re-open the connection
me.lucko.luckperms.lib.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset
        at me.lucko.luckperms.lib.jedis.util.RedisInputStream.ensureFill(RedisInputStream.java:208) ~[?:?]
        at me.lucko.luckperms.lib.jedis.util.RedisInputStream.readByte(RedisInputStream.java:46) ~[?:?]
        at me.lucko.luckperms.lib.jedis.Protocol.process(Protocol.java:126) ~[?:?]
        at me.lucko.luckperms.lib.jedis.Protocol.read(Protocol.java:192) ~[?:?]
        at me.lucko.luckperms.lib.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:335) ~[?:?]
        at me.lucko.luckperms.lib.jedis.Connection.getStatusCodeReply(Connection.java:262) ~[?:?]
        at me.lucko.luckperms.lib.jedis.Connection.auth(Connection.java:446) ~[?:?]
        at me.lucko.luckperms.lib.jedis.Connection.initializeFromClientConfig(Connection.java:380) ~[?:?]
        at me.lucko.luckperms.lib.jedis.Connection.<init>(Connection.java:61) ~[?:?]
        at me.lucko.luckperms.lib.jedis.ConnectionFactory.makeObject(ConnectionFactory.java:68) ~[?:?]
        at me.lucko.luckperms.lib.commonspool2.impl.GenericObjectPool.create(GenericObjectPool.java:918) ~[?:?]
        at me.lucko.luckperms.lib.commonspool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:431) ~[?:?]
        at me.lucko.luckperms.lib.commonspool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:356) ~[?:?]
        at me.lucko.luckperms.lib.jedis.util.Pool.getResource(Pool.java:38) ~[?:?]
        at me.lucko.luckperms.lib.jedis.ConnectionPool.getResource(ConnectionPool.java:29) ~[?:?]
        at me.lucko.luckperms.lib.jedis.ConnectionPool.getResource(ConnectionPool.java:7) ~[?:?]
        at me.lucko.luckperms.lib.jedis.providers.PooledConnectionProvider.getConnection(PooledConnectionProvider.java:63) ~[?:?]
        at me.lucko.luckperms.lib.jedis.UnifiedJedis.subscribe(UnifiedJedis.java:3538) ~[?:?]
        at me.lucko.luckperms.common.messaging.redis.RedisMessenger$Subscription.run(RedisMessenger.java:125) ~[?:?]
        at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395) ~[?:?]
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373) ~[?:?]
        at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182) ~[?:?]
        at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655) ~[?:?]
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622) ~[?:?]
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165) ~[?:?]
Caused by: java.net.SocketException: Connection reset
        at sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:328) ~[?:?]
        at sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:355) ~[?:?]
        at sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:808) ~[?:?]
        at java.net.Socket$SocketInputStream.read(Socket.java:966) ~[?:?]
        at java.io.InputStream.read(InputStream.java:218) ~[?:?]
        at me.lucko.luckperms.lib.jedis.util.RedisInputStream.ensureFill(RedisInputStream.java:202) ~[?:?]
        ... 24 more