Как извлечь корневой и подчиненный ЦС из цепочки сертификатов в Linux?

Использование Sed
sed -e 's/=\([^,]*\)/="\1"/g' file.txt

Использование Awk

awk -F, -v OFS=, '{for (f=1;f<=NF;f++) {sub(/=/,"&\"",$f); sub(/$/,"\"",$f)}; print}' file.txt

Или, короче:

awk -F, -v OFS=, '{for (f=1;f<=NF;f++) {gsub(/=|$/,"&\"",$f)} print}' file.txt 

Еще короче:

awk -F, -v OFS=, '{for (f=1;f<=NF;f++) {gsub(/=|$/,"&\"",$f)}} 1' file.txt 

Использование ex

Ex предназначен для редактирования файла , но вы можете предварительно просмотреть изменения, не сохраняя их обратно в файл, вот так:

ex -sc '%s/=\([^,]*\)/="\1"/g | %p | q!' file.txt 

Чтобы действительно внести изменения и сохранить их в файл, используйте:

ex -sc '%s/=\([^,]*\)/="\1"/g | x' file.txt

Однако, если вы дадите шаблон, который нигде не встречается в файл (например, нигде в файле нет = ), то Ex не выйдет автоматически. Таким образом, для большей надежности я обычно использую printf для передачи команд в Ex:

printf '%s\n' '%s/=\([^,]*\)/="\1"/g' %p | ex file.txt

И для сохранения изменений:

printf '%s\n' '%s/=\([^,]*\)/="\1"/g' x | ex file.txt
25
14.06.2017, 16:10
4 ответа

С веб-сайта вы можете сделать следующее:

openssl s_client -showcerts -verify 5 -connect stackexchange.com:443 < /dev/null

Это покажет цепочку сертификатов и все сертификаты, представленные сервером.

Теперь, если я сохраню эти два сертификата в файлы, я могу использовать openssl verify:

$ openssl verify -show_chain -untrusted dc-sha2.crt se.crt 
se.crt: OK
Chain:
depth=0: C = US, ST = NY, L = New York, O = "Stack Exchange, Inc.", CN = *.stackexchange.com (untrusted)
depth=1: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA (untrusted)
depth=2: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA

Опция -untrusted используется для предоставления промежуточных сертификатов; se.crt — сертификат для проверки. Результат depth=2 был получен из доверенного системного хранилища ЦС.

Если у вас нет промежуточных сертификатов, вы не сможете выполнить проверку. Именно так работает X.509.

В зависимости от сертификата он может содержать URI для получения промежуточного звена. Например, openssl x509 -in se.crt -noout -text содержит:

        Authority Information Access: 
            OCSP - URI:http://ocsp.digicert.com
            CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt

Этот URI "CA Issuers" указывает на промежуточный сертификат (в формате DER, поэтому вам нужно использовать openssl x509 -inform der -in DigiCertSHA2HighAssuranceServerCA.crt -out DigiCertSHA2HighAssuranceServerCA.pem, чтобы преобразовать его для дальнейшего использования OpenSSL).

Если вы запустите openssl x509 -in /tmp/DigiCertSHA2HighAssuranceServerCA.pem -noout -issuer_hash, вы получите 244b5494, который вы можете найти в системном корневом хранилище ЦС по адресу . ]/etc/ssl/certs/244b5494.0 (просто добавьте .0 к имени).

Я не думаю, что существует хорошая и простая команда OpenSSL, которая сделает все это за вас.

63
27.01.2020, 19:40

tl;dr -один лайнер bash magic для сброса всех сертификатов в цепочке

openssl s_client -showcerts -verify 5 -connect wikipedia.org:443 < /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; out="cert"a".pem"; print >out}'; for cert in *.pem; do newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem; echo "${newname}"; mv "${cert}" "${newname}"; done

Объяснение в 2 шага

Для сброса всех сертификатов в цепочке в текущий каталог какcert${chain_number}.pem:

openssl s_client -showcerts -verify 5 -connect your_host:443 < /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; out="cert"a".pem"; print >out}' 

Бонусный -трек, чтобы переименовать их в их обычное имя:

for cert in *.pem; do newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem; mv $cert $newname; done
42
27.01.2020, 19:40

Я обнаружил, что с параметром -verify 5openssl углубляется в цепочку, показывая все сертификаты, даже те, которые не включены в развертывание вашего сертификата.

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

openssl s_client -showcerts -partial_chain -connect YOUR_ENDPOINT:443 < /dev/null |less
5
27.01.2020, 19:40

Описанное выше не сработало, когда я использовал сертификат Lets Encrypt Free Wildcard.

Чтобы быть более конкретным:
У меня есть Kubernetes Cluster + Ingress Controller, который настроен с использованием бесплатного сертификата Lets Encrypt для *.mydomain.dev, на нем размещены следующие 2 доменных имени:

  • grafana.mydomain.dev
  • prometheus.mydomain.dev

Мне пришлось добавить флаг имени сервера -после этого сайта:https://community.letsencrypt.org/t/where-can-i-download-the-trusted-root-ca-certificates-for-lets-encrypt/33241/2

export DOMAIN=grafana.mydomain.dev
openssl s_client -showcerts -verify 5 -connect $DOMAIN:443 -servername $DOMAIN < /dev/null 2> /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; print}'

Я также настроил цепочку, чтобы получить полный сертификат + промежуточный код + корень для стандартного вывода и скрыть шум стандартного вывода.

На самом деле... При тестировании я обнаружил, что это не дает мне ЦС...openssl s_client -showcerts -verify 5 -connect letsencrypt.org:443 < /dev/null 2> /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; print}'

curl https://letsencrypt.org/certs/isrgrootx1.pemДает другое значение (, и при тестировании некоторых вещей это значение работает.)

0
26.10.2021, 18:51

Теги

Похожие вопросы