Easy-RSA index.txt, серийный номер и дубликаты

Easy-RSA index.txt, серийный номер и дубликаты

У нас есть более 700 сертификатов, сгенерированных для использования OpenVPN с помощью Easy-RSA 2. Я не знаю, как это произошло (подозреваю, что кто-то удалил один раз index.txt, serialили и то, и другое), но более половины сгенерированных сертификатов имеют одинаковые серийные номера. Кроме того, оригинал index.txtсодержит только половину всех сертификатов (последнюю половину), не включая предыдущие.

Итак, новые сертификаты можно сделать, это нормально. Но когда я пытаюсь отозвать сертификат, которого нет в index.txt, у меня возникает ошибка.

Я попробовал воссоздать index.txtпо скрипту:

    for cert in *.crt
do
  echo "-> $cert"
  enddate=`openssl x509 -enddate -noout -in $cert | sed 's/notAfter=//' | awk '\
    { year=$4-2000;
      months="JanFebMarAprMayJunJulAugSepOctNovDec" ;
      month=1+index(months, $1)/3 ;
      day=$2;
      hour=substr($3,1,2) ;
      minutes=substr($3,4,2);
      seconds=substr($3,7,2);
      printf "%02d%02d%02d%02d%02d%02dZ", year, month, day, hour, minutes, seconds}'`

  serial=`openssl x509 -serial -noout -in  $cert  |sed 's/serial=//'`
  subject=`openssl x509 -subject -noout -in  $cert  |sed 's/subject= //'`

  echo -e "V\t$enddate\t\t$serial\tunknown\t$subject" >>index.txt
done

Он считывает сертификаты один за другим, получает их данные и заполняет новые index.txt. Все вроде бы в порядке.

Но, согласно верхнему тексту, скрипт заполняет его сертификатами, которые имеют одинаковые серийные номера. Так что, с этим вновь созданным сертификатом index.txtя не могу ничего сделать с сертификатами (создать, отозвать и т. д.)

Вопрос: есть ли возможность восстановить index.txtбазу, если у меня есть все сертификаты? Или, может быть, как-то изменить серийный номер сертификата (простое изменение заголовка *.crtфайла ничего не даст - серийный номер останется старым при запросе openssl)

Если нет - мне нужно только отозвать сертификаты, которых нет в index.txt, могу ли я сделать это без index.txtбазы?

решение1

У нас более 700 сертификатов... более половины сгенерированных сертификатов имеют одинаковый серийный номер... исходный index.txt содержит только половину всех сертификатов (последнюю половину), не считая предыдущих.

Я попытаюсь указать вам правильное направление, но, вероятно, не смогу довести это до конца, поскольку я не настроил тестовую установку и не воспроизвел проблему. Заранее приношу извинения.

Если вам нужен более подробный обзор выпуска сертификата в закрытой PKI, см.Как подписать запрос на подпись сертификата в вашем центре сертификации?В нем объясняется, как бы вы делали все вручную, если бы Easy-RSA не делал этого за вас.

Еще один важный документ —RFC 4158, Инфраструктура открытых ключей Internet X.509: Построение пути сертификации. Это__the__документ, который объясняет, что такое соответствия, и как можно использовать кортежи, такие как {Issuer Distinguished Name,Serial Number}или {Subject Distinguished Name,Public Key Identifier}для сравнения двух сертификатов на эквивалентность. OpenSSL использует этот документ для сопоставления. Также см. раздел 3.5.15,«Соответствие отличительного имени конечной точки (DN)»и раздел 3.5.12,«Совпадение идентификаторов ключей (KID)».


Серийные номера должны быть уникальными. Это проблема, которую нужно преодолеть.Отличительные имена субъектов (DN)— это другая история. Если у вас openssl.cnfесть unique_subject=yes, то они не могут быть продублированы. Если unique_subject=no, то DN могут быть продублированы.

Я думаю, вам нужно сделать несколько вещей. Во-первых, используйте современную или обновленную версию утилит OpenSSL. Здесь «современная» означает одну из последних версий 1.0.2 или 1.1.0. В предыдущих версиях утилиты были тонкие проблемы с сопоставлением имен и серийных номеров.

Во-вторых, проверьте свой файл конфигурации (обычно, openssl.cnfно вы можете использовать другой, возможно, скопированный файл с помощью -config filename) и запишите соответствующие настройки, такие как serial.txtи unique_subject=no. Я считаю, что это соответствующие настройки [CA_Default]из openssl.cnf:

base_dir       = .
certificate    = $base_dir/cacert.pem  # The CA certifcate
private_key    = $base_dir/cakey.pem   # The CA private key
new_certs_dir  = $base_dir             # Location for new certs after signing
database       = $base_dir/index.txt   # Database index file
serial         = $base_dir/serial.txt  # The current serial number
unique_subject = no                    # Allow reuse of subjects

В-третьих, сделайте резервную копию всего, особенно важных данных, таких как index.txtи serial.txt.

В-четвертых, создайте список сертификатов, которые вы хотите отозвать. В списке могут быть записи типа имен файлов - john-doe-vpn.pem. Переместите их в отдельную папку, если хотите. Предпочтительно, чтобы каждый имел уникальный серийный номер, и все они ДОЛЖНЫ иметь одинаковое имя эмитента; функции openssl caи ocspне могут обрабатывать более одного эмитента одновременно, хотя для протокола OCSP это возможно.

Пятое, создайте новый, index.txtсодержащий строку для каждого серийного номера. Один из подходов — извлечь тему, серийный номер и срок действия из каждого файла сертификата, как в скрипте, который вы опубликовали, хотя вы можете свернуть большую часть работы оболочки в один openssl и один awk на сертификат:

for f in *files*; do 
  openssl x509 -noout -enddate -serial -subject -in $f \
  | awk 'BEGIN{FS="=";OFS="\t"} /^serial/{num=$2} /^subject/{sub=$2} 
      /^notAfter/{split($2,a,/ /);mon=index(months,a[1])/3+1;day=a[2]...exp=sprintf(...)}
      END{print "V",exp,"",num,sub}' >>index.txt
done

Если сложно (надежно) удалить дубликаты серийных номеров заранее, вы можете поместить все данные, а затем удалить дубликаты с помощью awk -F'\t' '!already[$4]++'или sort -t$'\t' -k4,4 -uили аналогичного метода.

Другой подход, доступный в версии 1.0.2 и выше, но задокументированный только в версии 1.1.0, заключается в использовании openssl ca [-config conffile] -valid certfileдля автоматического извлечения. Но -validэто излишне загружает закрытый ключ CA каждый раз, поэтому, если ваш закрытый ключ зашифрован паролем, что является хорошей практикой, это будет означать, что вам придется вводить пароль снова и снова; для экономии времени временно замените настоящий ключ CA и сертификат на незашифрованный ключ и соответствующий, но в остальном поддельный (вероятно, самоподписанный) сертификат. -validне запишет дублирующую серийную запись, поэтому вам не нужно беспокоиться об их исключении или удалении.

Введите в serialфайл значение, котороепо меньшей меренаивысшее значение любого ранее выданного сертификата; если вы хотите перейти к следующему 10000или 1000000или чему-то еще, чтобы быть в безопасности и, возможно, также более ясным, это нормально. Вам может потребоваться установить unique_subject=noв этой точке.

Шестое, отметьте каждый сертификат (серийный) в indexфайле как отозванный. Вы можете пройтись по файлам сертификатов, используя openssl ca -revokeon each, но проще просто использовать awk, например:

awk -F'\t' -vOFS='\t' '{$1="R"; $3="161101000000Z"}' <index.txt >temp && mv temp index.txt
# if you want, you can add a comma and a reason, see man ca or 
# online at https://www.openssl.org/docs/manmaster/man1/ca.html
# under -crl_reason. But there isn't a code for 'CA stupid', and 
# in practice the reason doesn't really matter to reliers except 
# you should't use hold or remove (latter noted in the man) 

В-седьмых, сгенерируйте CRL из этого indexи openssl ca -gencrl [-crldays n] [-out file]/или настройте ответчик OCSP с его помощью, если (какой-либо из) старых сертификатов указывал расширение OCSP.

В-восьмых, как только вы распространите CRL и/или начнете работу (нового) ответчика OCSP,всесертификаты с затронутыми серийными номерами отзываются и приведут к сбою связи, если они используются (и должным образом проверены). Еслилюбойдублированных серийных номеров находятся в сертификатах, которые ваши системы все еще используют, их необходимо сначала заменить. Если у вас все еще есть файлы запросов (CSR) из систем, использующих затронутые сертификаты, вы можете просто повторно выпустить openssl ca [-config conffile] [-in reqfile | -infiles reqfile...]и отправить новые сертификаты в соответствующие системы и попросить операторов этих систем установить их. В противном случае вам сначала нужно, чтобы оператор каждой системы отправил вам CSR, который может быть тем, который они ранее использовали (и сохранили), или новым, который они сгенерировали.

Наконец, восстановите все «хорошие» записи (серийные номера, которые вы не отозвали) из старого indexфайла, объединив их с новыми записями для замены сертификатов, выданных в #8 выше. Если вы используете ответчик OCSP (см. выше), вы также должны сохранить отозванные записи; это не имеет значения, но, вероятно, проще. Делатьнетвосстановить старое значение, serialесли оно ниже самого высокого старого сертификатаилинаивысший новый заменяющий сертификат, вместо этого позвольте ему продолжать увеличиваться от нового значения.


Относительно for-loopдат и печати:

hour=substr($3,1,2) ;
minutes=substr($3,4,2);
seconds=substr($3,7,2);
printf "%02d%02d%02d%02d%02d%02dZ", year, month, day, hour, minutes, seconds}'`

Даже не беспокойтесь о датах. Если они просрочены, их нельзя использовать, если ваш PKI функционирует нормально. Если вам от этого станет легче, то удалите закрытый ключ, связанный с сертификатом и открытым ключом.

Все, что вас волнует, это список сертификатов для отзыва, их серийный номер и отличительное имя. Здесь ваш список будет состоять из таких сертификатов, как (1) увольняющийся сотрудник, который имеет непросроченный сертификат и закрытый ключ (т. е. сотрудник уходит на пенсию или уволен); (2) сотрудник, который потерял устройство (т. е. закрытый ключ находится в свободном доступе); и т. д.


Другой вариант, который у вас есть... Сжечь существующий PKI до основания и начать заново. В этом случае шаг (1) — отозвать корневой CA и все промежуточные/подчиненные CA. Затем выбросить закрытый ключ. Шаг (2) — создать новый корневой CA, выпустить новые промежуточные/подчиненные CA и, наконец, выпустить новые сертификаты конечных субъектов. Для шага (2) вы даже можете станцевать танец подписи.

Хотите верьте, хотите нет, но OpenStack использует эту стратегию (или рассматривал возможность ее использования). Это своего рода «эфемерный PKI», который должен оставаться достаточно долго, чтобы удовлетворить ваши потребности; а затем быть отброшенным, когда что-то пойдет не так.

Ради смеха вы можете посмотреть Питера ГутманаИнженерная безопасность. Он безжалостен, когда дело касается PKI и публичных центров сертификации.

Связанный контент