Как включить SSL для подключений к PostgreSQL

По умолчанию все подключения к 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. Если у вас есть вопросы, задавайте их в комментариях ниже.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *