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
|
port: 6379
|
||||||
# dbid: <redis_logical_db_id>
|
# dbid: <redis_logical_db_id>
|
||||||
# password: <secret_password>
|
# 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.
|
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
|
localhost and 6379
|
||||||
* `password`: Optional password if configured on the Redis instance.
|
* `password`: Optional password if configured on the Redis instance.
|
||||||
* `dbid`: Optional redis dbid if needs to connect to specific redis logical db.
|
* `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._
|
_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:
|
Example configuration:
|
||||||
```yaml
|
```yaml
|
||||||
redis:
|
redis:
|
||||||
|
@ -3992,6 +3999,10 @@ redis:
|
||||||
port: 6379
|
port: 6379
|
||||||
password: <secret_password>
|
password: <secret_password>
|
||||||
dbid: <dbid>
|
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
|
## Individual worker configuration
|
||||||
|
|
|
@ -35,3 +35,9 @@ class RedisConfig(Config):
|
||||||
self.redis_port = redis_config.get("port", 6379)
|
self.redis_port = redis_config.get("port", 6379)
|
||||||
self.redis_dbid = redis_config.get("dbid", None)
|
self.redis_dbid = redis_config.get("dbid", None)
|
||||||
self.redis_password = redis_config.get("password")
|
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,
|
UserIpCommand,
|
||||||
UserSyncCommand,
|
UserSyncCommand,
|
||||||
)
|
)
|
||||||
|
from synapse.replication.tcp.context import ClientContextFactory
|
||||||
from synapse.replication.tcp.protocol import IReplicationConnection
|
from synapse.replication.tcp.protocol import IReplicationConnection
|
||||||
from synapse.replication.tcp.streams import (
|
from synapse.replication.tcp.streams import (
|
||||||
STREAMS_MAP,
|
STREAMS_MAP,
|
||||||
|
@ -348,13 +349,27 @@ class ReplicationCommandHandler:
|
||||||
outbound_redis_connection,
|
outbound_redis_connection,
|
||||||
channel_names=self._channels_to_subscribe_to,
|
channel_names=self._channels_to_subscribe_to,
|
||||||
)
|
)
|
||||||
hs.get_reactor().connectTCP(
|
|
||||||
hs.config.redis.redis_host,
|
reactor = hs.get_reactor()
|
||||||
hs.config.redis.redis_port,
|
redis_config = hs.config.redis
|
||||||
self._factory,
|
if hs.config.redis.redis_use_tls:
|
||||||
timeout=30,
|
ssl_context_factory = ClientContextFactory(hs.config.redis)
|
||||||
bindAddress=None,
|
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]:
|
def get_streams(self) -> Dict[str, Stream]:
|
||||||
"""Get a map from stream name to all streams."""
|
"""Get a map from stream name to all streams."""
|
||||||
|
|
|
@ -35,6 +35,7 @@ from synapse.replication.tcp.commands import (
|
||||||
ReplicateCommand,
|
ReplicateCommand,
|
||||||
parse_command_from_line,
|
parse_command_from_line,
|
||||||
)
|
)
|
||||||
|
from synapse.replication.tcp.context import ClientContextFactory
|
||||||
from synapse.replication.tcp.protocol import (
|
from synapse.replication.tcp.protocol import (
|
||||||
IReplicationConnection,
|
IReplicationConnection,
|
||||||
tcp_inbound_commands_counter,
|
tcp_inbound_commands_counter,
|
||||||
|
@ -386,12 +387,24 @@ def lazyConnection(
|
||||||
factory.continueTrying = reconnect
|
factory.continueTrying = reconnect
|
||||||
|
|
||||||
reactor = hs.get_reactor()
|
reactor = hs.get_reactor()
|
||||||
reactor.connectTCP(
|
|
||||||
host,
|
if hs.config.redis.redis_use_tls:
|
||||||
port,
|
ssl_context_factory = ClientContextFactory(hs.config.redis)
|
||||||
factory,
|
reactor.connectSSL(
|
||||||
timeout=30,
|
host,
|
||||||
bindAddress=None,
|
port,
|
||||||
)
|
factory,
|
||||||
|
ssl_context_factory,
|
||||||
|
timeout=30,
|
||||||
|
bindAddress=None,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
reactor.connectTCP(
|
||||||
|
host,
|
||||||
|
port,
|
||||||
|
factory,
|
||||||
|
timeout=30,
|
||||||
|
bindAddress=None,
|
||||||
|
)
|
||||||
|
|
||||||
return factory.handler
|
return factory.handler
|
||||||
|
|
Loading…
Reference in a new issue