Налаштування SSL-шифрування підключень до бази даних
SSL/TLS шифрування з'єднань з БД захищає дані при передачі між додатком та сервером бази даних. Обов'язково для compliance (PCI DSS, GDPR, SOC 2) та необхідно, коли додаток та БД знаходяться в різних мережах.
PostgreSQL SSL
Генерація самопідписаного сертифіката
# Для production використовуйте Let's Encrypt або внутрішній CA
openssl req -new -x509 -days 365 -nodes \
-out /etc/ssl/certs/postgresql.crt \
-keyout /etc/ssl/private/postgresql.key \
-subj "/CN=db.company.internal"
# Дозволи
chmod 600 /etc/ssl/private/postgresql.key
chown postgres:postgres /etc/ssl/certs/postgresql.crt /etc/ssl/private/postgresql.key
Конфігурація сервера
# postgresql.conf
ssl = on
ssl_cert_file = '/etc/ssl/certs/postgresql.crt'
ssl_key_file = '/etc/ssl/private/postgresql.key'
ssl_ca_file = '/etc/ssl/certs/ca.crt' # для mutual TLS
ssl_min_protocol_version = 'TLSv1.2'
ssl_ciphers = 'HIGH:!aNULL:!MD5'
Примусове SSL у pg_hba.conf:
# Тільки SSL підключення з визначеної підмережі
hostssl all all 10.0.0.0/8 scram-sha-256
# Заборона non-SSL
host all all 10.0.0.0/8 reject
Перевірка:
SELECT ssl, client_addr, version, cipher FROM pg_stat_ssl
JOIN pg_stat_activity USING (pid)
WHERE datname = current_database();
Рядки підключення з SSL
# psql
psql "host=db.company.internal sslmode=require sslcert=/etc/ssl/app.crt sslkey=/etc/ssl/app.key"
# DSN у додатку
DATABASE_URL=postgresql://user:[email protected]:5432/myapp?sslmode=require
Параметри sslmode:
-
disable— без SSL -
require— SSL обов'язковий, сертифікат не перевіряється -
verify-ca— SSL + перевірка CA -
verify-full— SSL + перевірка CA + hostname
MySQL SSL
# /etc/mysql/mysql.conf.d/mysqld.cnf
ssl-ca=/etc/mysql/ssl/ca-cert.pem
ssl-cert=/etc/mysql/ssl/server-cert.pem
ssl-key=/etc/mysql/ssl/server-key.pem
require_secure_transport=ON # примусовий SSL для всіх
-- Вимагати SSL для конкретного користувача
ALTER USER 'app_user'@'%' REQUIRE SSL;
-- Або з конкретним сертифікатом
ALTER USER 'app_user'@'%' REQUIRE X509;
Рядок підключення:
mysql://user:pass@host/db?ssl-ca=/path/ca.pem&ssl-cert=/path/cert.pem&ssl-key=/path/key.pem
Клієнтські бібліотеки
Node.js (pg)
const { Pool } = require('pg')
const pool = new Pool({
host: 'db.company.internal',
ssl: {
rejectUnauthorized: true,
ca: fs.readFileSync('/etc/ssl/certs/ca.crt'),
cert: fs.readFileSync('/etc/ssl/certs/client.crt'),
key: fs.readFileSync('/etc/ssl/private/client.key'),
}
})
Python (psycopg2)
import psycopg2
conn = psycopg2.connect(
host='db.company.internal',
sslmode='verify-full',
sslcert='/etc/ssl/app.crt',
sslkey='/etc/ssl/app.key',
sslrootcert='/etc/ssl/ca.crt'
)
Ротація сертифікатів без простою
# 1. Додати новий CA до старого (обидва активні)
cat old-ca.crt new-ca.crt > combined-ca.crt
# 2. Оновити ssl_ca_file у postgresql.conf, перечитати конфіг
pg_ctl reload
# 3. Видати нові клієнтські сертифікати
# 4. Оновити клієнтів
# 5. Видалити старий CA з combined-ca.crt
Моніторинг терміну дії сертифікатів
# Перевірити дату закінчення
openssl x509 -in /etc/ssl/certs/postgresql.crt -noout -dates
# Автоматична перевірка (в cron)
EXPIRY=$(openssl x509 -in /etc/ssl/certs/postgresql.crt -noout -checkend 2592000)
if echo "$EXPIRY" | grep -q "will expire"; then
curl -X POST "$SLACK_WEBHOOK" -d '{"text": "DB SSL cert expires in < 30 days"}'
fi
Час виконання
Налаштування SSL для PostgreSQL або MySQL з перевіркою сертифіката — 0,5–1 робочий день.







