🔒 Безопасность PostgreSQL 16: гайд по настройке защиты доступа
Открытый порт 5432, стандартный логин postgres со слабым паролем, отсутствие SSL и логов — классический сценарий компрометации БД. Настройка комплексной защиты PostgreSQL 16 включает 3 базовых слоя: контроль доступа, шифрование и аудит.
🛡 1. Контроль доступа (pg_hba.conf)
Файл pg_hba.conf определяет правила аутентификации. Правила проверяются сверху вниз до первого совпадения.
❌ Опасная конфигурация:
host all all 0.0.0.0/0 trust
✅ Правильная конфигурация:
# TYPE DATABASE USER ADDRESS METHOD
# Приложение ходит локально под системным пользователем www-data,
# а в базу — как app_user. Более специфичное правило идёт ПЕРВЫМ.
local all app_user scram-sha-256
# Остальные локальные подключения через Unix-сокет — peer (сверка с пользователем ОС)
local all all peer
# Сетевые подключения: только по SSL и только из доверенной подсети
hostssl all all 192.168.1.0/24 scram-sha-256
# Всё остальное — явный отказ. Обе версии протокола.
host all all 0.0.0.0/0 reject
host all all ::0/0 reject
Ключевые правила:
• Используйте hostssl (требует шифрования) и scram-sha-256 (безопасный алгоритм). Методы md5 и trust использовать нельзя.
• Порядок строк критичен: специфичные правила ставятся выше общих.
• Для peer имя ОС-пользователя должно совпадать с ролью в БД (для связки www-data ➔ app_user нужна отдельная строка).
Привязываем СУБД к внутреннему IP в postgresql.conf:
listen_addresses = '192.168.1.100'
password_encryption = scram-sha-256
scram_iterations = 4096 # значение по умолчанию, можно поднять
Изменения pg_hba.conf применяются через SELECT pg_reload_conf();, а listen_addresses требует перезапуска СУБД. Проверка ошибок в конфиге:
SELECT rule_number, type, database, user_name, address, auth_method, error
FROM pg_hba_file_rules;
*(В PG 16 правила можно раскладывать по отдельным файлам с помощью `include_dir`).*
🔐 2. Шифрование трафика (SSL/TLS)
Передача данных в открытом виде уязвима к перехвату. Включаем SSL на сервере в postgresql.conf:
ssl = on
ssl_cert_file = '/etc/postgresql/ssl/server.crt'
ssl_key_file = '/etc/postgresql/ssl/server.key'
ssl_ca_file = '/etc/postgresql/ssl/root.crt' # нужен для клиентских сертификатов
ssl_min_protocol_version = 'TLSv1.2'
ssl_prefer_server_ciphers = on
Права на ключ (при иных правах PostgreSQL не запустится):
chmod 600 /etc/postgresql/ssl/server.key
chown postgres:postgres /etc/postgresql/ssl/server.key
Защита клиентом от MITM-атак:
По умолчанию клиент (`sslmode=prefer`) не проверяет подлинность сервера. Правильное подключение:
psql "host=db.internal dbname=app user=app_user \
sslmode=verify-full \
sslrootcert=/etc/ssl/certs/internal-ca.crt \
require_auth=scram-sha-256"
• sslmode=verify-full проверяет подпись CA и имя хоста.
• require_auth=scram-sha-256 (PG 16) запрещает серверу понижать метод аутентификации.
📊 3. Аудит и защита от брутфорса (Fail2ban)
Настраиваем логирование в postgresql.conf:
logging_collector = on
log_directory = '/var/log/postgresql'
log_filename = 'postgresql-%Y-%m-%d.log'
log_rotation_age = 1d
log_rotation_size = 100MB
# ОБЯЗАТЕЛЬНО: %r выводит IP-адрес и порт клиента.
# Без этого escape в логе не будет адреса, и Fail2ban не сможет никого забанить.
log_line_prefix = '%m [%p] %q%u@%d %r '
log_connections = on
log_disconnections = on
log_statement = 'ddl'
*Важно: %r обязателен, так как он добавляет IP-адрес клиента в лог.*