mirror of
https://github.com/element-hq/synapse.git
synced 2024-12-14 11:57:44 +00:00
Add redis SSL configuration options (#15312)
* Add SSL options to redis config * fix lint issues * Add documentation and changelog file * add missing . at the end of the changelog * Move client context factory to new file * Rename ssl to tls and fix typo * fix lint issues * Added when redis attributes were added
This commit is contained in:
parent
5bf9ec9e3e
commit
2611433b70
7 changed files with 98 additions and 14 deletions
1
changelog.d/15312.feature
Normal file
1
changelog.d/15312.feature
Normal file
|
@ -0,0 +1 @@
|
|||
Add redis TLS configuration options.
|
|
@ -70,6 +70,10 @@ redis:
|
|||
port: 6379
|
||||
# dbid: <redis_logical_db_id>
|
||||
# password: <secret_password>
|
||||
# use_tls: True
|
||||
# certificate_file: <path_to_certificate>
|
||||
# private_key_file: <path_to_private_key>
|
||||
# ca_file: <path_to_ca_certificate>
|
||||
```
|
||||
|
||||
This assumes that your Redis service is called `redis` in your Docker Compose file.
|
||||
|
|
|
@ -3981,9 +3981,16 @@ This setting has the following sub-options:
|
|||
localhost and 6379
|
||||
* `password`: Optional password if configured on the Redis instance.
|
||||
* `dbid`: Optional redis dbid if needs to connect to specific redis logical db.
|
||||
* `use_tls`: Whether to use tls connection. Defaults to false.
|
||||
* `certificate_file`: Optional path to the certificate file
|
||||
* `private_key_file`: Optional path to the private key file
|
||||
* `ca_file`: Optional path to the CA certificate file. Use this one or:
|
||||
* `ca_path`: Optional path to the folder containing the CA certificate file
|
||||
|
||||
_Added in Synapse 1.78.0._
|
||||
|
||||
_Changed in Synapse 1.84.0: Added use\_tls, certificate\_file, private\_key\_file, ca\_file and ca\_path attributes_
|
||||
|
||||
Example configuration:
|
||||
```yaml
|
||||
redis:
|
||||
|
@ -3992,6 +3999,10 @@ redis:
|
|||
port: 6379
|
||||
password: <secret_password>
|
||||
dbid: <dbid>
|
||||
#use_tls: True
|
||||
#certificate_file: <path_to_the_certificate_file>
|
||||
#private_key_file: <path_to_the_private_key_file>
|
||||
#ca_file: <path_to_the_ca_certificate_file>
|
||||
```
|
||||
---
|
||||
## Individual worker configuration
|
||||
|
|
|
@ -35,3 +35,9 @@ class RedisConfig(Config):
|
|||
self.redis_port = redis_config.get("port", 6379)
|
||||
self.redis_dbid = redis_config.get("dbid", None)
|
||||
self.redis_password = redis_config.get("password")
|
||||
|
||||
self.redis_use_tls = redis_config.get("use_tls", False)
|
||||
self.redis_certificate = redis_config.get("certificate_file", None)
|
||||
self.redis_private_key = redis_config.get("private_key_file", None)
|
||||
self.redis_ca_file = redis_config.get("ca_file", None)
|
||||
self.redis_ca_path = redis_config.get("ca_path", None)
|
||||
|
|
34
synapse/replication/tcp/context.py
Normal file
34
synapse/replication/tcp/context.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from OpenSSL.SSL import Context
|
||||
from twisted.internet import ssl
|
||||
|
||||
from synapse.config.redis import RedisConfig
|
||||
|
||||
|
||||
class ClientContextFactory(ssl.ClientContextFactory):
|
||||
def __init__(self, redis_config: RedisConfig):
|
||||
self.redis_config = redis_config
|
||||
|
||||
def getContext(self) -> Context:
|
||||
ctx = super().getContext()
|
||||
if self.redis_config.redis_certificate:
|
||||
ctx.use_certificate_file(self.redis_config.redis_certificate)
|
||||
if self.redis_config.redis_private_key:
|
||||
ctx.use_privatekey_file(self.redis_config.redis_private_key)
|
||||
if self.redis_config.redis_ca_file:
|
||||
ctx.load_verify_locations(cafile=self.redis_config.redis_ca_file)
|
||||
elif self.redis_config.redis_ca_path:
|
||||
ctx.load_verify_locations(capath=self.redis_config.redis_ca_path)
|
||||
return ctx
|
|
@ -46,6 +46,7 @@ from synapse.replication.tcp.commands import (
|
|||
UserIpCommand,
|
||||
UserSyncCommand,
|
||||
)
|
||||
from synapse.replication.tcp.context import ClientContextFactory
|
||||
from synapse.replication.tcp.protocol import IReplicationConnection
|
||||
from synapse.replication.tcp.streams import (
|
||||
STREAMS_MAP,
|
||||
|
@ -348,13 +349,27 @@ class ReplicationCommandHandler:
|
|||
outbound_redis_connection,
|
||||
channel_names=self._channels_to_subscribe_to,
|
||||
)
|
||||
hs.get_reactor().connectTCP(
|
||||
hs.config.redis.redis_host,
|
||||
hs.config.redis.redis_port,
|
||||
self._factory,
|
||||
timeout=30,
|
||||
bindAddress=None,
|
||||
)
|
||||
|
||||
reactor = hs.get_reactor()
|
||||
redis_config = hs.config.redis
|
||||
if hs.config.redis.redis_use_tls:
|
||||
ssl_context_factory = ClientContextFactory(hs.config.redis)
|
||||
reactor.connectSSL(
|
||||
redis_config.redis_host,
|
||||
redis_config.redis_port,
|
||||
self._factory,
|
||||
ssl_context_factory,
|
||||
timeout=30,
|
||||
bindAddress=None,
|
||||
)
|
||||
else:
|
||||
reactor.connectTCP(
|
||||
redis_config.redis_host,
|
||||
redis_config.redis_port,
|
||||
self._factory,
|
||||
timeout=30,
|
||||
bindAddress=None,
|
||||
)
|
||||
|
||||
def get_streams(self) -> Dict[str, Stream]:
|
||||
"""Get a map from stream name to all streams."""
|
||||
|
|
|
@ -35,6 +35,7 @@ from synapse.replication.tcp.commands import (
|
|||
ReplicateCommand,
|
||||
parse_command_from_line,
|
||||
)
|
||||
from synapse.replication.tcp.context import ClientContextFactory
|
||||
from synapse.replication.tcp.protocol import (
|
||||
IReplicationConnection,
|
||||
tcp_inbound_commands_counter,
|
||||
|
@ -386,12 +387,24 @@ def lazyConnection(
|
|||
factory.continueTrying = reconnect
|
||||
|
||||
reactor = hs.get_reactor()
|
||||
reactor.connectTCP(
|
||||
host,
|
||||
port,
|
||||
factory,
|
||||
timeout=30,
|
||||
bindAddress=None,
|
||||
)
|
||||
|
||||
if hs.config.redis.redis_use_tls:
|
||||
ssl_context_factory = ClientContextFactory(hs.config.redis)
|
||||
reactor.connectSSL(
|
||||
host,
|
||||
port,
|
||||
factory,
|
||||
ssl_context_factory,
|
||||
timeout=30,
|
||||
bindAddress=None,
|
||||
)
|
||||
else:
|
||||
reactor.connectTCP(
|
||||
host,
|
||||
port,
|
||||
factory,
|
||||
timeout=30,
|
||||
bindAddress=None,
|
||||
)
|
||||
|
||||
return factory.handler
|
||||
|
|
Loading…
Reference in a new issue