Ssl-cc » История » Версия 7
Андрей Волков, 2016-11-10 16:16
1 | 1 | Андрей Волков | h1. Подключение к postgres с обязательным использованием SSL и клиентского сертификата |
---|---|---|---|
2 | |||
3 | h1. Дано |
||
4 | |||
5 | Cервера postgresql с адресами: |
||
6 | |||
7 | * *myserver1.example.com* |
||
8 | * *myserver2.example.com* |
||
9 | |||
10 | h1. Задача |
||
11 | |||
12 | Предоставить клиентам доступ к серверам через публичную сеть (Интернет). |
||
13 | |||
14 | - Включить шифрование канала между клиентом и сервером |
||
15 | - Требовать от клиента клиентский сертификат |
||
16 | - Требовать от клиента пароль |
||
17 | - Проверять, что сервер действительно то, за кого он себя выдает |
||
18 | |||
19 | h1. Решение |
||
20 | |||
21 | Данное решение реализовывалось на серверах postgresql-9.2+ и было актуально на 2016 год. |
||
22 | |||
23 | h2. 1. Генерация сертификатов |
||
24 | |||
25 | Если в вашем случае за настройку серверов и выдачу клиентских сертификатов отвечает один человек, то можно использовать одну CA для подписания, как клиентских так и серверных сертификатов. |
||
26 | |||
27 | Я рассмотрю вариант, когда CA отличаются |
||
28 | |||
29 | h3. 1.1. Генерация сертификатов серверов |
||
30 | |||
31 | Одним из вариантов решения могла бы быть покупка серверного сертификата |
||
32 | Но здесь это нецелесообразно, потому что клиенты не всегда используют системные ca-bundle, и раз уж нам все равно нужно передавать пользователям клиентские сертификаты, то передадим и CA сервера. |
||
33 | |||
34 | h4. 1.1.1. CA сертификат для подписания серверных сертификатов |
||
35 | |||
36 | Не буду вдаваться в подробности создания CA |
||
37 | |||
38 | *openssl genrsa -out server-ca.key -camellia256 2048* |
||
39 | *chmod 400 server-ca.key* |
||
40 | *openssl req -new -x509 -days 3650 -key server-ca.key -out server-ca.crt -subj '/C=RU/O=EKB-Info/CN=server-CA' -extensions v3_ca -sha256* |
||
41 | |||
42 | ШИфр для ключа *-camellia256* - дело вкуса. |
||
43 | Можно выбрать и что-то другое из: |
||
44 | |||
45 | * -aes128 |
||
46 | * -aes192 |
||
47 | * -aes256 |
||
48 | * -camellia128 |
||
49 | * -camellia192 |
||
50 | * -camellia256 |
||
51 | * -des |
||
52 | * -des3 |
||
53 | * -idea |
||
54 | |||
55 | Тип ЭЦП для сертификата *-sha256* - тоже дело вкуса. |
||
56 | По большому счету здесь можно использовать другой тип ЭЦП, т.к. на корневом сертификате ЭЦП не проверяется. |
||
57 | |||
58 | Значение параметра *-subj* нужно поправить под себя. |
||
59 | |||
60 | h4. 1.1.2 Создаем серверные сертификаты |
||
61 | |||
62 | 3 | Андрей Волков | +Создаем файл настроек для генерации серверного сертификата:+ |
63 | 1 | Андрей Волков | |
64 | *cat > openssl.cnf* |
||
65 | |||
66 | <pre> |
||
67 | [ server ] |
||
68 | basicConstraints = CA:FALSE |
||
69 | extendedKeyUsage = serverAuth |
||
70 | subjectKeyIdentifier = hash |
||
71 | authorityKeyIdentifier = keyid,issuer:always |
||
72 | 2 | Андрей Волков | keyUsage = digitalSignature |
73 | 1 | Андрей Волков | </pre> |
74 | |||
75 | 3 | Андрей Волков | +Генерируем запросы на серверные сертификаты:+ |
76 | 1 | Андрей Волков | |
77 | *openssl req -new -nodes -newkey rsa:2048 -keyout myserver1.example.com.key -out myserver1.example.com.csr -subj '/C=RU/O=EKB-Info/CN=myserver1.example.com/' -sha256* |
||
78 | 2 | Андрей Волков | |
79 | 1 | Андрей Волков | *openssl req -new -nodes -newkey rsa:2048 -keyout myserver2.example.com.key -out myserver1.example.com.csr -subj '/C=RU/O=EKB-Info/CN=myserver2.example.com/' -sha256* |
80 | |||
81 | 2 | Андрей Волков | *chmod 400 myserver1.example.com.key* |
82 | *chmod 400 myserver2.example.com.key* |
||
83 | 1 | Андрей Волков | |
84 | Здесь важно указать CN= в виде реального имени, по которому клиенты будут соединяться к серверу. Иначе не будет работать verify-full |
||
85 | https://www.postgresql.org/docs/9.5/static/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS |
||
86 | |||
87 | Тип ЭЦП *-sha256* здесь не очень важен, потому что используется только для подписи запроса, а не самого сертификата. |
||
88 | |||
89 | 3 | Андрей Волков | +Подписываем сертификаты:+ |
90 | 1 | Андрей Волков | |
91 | *openssl x509 -req -days 3650 -in myserver1.example.com.csr -CA server-ca.crt -CAkey server-ca.key -CAserial server-ca.srl -CAcreateserial -out myserver1.example.com.crt -extfile openssl.cnf -extensions server -sha256* |
||
92 | |||
93 | *openssl x509 -req -days 3650 -in myserver2.example.com.csr -CA server-ca.crt -CAkey server-ca.key -CAserial server-ca.srl -out myserver1.example.com.crt -extfile openssl.cnf -extensions server -sha256* |
||
94 | |||
95 | 2 | Андрей Волков | Тип ЭЦП *-sha256* здесь важен с точки зрения надежности. В 2016 году некоторые распространенные ранее типы ЭЦП, например sha1 не считается надежными. |
96 | 1 | Андрей Волков | |
97 | Параметр *-CAcreateserial* Используется только первый раз. |
||
98 | |||
99 | h4. 1.2.1 CA сертификат для подписания клиентских сертификатов |
||
100 | |||
101 | Тут все по аналогии с пунктом 1.1.1. |
||
102 | |||
103 | Приведу только команды |
||
104 | |||
105 | *openssl genrsa -out client-ca.key -camellia256 2048* |
||
106 | *chmod 400 client-ca.key* |
||
107 | *openssl req -new -x509 -days 3650 -key client-ca.key -out client-ca.crt -subj '/C=RU/O=EKB-Info/CN=client-CA' -extensions v3_ca -sha256* |
||
108 | 2 | Андрей Волков | |
109 | 5 | Андрей Волков | Возможно в будущем нам потребуется отзывать сертификаты у пользователей: |
110 | |||
111 | Создадим файл отозванных сертификатов |
||
112 | |||
113 | *cat >> openssl.cnf* |
||
114 | |||
115 | <pre> |
||
116 | 6 | Андрей Волков | [ ca ] |
117 | 7 | Андрей Волков | default_ca = CA |
118 | 5 | Андрей Волков | |
119 | 6 | Андрей Волков | [ CA ] |
120 | 7 | Андрей Волков | database = index.txt |
121 | default_md = default |
||
122 | default_crl_days = 30 |
||
123 | 5 | Андрей Волков | </pre> |
124 | |||
125 | openssl ca -config openssl.cnf -cert client-ca.crt -keyfile client-ca.key -gencrl -out client-ca.crl |
||
126 | |||
127 | 4 | Андрей Волков | h4. 1.2.2 Создаем серверные сертификаты |
128 | 2 | Андрей Волков | |
129 | Тут все по аналогии с пунктом 1.1.2. |
||
130 | |||
131 | 3 | Андрей Волков | +Создаем файл настроек для генерации клиентского сертификата:+ |
132 | 2 | Андрей Волков | |
133 | *cat >> openssl.cnf* |
||
134 | |||
135 | <pre> |
||
136 | [ client ] |
||
137 | basicConstraints = CA:FALSE |
||
138 | extendedKeyUsage = clientAuth |
||
139 | subjectKeyIdentifier = hash |
||
140 | authorityKeyIdentifier = keyid,issuer:always |
||
141 | keyUsage = digitalSignature |
||
142 | </pre> |
||
143 | |||
144 | 3 | Андрей Волков | +Генерируем запросы на клиентские сертификаты:+ |
145 | 2 | Андрей Волков | |
146 | *openssl req -new -nodes -newkey rsa:2048 -keyout ivanov_ii.key -out ivanov_ii.csr -subj '/C=RU/O=EKB-Info/CN=ivanov_ii/' -sha256* |
||
147 | |||
148 | *openssl req -new -nodes -newkey rsa:2048 -keyout petrov_pp.key -out petrov_pp.csr -subj '/C=RU/O=EKB-Info/CN=petrov_pp/' -sha256* |
||
149 | |||
150 | *chmod 400 ivanov_ii.key* |
||
151 | *chmod 400 petrov_pp.key* |
||
152 | |||
153 | Здесь желательно указать CN= в виде реального фио, чтобы потом можно было различать принадлежность сертификатов сотрудников. |
||
154 | |||
155 | 3 | Андрей Волков | +Подписываем сертификаты:+ |
156 | 2 | Андрей Волков | |
157 | *openssl x509 -req -days 3650 -in ivanov_ii.csr -CA client-ca.crt -CAkey client-ca.key -CAserial client-ca.srl -CAcreateserial -out ivanov_ii.crt -extfile openssl.cnf -extensions client -sha256* |
||
158 | |||
159 | *openssl x509 -req -days 3650 -in petrov_pp.csr -CA client-ca.crt -CAkey client-ca.key -CAserial client-ca.srl -out petrov_pp.crt -extfile openssl.cnf -extensions client -sha256* |
||
160 | |||
161 | Параметр *-CAcreateserial* Используется только первый раз. |
||
162 | 5 | Андрей Волков | |
163 | h2. 2. Раскладываем ключи и сертификаты |
||
164 | |||
165 | h3. 2.1. Сертификаты на серверах |
||
166 | |||
167 | myserver1.example.com.crt => /etc/postgresql-9.5/ssl/server.crt |
||
168 | myserver1.example.com.key => /etc/postgresql-9.5/ssl/server.key |
||
169 | client-ca.crt => /etc/postgresql-9.5/ssl/client-ca.crt |
||
170 | client-ca.crl => /etc/postgresql-9.5/ssl/client-ca.crl |
||
171 | |||
172 | myserver2.example.com.crt => /etc/postgresql-9.2/ssl/server.crt |
||
173 | myserver2.example.com.key => /etc/postgresql-9.2/ssl/server.key |
||
174 | client-ca.crt => /etc/postgresql-9.2/ssl/client-ca.crt |
||
175 | client-ca.crl => /etc/postgresql-9.5/ssl/client-ca.crl |
||
176 | |||
177 | h3. 2.1. Сертификаты на клиентcких машинах |
||
178 | |||
179 | Настройки для psql |
||
180 | |||
181 | ivanov_ii.crt => ~ivanov/.postgresql/postgresql.crt |
||
182 | ivanov_ii.key => ~ivanov/.postgresql/postgresql.key |
||
183 | server-ca.crt => ~ivanov/.postgresql/root.crt |
||
184 | |||
185 | petrov_pp.crt => ~petrov/.postgresql/postgresql.crt |
||
186 | petrov_pp.key => ~petrov/.postgresql/postgresql.key |
||
187 | server-ca.crt => ~petrov/.postgresql/root.crt |
||
188 | |||
189 | h2. 3. Настраиваем серверы: |
||
190 | |||
191 | h3. postgresql.conf |
||
192 | |||
193 | <pre> |
||
194 | ssl = on # (change requires restart) |
||
195 | ssl_ciphers = 'DHE-RSA-AES256-SHA' # allowed SSL ciphers |
||
196 | # (change requires restart) |
||
197 | ssl_prefer_server_ciphers = on # (change requires restart) |
||
198 | ssl_cert_file = 'server.crt' # (change requires restart) |
||
199 | ssl_key_file = 'server.key' # (change requires restart) |
||
200 | ssl_ca_file = 'client-ca.crt' # (change requires restart) |
||
201 | ssl_crl_file = 'client-ca.crl' # (change requires restart) |
||
202 | </pre> |
||
203 | |||
204 | ssl_ciphers - дело вкуса |
||
205 | |||
206 | Для применения настроек потребуется перезапуск базы =( |
||
207 | Для смены содержимого серверного сертификата потребуется перезапуск базы =(( |
||
208 | |||
209 | h3. pg_hba.conf |
||
210 | |||
211 | <pre> |
||
212 | # TYPE DATABASE USER ADDRESS METHOD [OPTIONS] |
||
213 | hostssl production ivanov 10.10.20.20/32 md5 clientcert=1 |
||
214 | hostssl production petrov 10.10.20.50/32 md5 clientcert=1 |
||
215 | </pre> |
||
216 | |||
217 | Для добавления пользователей достаточно попросить postgres перечитать настройки. |