Как научить 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
Что нам может потребоваться из софта
- собственно git
- браузер - в статье я буду описывать вариант для chromium
- notepad++ или любой другой редактор который аккуратно относится кодировкам и символам переноса строк
- openssl - опционально. можно посмотреть информацию о сертификатах
- 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 репозитория к дальнейшему использованию
- заходим браузером на адрес, и вне зависимости от того выдает он ошибку подключения или нет - открываем на просмотр сертификат
- Переходим на вкладку с цепочкой сертификации, и ищем CA сертификат (самый верхний в цепочке). открываем его на просмотр
- Переходим на вкладку 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!