forked from CGM_Public/pretix_original
Add PostgreSQL & Redis TLS/mTLS support (#3435)
This commit is contained in:
committed by
GitHub
parent
6dbbfe3b04
commit
b35a388685
@@ -152,6 +152,10 @@ Example::
|
||||
password=abcd
|
||||
host=localhost
|
||||
port=3306
|
||||
sslmode=require
|
||||
sslrootcert=/etc/pretix/postgresql-ca.crt
|
||||
sslcert=/etc/pretix/postgresql-client-crt.crt
|
||||
sslkey=/etc/pretix/postgresql-client-key.key
|
||||
|
||||
``backend``
|
||||
One of ``sqlite3`` and ``postgresql``.
|
||||
@@ -163,6 +167,11 @@ Example::
|
||||
``user``, ``password``, ``host``, ``port``
|
||||
Connection details for the database connection. Empty by default.
|
||||
|
||||
``sslmode``, ``sslrootcert``
|
||||
Connection TLS details for the PostgreSQL database connection. Possible values of ``sslmode`` are ``disable``, ``allow``, ``prefer``, ``require``, ``verify-ca``, and ``verify-full``. ``sslrootcert`` should be the accessible path of the ca certificate. Both values are empty by default.
|
||||
|
||||
``sslcert``, ``sslkey``
|
||||
Connection mTLS details for the PostgreSQL database connection. It's also necessary to specify ``sslmode`` and ``sslrootcert`` parameters, please check the correct values from the TLS part. ``sslcert`` should be the accessible path of the client certificate. ``sslkey`` should be the accessible path of the client key. All values are empty by default.
|
||||
.. _`config-replica`:
|
||||
|
||||
Database replica settings
|
||||
@@ -324,6 +333,10 @@ to speed up various operations::
|
||||
["sentinel_host_3", 26379]
|
||||
]
|
||||
password=password
|
||||
ssl_cert_reqs=required
|
||||
ssl_ca_certs=/etc/pretix/redis-ca.pem
|
||||
ssl_keyfile=/etc/pretix/redis-client-crt.pem
|
||||
ssl_certfile=/etc/pretix/redis-client-key.key
|
||||
|
||||
``location``
|
||||
The location of redis, as a URL of the form ``redis://[:password]@localhost:6379/0``
|
||||
@@ -347,6 +360,22 @@ to speed up various operations::
|
||||
If your redis setup doesn't require a password or you already specified it in the location you can omit this option.
|
||||
If this is set it will be passed to redis as the connection option PASSWORD.
|
||||
|
||||
``ssl_cert_reqs``
|
||||
If this is set it will be passed to redis as the connection option ``SSL_CERT_REQS``.
|
||||
Possible values are ``none``, ``optional``, and ``required``.
|
||||
|
||||
``ssl_ca_certs``
|
||||
If your redis setup doesn't require TLS you can omit this option.
|
||||
If this is set it will be passed to redis as the connection option ``SSL_CA_CERTS``. Possible value is the ca path.
|
||||
|
||||
``ssl_keyfile``
|
||||
If your redis setup doesn't require mTLS you can omit this option.
|
||||
If this is set it will be passed to redis as the connection option ``SSL_KEYFILE``. Possible value is the keyfile path.
|
||||
|
||||
``ssl_certfile``
|
||||
If your redis setup doesn't require mTLS you can omit this option.
|
||||
If this is set it will be passed to redis as the connection option ``SSL_CERTFILE``. Possible value is the certfile path.
|
||||
|
||||
If redis is not configured, pretix will store sessions and locks in the database. If memcached
|
||||
is configured, memcached will be used for caching instead of redis.
|
||||
|
||||
@@ -396,6 +425,8 @@ The two ``transport_options`` entries can be omitted in most cases.
|
||||
If they are present they need to be a valid JSON dictionary.
|
||||
For possible entries in that dictionary see the `Celery documentation`_.
|
||||
|
||||
It is possible the use Redis with TLS/mTLS for the broker or the backend. To do so, it is necessary to specify the TLS identifier ``rediss``, the ssl mode ``ssl_cert_reqs`` and optionally specify the CA (TLS) ``ssl_ca_certs``, cert ``ssl_certfile`` and key ``ssl_keyfile`` (mTLS) path as encoded string. the following uri describes the format and possible parameters ``rediss://0.0.0.0:6379/1?ssl_cert_reqs=required&ssl_ca_certs=%2Fetc%2Fpretix%2Fredis-ca.pem&ssl_certfile=%2Fetc%2Fpretix%2Fredis-client-crt.pem&ssl_keyfile=%2Fetc%2Fpretix%2Fredis-client-key.key``
|
||||
|
||||
To use redis with sentinels set the broker or backend to ``sentinel://sentinel_host_1:26379;sentinel_host_2:26379/0``
|
||||
and the respective transport_options to ``{"master_name":"mymaster"}``.
|
||||
If your redis instances behind the sentinel have a password use ``sentinel://:my_password@sentinel_host_1:26379;sentinel_host_2:26379/0``.
|
||||
|
||||
@@ -116,6 +116,29 @@ elif 'mysql' in db_backend:
|
||||
|
||||
db_options = {}
|
||||
|
||||
postgresql_sslmode = config.get('database', 'sslmode', fallback='disable')
|
||||
USE_DATABASE_TLS = postgresql_sslmode != 'disable'
|
||||
USE_DATABASE_MTLS = USE_DATABASE_TLS and config.has_option('database', 'sslcert')
|
||||
|
||||
if USE_DATABASE_TLS or USE_DATABASE_MTLS:
|
||||
tls_config = {}
|
||||
if not USE_DATABASE_MTLS:
|
||||
if 'postgresql' in db_backend:
|
||||
tls_config = {
|
||||
'sslmode': config.get('database', 'sslmode'),
|
||||
'sslrootcert': config.get('database', 'sslrootcert'),
|
||||
}
|
||||
else:
|
||||
if 'postgresql' in db_backend:
|
||||
tls_config = {
|
||||
'sslmode': config.get('database', 'sslmode'),
|
||||
'sslrootcert': config.get('database', 'sslrootcert'),
|
||||
'sslcert': config.get('database', 'sslcert'),
|
||||
'sslkey': config.get('database', 'sslkey'),
|
||||
}
|
||||
|
||||
db_options.update(tls_config)
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.' + db_backend,
|
||||
@@ -228,6 +251,9 @@ if HAS_MEMCACHED:
|
||||
|
||||
HAS_REDIS = config.has_option('redis', 'location')
|
||||
USE_REDIS_SENTINEL = config.has_option('redis', 'sentinels')
|
||||
redis_ssl_cert_reqs = config.get('redis', 'ssl_cert_reqs', fallback='none')
|
||||
USE_REDIS_TLS = redis_ssl_cert_reqs != 'none'
|
||||
USE_REDIS_MTLS = USE_REDIS_TLS and config.has_option('redis', 'ssl_certfile')
|
||||
HAS_REDIS_PASSWORD = config.has_option('redis', 'password')
|
||||
if HAS_REDIS:
|
||||
OPTIONS = {
|
||||
@@ -243,6 +269,29 @@ if HAS_REDIS:
|
||||
OPTIONS["SENTINEL_KWARGS"] = {"socket_timeout": 1}
|
||||
OPTIONS["SENTINELS"] = [tuple(sentinel) for sentinel in loads(config.get('redis', 'sentinels'))]
|
||||
|
||||
if USE_REDIS_TLS or USE_REDIS_MTLS:
|
||||
tls_config = {}
|
||||
if not USE_REDIS_MTLS:
|
||||
tls_config = {
|
||||
'ssl_cert_reqs': config.get('redis', 'ssl_cert_reqs'),
|
||||
'ssl_ca_certs': config.get('redis', 'ssl_ca_certs'),
|
||||
}
|
||||
else:
|
||||
tls_config = {
|
||||
'ssl_cert_reqs': config.get('redis', 'ssl_cert_reqs'),
|
||||
'ssl_ca_certs': config.get('redis', 'ssl_ca_certs'),
|
||||
'ssl_keyfile': config.get('redis', 'ssl_keyfile'),
|
||||
'ssl_certfile': config.get('redis', 'ssl_certfile'),
|
||||
}
|
||||
|
||||
if USE_REDIS_SENTINEL is False:
|
||||
# The CONNECTION_POOL_KWARGS option is necessary for self-signed certs. For further details, please check
|
||||
# https://github.com/jazzband/django-redis/issues/554#issuecomment-949498321
|
||||
OPTIONS["CONNECTION_POOL_KWARGS"] = tls_config
|
||||
OPTIONS["REDIS_CLIENT_KWARGS"].update(tls_config)
|
||||
else:
|
||||
OPTIONS["SENTINEL_KWARGS"].update(tls_config)
|
||||
|
||||
if HAS_REDIS_PASSWORD:
|
||||
OPTIONS["PASSWORD"] = config.get('redis', 'password')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user