Перейти к основному содержимому

Задание 3: Сертификаты TLS

В этом разделе будет подробно описан процесс развертывания инфраструктуры открытых ключей: установка ПО openssl, подготовка среды, генерация сертификата удостоверяющего центра, а также создание и установка сертификатов для серверов и клиентов.

Внимание!

В примерах этого задания показаны приглашения командной строки, в которых присутствуют имена серверов. Обращайте внимание, на сервер, где должна быть выполнена команда.

Циклы for, активно используемые в этом задании позволяют выполнять команды, подставляя в них заданный итератор. Обычное использование этих циклов здесь состоит в необходимости выполнять одинаковые команды на нескольких узлах кластера.

Команды с циклами for запускаются один раз и обычно на сервере srv1, но они повторяют заданные им команды на нескольких серверах.

Установка ПО openssl​

Установим ПО для генерации и управления сертификатами SSL:

[student@srv1 ~]$ sudo dnf install -y openssl
Updating Subscription Management repositories.
redos8.0-for-x86_64-powertools-rpms 7.7 kB/s | 2.6 kB 00:00
redos8.0-for-x86_64-baseos-rpms 6.5 kB/s | 2.3 kB 00:00
redos8.0-for-x86_64-baseos-debug-rpms 6.5 kB/s | 2.0 kB 00:00
redos8.0-for-x86_64-appstream-rpms 8.5 kB/s | 2.6 kB 00:00
redos8.0-for-x86_64-appstream-debug-rpms 6.1 kB/s | 2.0 kB 00:00
Package openssl-1:3.5.5-2.sl9_8^1.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!

Установка ПО уже была произведена ранее.

Проверим версии ПО openssl, установленные на узлах стенда:

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n${comp}"; ssh $comp rpm -qa 'openssl*'; done
srv1
openssl-gost-engine-3.0.1-8.redos8.0.x86_64
openssl-pkcs11-0.4.12-1.redos8.0.x86_64
openssl-libs-3.1.5-7.redos8.0.x86_64
openssl-3.1.5-7.redos8.0.x86_64

srv2
openssl-gost-engine-3.0.1-8.redos8.0.x86_64
openssl-pkcs11-0.4.12-1.redos8.0.x86_64
openssl-libs-3.1.5-7.redos8.0.x86_64
openssl-3.1.5-7.redos8.0.x86_64

srv3
openssl-gost-engine-3.0.1-8.redos8.0.x86_64
openssl-pkcs11-0.4.12-1.redos8.0.x86_64
openssl-libs-3.1.5-7.redos8.0.x86_64
openssl-3.1.5-7.redos8.0.x86_64

Серверы были клонированы, поэтому ПО пока на них одинаковое. Но, при добавлении новых узлов в кластер ПО, на новых узлах может отличаться.

Подготовка​

Создание временных каталогов для сертификатов SSL​

На всех трех узлах стенда в домашнем каталоге пользователя student создадим одинаковые каталоги для временного хранения сертификатов перед их установкой:

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n${comp}"; ssh $comp mkdir -p ~/cert/{ca_ssl,cnf,crt}; ls -l ~/cert; done
srv1
итого 12
drwxr-xr-x 2 student student 4096 апр 14 13:57 ca_ssl
drwxr-xr-x 2 student student 4096 апр 14 13:57 cnf
drwxr-xr-x 2 student student 4096 апр 14 13:57 crt

srv2
итого 12
drwxr-xr-x 2 student student 4096 апр 14 13:57 ca_ssl
drwxr-xr-x 2 student student 4096 апр 14 13:57 cnf
drwxr-xr-x 2 student student 4096 апр 14 13:57 crt

srv3
итого 12
drwxr-xr-x 2 student student 4096 апр 14 13:57 ca_ssl
drwxr-xr-x 2 student student 4096 апр 14 13:57 cnf
drwxr-xr-x 2 student student 4096 апр 14 13:57 crt

Генерация сертификата удостоверяющего центра​

Сертификат удостоверяющего центра (далее УЦ — Certification Authority CA) — единый для всех узлов кластера. Этим сертификатом подписываются сертификаты узлов кластера и клиентов.

Так как сертификат УЦ — единственный, то можно создать его на srv1, а затем скопировать его на другие узлы.

Для временного размещения сертификата УЦ предусмотрен каталог ~/cert/ca_ssl/:

[student@srv1 ~]$ cd ~/cert/ca_ssl/

Показанный далее способ генерации вовсе не единственный, но он обеспечивает минимальную интерактивность команд openssl.

Сначала сгенерируем приватный ключ УЦ, назовем его root.key:

[student@srv1 ca_ssl]$ openssl genpkey -quiet -algorithm RSA -out root.key
[student@srv1 ca_ssl]$ ls -l root.key
-rw------- 1 student student 1708 апр 14 14:01 root.key

Теперь можно сгенерировать самоподписанный сертификат Удостоверяющего Центра (Certification Authority):

[student@srv1 ca_ssl]$ openssl req -x509 -new -extensions v3_ca -days 3650 -key root.key -out root.crt -subj "/C=RU/ST=Moscow/L=Moscow/O=Sbt/CN=CA_DBP2"
[student@srv1 ca_ssl]$ ls -ltrh
итого 8,0K
-rw------- 1 student student 1,7K апр 14 14:01 root.key
-rw-r--r-- 1 student student 1,3K апр 14 14:02 root.crt

В предыдущей команде был использован режим Request (man openssl-req) для получения сертификата X509 в формате PKCS#12.

Сертификат будет валиден в течении почти десяти лет. В сертификате указан субъект:

[student@srv1 ca_ssl]$ openssl x509 -text -noout -in root.crt
Вывод команды:

Certificate:
Data:
Version: 3 (0x2)
Serial Number:
1a:6b:c8:1b:aa:3a:6e:c6:01:f2:dd:43:3e:62:bc:5d:9a:6c:26:c8
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=RU, ST=Moscow, L=Moscow, O=Sbt, CN=CA_DBP2
Validity
Not Before: Apr 14 11:02:11 2026 GMT
Not After : Apr 11 11:02:11 2036 GMT
Subject: C=RU, ST=Moscow, L=Moscow, O=Sbt, CN=CA_DBP2
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:e2:28:21:61:f9:4d:31:8b:e4:0e:a9:f6:d2:3e:
e5:69:db:a1:db:40:48:51:23:1c:e2:50:d7:fa:52:
b7:5c:7f:65:2a:ec:9f:84:01:92:d0:e5:13:3a:45:
ee:9f:f3:19:7f:c9:2e:53:be:23:76:4f:28:8c:c0:
10:59:ba:61:b2:11:ad:d3:a6:ff:86:33:84:2e:93:
3f:75:1a:e8:51:aa:98:06:8a:bc:a1:ac:16:5d:b5:
f4:2c:24:47:42:8f:3a:66:fd:6f:af:f2:b5:8e:f6:
5a:84:1d:ce:c2:86:1d:bf:d6:f3:9c:d5:76:f0:ef:
17:b4:c1:33:a3:fc:2e:d6:f0:cd:ea:f5:62:0e:39:
56:d1:4a:d7:d7:be:41:ed:3d:83:18:b5:3e:be:12:
9d:0f:dd:de:09:e5:f8:54:04:71:7b:c3:b9:15:ef:
f4:f0:02:a0:db:40:3f:c2:49:44:9b:c7:29:9a:ba:
f0:0e:d6:e1:9b:3c:53:99:69:7b:23:95:59:2a:ae:
a6:be:68:c2:50:01:29:26:71:18:f8:4e:92:f4:c0:
30:0f:55:a1:9a:40:f9:3e:c4:85:e5:83:4b:6d:1f:
91:15:fe:ee:aa:9a:73:f8:f8:05:b2:ff:3f:1b:be:
ee:a5:55:81:93:f1:a5:48:6d:0c:ca:be:fb:5f:d8:
e6:53
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
CE:F2:15:FF:E0:D1:B7:E6:D4:0C:04:5E:4A:EA:DB:46:C5:2B:6B:27
X509v3 Authority Key Identifier:
CE:F2:15:FF:E0:D1:B7:E6:D4:0C:04:5E:4A:EA:DB:46:C5:2B:6B:27
X509v3 Basic Constraints: critical
CA:TRUE
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
39:c2:4b:d1:88:b2:1e:b0:63:0d:5c:36:78:de:09:18:cb:e6:
ce:bb:3b:cb:c5:fd:c2:41:0a:d1:5f:83:d3:be:3a:52:e0:da:
e7:41:bb:93:e9:1d:61:a9:33:17:90:0e:09:4b:03:0f:1c:ce:
f5:2e:b9:77:d6:37:1d:d2:2a:c0:b9:f7:23:73:07:c4:58:e6:
f8:cd:99:8f:1b:df:82:78:60:2f:d6:dd:ce:8b:e2:23:c8:2e:
55:87:e5:1d:1e:46:1b:15:82:b3:8f:73:7a:09:54:93:b4:d8:
10:60:53:3c:52:e6:4e:11:6b:e0:38:3e:be:b8:ba:37:b8:ec:
c8:2d:0b:7b:ee:5c:6f:80:5a:61:54:17:df:21:27:6e:6b:bf:
b7:5c:cd:cc:af:46:da:e2:a2:6e:13:db:1e:b0:d9:00:d5:38:
a5:37:c8:d0:74:42:9c:d9:f7:26:a0:45:a8:c9:80:0e:cc:59:
84:bd:94:2d:e4:df:5d:60:c4:66:c2:5f:31:26:33:bd:c2:09:
2a:98:61:de:57:94:7c:1c:af:1d:4e:a5:54:94:a7:8b:0c:e8:
58:6f:ae:0e:e8:16:6e:94:ac:1d:00:fe:29:38:30:df:7c:b0:
74:65:44:17:38:ad:cc:ff:66:1b:8f:5b:13:7e:93:4f:b3:bf:
d7:d1:84:b1

Скопируем каталог ~/cert/ca_ssl со всем его содержимым на два других узла стенда:

[student@srv1 ca_ssl]$ cd ..
[student@srv1 cert]$ for comp in srv{2,3}; do echo $comp; scp -r ca_ssl/ $comp:`pwd`; done
srv2
root.key 100% 1708 3.8MB/s 00:00
root.crt 100% 1273 3.4MB/s 00:00
srv3
root.key 100% 1708 5.7MB/s 00:00
root.crt 100% 1273 3.8MB/s 00:00

Теперь сертификат УЦ должен быть на всех узлах стенда:

[student@srv1 cert]$ for comp in srv{2,3}; do echo -e "\n$comp"; ssh $comp ls -l `pwd`/ca_ssl; done
srv2
итого 8
-rw-r--r-- 1 student student 1273 апр 14 14:04 root.crt
-rw------- 1 student student 1708 апр 14 14:04 root.key

srv3
итого 8
-rw-r--r-- 1 student student 1273 апр 14 14:04 root.crt
-rw------- 1 student student 1708 апр 14 14:04 root.key

Генерация сертификатов серверов и клиентов​

Генерация сертификатов описана в документации.

Рекомендованные названия файлов сертификатов​

НазначениеСертификатКлюч
Сертификат сервераserver.crtserver.key
Сертификат пользователя postgrespostgres.crtpostgres.key
Сертификат пользователя Pangolin Poolerpgbouncer.crtpgbouncer.key
Сертификат пользователя подключения к etcdpatronietcd.crtpatronietcd.key
Сертификат пользователя Pangolin Managerpatroni.crtpatroni.key

Настройка сертификатов серверов​

Сертификат сервера индивидуален, как и для каждого клиента. Сертификаты сервера и клиентов можно сгенерировать как на одном узле с последующим перемещением их на узлы их предназначения, так и сразу на тех узлах, где они и должны быть.

Пойдем по второму пути — сгенерируем сертификаты на тех узлах, где они будут использоваться.

Перед созданием серверных сертификатов удобно заранее создать файлы настроек, в которых должны находиться детали, связанные с возможными путями использования сертификатов и прочее.

Создадим файлы конфигурации на всех узлах стенда. Сначала запишем фиксированную часть файла настроек, неизменную на всех узлах:

[student@srv1 cert]$ cd
[student@srv1 ~]$ vi ~/cert/cnf/server.cnf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ ssl_client ]
extendedKeyUsage = clientAuth, serverAuth
basicConstraints = CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName = @alt_names
[ v3_ca ]
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
authorityKeyIdentifier=keyid:always,issuer
[alt_names]

Проверим, что получилось в файле конфигурации:

[student@srv1 ~]$ less ~/cert/cnf/server.cnf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ ssl_client ]
extendedKeyUsage = clientAuth, serverAuth
basicConstraints = CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName = @alt_names
[ v3_ca ]
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
authorityKeyIdentifier=keyid:always,issuer
[alt_names]

Скопируем этот файл на оставшиеся узлы стенда:

[student@srv1 ~]$ for comp in srv{2,3}; do echo -e "\n$comp"; scp ~/cert/cnf/server.cnf $comp:~/cert/cnf ; done
srv2
server.cnf 100% 583 1.5MB/s 00:00

srv3
server.cnf 100% 583 701.6KB/s 00:00

Проверим содержимое файла на узлах srv2 и srv3:

[student@srv1 ~]$ for comp in srv{2,3}; do echo -e "\n$comp\n"; ssh $comp cat ~/cert/cnf/server.cnf ; done
Вывод команды:

srv2

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ ssl_client ]
extendedKeyUsage = clientAuth, serverAuth
basicConstraints = CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName = @alt_names
[ v3_ca ]
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
authorityKeyIdentifier=keyid:always,issuer
[alt_names]

srv3

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ ssl_client ]
extendedKeyUsage = clientAuth, serverAuth
basicConstraints = CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName = @alt_names
[ v3_ca ]
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
authorityKeyIdentifier=keyid:always,issuer
[alt_names]

В этих конфигурационных файлах пока не хватает двух строк, индивидуальных для каждого узла стенда. Эти строки должны быть записаны после [alt_names] и показывают имя узла и его IPv4 адрес.

Сначала добавим DNS имена узлов:

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n${comp}"; echo "DNS.1 = ${comp}" | ssh $comp tee -a ~/cert/cnf/server.cnf; done
srv1
DNS.1 = srv1

srv2
DNS.1 = srv2

srv3
DNS.1 = srv3

Затем добавим IPv4 адреса узлов:

[student@srv1 ~]$ for comp in {<IP-Address1>,<IP-Address2>,<IP-Address3>}; do echo -e "\n$comp"; echo "IP.1 = ${comp}" | ssh $comp tee -a ~/cert/cnf/server.cnf; done
Важно

Не ставьте пробел между запятыми. Если цикл кажется вам не удобным – внесите изменения вручную удобным текстовым редактором.

<IP-Address1>
IP.1 = <IP-Address1>

<IP-Address2>
IP.1 = <IP-Address2>

<IP-Address3>
IP.1 = <IP-Address3>

Завершив настройки, проверим, что получилось:

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp\n"; ssh $comp cat ~/cert/cnf/server.cnf ; done
Вывод команды:

srv1

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ ssl_client ]
extendedKeyUsage = clientAuth, serverAuth
basicConstraints = CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName = @alt_names
[ v3_ca ]
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
authorityKeyIdentifier=keyid:always,issuer
[alt_names]
DNS.1 = srv1
IP.1 = <IP-Address1>

srv2

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ ssl_client ]
extendedKeyUsage = clientAuth, serverAuth
basicConstraints = CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName = @alt_names
[ v3_ca ]
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
authorityKeyIdentifier=keyid:always,issuer
[alt_names]
DNS.1 = srv2
IP.1 = <IP-Address2>

srv3

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ ssl_client ]
extendedKeyUsage = clientAuth, serverAuth
basicConstraints = CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName = @alt_names
[ v3_ca ]
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
authorityKeyIdentifier=keyid:always,issuer
[alt_names]
DNS.1 = srv3
IP.1 = <IP-Address3>

Настройки сертификатов клиентов​

Генерировать сертификаты клиентов удобно при наличии конфигурационного файла. Сначала сделаем этот файл на srv1:

[student@srv1 ~]$ vi ~/cert/cnf/client.cnf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ ssl_client ]
extendedKeyUsage = clientAuth
basicConstraints = CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ v3_ca ]
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
authorityKeyIdentifier=keyid:always,issuer

Проверим получившееся содержимое файла настройки client.cnf:

[student@srv1 ~]$ less ~/cert/cnf/client.cnf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ ssl_client ]
extendedKeyUsage = clientAuth
basicConstraints = CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ v3_ca ]
basicConstraints = CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
authorityKeyIdentifier=keyid:always,issuer

Скопируем файл на другие узлы кластера:

[student@srv1 ~]$ for comp in srv{2,3}; do echo -e "\n$comp"; scp ~/cert/cnf/client.cnf ${comp}:~/cert/cnf/ ; done
srv2
client.cnf 100% 475 838.7KB/s 00:00

srv3
client.cnf 100% 475 1.1MB/s 00:00

Генерирование запросов на сертификат​

Следующий шаг — создание запросов на сертификат (CSR — Certification Signing Request). Запросы будут генерироваться сразу на всех узлах. Вид запросов одинаковый, но следует обращать внимание на имена файлов в командах.

  1. Сгенерируем запрос на сертификат сервера:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl req -new -nodes -text -out ~/cert/crt/server.csr -keyout ~/cert/crt/server.key -config ~/cert/cnf/server.cnf -subj "/CN=$comp"; done
    Вывод команды:

    srv1
    ......+.....+...+......+....+..+...+................+.....+......+.+..+.+......+++++++++++++++++++++++++++++++++++++++*.+++++++++++++++++++++++++++++++++++++++*....+......+.........+...+..+.+...+............+...+..+............+.+.....+.......+.....+...+.+.....+................+...+..+.........+..........+...++++++
    ...+++++++++++++++++++++++++++++++++++++++*..+...+............+.+.....+.......+.........+.....+.+++++++++++++++++++++++++++++++++++++++*...+......+..+.......+........+...+....+...+..............+.........+.+.....+......+...................+...+........+...+.......+..+.+..+....+.....+...+...+..........+...+......+..............+......+......+............+..........+...........+......+.+...........................+......+.....+.+...+..+...+.......+.....+.++++++
    -----

    srv2
    ..+............+............+....+.....+.+.....+.+............+...........+.+.....+.+..................+++++++++++++++++++++++++++++++++++++++*..........+.......+.....+......+.+...+..+....+..............+.+..+.......+++++++++++++++++++++++++++++++++++++++*.+..+...+......+.+........+....+..+....+...........+.+..+...+.........+.............+...+...+...........+...+.+...........+.+...+......+...+..+...............+....+.........+.....+..........+.....+......+.+.........+......+......+.........+.........+..+............+..................+...+.......+.......................+....+.....+.++++++
    -----

    srv3
    ......+....+...+.....+++++++++++++++++++++++++++++++++++++++*.+.+..+.......+.....+.+++++++++++++++++++++++++++++++++++++++*.....++++++
    .+...+...........+....+...+..+.+..+++++++++++++++++++++++++++++++++++++++*.+..+.............+...+++++++++++++++++++++++++++++++++++++++*...........+....+........+................+.....+.........+.........................+...+..+.+......+...+.....+...+...+.+...+...+............+...+..............+....+......+...+..+...............+....+..++++++
    -----

    Проверим запросы на сертификаты серверов:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl req -noout -text -in ~/cert/crt/server.csr -reqopt no_sigdump,no_validity,no_pubkey; done
    Вывод команды:

    srv1
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=srv1
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment
    X509v3 Subject Alternative Name:
    DNS:srv1, IP Address:<IP-Address1>

    srv2
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=srv2
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment
    X509v3 Subject Alternative Name:
    DNS:srv2, IP Address:<IP-Address2>

    srv3
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=srv3
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment
    X509v3 Subject Alternative Name:
    DNS:srv3, IP Address:<IP-Address3>
    Примечание

    Обратите внимание на вывод X509v3 Subject Alternative Name, в котором должно быть видно соответствие имен серверов и их IPv4 адресов.

  2. Запрос на сертификат клиента postgres:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl req -new -nodes -text -out ~/cert/crt/postgres.csr -keyout ~/cert/crt/postgres.key -config ~/cert/cnf/client.cnf -subj "/CN=postgres"; done
    Вывод команды:

    srv1
    ..+......+.+++++++++++++++++++++++++++++++++++++++*.+..............+............+...+......+.+++++++++++++++++++++++++++++++++++++++*......+.+.....+.............+..+....+.........+.....+.+..+.............+..............+.......+..................+..+...+...+..........+........+....+....................+.+.................+.........+...+.+...........+....+.........+..+...................+..+..........+...+......+...+..+...+..........+.....+...+...+.........+.............+........+.+...+........+...+.+...........+...............+.......+..+....+......+......+.........+.........+...........++++++
    -----

    srv2
    ......+.+......+..+.+...........+.+++++++++++++++++++++++++++++++++++++++*..+..................+.+..+....+......+...+..............+++++++++++++++++++++++++++++++++++++++*.....+.......+...+............+...............+........+................+........++++++
    ......+......+..+............+...+....+...+........+...+....+..+.........+.+++++++++++++++++++++++++++++++++++++++*...................+.+......+......+.........+......+..+.+.........+............+...+.................+......+....+++++++++
    -----

    srv3
    ..+...........+...+......+....+......+........+...+..........+..+...+....+...+...+++++++++++++++++++++++++++++++++++++++*.+.....+.+...+++++++++++++++++++++++++++++++++++++++*.......+..+.............+..+............+....+............+.....+....+........+.+..+...+.+...+........+.........+.+.........+........+++++
    -----
    Проверка:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl req -noout -text -in ~/cert/crt/postgres.csr -reqopt no_sigdump,no_validity,no_pubkey; done

    Вывод команды:

    srv1
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=postgres
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment

    srv2
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=postgres
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment

    srv3
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=postgres
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment

    Этой же командой, но подставив верное имя файла запроса на сертификат, можно проверить и другие запросы, которые будут созданы далее.

  3. Запрос на генерацию сертификата для пользователя patroni:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl req -new -nodes -text -out ~/cert/crt/patroni.csr -keyout ~/cert/crt/patroni.key -config ~/cert/cnf/client.cnf -subj "/CN=patroni"; done
    Вывод команды:

    srv1
    .+..................+.+..+.........+..........+...+.....+...+++++++++++++++++++++++++++++++++++++++*...+......+.......+...+.....+...+..........+..+....+........+.......+........+......+.+...+.....+.+++++++++++++++++++++++++++++++++++++++*..+...+.+......+........+...+..................+..........+.....+....+..+.+...........................+...+..+.+..+.........+.+...+.................+...............+.......+..+......+...+....+..+..........+...+..+..........+...+.....+.......+.........+...........+....+.........+...........+......+.+........+.......+............+......+......+........+.+.........+..+...+................+......+...+..+..........+...+..+.+.....+............+...++++++
    ...+.....+...+.+......+...+.....+...+.......+++++++++++++++++++++++++++++++++++++++*.+...........+++++++++++++++++++++++++++++++++++++++*..+.+...+..+................+.....+.......+..+...+.+...............+............+.....+.......+.....+.......+.....................+........+......+.............+......+......+.........+..+..................+.+.....+....+...........+.+........+.+...+.....+...+.........+....+.........+......+.........+.....++++++
    -----

    srv2
    ..........+..+..........+.....+..........+...+.....+....+++++++++++++++++++++++++++++++++++++++*...........+...+....+...+...+..+...+.......+........+.+.....+....+.........+...+..+..........+...........+......+.+............+........+...+.+...+........+...+.........+.+...........+.+.........+...+...........+............+...+......+++++++++++++++++++++++++++++++++++++++*.+.....+...+......+.+......+.....+.............+..+....+........+.+..............+...+.........+.+..+..................+...+.+.....+.+..+......+.......+...+.........+.....+...+.......+...............+................................+...+..........+.....+............+.+.....+...+....+...+....................+...+.......+...+......+......+...+......+......+........+......++++++
    ......+.+..+......+++++++++++++++++++++++++++++++++++++++*..+++++++++++++++++++++++++++++++++++++++*.....+.+........+..........+..+...+....+......+......+.........+..............+.......+.....+.+...+......+...........+.........+.+..+...+....+.....+.+.................++++++
    -----

    srv3
    ............+++++++++++++++++++++++++++++++++++++++*.....+......+.+..+.......+.........+............+++++++++++++++++++++++++++++++++++++++*......+...+.........+.+...........+......+.......+...+..+.+.........+..+.+........+.+........+.........................+...........+.........+...+.......+..+....+.....+.......+..+...+.......+.....++++++
    ...+++++++++++++++++++++++++++++++++++++++*..+++++++++++++++++++++++++++++++++++++++*....+...+............+......+...+.......+..+.......+.....+.........+....+...+............+..+....+...........+.+.....+....+.....+.+........+....+...........+....+...+..+...+....+........+.+..+.......+...........+....+...........+.+.....+.........+.+...+.....+.......+...+......+...........+.+...+..+....+...............+........+..........+...+..+.+.....+.......+...+...........................+............+......+.........+..+...+...+...+...............+.......+...............+..+.+.....+............+....+.....+.+...+..+...+....+...+..+.+......+...+..+...+...............+.+......+......+........+......+...+.............++++++
    -----
    Проверка:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl req -noout -text -in ~/cert/crt/patroni.csr -reqopt no_sigdump,no_validity,no_pubkey; done

    Вывод команды:

    srv1
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=patroni
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment

    srv2
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=patroni
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment

    srv3
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=patroni
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment
  4. Запрос на сертификат patronietcd:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl req -new -nodes -text -out ~/cert/crt/patronietcd.csr -keyout ~/cert/crt/patronietcd.key -config ~/cert/cnf/client.cnf -subj "/CN=patronietcd"; done
    Вывод команды:

    srv1
    ...+...+..+++++++++++++++++++++++++++++++++++++++*......+............+.....+...+......+................+++++++++++++++++++++++++++++++++++++++*.++++++
    .....+....+..+.+.........+........+.+.........+..+...+...+..........+...+..+...+.......+..+++++++++++++++++++++++++++++++++++++++*................+...+.....+......+....+.....+...+...+.+......+........+++++++++++++++++++++++++++++++++++++++*.+....+.........+...........+....+............+.........+.....+.+...........+...+.+.....+.........+......+......+..........+..+.+...........+..........+......+............+......+...........+....+......+...+.....+..........+...........+....+...+..+.......+........+......+.+......+.....+...+.........+.+.....+......+.+..+............+...+...+.........+....+..............+...+.......+......+.....+.........+.+............+..+......+.+.........+.........+...+.....+...+.+...+...++++++
    -----

    srv2
    ....+...+.....+...+..........+.....+.......+..+++++++++++++++++++++++++++++++++++++++*......+..+...+.+..+...+.......+...+..+.......+...+++++++++++++++++++++++++++++++++++++++*.......+......+.+...........+..........+..+...+....+...............+......+...+.....+....+..+...+............+.+...+...........+......+.........+.+.....+.........+.............+...............+...+.........+...+...+..................+..+..........+.....+.........+.+..............+.+..+.+..+.......+.....+.+.........+...+..+.+.....+.+......+.........+..............+....+..+......+...+....+..+.+.....+...+.......+..+.......+.........+.....+....+...............+..+..........+...........+.........+.+........+......+....+..+..........+...+......+.....+...+.+.....+....+......+.....................+......+.....+....+........+..........+..+.........+......+..................+..........+...+..+..........+...+...+.....+
    -----

    srv3
    ..+.....+...+...+.+++++++++++++++++++++++++++++++++++++++*.+.........+.....................+++++++++++++++++++++++++++++++++++++++*.+.........+...+..+.......+...........+.......+..+.+..+.......+.....+...+.......+...+...+...+.....+.+..............+.........+.+......+...+..+...+............+.........+.........+...+.........+....+.....+.+.....................+...............+...+..............+...+...++++++
    .....+...+.+...+.................+..........+......+...+..+...+.......+..+.......+++++++++++++++++++++++++++++++++++++++*...+..+....+.....+.+......+..............+.+...............+..+.+..+.........+.+.....+.............+..+.......+..+.+.....+++++++++++++++++++++++++++++++++++++++*............+.....+.+..+.+......+.........+............+.............................+....+......+.....+....+.........+......+..+....+.....+.........+.........+.+..+...+.+...+.....+..................+.......+...+...+....................+.+......+...+..+.......+............+.....+...+.+...........+...+.......+.........+.........++++++
    -----
    Проверка:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl req -noout -text -in ~/cert/crt/patronietcd.csr -reqopt no_sigdump,no_validity,no_pubkey; done

    Вывод команды:

    srv1
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=patronietcd
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment

    srv2
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=patronietcd
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment

    srv3
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=patronietcd
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment
  5. Запрос на сертификат pgbouncer:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl req -new -nodes -text -out ~/cert/crt/pgbouncer.csr -keyout ~/cert/crt/pgbouncer.key -config ~/cert/cnf/client.cnf -subj "/CN=pgbouncer"; done
    Вывод команды:

    srv1
    .....+.+..+..........+.....+......+++++++++++++++++++++++++++++++++++++++*.......+.+...+...+...+.....+.....................+++++++++++++++++++++++++++++++++++++++*.+.....+......+...+.......+...+......+.....+...+...............+..........+...+..+.+............+...+......+...........+...+......+....+..+.......+...+...+...........+......+.............+.....+....++++++
    ...+......+..+...+....+.....+.+..+....+.........+..+...+....+.....+...+....+...+.....+.+.....+............+....+.....+.+.........+.........+..+...+......+.+...+......+..............+...................+.....+......+.+.....+...+...+++++++++++++++++++++++++++++++++++++++*..+..+.+........+.......+++++++++++++++++++++++++++++++++
    -----

    srv2
    .+........+....+...+...+..+++++++++++++++++++++++++++++++++++++++*..+.+........+...+...+.+...+..+++++++++++++++++++++++++++++++++++++++*....+...+.+...+...+........+....+......+..............+...+...+.+.........+......+...+...+..+.......+...............+.....+..........++++++
    ....+++++++++++++++++++++++++++++++++++++++*.........+.........+......+..+.......+...+..+......+...+....+..+....+..+...+++++++++++++++++++++++++++++++++++++++*.....+...+...+..+.........+.+.....+............................+......+...+......+.....+.......+..+..........+..+...+......+....+.....................+.........+..+......+...+.+......+...+..+....+......+...+............+.....+....+.....+......+..........+...+.....+......+.+..+.......+.........+.........+.................+...+.......+.........++++++
    -----

    srv3
    ....+....+..+.......+.....+...+....+...+...+...+...............+...........+....+.....+....+..+.+........+......+.+...............+...+++++++++++++++++++++++++++++++++++++++*.+++++++++++++++++++++++++++++++++++++++*...+...+.............+..+..........+..+.+.........+...........+...+....+..+.+..............+................+..+................+......+....................+.............+......+...........+.+...+..+....+.....+..........+...+.....+.+..+.......+..+....+......+.....+....+..+.........+...+......+.+.........+.........+.....+............+.............+...........+......+.+..+............+....+..+...+............+.........+.........+......+....+..+....+...+..+......+...+.+...+.....+...+....+...............+..........................+....+......+...+..+.......+.....+.+......+.........+.....+.+........+...+....+......+........+.........+.+..+....+.....++++++
    ....+...+...+........+++++++++++++++++++++++++++++++++++++++*...+....+...+...+......+++++++++++++++++++++++++++++++++++++++*....+.+.....+...+.......+.....+....+.....+................+........+.+...++++++
    -----
    Проверка:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl req -noout -text -in ~/cert/crt/pgbouncer.csr -reqopt no_sigdump,no_validity,no_pubkey; done

    Вывод команды:

    srv1
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=pgbouncer
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment

    srv2
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=pgbouncer
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment

    srv3
    Certificate Request:
    Data:
    Version: 1 (0x0)
    Subject: CN=pgbouncer
    Attributes:
    Requested Extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Key Usage:
    Digital Signature, Non Repudiation, Key Encipherment

    Проверим наличие запросов на сертификат на всех узлах:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp ls -l ~/cert/crt/*.csr; done
    srv1
    -rw-r--r-- 1 student student 3569 апр 14 19:45 /home/student/cert/crt/patroni.csr
    -rw-r--r-- 1 student student 3577 апр 14 19:47 /home/student/cert/crt/patronietcd.csr
    -rw-r--r-- 1 student student 3575 апр 14 19:49 /home/student/cert/crt/pgbouncer.csr
    -rw-r--r-- 1 student student 3570 апр 14 15:22 /home/student/cert/crt/postgres.csr
    -rw-r--r-- 1 student student 3699 апр 14 15:26 /home/student/cert/crt/server.csr

    srv2
    -rw-r--r-- 1 student student 3569 апр 14 19:45 /home/student/cert/crt/patroni.csr
    -rw-r--r-- 1 student student 3577 апр 14 19:47 /home/student/cert/crt/patronietcd.csr
    -rw-r--r-- 1 student student 3575 апр 14 19:49 /home/student/cert/crt/pgbouncer.csr
    -rw-r--r-- 1 student student 3570 апр 14 15:22 /home/student/cert/crt/postgres.csr
    -rw-r--r-- 1 student student 3699 апр 14 15:26 /home/student/cert/crt/server.csr

    srv3
    -rw-r--r-- 1 student student 3569 апр 14 19:45 /home/student/cert/crt/patroni.csr
    -rw-r--r-- 1 student student 3577 апр 14 19:47 /home/student/cert/crt/patronietcd.csr
    -rw-r--r-- 1 student student 3575 апр 14 19:50 /home/student/cert/crt/pgbouncer.csr
    -rw-r--r-- 1 student student 3570 апр 14 15:22 /home/student/cert/crt/postgres.csr
    -rw-r--r-- 1 student student 3699 апр 14 15:26 /home/student/cert/crt/server.csr

Генерирование сертификатов​

Запрос на сертификат используется для подписи его сертификатом УЦ, в результате чего создается сертификат.

  1. Подпишем запрос на серверный сертификат корневым сертификатом УЦ.

    Внимание!

    Обратите внимание на -extensions ssl_client в командной строке.

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl x509 -req -in ~/cert/crt/server.csr -text -days 1800 -CA ~/cert/ca_ssl/root.crt -CAkey ~/cert/ca_ssl/root.key -CAcreateserial -out ~/cert/crt/server.crt -extfile ~/cert/cnf/server.cnf -extensions ssl_client; done
    srv1
    Certificate request self-signature ok
    subject=CN=srv1

    srv2
    Certificate request self-signature ok
    subject=CN=srv2

    srv3
    Certificate request self-signature ok
    subject=CN=srv3

    Проверка:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl x509 -in ~/cert/crt/server.crt -text -noout -ext subjectAltName -certopt ca_default,no_sigdump; done
    Вывод команды:

    srv1
    Serial Number:
    3e:da:b7:7b:ae:99:45:92:71:e8:a2:6f:02:71:be:71:3e:89:f0:0f
    Signature Algorithm: sha256WithRSAEncryption
    Validity
    Not Before: Apr 14 16:57:47 2026 GMT
    Not After : Mar 19 16:57:47 2031 GMT
    Subject: CN=srv1
    X509v3 extensions:
    X509v3 Subject Alternative Name:
    DNS:srv1, IP Address:<IP-Address1>
    X509v3 Subject Alternative Name:
    DNS:srv1, IP Address:<IP-Address1>

    srv2
    Serial Number:
    4f:74:2f:a4:57:ab:4c:5e:e0:56:f7:06:dd:38:6b:51:6a:22:9f:18
    Signature Algorithm: sha256WithRSAEncryption
    Validity
    Not Before: Apr 14 16:57:48 2026 GMT
    Not After : Mar 19 16:57:48 2031 GMT
    Subject: CN=srv2
    X509v3 extensions:
    X509v3 Subject Alternative Name:
    DNS:srv2, IP Address:<IP-Address2>
    X509v3 Subject Alternative Name:
    DNS:srv2, IP Address:<IP-Address2>

    srv3
    Serial Number:
    5e:84:f6:a0:77:58:e5:48:dc:de:ed:c5:d9:55:db:7d:f9:a7:5c:b2
    Signature Algorithm: sha256WithRSAEncryption
    Validity
    Not Before: Apr 14 16:57:48 2026 GMT
    Not After : Mar 19 16:57:48 2031 GMT
    Subject: CN=srv3
    X509v3 extensions:
    X509v3 Subject Alternative Name:
    DNS:srv3, IP Address:<IP-Address3>
    X509v3 Subject Alternative Name:
    DNS:srv3, IP Address:<IP-Address3>
  2. Подпишем запрос на клиентский сертификат корневым сертификатом УЦ:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl x509 -req -in ~/cert/crt/postgres.csr -text -days 1800 -CA ~/cert/ca_ssl/root.crt -CAkey ~/cert/ca_ssl/root.key -CAcreateserial -out ~/cert/crt/postgres.crt -extfile ~/cert/cnf/client.cnf; done
    Вывод команды:

    srv1
    Certificate request self-signature ok
    subject=CN=postgres

    srv2
    Certificate request self-signature ok
    subject=CN=postgres

    srv3
    Certificate request self-signature ok
    subject=CN=postgres
  3. Подпишем запрос на сертификат для patroni корневым сертификатом УЦ:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl x509 -req -in ~/cert/crt/patroni.csr -text -days 1800 -CA ~/cert/ca_ssl/root.crt -CAkey ~/cert/ca_ssl/root.key -CAcreateserial -out ~/cert/crt/patroni.crt -extfile ~/cert/cnf/client.cnf -extensions ssl_client; done
    Вывод команды:

    srv1
    Certificate request self-signature ok
    subject=CN=patroni

    srv2
    Certificate request self-signature ok
    subject=CN=patroni

    srv3
    Certificate request self-signature ok
    subject=CN=patroni
  4. Подпишем запрос на сертификат для patronietcd корневым сертификатом УЦ:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl x509 -req -in ~/cert/crt/patronietcd.csr -text -days 1800 -CA ~/cert/ca_ssl/root.crt -CAkey ~/cert/ca_ssl/root.key -CAcreateserial -out ~/cert/crt/patronietcd.crt -extfile ~/cert/cnf/client.cnf -extensions ssl_client; done
    Вывод команды:

    srv1
    Certificate request self-signature ok
    subject=CN=patronietcd

    srv2
    Certificate request self-signature ok
    subject=CN=patronietcd

    srv3
    Certificate request self-signature ok
    subject=CN=patronietcd
  5. Подпишем запрос на сертификат для pgbouncer корневым сертификатом УЦ.

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp openssl x509 -req -in ~/cert/crt/pgbouncer.csr -text -days 1800 -CA ~/cert/ca_ssl/root.crt -CAkey ~/cert/ca_ssl/root.key -CAcreateserial -out ~/cert/crt/pgbouncer.crt -extfile ~/cert/cnf/client.cnf -extensions ssl_client; done
    Вывод команды:

    srv1
    Certificate request self-signature ok
    subject=CN=pgbouncer

    srv2
    Certificate request self-signature ok
    subject=CN=pgbouncer

    srv3
    Certificate request self-signature ok
    subject=CN=pgbouncer

    Проверим наличие сертификатов:

    [student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp ls -l ~/cert/crt/*.crt; done
    srv1
    -rw-r--r-- 1 student student 4338 апр 14 20:00 /home/student/cert/crt/patroni.crt
    -rw-r--r-- 1 student student 4346 апр 14 20:01 /home/student/cert/crt/patronietcd.crt
    -rw-r--r-- 1 student student 4340 апр 14 20:02 /home/student/cert/crt/pgbouncer.crt
    -rw-r--r-- 1 student student 4145 апр 14 19:56 /home/student/cert/crt/postgres.crt
    -rw-r--r-- 1 student student 4504 апр 14 19:57 /home/student/cert/crt/server.crt

    srv2
    -rw-r--r-- 1 student student 4338 апр 14 20:00 /home/student/cert/crt/patroni.crt
    -rw-r--r-- 1 student student 4346 апр 14 20:01 /home/student/cert/crt/patronietcd.crt
    -rw-r--r-- 1 student student 4340 апр 14 20:02 /home/student/cert/crt/pgbouncer.crt
    -rw-r--r-- 1 student student 4145 апр 14 19:56 /home/student/cert/crt/postgres.crt
    -rw-r--r-- 1 student student 4504 апр 14 19:57 /home/student/cert/crt/server.crt

    srv3
    -rw-r--r-- 1 student student 4338 апр 14 20:00 /home/student/cert/crt/patroni.crt
    -rw-r--r-- 1 student student 4346 апр 14 20:01 /home/student/cert/crt/patronietcd.crt
    -rw-r--r-- 1 student student 4340 апр 14 20:02 /home/student/cert/crt/pgbouncer.crt
    -rw-r--r-- 1 student student 4145 апр 14 19:56 /home/student/cert/crt/postgres.crt
    -rw-r--r-- 1 student student 4504 апр 14 19:57 /home/student/cert/crt/server.crt

Установка сертификатов​

На всех узлах кластера создадим каталог /pg_ssl с подкаталогом root_dir:

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp sudo mkdir -p /pg_ssl{,/root_dir}; done
srv1

srv2

srv3

Проверим:

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp sudo ls -ld /pg_ssl{,/root_dir}; done
srv1
drwxr-xr-x 3 root root 4096 апр 14 20:18 /pg_ssl
drwxr-xr-x 2 root root 4096 апр 14 20:18 /pg_ssl/root_dir

srv2
drwxr-xr-x 3 root root 4096 апр 14 20:18 /pg_ssl
drwxr-xr-x 2 root root 4096 апр 14 20:18 /pg_ssl/root_dir

srv3
drwxr-xr-x 3 root root 4096 апр 14 20:18 /pg_ssl
drwxr-xr-x 2 root root 4096 апр 14 20:18 /pg_ssl/root_dir

Скопируем в этот каталог ключи и сертификаты:

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp sudo cp -v ~/cert/{crt,ca_ssl}/*.{crt,key} /pg_ssl; done
Вывод команды:

srv1
'/home/student/cert/crt/patroni.crt' -> '/pg_ssl/patroni.crt'
'/home/student/cert/crt/patronietcd.crt' -> '/pg_ssl/patronietcd.crt'
'/home/student/cert/crt/pgbouncer.crt' -> '/pg_ssl/pgbouncer.crt'
'/home/student/cert/crt/postgres.crt' -> '/pg_ssl/postgres.crt'
'/home/student/cert/crt/server.crt' -> '/pg_ssl/server.crt'
'/home/student/cert/crt/patronietcd.key' -> '/pg_ssl/patronietcd.key'
'/home/student/cert/crt/patroni.key' -> '/pg_ssl/patroni.key'
'/home/student/cert/crt/pgbouncer.key' -> '/pg_ssl/pgbouncer.key'
'/home/student/cert/crt/postgres.key' -> '/pg_ssl/postgres.key'
'/home/student/cert/crt/server.key' -> '/pg_ssl/server.key'
'/home/student/cert/ca_ssl/root.crt' -> '/pg_ssl/root.crt'
'/home/student/cert/ca_ssl/root.key' -> '/pg_ssl/root.key'

srv2
'/home/student/cert/crt/patroni.crt' -> '/pg_ssl/patroni.crt'
'/home/student/cert/crt/patronietcd.crt' -> '/pg_ssl/patronietcd.crt'
'/home/student/cert/crt/pgbouncer.crt' -> '/pg_ssl/pgbouncer.crt'
'/home/student/cert/crt/postgres.crt' -> '/pg_ssl/postgres.crt'
'/home/student/cert/crt/server.crt' -> '/pg_ssl/server.crt'
'/home/student/cert/crt/patronietcd.key' -> '/pg_ssl/patronietcd.key'
'/home/student/cert/crt/patroni.key' -> '/pg_ssl/patroni.key'
'/home/student/cert/crt/pgbouncer.key' -> '/pg_ssl/pgbouncer.key'
'/home/student/cert/crt/postgres.key' -> '/pg_ssl/postgres.key'
'/home/student/cert/crt/server.key' -> '/pg_ssl/server.key'
'/home/student/cert/ca_ssl/root.crt' -> '/pg_ssl/root.crt'
'/home/student/cert/ca_ssl/root.key' -> '/pg_ssl/root.key'

srv3
'/home/student/cert/crt/patroni.crt' -> '/pg_ssl/patroni.crt'
'/home/student/cert/crt/patronietcd.crt' -> '/pg_ssl/patronietcd.crt'
'/home/student/cert/crt/pgbouncer.crt' -> '/pg_ssl/pgbouncer.crt'
'/home/student/cert/crt/postgres.crt' -> '/pg_ssl/postgres.crt'
'/home/student/cert/crt/server.crt' -> '/pg_ssl/server.crt'
'/home/student/cert/crt/patronietcd.key' -> '/pg_ssl/patronietcd.key'
'/home/student/cert/crt/patroni.key' -> '/pg_ssl/patroni.key'
'/home/student/cert/crt/pgbouncer.key' -> '/pg_ssl/pgbouncer.key'
'/home/student/cert/crt/postgres.key' -> '/pg_ssl/postgres.key'
'/home/student/cert/crt/server.key' -> '/pg_ssl/server.key'
'/home/student/cert/ca_ssl/root.crt' -> '/pg_ssl/root.crt'
'/home/student/cert/ca_ssl/root.key' -> '/pg_ssl/root.key'

Установим на каталог /pg_ssl и его содержимое владельца postgres:

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp sudo chown -cR postgres:postgres /pg_ssl; done
Вывод команды:

srv1
изменен владелец '/pg_ssl/server.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/pgbouncer.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/root.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/postgres.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patroni.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patronietcd.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patroni.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/postgres.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patronietcd.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/server.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/root_dir' с root:root на postgres:postgres
изменен владелец '/pg_ssl/pgbouncer.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/root.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl' с root:root на postgres:postgres

srv2
изменен владелец '/pg_ssl/server.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/pgbouncer.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/root.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/postgres.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patroni.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patronietcd.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patroni.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/postgres.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patronietcd.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/server.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/root_dir' с root:root на postgres:postgres
изменен владелец '/pg_ssl/pgbouncer.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/root.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl' с root:root на postgres:postgres

srv3
изменен владелец '/pg_ssl/server.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/pgbouncer.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/root.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/postgres.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patroni.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patronietcd.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patroni.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/postgres.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/patronietcd.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/server.key' с root:root на postgres:postgres
изменен владелец '/pg_ssl/root_dir' с root:root на postgres:postgres
изменен владелец '/pg_ssl/pgbouncer.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl/root.crt' с root:root на postgres:postgres
изменен владелец '/pg_ssl' с root:root на postgres:postgres

Проверим результат:

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp sudo ls -l /pg_ssl; done
Вывод команды:

srv1
итого 72
-rw-r--r-- 1 postgres postgres 4338 апр 14 20:19 patroni.crt
-rw-r--r-- 1 postgres postgres 4346 апр 14 20:19 patronietcd.crt
-rw------- 1 postgres postgres 1704 апр 14 20:19 patronietcd.key
-rw------- 1 postgres postgres 1704 апр 14 20:19 patroni.key
-rw-r--r-- 1 postgres postgres 4340 апр 14 20:19 pgbouncer.crt
-rw------- 1 postgres postgres 1704 апр 14 20:19 pgbouncer.key
-rw-r--r-- 1 postgres postgres 4145 апр 14 20:19 postgres.crt
-rw------- 1 postgres postgres 1704 апр 14 20:19 postgres.key
-rw-r--r-- 1 postgres postgres 1273 апр 14 20:19 root.crt
drwxr-xr-x 2 postgres postgres 4096 апр 14 20:18 root_dir
-rw------- 1 postgres postgres 1708 апр 14 20:19 root.key
-rw-r--r-- 1 postgres postgres 4504 апр 14 20:19 server.crt
-rw------- 1 postgres postgres 1704 апр 14 20:19 server.key

srv2
итого 72
-rw-r--r-- 1 postgres postgres 4338 апр 14 20:19 patroni.crt
-rw-r--r-- 1 postgres postgres 4346 апр 14 20:19 patronietcd.crt
-rw------- 1 postgres postgres 1704 апр 14 20:19 patronietcd.key
-rw------- 1 postgres postgres 1708 апр 14 20:19 patroni.key
-rw-r--r-- 1 postgres postgres 4340 апр 14 20:19 pgbouncer.crt
-rw------- 1 postgres postgres 1708 апр 14 20:19 pgbouncer.key
-rw-r--r-- 1 postgres postgres 4145 апр 14 20:19 postgres.crt
-rw------- 1 postgres postgres 1704 апр 14 20:19 postgres.key
-rw-r--r-- 1 postgres postgres 1273 апр 14 20:19 root.crt
drwxr-xr-x 2 postgres postgres 4096 апр 14 20:18 root_dir
-rw------- 1 postgres postgres 1708 апр 14 20:19 root.key
-rw-r--r-- 1 postgres postgres 4504 апр 14 20:19 server.crt
-rw------- 1 postgres postgres 1704 апр 14 20:19 server.key

srv3
итого 72
-rw-r--r-- 1 postgres postgres 4338 апр 14 20:19 patroni.crt
-rw-r--r-- 1 postgres postgres 4346 апр 14 20:19 patronietcd.crt
-rw------- 1 postgres postgres 1704 апр 14 20:19 patronietcd.key
-rw------- 1 postgres postgres 1704 апр 14 20:19 patroni.key
-rw-r--r-- 1 postgres postgres 4340 апр 14 20:19 pgbouncer.crt
-rw------- 1 postgres postgres 1704 апр 14 20:19 pgbouncer.key
-rw-r--r-- 1 postgres postgres 4145 апр 14 20:19 postgres.crt
-rw------- 1 postgres postgres 1704 апр 14 20:19 postgres.key
-rw-r--r-- 1 postgres postgres 1273 апр 14 20:19 root.crt
drwxr-xr-x 2 postgres postgres 4096 апр 14 20:18 root_dir
-rw------- 1 postgres postgres 1708 апр 14 20:19 root.key
-rw-r--r-- 1 postgres postgres 4504 апр 14 20:19 server.crt
-rw------- 1 postgres postgres 1704 апр 14 20:19 server.key

Скопируем файлы /pg_ssl/root.crt в каталог /etc/pki/ca-trust/source/anchors/.

Зачем?

/etc/pki/ca-trust/source/anchors/ – это каталог операционной системы, используемый для хранения доверенных системных ключей, например, корневого сертификата нашего удостоверяющего центра (УЦ), позволяющий операционной системе устанавливать доверие к издателям, сертификаты которых подписаны этим корневым УЦ.

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp sudo cp -v /pg_ssl/root.crt /etc/pki/ca-trust/source/anchors/; done
srv1
'/pg_ssl/root.crt' -> '/etc/pki/ca-trust/source/anchors/root.crt'

srv2
'/pg_ssl/root.crt' -> '/etc/pki/ca-trust/source/anchors/root.crt'

srv3
'/pg_ssl/root.crt' -> '/etc/pki/ca-trust/source/anchors/root.crt'

Зарегистрируем сертификат УЦ на всех узлах стенда:

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp sudo update-ca-trust; done
srv1

srv2

srv3

Проверим регистрацию:

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp sudo trust list | grep -B1 -A3 DBP; done
srv1
type: certificate
label: CA_DBP2
trust: anchor
category: authority

srv2
type: certificate
label: CA_DBP2
trust: anchor
category: authority

srv3
type: certificate
label: CA_DBP2
trust: anchor
category: authority

Скопируем файлы ключа и сертификата УЦ в каталог root_dir на всех узлах кластера:

А root_dir чей каталог?

root_dir – это каталог Pangolin доверенных системных ключей. По умолчанию это /pg_ssl/root_dir/, но путь и название можно изменить в конфигурационном файле postgresql.conf.

[student@srv1 ~]$ for comp in srv{1..3}; do echo -e "\n$comp"; ssh $comp sudo cp -v /pg_ssl/root.{crt,key} /pg_ssl/root_dir/; done
srv1
'/pg_ssl/root.crt' -> '/pg_ssl/root_dir/root.crt'
'/pg_ssl/root.key' -> '/pg_ssl/root_dir/root.key'

srv2
'/pg_ssl/root.crt' -> '/pg_ssl/root_dir/root.crt'
'/pg_ssl/root.key' -> '/pg_ssl/root_dir/root.key'

srv3
'/pg_ssl/root.crt' -> '/pg_ssl/root_dir/root.crt'
'/pg_ssl/root.key' -> '/pg_ssl/root_dir/root.key'

Подведем итоги​

Вопрос 1

Вопрос 1: Какой параметр расширения (-extensions) необходимо указать при подписании серверных сертификатов с помощью корневого сертификата УЦ?

Вопрос 2

Вопрос 2: Какой командой обновляется доверие к сертификатам на узлах после добавления корневого сертификата УЦ?

Вопрос 3

Вопрос 3: Какой командой можно проверить, что корневой сертификат УЦ успешно добавлен в систему доверия?