Как научить git доверять незнакомому CA сертификату а не выключать верификацию SSL

Мануал сделан под windows но работать должен работать и с *nix, использовать мы будем openssl, который есть везде и менее глючный чем schannel.

Собственно как выглядит ошибка

C:\Git>git clone https://domain/gitrep/
Cloning into 'gitrep'...
fatal: unable to access 'https://domain/gitrep/': SSL certificate problem: unable to get local issuer certificate

Что нам может потребоваться из софта

  1. собственно git
  2. браузер - в статье я буду описывать вариант для chromium
  3. notepad++ или любой другой редактор который аккуратно относится кодировкам и символам переноса строк
  4. openssl - опционально. можно посмотреть информацию о сертификатах
  5. keytool из jdk или jre, что бы прочитать файл со связкой сертификатов

Как подтвердить ошибку

C:\Git>openssl s_client -connect domain:443
CONNECTED(00000194)
depth=0 C = XX, ST = Xxxxxx, O = Xxxxxxxxx, OU = Xxxxxxxxx, CN = xxxxxxxx
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = XX, ST = Xxxxxx, O = Xxxxxxxxx, OU = Xxxxxxxxx, CN = xxxxxxxx
verify error:num=21:unable to verify the first certificate
verify return:1

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

выполняем команду в git и находим расположение хранилища доверенных сертификатов:

C:\Git\>git config --system --list
http.sslcainfo=C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
http.sslbackend=openssl
diff.astextplain.textconv=astextplain
filter.lfs.clean=git-lfs clean -- %f
filter.lfs.smudge=git-lfs smudge --skip -- %f
filter.lfs.process=git-lfs filter-process --skip
filter.lfs.required=true
credential.helper=manager

Мы видим что git хранит цепочку сертификатов в файле C:\Program Files\Git\mingw64\ssl\certs

ca-bundle.crt

проверим что выдаст openssl:

C:\Git>openssl s_client -connect domain:443 -CAfile C:\Program Files\Git\mingw64\ssl\certs\ca-bundle.crt
CONNECTED(00000194)
depth=0 C = XX, ST = Xxxxxx, O = Xxxxxxxxx, OU = Xxxxxxxxx, CN = xxxxxxxx
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = XX, ST = Xxxxxx, O = Xxxxxxxxx, OU = Xxxxxxxxx, CN = xxxxxxxx
verify error:num=21:unable to verify the first certificate
verify return:1

мы подтвердили - openssl не может подтвердить git корректность сертификатов, т.к. не знает корневого издателя сертификата.

При желании мы можем сами прочитать что лежит в ca-bundle.crt используя keytool, т.к. выдача будет длинная сразу стоит отправить её в текстовый файл:

C:\Git>keytool -printcert -v -file C:\Program Files\Git\mingw64\ssl\certs\ca-bundle.crt > certs_info.txt

Начало файла будет выглядеть приблизительно так:

Certificate[1]:
Owner: C=ES, O=ACCV, OU=PKIACCV, CN=ACCVRAIZ1
Issuer: C=ES, O=ACCV, OU=PKIACCV, CN=ACCVRAIZ1
Serial number: 5ec3b7a6437fa4e0
Valid from: Thu May 05 13:37:37 MSK 2011 until: Tue Dec 31 12:37:37 MSK 2030
Certificate fingerprints:
         MD5:  D0:A0:5A:EE:05:B6:09:94:21:A1:7D:F1:B2:29:82:02
         SHA1: 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17
         SHA256: 9A:6E:C0:12:E1:A7:DA:9D:BE:34:19:4D:47:8A:D7:C0:DB:18:22:FB:07:1D:F1:29:81:49:6E:D1:04:38:41:13
Signature algorithm name: SHA1withRSA
Subject Public Key Algorithm: 4096-bit RSA key
Version: 3

Extensions:
...

в файле будет весь список CA сертификатов которым Git доверяет.

Как сделать что бы Git начал доверять CA сертификату сервера

Подготовим CA сертификат нашего https репозитория к дальнейшему использованию

  1. заходим браузером на адрес, и вне зависимости от того выдает он ошибку подключения или нет - открываем на просмотр сертификат
  2. Переходим на вкладку с цепочкой сертификации, и ищем CA сертификат (самый верхний в цепочке). открываем его на просмотр
  3. Переходим на вкладку Details/Состав для CA сертификата. нажимаем кнопку Copy to File/Копировать в файл в мастере выбираем X.509 (.CER) в Base64 кодировке. сохраняем файл например с названием ca.crt

Альтернативно можно выгрузить его с помощью openssl, т.к. в его выдаче при выполнении подключения мы получаем сертификат сервера (или цепочку сертификатов) . сохранив их в файл .cer можно с помощью оснастки так же найти корневой сертификат

Подготавливаем цепочку доверенных сертификатов к изменению

выполняем команду в git и находим расположение хранилища доверенных сертификатов:

Ранее мы уже нашли где git хранит свою цепочку доверенных ssl CA сертификатов: C:\Program Files\Git\mingw64\ssl\certs

Мне не понравилась папка в которой расположен текущий поэтому я переместил файл и затем указал новый путь командой:

git config --system http.sslcainfo C:/Git/_certs/ca-bundle.crt

Если вы не являетесь администратором машины, или хотите сохранить изменения только для себя, команда немного изменится:

git config --global http.sslcainfo C:/Git/_certs/ca-bundle.crt

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

теперь открываем текстовым редактором (крайне желательно - не notepad! и желательно - делайте резервные копии!) наш ca-bundle.crt видим сертификаты

-----BEGIN CERTIFICATE-----
куча символов в Base64
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
еще одна куча
-----END CERTIFICATE-----
...

открываем файл ca.crt и извлекаем из него текст нашего CA сертификата

аккуратно копируем сертификат из ca.crt в конец файла ca-bundle.crt так что бы не сломать структуру файла, и сохраняем.

можем проверить что все ок последовательно теми же командами что ошибку помогли локализовать:

C:\Git>keytool -printcert -v -file C:\Git\_certs\ca-bundle.crt > certs_info.txt

В конце файла последним мы должны увидеть данные нашего добавленного сертификата

далее проверим что openssl не выдаст больше ошибку о том что не может подтвердить ssl сертификат сервера:

C:\Git>openssl s_client -connect domain:443 -CAfile C:\Git\_certs\ca-bundle.crt
CONNECTED(00000194)
depth=0 C = XX, ST = Xxxxxx, O = Xxxxxxxxx, OU = Xxxxxxxxx, CN = xxxxxxxx
verify return:1
depth=0 C = XX, ST = Xxxxxx, O = Xxxxxxxxx, OU = Xxxxxxxxx, CN = xxxxxxxx
verify return:1

ошибки исправлены - теперь нужно снова попробовать склонировать git-репозиторий.

PROFIT!


786 Words

2019-11-08 07:22 +0300