Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TLS/mTLS options in database and cache settings for PostgreSQL and Redis #46

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 70 additions & 8 deletions src/pretix/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,30 @@
db_options['charset'] = 'utf8mb4'
JSON_FIELD_AVAILABLE = db_backend in ('mysql', 'postgresql')

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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

db_backend is a string, like 'postgresql' or 'mysql'.
The way you are checking if 'postgresql' in db_backend is weird.
Please do just normal, common way with ==.

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,
Expand Down Expand Up @@ -208,23 +232,61 @@
}

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 = {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"REDIS_CLIENT_KWARGS": {"health_check_interval": 30}
}
if USE_REDIS_SENTINEL:
DJANGO_REDIS_CONNECTION_FACTORY = "django_redis.pool.SentinelConnectionFactory"
OPTIONS["CLIENT_CLASS"] = "django_redis.client.SentinelClient"
OPTIONS["CONNECTION_POOL_CLASS"] = "redis.sentinel.SentinelConnectionPool"
# See https://github.com/jazzband/django-redis/issues/540
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')

CACHES['redis'] = {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": config.get('redis', 'location'),
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"REDIS_CLIENT_KWARGS": {"health_check_interval": 30}
}
"OPTIONS": OPTIONS
}
CACHES['redis_sessions'] = {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": config.get('redis', 'location'),
"TIMEOUT": 3600 * 24 * 30,
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"REDIS_CLIENT_KWARGS": {"health_check_interval": 30}
}
"OPTIONS": OPTIONS
}
if not HAS_MEMCACHED:
CACHES['default'] = CACHES['redis']
Expand Down