Проект

Общее

Профиль

Ssl-cc » История » Версия 15

Андрей Волков, 2016-11-10 17:19

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 10 Андрей Волков
*touch index.txt*
126
*touch index.txt.attr*
127
*openssl ca -config openssl.cnf -cert client-ca.crt -keyfile client-ca.key -gencrl -out client-ca.crl*
128
129 5 Андрей Волков
130 4 Андрей Волков
h4. 1.2.2 Создаем серверные сертификаты
131 2 Андрей Волков
132
Тут все по аналогии с пунктом 1.1.2.
133
134 3 Андрей Волков
+Создаем файл настроек для генерации клиентского сертификата:+
135 2 Андрей Волков
136
*cat >> openssl.cnf*
137
138
<pre>
139
[ client ]
140
basicConstraints = CA:FALSE
141
extendedKeyUsage = clientAuth
142
subjectKeyIdentifier = hash
143
authorityKeyIdentifier = keyid,issuer:always
144
keyUsage = digitalSignature
145
</pre>
146
147 3 Андрей Волков
+Генерируем запросы на клиентские сертификаты:+
148 2 Андрей Волков
149
*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*
150
151
*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*
152
153
*chmod 400 ivanov_ii.key*
154
*chmod 400 petrov_pp.key*
155
156
Здесь желательно указать CN= в виде реального фио, чтобы потом можно было различать принадлежность сертификатов сотрудников.
157
158 3 Андрей Волков
+Подписываем сертификаты:+
159 2 Андрей Волков
160
*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*
161
162
*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*
163
164
Параметр *-CAcreateserial* Используется только первый раз.
165 5 Андрей Волков
166
h2. 2. Раскладываем ключи и сертификаты
167
168
h3. 2.1. Сертификаты на серверах
169
170
myserver1.example.com.crt => /etc/postgresql-9.5/ssl/server.crt
171
myserver1.example.com.key => /etc/postgresql-9.5/ssl/server.key
172
client-ca.crt => /etc/postgresql-9.5/ssl/client-ca.crt
173
client-ca.crl => /etc/postgresql-9.5/ssl/client-ca.crl
174
175
myserver2.example.com.crt => /etc/postgresql-9.2/ssl/server.crt
176
myserver2.example.com.key => /etc/postgresql-9.2/ssl/server.key
177
client-ca.crt => /etc/postgresql-9.2/ssl/client-ca.crt
178
client-ca.crl => /etc/postgresql-9.5/ssl/client-ca.crl
179
180
h3. 2.1. Сертификаты на клиентcких машинах
181
182
Настройки для psql
183
184
ivanov_ii.crt => ~ivanov/.postgresql/postgresql.crt
185
ivanov_ii.key => ~ivanov/.postgresql/postgresql.key
186 8 Андрей Волков
server-ca.crt => ~ivanov/.postgresql/root.crt  (нужен только для sslmode=verify-full или sslmode=verify-ca)
187 5 Андрей Волков
188
petrov_pp.crt => ~petrov/.postgresql/postgresql.crt
189
petrov_pp.key => ~petrov/.postgresql/postgresql.key
190 8 Андрей Волков
server-ca.crt => ~petrov/.postgresql/root.crt  (нужен только для sslmode=verify-full или sslmode=verify-ca)
191 5 Андрей Волков
192
h2. 3. Настраиваем серверы:
193
194
h3. postgresql.conf
195
196
<pre>
197
ssl = on                                # (change requires restart)
198
ssl_ciphers = 'DHE-RSA-AES256-SHA'      # allowed SSL ciphers
199
                                        # (change requires restart)
200
ssl_prefer_server_ciphers = on          # (change requires restart)
201
ssl_cert_file = 'server.crt'            # (change requires restart)
202
ssl_key_file = 'server.key'             # (change requires restart)
203
ssl_ca_file = 'client-ca.crt'           # (change requires restart)
204
ssl_crl_file = 'client-ca.crl'          # (change requires restart)
205
</pre>
206
207
ssl_ciphers - дело вкуса
208
209
Для применения настроек потребуется перезапуск базы =(
210
Для смены содержимого серверного сертификата потребуется перезапуск базы =((
211
212
h3. pg_hba.conf
213
214
<pre>
215
# TYPE  DATABASE        USER            ADDRESS                 METHOD      [OPTIONS]
216
hostssl production      ivanov          10.10.20.20/32          md5         clientcert=1
217
hostssl production      petrov          10.10.20.50/32          md5         clientcert=1
218
</pre>
219 1 Андрей Волков
220
Для добавления пользователей достаточно попросить postgres перечитать настройки.
221 8 Андрей Волков
222
h2. 4. Настраиваем клиентов:
223
224 14 Андрей Волков
h3. 4.1. psql
225
226 8 Андрей Волков
*psql -U ivanov_ii -h myserver1.example.com -d "dbname=production sslmode=verify-full"*
227
228
Если вместо DNS имени указать IP(55.66.77.88), то будет ошибка вида
229
230
<pre>
231
psql: server certificate for "myserver2.example.com" does not match host name "55.66.77.88"
232
</pre>
233
234
Если иначе никак, то можно более слабый режим проверки доверия клиента серверу (verify-ca)
235
236
*psql -U petrov_pp -h 55.66.77.88 -d "dbname=production sslmode=verify-ca"*
237
238
В этом случае если у вас несколько серверов смотрят во внешний мир через один IP маршрутизатора, но с разными портами, есть риск, нечаянно, подключиться не к тому серверу.
239 14 Андрей Волков
240
h3. 4.2. pgadmin3
241
242
!cut-2016-11-10_17-08-52_Un7NIqZdQgd.png!
243 9 Андрей Волков
244 15 Андрей Волков
!cut-2016-11-10_17-12-43_ZIzrfBCtZHf.png!
245
246
+Для параноиков:+
247
248
Сжатие SSL Compression уязвимо к атаке CRIME
249
https://threatpost.com/crime-attack-uses-compression-ratio-tls-requests-side-channel-hijack-secure-sessions-091312/77006/
250
251 13 Андрей Волков
h2. 5. Отзыв сертификатов:
252 1 Андрей Волков
253 13 Андрей Волков
+Пополняем список отозванных сертификатов:+
254
255 1 Андрей Волков
*openssl ca -config openssl.cnf -cert client-ca.crt -keyfile client-ca.key -revoke ivanov_ii.crt*
256 13 Андрей Волков
*openssl ca -config openssl.cnf -cert client-ca.crt -keyfile client-ca.key -revoke petrov_pp.crt*
257
258
+Перегенерируем crl файл:+
259
260 11 Андрей Волков
*openssl ca -config openssl.cnf -cert ca.crt -keyfile ca.key -gencrl -out ca.crl*
261
262 12 Андрей Волков
+Самое печальное:+
263
264 11 Андрей Волков
Для того чтобы postgres перечитал файл отозванных сертификатов, необходимо перезапустить postgres.
265
266
Потому, доступ лучше забирать сначала через pg_hba.conf
267 1 Андрей Волков
А отзыв сертификата применить при очередном плановом перезапуске базы
268 11 Андрей Волков
269 12 Андрей Волков
+Сообщение на стороне клиента:+
270 11 Андрей Волков
271
<pre>
272
psql: SSL error: sslv3 alert certificate revoked
273
</pre>