LINUX.ORG.RU
ФорумAdmin

Как правильно создать доверенный самоподписанный SSL-сертификат для Web-ресурса

 , , ,


0

1

Переадресую тему с Как исправить ошибку CORS?

Читать с конца, т.к. вначале обсуждается проблема с CORS, причина которой в проблеме с сертификатом.

Коротко повторю: По инструкции: https://coderoad.ru/34807073/%D0%9A%D0%B0%D0%BA-%D1%81%D0%B3%D0%B5%D0%BD%D0%B5%D1%80%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-%D1%81%D0%B5%D1%80%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D1%8B-cowboy-SSL

создал структуру подкаталогов в приложении, описанную в инструкции и все описанные сертификаты. В приложении (Erlang/OTP 23, https-сервер Cowboy), использую конечный сертификат из каталога end_cert, подключаю вот так

	  {cacertfile, PrivDir ++ "/ssl/end_cert/end.csr"},
	  {certfile, PrivDir ++ "/ssl/end_cert/end.crt"},
	  {keyfile, PrivDir ++ "/ssl/end_cert/end.key"}

полный код функции

%% API.
start(_Type, _Args) ->
	Dispatch = cowboy_router:compile([
		{'_', [
			{"/"            , cowboy_static, {priv_file, upserver, "index.html"}},
			{"/assets/[...]", cowboy_static, 
{priv_dir , upserver, "assets"}},
			{"/upload"      , upload_handler, []}
		]}
	]),
	PrivDir = code:priv_dir(upserver),
	{ok, _} = cowboy:start_tls(https, [
	     	  {port, 8888},
		  {cacertfile, PrivDir ++ "/ssl/end_cert/end.csr"},
		  {certfile, PrivDir ++ "/ssl/end_cert/end.crt"},
		  {keyfile, PrivDir ++ "/ssl/end_cert/end.key"}
		], #{env => #{dispatch => Dispatch}}),
	upserver_sup:start_link().

в каталоге …/priv/ssl/ созданы 3 подкаталога, по вышеупомянутой инструкции. Вот, все файлы

$ ls . -R
.:
end_cert  inter_ca  root_ca

./end_cert:
end.crt  end.csr  end.key

./inter_ca:
inter.crt  inter.csr  inter.key  inter.srl  v3x509extensions.txt

./root_ca:
180d30a1.0  rootca.key  rootca.pem  rootca.srl

При предварительной верификации сертификата, находясь в каталоге ssl

openssl s_client -servername upserver:8888 -connect upserver:8888 -CApath root_ca -verify 5

получаю ошибку

verify depth is 5
CONNECTED(00000003)
depth=0 C = RU, ST = State, L = City, O = Company, OU = Department, CN = upserver, emailAddress = support@firma.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = RU, ST = State, L = City, O = Company, OU = Department, CN = upserver, emailAddress = support@firma.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:C = RU, ST = State, L = City, O = Company, OU = Department, CN = upserver, emailAddress = support@firma.com
   i:C = RU, ST = State, L = City, O = Company, OU = Department, CN = inter.upserver, emailAddress = support@firma.com
---
Server certificate
-----BEGIN CERTIFICATE-----
... удалено
opV7k19LRNPAKksKqg==
-----END CERTIFICATE-----
subject=C = RU, ST = State, L = City, O = Company, OU = Department, CN = upserver, emailAddress = support@firma.com

issuer=C = RU, ST = State, L = City, O = Company, OU = Department, CN = inter.upserver, emailAddress = support@firma.com

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1481 bytes and written 385 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 21 (unable to verify the first certificate)
---
read:errno=0

Проблемы следующие:

  1. Почему CONNECTED(00000003), должно быть CONNECTED(00000004) ?
  2. Почему везде depth=0, когда должно быть 2,1,0 ?
  3. Почему получаются только 2 уровня, а не три ?
  4. Почему на каждом уровне получаю ошибки ?
verify error:num=20:unable to get local issuer certificate
verify error:num=21:unable to verify the first certificate
No client certificate CA names sent

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

Смотрите также другие выхлопы в исходном посте.

Как всё это исправить?



Последнее исправление: MariaRTI (всего исправлений: 5)

В CA должна быть вся цепочка, либо нужно использовать AIA fetching, который в OpenSSL утилитах вроде даже и не реализован.

Альтернатива - указать всю цепочку на сервере, но для этого сервер должен уметь её отсылать (TLS это позволяет, а что там у тебя на сервере я х3 в ковбоях не разбираюсь).

faq2
()
Ответ на: комментарий от faq2

Точнее, правильно будет как раз на сервере всю цепочку отсылать либо использовать AIA fetching для экономии трафика и ускорения соединений.

faq2
()

В случае x509(а это твой случай) достаточно конкатенировать файлы сертификатов из цепочки, только не помню начиная с корневого или с листового.

faq2
()
Ответ на: комментарий от faq2

В инструкции пишут что начиная с промежуточного к листовому

cat ../inter_ca/inter.crt end.crt | openssl verify -CApath ../root_ca

, верификация по инструкции дает OK

stdin: OK

, но теоретически это неправильно, должно быть наоборот - от листового к промежуточному и корневому Пробовал все варианты (и частичные и полные, в разном порядке), листинги разные, конечная ошибка одинаковая - нет CA сертификата

Вот, например, вариант по инструкции. Склеиваем 2 сертификата, тот вариант, который при верификации дает OK

cat ../inter_ca/inter.crt end.crt > end.list.crt

Меняем имя сертификата в исходнике на end.list.crt Перезапускаем сервер Проверяем

openssl s_client -servername upserver:8888 -connect upserver:8888 -CApath root_ca -verify 5

старые ошибки пропадают, dept=1, 0 Но появляются новые

140246799004800:error:0407E086:rsa routines:RSA_verify_PKCS1_PSS_mgf1:last octet invalid:../crypto/rsa/rsa_pss.c:88:
140246799004800:error:1417B07B:SSL routines:tls_process_cert_verify:bad signature:../ssl/statem/statem_lib.c:505:

а в конце

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2365 bytes and written 312 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

Хотя Verification: OK и Verify return code: 0 (ok) Но проблема с сертификатом «No client certificate CA names sent» и ошибка CORS остаются как раньше

MariaRTI
() автор топика
Последнее исправление: MariaRTI (всего исправлений: 1)
Ответ на: комментарий от MariaRTI

Новые ошибки наводят на мысль, что склеивать файлы в данном случае нельзя, т.к. содержимое результирующего файла формально отличается от двух исходников, и , last octet и signature, которые записаны в хешах или где-то там, становятся инвалидными

И да, у меня TLS-сервер, он должен поддерживать всё что по стандарту положено.

MariaRTI
() автор топика
Последнее исправление: MariaRTI (всего исправлений: 2)
Ответ на: комментарий от MariaRTI

Если это x509 - то всё должно быть валидно, оно расценивается не как сертификат а как хранилище сертификатов.

faq2
()
Ответ на: комментарий от MariaRTI

Вопрос по какому именно стандарту и что из этого поддерживает клиент :)

Попробуй для начала завести свой конфиг с openssl s_server.

Ты кстати скормил же серверу цепочку по итогу вместо сертификата? Проверить можно посмотрев server hello в wireshark.

faq2
()
Ответ на: комментарий от faq2

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

MariaRTI
() автор топика

Зачем ты полез в экзотику, ламер?

anonymous
()
Ответ на: комментарий от faq2

Теоретически, вроде так правильно, только теоретически, но практически верификация в таком варианте не проходит.

MariaRTI
() автор топика
Ответ на: комментарий от faq2

man openssl s_server.

«The s_server command implements a generic SSL/TLS server which listens for connections on a given port using SSL/TLS.»

Зачем это мне в данном случае?

MariaRTI
() автор топика
Ответ на: комментарий от faq2

Всё же так правильнее, сделал так.

cat end.crt ../inter_ca/inter.crt ../root_ca/rootca.pem > end.list.crt

Давайте разберемся куда эту цепочку вставлять, т.к. что-то стало значительно лучше, а что-то вообще перестало работать. Долго объяснять.

Вот вычищенный и упрощенный код , по смыслу понятно что есть что.

cacertfile = /ssl/end_cert/end.csr  слева CA-переменная, справа -CERTIFICATE REQUEST файл
certfile = /ssl/end_cert/end.list.crt слева переменная сертификата, справа - цепочка сертификатов от end + int + root
keyfile = /ssl/end_cert/end.key  приватный ключ

Вы говорите, что цепочка сертификатов должна быть в CA, но там обычно, в примерах, CERTIFICATE REQUEST, а куда девать CERTIFICATE REQUEST ?

сейчас такая ситуация

  • на сервере в командной строке, получаю верификация - OK, несколькими способами, казалось бы в таком случае всё замечательно должно работать!

  • в логе своего сервера получаю TLS server: In state wait_finished received CLIENT ALERT: Fatal - Certificate Unknown

Хотя это всегда было, но не было фатально. Но сейчас перестали проходить загрузки файлов

а на клиенте в браузере failed ERR_CERT_AUTHORITY_INVALID , вместо ошибки CORS

MariaRTI
() автор топика
Последнее исправление: MariaRTI (всего исправлений: 1)
Ответ на: комментарий от MariaRTI

Чтобы отладить конфигурацию на референсном ПО.

faq2
()
Ответ на: комментарий от MariaRTI

Поставь для проверки соединения и настроек CA вместо ковбоя openssl s_server. Это позволит исключить значительную часть системы и сосредоточиться на поиске проблемы в настройках CA.

faq2
()

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

anonymous
()
Ответ на: комментарий от anonymous

Эх, зря ты влез каментом, анон. Предыдущий в качестве завершающего аккорда смотрелся просто восхитительно. Типа БАМММММ, крышка рояля захлопнута, все присутствующие откидываются на спинки стульев с чувством глубокого катарсиса.
Романс окончен, воздух плавал важно над струнами, стремясь покинуть зал.

thesis ★★★★★
()
Последнее исправление: thesis (всего исправлений: 1)
Ответ на: комментарий от MariaRTI

картинка_с_котом-стендапером.jpg

anonymous
()
Ответ на: комментарий от anonymous

Он - владелец удостоверяющего центра?!

anonymous
()
Ответ на: комментарий от thesis

Эх, зря ты влез каментом, анон.

Начиная со знака вопрос идёт сиквел – «Как сертификат 2».

anonymous
()
Ответ на: комментарий от anc

Ну, «бадум-тссс» ниже гораздо лаконичнее)

thesis ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.