По умолчанию все подключения к PostgreSQL являются незащищенными, что может привести к проблемам безопасности при работе в производственных средах с высокой нагрузкой. Шифрование SSL гарантирует, что передаваемые данные не будут перехвачены третьими лицами в процессе соединения.
В этом руководстве вы узнаете, как включить SSL/TLS для подключений к PostgreSQL.
Необходимые условия
- Сервер под управлением Linux. В нашем руководстве мы используем сервер Ubuntu 22.04.
- Пользователь с правами sudo, не являющийся root.
- Полное доменное имя (FQDN), например
postgresql.example.com. - Убедитесь, что все обновлено.
$ sudo apt update $ sudo apt upgrade
- Несколько пакетов, необходимых вашей системе.
$ sudo apt install curl nano software-properties-common apt-transport-https ca-certificates lsb-release ubuntu-keyring -y
Некоторые из этих пакетов, возможно, уже установлены в вашей системе.
Шаг 1 — Настройка брандмауэра
Перед установкой каких-либо пакетов первым делом необходимо настроить брандмауэр, чтобы открыть порты для HTTP, HTTPS и PostgreSQL.
Проверьте состояние брандмауэра.
$ sudo ufw status
Вы должны увидеть что-то подобное.
Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6)
Откройте порты HTTP, HTTPS и PostgreSQL в брандмауэре.
$ sudo ufw allow 5432 $ sudo ufw allow http $ sudo ufw allow https
Проверьте состояние еще раз, чтобы убедиться.
$ sudo ufw status Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 80/tcp ALLOW Anywhere 443 ALLOW Anywhere 5432 ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 80/tcp (v6) ALLOW Anywhere (v6) 443 (v6) ALLOW Anywhere (v6) 5432 (v6) ALLOW Anywhere (v6)
Шаг 2 — Установка PostgreSQL 14
Ubuntu 22.04 по умолчанию поставляется с PostgreSQL 14. Для установки выполните следующую команду.
$ sudo apt install postgresql postgresql-contrib
Пакет postgresql-contrib содержит несколько дополнительных утилит.
Вы также можете использовать официальный репозиторий APT PostgreSQL для установки. Выполните следующую команду, чтобы добавить ключ GPG PostgreSQL.
$ curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /usr/share/keyrings/postgresql-key.gpg >/dev/null
Добавьте репозиторий APT в список источников.
$ sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/postgresql-key.gpg arch=amd64] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
Обновите системный репозиторий.
$ sudo apt update
Теперь вы можете установить PostgreSQL с помощью команды, указанной выше.
Проверьте состояние службы PostgreSQL.
$ sudo systemctl status postgresql
? postgresql.service - PostgreSQL RDBMS
Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor preset: enabled)
Active: active (exited) since Mon 2022-12-12 00:01:06 UTC; 19s ago
Main PID: 3497 (code=exited, status=0/SUCCESS)
CPU: 1ms
Dec 12 00:01:06 postgresql systemd[1]: Starting PostgreSQL RDBMS...
Dec 12 00:01:06 postgresql systemd[1]: Finished PostgreSQL RDBMS.
Вы можете видеть, что служба включена и работает по умолчанию.
Установите пароль для postgres учетной записи.
$ sudo -i -u postgres psql -c "ALTER USER postgres PASSWORD '';"
Шаг 3 — Установка SSL
Чтобы установить SSL-сертификат с помощью Let’s Encrypt, нам нужно загрузить инструмент Certbot. Для этого мы будем использовать установщик пакетов Snapd. В Ubuntu 22.04 Snap уже предустановлен.
Убедитесь, что ваша версия Snapd обновлена.
$ sudo snap install core $ sudo snap refresh core
Установите Certbot.
$ sudo snap install --classic certbot
Используйте следующую команду, чтобы убедиться, что команда Certbot запускается, создав символическую ссылку на /usr/bin каталог.
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
Сгенерируйте SSL-сертификат.
$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d postgresql.example.com
Вышеуказанная команда загрузит сертификат в /etc/letsencrypt/live/postgresql.example.com каталог на вашем сервере.
Сгенерируйте группы Диффи-Хеллмана .
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
Шаг 4 — Настройте обновление Certbot для PostgreSQL
PostgreSQL не имеет прав доступа к сертификатам из папки Let’s Encrypt, поэтому мы не можем указать ему использовать сертификаты из этой папки напрямую. Альтернативный вариант — скопировать сертификаты в каталог PostgreSQL, но это работает только временно, так как срок их действия истечет, и вам придется скопировать их снова вручную.
Лучший способ — использовать хук обновления, который будет запускаться автоматически при каждом обновлении и выполнять операции копирования.
Найдите каталог данных PostgreSQL.
$ sudo -i -u postgres psql -U postgres -c 'SHOW data_directory'
Создайте файл хука обновления и откройте его для редактирования.
$ sudo nano /etc/letsencrypt/renewal-hooks/deploy/postgresql.sh
Вставьте в него следующий код.
#!/bin/bash umask 0177 DOMAIN=postgresql.example.com DATA_DIR=/var/lib/postgresql/15/main cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem $DATA_DIR/server.crt cp /etc/letsencrypt/live/$DOMAIN/privkey.pem $DATA_DIR/server.key chown postgres:postgres $DATA_DIR/server.crt $DATA_DIR/server.key # only for SELinux - CentOS, Red Hat # chcon -t postgresql_db_t $DATA_DIR/server.crt $DATA_DIR/server.key
Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.
Сделайте файл исполняемым.
$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/postgresql.sh
Шаг 5 — Настройте PostgreSQL
Найдите путь к файлу конфигурации PostgreSQL.
$ sudo -i -u postgres psql -U postgres -c 'SHOW config_file'
Откройте файл для редактирования.
$ sudo nano /etc/postgresql/15/main/postgresql.conf
Найдите раздел Настройки подключения и удалите комментарий из переменной listen_address и измените его значение на *. Убедитесь, что он выглядит следующим образом.
listen_address = '*' # what IP address(es) to listen on;
Найдите раздел SSL и отредактируйте файл, чтобы он соответствовал следующим значениям.
ssl = on ssl_cert_file = 'server.crt' ssl_key_file = 'server.key' ssl_prefer_server_ciphers = on ssl_dh_params_file = '/etc/ssl/certs/dhparam.pem'
Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.
Шаг 6 — Настройка подключения к PostgreSQL
Откройте файл /etc/postgresql/15/main/pg_hba.conf для редактирования.
$ sudo nano /etc/postgresql/15/main/pg_hba.conf
Добавьте следующую строку, чтобы включить SSL для PostgreSQL.
hostssl all all 0.0.0.0/0 scram-sha-256
Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.
Шаг 7 — Обновление сертификата
Выполните следующую команду для принудительного обновления. Это запустит скрипт развертывания, который скопирует сертификаты в нужное место для использования PostgreSQL.
$ sudo certbot renew --force-renewal
Убедитесь, что сертификаты скопированы в каталог данных PostgreSQL.
$ sudo ls /var/lib/postgresql/15/main/
Вы увидите следующий вывод, в котором будут отображены сертификаты.
base pg_dynshmem pg_notify pg_snapshots pg_subtrans PG_VERSION postgresql.auto.conf server.crt global pg_logical pg_replslot pg_stat pg_tblspc pg_wal postmaster.opts server.key pg_commit_ts pg_multixact pg_serial pg_stat_tmp pg_twophase pg_xact postmaster.pid
Перезапустите PostgreSQL, чтобы применить изменения.
$ sudo systemctl restart postgresql
Шаг 8 — Проверка подключения
Подключитесь к базе данных с другого компьютера, на котором установлен клиент PostgreSQL.
$ psql -d "dbname=postgres sslmode=require" -h postgresql.example.com -U postgres
Вы должны увидеть следующий приглашение PostgreSQL. Мы используем клиент с PostgreSQL 14, поэтому вы увидите предупреждение о несовместимых версиях.
Password for user postgres:
psql (14.5 (Ubuntu 14.5-0ubuntu0.22.04.1), server 15.1 (Ubuntu 15.1-1.pgdg22.04+1))
WARNING: psql major version 14, server major version 15.
Some psql features might not work.
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
postgres=#
Это подтверждает успешное SSL-соединение.
Выйдите из оболочки.
postgres=# \q
Если ваше приложение использует строку подключения, используйте ее в следующем формате для SSL-соединения.
postgres://user:[email protected]:5432/database_name?sslmode=require
Вы можете изменить режим SSL на verify-full или verify-ca , если у вас есть корневой сертификат Let’s Encrypt, доступный в /var/lib/postgresql/.postgresql на стороне клиента.
Создайте каталог /var/lib/postgresql/.postgresql .
$ sudo mkdir -p /var/lib/postgresql/.postgresql
Корневой сертификат Let’s Encrypt — это ISRG Root X1, который находится на сервере в /usr/share/ca-certificates/mozilla/ISRG_Root_X1.crt .
Скопируйте корневой сертификат в /var/lib/postgresql/.postgresql каталог.
$ sudo cp /usr/share/ca-certificates/mozilla/ISRG_Root_X1.crt /var/lib/postgresql/.postgresql/root.crt
Проверьте соединение, используя verify-full или verify-ca режим, и вы должны увидеть успешное соединение.
Шаг 9 — Проверка клиентов
Войдите в оболочку PostgreSQL на сервере.
$ sudo -i -u postgres psql
Выполните следующую SQL-команду, чтобы проверить подключенные клиенты.
SELECT ssl.pid, usename, datname, ssl, ssl.version, ssl.cipher, ssl.bits, client_addr FROM pg_catalog.pg_stat_ssl ssl, pg_catalog.pg_stat_activity activity WHERE ssl.pid = activity.pid;
Вы должны увидеть подобный вывод.
pid | usename | datname | ssl | version | cipher | bits | client_addr ------+----------+----------+-----+---------+------------------------+------+---------------- 5126 | postgres | postgres | t | TLSv1.3 | TLS_AES_256_GCM_SHA384 | 256 | 122.161.84.220 5154 | postgres | postgres | f | | | | (2 rows)
Это подтверждает подключение клиентов со стороны сервера.
Заключение
На этом завершается руководство по включению SSL для подключений PostgreSQL. Если у вас есть вопросы, задавайте их в комментариях ниже.