diff --git a/django-postgres/django_postgres/django_postgres/settings.py b/django-postgres/django_postgres/django_postgres/settings.py index 2791ed4..1e76767 100644 --- a/django-postgres/django_postgres/django_postgres/settings.py +++ b/django-postgres/django_postgres/django_postgres/settings.py @@ -11,6 +11,7 @@ """ from pathlib import Path +import os # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -27,7 +28,6 @@ ALLOWED_HOSTS = ["*"] - # Application definition INSTALLED_APPS = [ @@ -71,6 +71,31 @@ WSGI_APPLICATION = 'django_postgres.wsgi.application' +def _db_options_from_env(): + """ + Build psycopg2 OPTIONS dict, adding SSL keys only if requested. + """ + opts = {} + sslmode = os.getenv("DB_SSLMODE", "disable").strip() + print("DB_SSLMODE is:", sslmode) + if sslmode and sslmode.lower() != "disable": + # Common values: require | verify-ca | verify-full + opts["sslmode"] = sslmode + # Optional files if you want verification / mTLS + rootcert = os.getenv("DB_SSLROOTCERT", "").strip() + sslcert = os.getenv("DB_SSLCERT", "").strip() + sslkey = os.getenv("DB_SSLKEY", "").strip() + sslcrl = os.getenv("DB_SSLCRL", "").strip() + if rootcert: + opts["sslrootcert"] = rootcert + if sslcert: + opts["sslcert"] = sslcert + if sslkey: + opts["sslkey"] = sslkey + if sslcrl: + opts["sslcrl"] = sslcrl + return opts + # Database # https://docs.djangoproject.com/en/4.2/ref/settings/#databases @@ -83,10 +108,10 @@ 'PASSWORD': 'postgres', 'HOST': '0.0.0.0', 'PORT': '5432', + 'OPTIONS': _db_options_from_env(), } } - # Password validation # https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators diff --git a/django-postgres/django_postgres/docker-compose.yml b/django-postgres/django_postgres/docker-compose.yml index e5a43b7..de47937 100644 --- a/django-postgres/django_postgres/docker-compose.yml +++ b/django-postgres/django_postgres/docker-compose.yml @@ -12,3 +12,17 @@ services: volumes: - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql + postgres_ssl: + image: postgres:latest + environment: + POSTGRES_DB: usersdb + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - "5432:5432" + volumes: + - pgdata_ssl:/var/lib/postgresql + - ./sql/enable-ssl.sh:/docker-entrypoint-initdb.d/enable-ssl.sh:ro + +volumes: + pgdata_ssl: diff --git a/django-postgres/django_postgres/sql/enable-ssl.sh b/django-postgres/django_postgres/sql/enable-ssl.sh new file mode 100755 index 0000000..2af15e9 --- /dev/null +++ b/django-postgres/django_postgres/sql/enable-ssl.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -e + +# Generate a self-signed server cert the first time the cluster initializes +if [[ ! -f "$PGDATA/server.crt" ]]; then + openssl req -new -x509 -days 365 -nodes -text \ + -subj "/CN=postgres_ssl" \ + -keyout "$PGDATA/server.key" \ + -out "$PGDATA/server.crt" + chmod 600 "$PGDATA/server.key" "$PGDATA/server.crt" + chown postgres:postgres "$PGDATA/server.key" "$PGDATA/server.crt" + echo "ssl = on" >> "$PGDATA/postgresql.conf" + echo "ssl_cert_file = 'server.crt'" >> "$PGDATA/postgresql.conf" + echo "ssl_key_file = 'server.key'" >> "$PGDATA/postgresql.conf" +fi