4 Июнь 2017

Технология DANE — безопасность через DNS

DANE technology — security thru DNS

Вопросы безопасности в целом, и проблемы аутентификации в частности, уже давно являются главной проблемой функционирования сети Интернет. К настоящему времени разработана масса способов, протоколов и стандартов, призванных сделать работу в глобальном киберпространстве надёжной и защищённой от различного рода угроз. К примеру, одним из самых известных и широкоупотребимых механизмов обеспечения безопасности является протокол HTTPS, который предназначен для передачи данных, в основном, во Всемирной паутине на базе криптографических методов SSL / TLS. Последние же неотъемлемо связаны с инфраструктурой удостоверяющих центров (CA), которые через цепочку доверия посредством цифровых подписей призваны гарантировать подлинность того или иного ресурса в сети.

Если удостоверяющий центр включён в список доверенных для данного программного обеспечения, в частности браузера в случае с протоколом HTTPS, то узел сети использующий выданный этим CA сертификат заведомо признаётся подлинным и, следовательно, заслуживающим доверия. Однако, именно здесь и находится главная проблема данной системы. Пользователь вынужден слепо доверять всем сертификатам, которые такие доверенные удостоверяющие центры выдали стороннему по отношению к ним самим ресурсу. При этом, нет никаких гарантий что это было сделано с ведома самого владельца такого ресурса. Ставшие достоянием общественности в последние годы многочисленные прецеденты выпуска известными удостоверяющими центрами сертификатов с серьёзными нарушениями правил их выдачи, самым громким из которых явился случай с DigiNotar, вновь поставили вопрос доверия к самой системе CA со стороны пользователей и заказчиков, а также разработку и внедрение более надёжных методов аутентификации в Интернет.

1. Технология DANE

Одним из таких методов, призванных решить проблему с участием самого владельца в процедуре удостоверения надёжности защищённого соединения с его ресурсами, и является технология DANE или DNS-based Authentication of Named Entities. DANE даёт возможность владельцу ресурса подтвердить подлинность используемого им сертификата или цифровой подписи посредством валидации через структуру системы доменных имён DNS средствами DNSSEC и, следовательно, обеспечить к нему доверие со стороны клиентов. Напомню, что ранее автор уже затрагивал тему DNSSEC в нескольких статьях о принципах функционирования и механизмах его внедрения и поддержания работоспособности.

В соответствии со стандартом RFC6698, описывающим технологию DANE, в набор ресурсных записей DNS вводится новый тип TLSA, посредством которого осуществляется ассоциация между именем хоста и используемых им сервисов в сети Интернет и удостоверяющими соединение с ними сертификатами. Создав цифровой отпечаток сертификата, разместив его в TLSA-записи и подписав зону посредством DNSSEC, владелец ресурса, тем самым, подтверждает его надёжность. Клиент при соединении с ресурсом сравнивает полученный от него сертификат по цифровому отпечатку с фигурирующим в DNS и принимает решение о том, доверять ли ему или нет.

В подходе сравнения задекларированного и реально предоставленного сертификата, DANE перекликается с технологией HTTP Public Key Pining (HPKP), которая уже была предметом публикации в рамках этого блога. Однако, в отличие от HPKP, DANE лишена главного его недостатка — отсутствия неопределённости при первом контакте с ресурсом, когда нет возможности убедиться в том, что предоставленный сертификат заслуживает доверия.

Типичная запись TLSA выглядит следующим образом.

_443._tcp.my.domain.   IN TLSA 3 0 1 06f14934d9fa4c8bc926306427aa4815c75f8af13e0dff4c40f1e10f047c7a80

В данном случае для домена my.domain в случае использования HTTPS (_443._tcp) должен использоваться конечный сертификат (первая цифра 3) с приведённым отпечатком, выполненным на основе всего сертификата целиком (вторая цифра 0) при помощи хэш-функции SHA256 (третья цифра 1).

Возможность использования конечного сертификата ресурса в качестве точки доверия приводит к, на первый взгляд, неочевидному преимуществу использования DANE — возможности использования в качестве доверенного самоподписанного сертификата! Действительно, механизм удостоверения DNSSEC сам по себе может быть признан источником доверия в связи с тем, что доменной зоной и её ресурсами так или иначе управляет сам их владелец. Таким образом, в теории отпадает необходимость в использовании сторонних удостоверяющих центров. Либо, в случае использования традиционного способа получения сертификата на стороне, как минимум, имеется ещё один независимый от CA механизм контроля за доверием выдаваемым ими сертификатам.

DANE не ограничивается лишь одним типом записи TLSA, удостоверяющей SSL / TLS сертификаты. На сегодня опеределены также ещё три расширения, которые на основе аналогичных принципов решают проблему доверия к предоставленным узлом или пользователем данным.

  • Стандарты RFC4255, RFC6594 и RFC7479 определяют DNS-запись типа SSHFP, которая служит для валидации ключей предоставляемых сервером при SSH соединении.
  • Черновик стандарта RFC7929 описывает ресурсную запись типа OPENPGPKEY, предназначенную для обмена открытыми ключами при цифровой подписи и шифрации посредством технологии PGP.
  • И, наконец, самый новый черновик стандарта draft-ietf-dane-smime, определяет запись SMIMEA служащую для аналогичных PGP целей, но по стандарту S/MIME.

Однако, именно запись TLSA на сегодня имеет наибольшую актуальность и практическую ценность, поэтому начнём опиcание практики по использованию технологии DANE именно с неё.

2. Удостоверение TLS сертификатов

2.1. Подходы

В общем случае, получить цифровой отпечаток сертификата данного хоста для указания его в TLSA записи можно как обратившись к его pem-файлу, так и непосредственно к серверу, обслуживающему данный сетевой ресурс, используя TLS. Например, для домена my.domain его генерация будет выглядеть так.

root@beta:~ # openssl x509 -in /usr/local/etc/letsencrypt/live/my.domain/cert.pem -outform DER | sha256
002bd7a8532f18362734609503625a972f96e9ff262a90a3b6cd9d3d758f0fb8

Или так.

root@beta:~ # openssl s_client -connect my.domain:443 | openssl x509 -outform DER | sha256
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = my.domain
verify return:1
002bd7a8532f18362734609503625a972f96e9ff262a90a3b6cd9d3d758f0fb8
^C

В данном случае мы обратились к HTTP-серверу по протоколу HTTPS. Однако, ничто не мешает воспользоваться тем же приёмом и обратиться, к примеру, к SMTP-серверу по протоколу STARTTLS.

root@beta:~ # openssl s_client -connect my.domain:25 -starttls smtp | openssl x509 -outform DER | sha256
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = my.domain
verify return:1
250 HELP
(stdin)= 002bd7a8532f18362734609503625a972f96e9ff262a90a3b6cd9d3d758f0fb8
^C

Ещё одним и, пожалуй, самым простым, вариантом получить уже готовую DNS-запись будет воспользоваться утилитой ldns-dane из пакета ldns.

root@beta:~ # pkg info | grep ldns
ldns-1.7.0                     Library for programs conforming to DNS RFCs and drafts
root@beta:~ # ldns-dane create my.domain 443 3 0 1
_443._tcp.my.domain. 3600    IN      TLSA    3 0 1 002bd7a8532f18362734609503625a972f96e9ff262a90a3b6cd9d3d758f0fb8

Судя по полученным отпечаткам оба интернет-сервиса используют один и тот же сертификат, выпущенный Let's Encrypt, который располагается на этой системе в файле /usr/local/etc/letsencrypt/live/my.domain/cert.pem.

Удостоверяющий центр Let's Encrypt, особенности работы с которым затрагивались автором в ряде статей, обладает некоторыми особенностями обуславливающими специфику работы с его сертификатами. Главная из них — небольшой срок действия сертификатов (в настоящее время до 90 дней) при наличии возможности их автоматической ротации. В этой связи, как и в случае с их использованием в механизме HTTP Public Key Pining, возникает вопрос выбора точки привязки в цепочке сертификатов для формирования отпечатка при реализации в рамках технологии DANE.

Наиболее простым вариантом представляется использование корневого сертификата Let's Encrypt, который используется в качестве корневого при выпуске клиентских сертификатов. Его можно увидеть первым в цепочке чуть выше под именем DST Root CA X3.

Ничто не мешает нам скачав его сформировать на его базе опечаток

root@beta:~ # fetch https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt
lets-encrypt-x3-cross-signed.pem.txt          100% of 1647  B 5765 kBps 00m00s
root@beta:~ # openssl x509 -in lets-encrypt-x3-cross-signed.pem.txt -outform DER | sha256
25847d668eb4f04fdd40b12b6b0740c567da7d024308eb6c2c96fe41d9de218d

и разместить полученных хэш в TLSA записи вида:

_443._tcp.my.domain.   IN TLSA 2 0 1 25847d668eb4f04fdd40b12b6b0740c567da7d024308eb6c2c96fe41d9de218d

Первая цифра 2 в строке говорит о том, что данный отпечаток принадлежит не конечному, а корневому сертификату.

Тогда до тех пор, покуда данный корневой сертификат будет использоваться для выпуска сертификатов Let's Encrypt, нужды в обновлении записей DANE не будет. В случае, если вы выберете этот вариант, обратите внимание на рекомендацию по использованию генерации отпечатка по Subject Public Key Info (некоторые подробности см. ниже) в качестве защиты от возможной ротации сертификата в будущем.

Однако, такой подход возвращает нас к вопросу о доверии самому CA, ведь, теоретически, ничто не мешает ему выпустить сертификат для нашего хоста без нашего ведома.

Вторым заслуживающим внимания вариантом может стать использование генерации цифрового отпечатка по CSR-сертификату и соответствующему ему в сертификате полю Subject Public Key Info (SPKI). Это достижимо при использовании опции --csr в штатном клиенте Let's Encrypt certbot. Она позволяет при каждом выпуске сертификата использовать определённый, ранее сгенерированный, CSR-сертификат, а не формировать его при каждой процедуре обновления, как это делает certbot по умолчанию.

Получить TLSA запись на базе поля SPKI можно, как вариант, воспользовавшись удобным онлайн генератором от Shumon Huque, скопировав в форму содержимое pem-файла и задав сопутствующие параметры, либо традиционным путём из командной строки.

root@beta:~ # openssl x509 -in /usr/local/etc/letsencrypt/live/my.domain/cert.pem -noout -pubkey | openssl pkey -pubin -outform DER | sha256
07e4f2f3e5deae946874fcb8e0b1b8a431832e79bd5dfd77e08668790a1dab74

Тогда DNS-запись с полученным отпечатком может выглядеть так.

_443._tcp.my.domain. IN TLSA 3 1 1 07e4f2f3e5deae946874fcb8e0b1b8a431832e79bd5dfd77e08668790a1dab74

Обратите внимание, что вторая цифра в строке 1 свидетельствует о том, что опечаток был получен на базе Subject Public Key Info, а не сертификата целиком.

И вновь говоря о недостатках такого подхода, во-первых, встаёт вопрос возможной компрометации CSR-сертификата, а, во-вторых, потребности по той или иной причине его обновления в будущем.

В связи с вышеизложенными соображениями, автор считает оптимальным использовать в качестве удостоверяемых посредством технологии DANE сертификатов именно сертификаты конечные, выдаваемые конкретным узлам. Остановимся на реализации этого варианта совместно с использованием сертификатов от Let's Encrypt.

2.2. Практическое внедрение

Прежде чем начать внедрение технологии DANE для ваших доменов следует, во-первых, развернуть и обеспечить поддержку обновления подписей DNSSEC (см., например, статью "Внедрение DNSSEC для вашего домена", а также её продолжение "Поддержка DNSSEC и ротация ключей цифровой подписи"), а, во-вторых, убедиться, что ваш DNS-сервер имеет поддержку относящихся к DANE типов ресурсных записей.

В моём случае используется DNS-сервер NSD, первичная настройка которого была ранее описана в статье "Настройка первичного DNS-сервера на базе NSD", который в полной мере эту поддержку обеспечивает, в среде FreeBSD.

root@beta:~ # uname -v
FreeBSD 11.0-RELEASE-p9 #0: Tue Apr 11 08:48:40 UTC 2017     root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC
root@beta:~ # nsd -v
NSD version 4.1.16
Written by NLnet Labs.
...

Далее, необходимо распланировать, какие интернет-сервисы и для каких хостов, включённых в сертификат, нам потребуются в виде DNS-записей для реализации технологии DANE. В частности, в нашем примере в сертификат включено несколько доменов, которые используются для обращения к различным ресурсам нашего сервера.

root@beta:~ # openssl x509 -in /usr/local/etc/letsencrypt/live/my.domain/cert.pem -text | grep DNS
                DNS:foo.my.domain, DNS:mail.my.domain, DNS:my.domain, DNS:www.my.domain

Так, foo.my.domain используется для доступа к административным страницами исключительно по протоколу HTTPS, mail.my.domain для почтовых сервисов по протоколам SMTP, IMAP4 и POP3, а хосты с именами my.domain и www.my.domain — для доступа к сайту и по защищённому и по незащищённому протоколу HTTP.

Исходя из этих сообращений сформируем адреса по стандарту DANE. При этом, ввиду того что для всех этих имён и сервисов будет использоваться один и тот же сертификат с, соответственно, одинаковым отпечатком, осуществим небольшой трюк посредством DNS-записей типа CNAME, которые буду ссылаться на TLSA запись c единым доменным именем. Такой подход позволит облегчить автоматизацию обновления DNS-зоны при новых выпусках сертификатов удостоверяющим центром.

root@foo:/usr/local/etc/nsd # cd /usr/local/etc/nsd/
root@foo:/usr/local/etc/nsd # cat zones/my.domain/my.domain.zone | grep _tlsa
_25._tcp.mail.my.domain.  IN CNAME        _tlsa.my.domain.
_465._tcp.mail.my.domain. IN CNAME        _tlsa.my.domain.
_587._tcp.mail.my.domain. IN CNAME        _tlsa.my.domain.
_993._tcp.mail.my.domain. IN CNAME        _tlsa.my.domain.
_995._tcp.mail.my.domain. IN CNAME        _tlsa.my.domain.
_443._tcp.foo.my.domain.  IN CNAME        _tlsa.my.domain.
_443._tcp.www.my.domain.  IN CNAME        _tlsa.my.domain.
_443._tcp.my.domain.      IN CNAME        _tlsa.my.domain.
_tlsa.my.domain.          IN TLSA 3 0 1   002bd7a8532f18362734609503625a972f96e9ff262a90a3b6cd9d3d758f0fb8
_tlsa.my.domain.          IN TLSA 3 0 1   6c7844bf9f56ca563cebb070a1a6d6207540636c3b50df232166838d204080b4

Как видно, перечислены порты сервисов для нашего набора доменов используемые для организации защищённого соединения в отсылке к служебному домену _tlsa.my.domain. Последний содержит две записи с двумя отпечатками двух сертификатов: используемого для удостоверения в настоящее время и выпущенного загодя второго, который будет использоваться после очередного автоматического перевыпуска. То есть здесь используется подход, аналогичный изложенному в статье "Технология HTTP Public Key Pining: внедрение и автоматизация совместно с Let's Encrypt", который позволяет избежать разрывов в аутентификации сертификатов связанных с их обновлением.

Сгенерируем для нашей зоны my.domain новый серийный номер, подпишем текущим набором ключей DNSSEC и дадим команду на её обновление DNS-серверу. Для первых двух действий используются скрипты dnsnewserial.sh и dnssignzone.sh из набора инструментов для работы с DNSSEC-зонами из статьи "Внедрение DNSSEC для вашего домена".

root@beta:/usr/local/etc/nsd # /bin/sh dnsnewserial.sh zones/my.domain/my.domain.zone
2017053000
root@beta:/usr/local/etc/nsd # /bin/sh dnssignzone.sh zones/my.domain/my.domain.zone
Kmy.domain.+006+12736 Kmy.domain.+006+44711
root@beta:/usr/local/etc/nsd # nsd-control reload my.domain
ok

В качестве первого этапа проверки правильности функционирования технологии DANE удостоверимся, что добавленные записи были корректно подписаны и доступы по запросу с использованием DNSSEC.

root@foo:/usr/local/etc/nsd # drill -D tlsa _443._tcp.my.domain
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 45897
;; flags: qr rd ra ad ; QUERY: 1, ANSWER: 5, AUTHORITY: 3, ADDITIONAL: 4
;; QUESTION SECTION:
;; _443._tcp.my.domain.   IN      TLSA

;; ANSWER SECTION:
_443._tcp.my.domain.      86400   IN      CNAME   _tlsa.my.domain.
_443._tcp.my.domain.      86400   IN      RRSIG   CNAME 6 4 86400 20170630190315 20170602190315 12736 my.domain. AH/zjSdYCoLX3JXxjWtWIJaHrsGgcMZCHNWdkzujfwcisIEVhdBwMvs=
_tlsa.my.domain.  86400   IN      TLSA    3 0 1 002bd7a8532f18362734609503625a972f96e9ff262a90a3b6cd9d3d758f0fb8
_tlsa.my.domain.  86400   IN      TLSA    3 0 1 6c7844bf9f56ca563cebb070a1a6d6207540636c3b50df232166838d204080b4
_tlsa.my.domain.  86400   IN      RRSIG   TLSA 6 3 86400 20170630190315 20170602190315 12736 my.domain. AELm3dUDXGh3gRGdef5La7+UXNL6IrtoLvbfUyXH0zvCPLSngcAb8Gc=

;; AUTHORITY SECTION:
my.domain.        86400   IN      NS      ns2.afraid.org.
my.domain.        86400   IN      NS      foo.my.domain.
my.domain.        86400   IN      RRSIG   NS 6 2 86400 20170630190315 20170602190315 12736 my.domain. AB1RPkEEH7+en02ZiW5kClYDSa4phLZn+TE8Xi1SxajIKSTDnjdibPk=

;; ADDITIONAL SECTION:
foo.my.domain.   86400   IN      AAAA    2000:100:200:300::1
foo.my.domain.   86400   IN      A       10.10.10.10
foo.my.domain.   86400   IN      RRSIG   AAAA 6 3 86400 20170630190315 20170602190315 12736 my.domain. AAexD4lHXhvf2cXCw2Nv+zxLnYYShf4j7vLXsaZz0NgsGHWOYY4Y71w=
foo.my.domain.   86400   IN      RRSIG   A 6 3 86400 20170630190315 20170602190315 12736 my.domain. AAHXlTA9YEKLx6KLo9wwWjJN2PpuOuYs0GbHM3k/bja0cG8t/UpPpNY=

;; Query time: 135 msec
;; EDNS: version 0; flags: do ; udp: 4096
;; SERVER: ::1
;; WHEN: Fri May 30 21:11:20 2017
;; MSG SIZE  rcvd: 651

При помощи утилиты drill с опцией для использования DNSSEC-запроса -D получен корректный ответ без ошибок из которого следует, что запрошенная для примера запись _443._tcp.my.domain была корректно подписана и доступна в системе DNS.

Также отличным вариантом комплексной проверки представляется использования онлайн-теста DANE на сайте sys4.de либо теста на сайте уже упоминавшегося Shumon Huque. Для примера приведу результаты последнего для нашей зоны.

my.domain dane check results

Также если вы воспользуетесь первым тестом то несмотря на подтверждение валидности всех типов записей, один из включённых в DNS-зону отпечатков будет помечен недействительным. Это совершенно нормальная ситуация при использованном подходе, поскольку второй отпечаток был сформирован с сертификата, который ещё не используется в обмене, поэтому данный онлайн-тест не смог получить необходимую информацию для его проверки.

2.3. Автоматизация при обновлении сертификатов

Так же как в случае с HPKP, с DANE при использовании средств автоматизации перевыпуска сертификатов от Let's Encrypt возникает и проблема автоматизации обновления TLSA записей в DNS.

Для этих целей воспользуемся модернизированным shell-скриптом lerenew.sh из уже неоднократно упоминавшейся выше статьи.

root@beta:/usr/local/etc/nsd # cd ../letsencrypt/
root@beta:/usr/local/etc/letsencrypt # cat lerenew.sh
#!/bin/sh

# Update "Let's Encrypt" certificates,
# make cert+key joined files, HPKP hashes and TLSA records
# v.20170530 (c)2016-17 by Max Kostikov http://kostikov.co e-mail: max@kostikov.co
#
# cat /etc/crontab | grep lerenew
# 0 0 * * 1 root /usr/local/etc/letsencrypt/lerenew.sh >/dev/null 2>&1

lepath="/usr/local/etc/letsencrypt"
log="/var/log/letsencrypt/lerenew.log"
pins="/usr/local/etc/lighttpd/env.d"                    # pins for Lightty
nsddir="/usr/local/etc/nsd"                             # path to NSD dir
tlsapref="_tlsa"                                        # prefix for TLSA records
joincrt="privandcert"                                   # joined file name
curpref="cur"                                           # current set postfix

echo "`date '+%Y-%m-%d %H:%M:%S'` --- Starting SSL certs renew..." >>$log

certbot renew -n $* >>$log 2>&1

certs=`find ${lepath}/archive/*/cert*.pem -mtime -1d`

if [ "${certs}" ];
then
        for i in $certs;
        do
                dir=`dirname $i`                        # path to certs
                dom=`basename $dir`                     # domain name
                ind=`basename $i | tr -d '[:alpha:].'`  # latest cert index
                cur=`expr $ind - 1`                     # previous cert index

                # create new joined cert and symlink
                cat ${dir}/privkey${ind}.pem $i > ${dir}/${joincrt}${ind}.pem
                cd ${lepath}/live/${dom}
                ln -fs ../../archive/${dom}/${joincrt}${ind}.pem ${joincrt}.pem

                # create symlinks for previous certs set
                for j in `ls -d ../../archive/${dom}/*${cur}.*`;
                do
                        ln -fs $j `basename -s .pem $j | tr -d '[:digit:]'`.${curpref}.pem
                done

                # create cert pins
                conf="${pins}/${dom}.conf"              # pin config name
                echo "# -- lerenew.sh generated v.`date '+%Y%m%d'`" >$conf
                echo '  setenv.add-response-header += (' >>$conf
                echo -n '               "Public-Key-Pins" => ' >>$conf
                echo -n '"pin-sha256=\"' >>$conf
                echo -n "`openssl x509 -in cert.${curpref}.pem -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64`" >>$conf
                echo -n '\"; pin-sha256=\"' >>$conf
                echo -n "`openssl x509 -in cert.pem -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64`" >>$conf
                echo '\"; max-age=3456000; includeSubDomains"' >>$conf
                echo '  )' >>$conf

                # update DNS zone if DNSSEC enabled
                zone="${nsddir}/zones/${dom}/${dom}.zone"
                if [ -f ${zone}.signed ];
                then
                        sed -i.bak "/TLSA/d" $zone
                        echo "${tlsapref}.${dom}        IN TLSA 3 0 1   `openssl x509 -in cert.${curpref}.pem -outform DER | sha256`" >>$zone
                        echo "${tlsapref}.${dom}        IN TLSA 3 0 1   `openssl x509 -in cert.pem -outform DER | sha256`" >>$zone
                        ${nsddir}/dnsnewserial.sh $zone
                        ${nsddir}/dnssignzone.sh $zone
                fi
        done

        # reload services
        nsd-control reload
        service lighttpd restart
        service dovecot restart
        service exim restart
fi

echo "`date '+%Y-%m-%d %H:%M:%S'` --- SSL certs renew done!" >>$log

По сути, в добавленной части реализуются те же действия, что были описаны в передыдущей части статьи. В случае, если имеется подписанная DNSSEC доменная зона, предварительно удаляются все ранее добавленные записи типа TLSA, генерируются цифровые отпечатки для текущего и вновь полученного сертификатов, изменяется серийный номер DNS-зоны после чего она подписывается текущим набором ключей.

3. Удостоверение ключей SSH

В случае с удостоверением ключей, используемых сервером при обмене к клиентом данными по протоколу SSH, через DNS используется примерно тот же подход, что и в случае с записью TLSA. Однако, здесь, очевидно, отсутствует необходимость в указании типа используемого сервиса, поэтому форма ресурсной записи SSHFP несколько проще.

foo.my.domian IN SSHFP 4 2 c6f0dd1cea5b8acc4be6e3bef92c6ba0546c061055a7ee43cf0cd1a32b39ff6e

Первая цифра 4 здесь означает используемый ключ типа Ed25519 (1 соответсвует RSA, 2 — DSA, 3 — ECDSA), а вторая 2 свидетельствует об использовании для получения хэша функции SHA256 (1 соответствует SHA1).

Простейший способ получить набор SSHFP записей для добавления в DNS-зону это воспользоваться штатной утилитой ssh-keygen из комплекта OpenSSH.

root@beta:~ # ssh-keygen -r foo.my.domian
foo.my.domian IN SSHFP 1 1 55e2c444ba9e0046707d43a4a2fde7b53f3a79b5
foo.my.domian IN SSHFP 1 2 4e8aae9287c66245c79600c2b60ce41aa157d1cdfef00dc1c1e69def4b375677
foo.my.domian IN SSHFP 2 1 3a7f6ee8f6969ba5376676c3d77662d5314ab008
foo.my.domian IN SSHFP 2 2 b6b3b952ea3c0dbb5ba95735bbcb6c4bd739992fcb6d99a0b9fae2f8288f9d32
foo.my.domian IN SSHFP 3 1 70b01e7f3a74373908a824b6628cbbf4ee7d4344
foo.my.domian IN SSHFP 3 2 9c36d05f3a9ce1a6cedda5147dc752a2782ec9ba875e982d972e0aaad45a1835
foo.my.domian IN SSHFP 4 1 e76368c21b28049fb1985be761dafd5ed4fde1d8
foo.my.domian IN SSHFP 4 2 c6f0dd1cea5b8acc4be6e3bef92c6ba0546c061055a7ee43cf0cd1a32b39ff6e

Как видно, был сформирован набор всевозможных комбинаций алгоритмов аутентификации для хоста foo.my.domian. Остаётся лишь добавить его в DNS-зону и подписать её используя DNSSEC.

С точки зрения клиента SSH для включения проверки можно воспользоваться обращением с указанием опции VerifyHostKeyDNS yes при обращении к хосту.

ssh -o "VerifyHostKeyDNS yes" my.domain
The authenticity of host 'my.domain (10.10.10.10)' can't be established.
ED25519 key fingerprint is SHA256:c6f0dd1cea5b8acc4be6e3bef92c6ba0546c061055a7ee43cf0cd1a32b39ff6e.
Matching host key fingerprint found in DNS.
Are you sure you want to continue connecting (yes/no)?

Как видно, клиент обнаружил отпечаток ключа типа 4 2 в DNS, подтвердив, тем самым, его подлинность.

Также можно включить её глобально в конфигурационном файле ssh_config.

root@beta:~ # cat /etc/ssh/ssh_config | grep VerifyHostKeyDNS
   VerifyHostKeyDNS yes

Если подходить к DNS-записи типа SSHFP формально, то возможно её использование без применения механизмов подписи DNSSEC. Однако, именно с посредством технологии DANE надёжность удостоверения ключей обмена SSH через DNS несравнимо выше.

4. Удостоверение ключей PGP

Обычно, открытые ключи PGP передаются непосредственно в сообщениях электронной почты в виде вложений или непосредственно в самом тексте письма. Принимая во внимание специфику транзита корреспоненции через SMTP-транспорты существует вероятность повреждения или подмены подписанного с использованием PGP сообщения.

И вновь хорошей идеей оказалась возможность аутентификации открытых ключей цифровой подписи PGP через подходы предлагаемые технологией DANE. Для этого используется DNS-запись OPENPGPKEY.

Предположим, что у нас нет подписей PGP для e-mail адреса автора данного блога max@kostikov.co. Создадим набор ключей используя GnuPG второй версии.

root@beta:~ # gpg2 --generate-key
gpg (GnuPG) 2.1.21; Copyright (C) 2017 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Note: Use "gpg2 --full-generate-key" for a full featured key generation dialog.

GnuPG needs to construct a user ID to identify your key.

Real name: Max Kostikov
Email address: max@kostikov.co
You selected this USER-ID:
    "Max Kostikov <max@kostikov.co>"

Change (N)ame, (E)mail, or (O)kay/(Q)uit? o
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
Please enter the passphrase to
protect your new key
Passphrase:
Repeat:
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 4EA33787B77BA6BC marked as ultimately trusted
gpg: directory '/root/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/690F4A8135CCE09C409638A14EA33787B77BA6BC.rev'
public and secret key created and signed.

pub   rsa2048 2017-06-03 [SC] [expires: 2019-06-03]
      690F4A8135CCE09C409638A14EA33787B77BA6BC
      690F4A8135CCE09C409638A14EA33787B77BA6BC
uid                      Max Kostikov <max@kostikov.co>
sub   rsa2048 2017-06-03 [E] [expires: 2019-06-03]

Теперь на базе созданного публичного ключа имеется возможность сгенерировать DNS-запись OPENPGPKEY. Для этого можно воспользоваться онлайн-генератором записи на сайте того же Shumon Huque. В этом случае нам понадобиться текстовое представление нашего открытого ключа по стандарту ASCII.

root@beta:~ # gpg2 -a --export max@kostikov.co
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQENBFkygD0BCADxhcWx5IuOZEPM999nPrYCYEMoK9xKhsmpSzIhM39g/U82uegi
USWW/ykt2yyvO8C5z2ud583jQb3v8LRaDtCsBveB8zbVarHkQg00EA1Oyg3fWxsY
hmtRGJqipReU1nyVz/y41LGpUzc83DROdi2aywLcjen108WRQwAWxzaAR3wOQsMf
lql6To8koyQQZDj7O7ltQPU13nwnX9ne/I5LfZSwCbeGhAczD+GLVLa7UsheejW3
1lk5R0qhylzbeaSVa66e4zX9+Fhd1RER3tXfjiDIuVNEeNcyLWuPD4yCn3Q6uo8e
//80+PwH7yayfFu/USAh0E9gTvLdq5+0bwVPABEBAAG0Hk1heCBLb3N0aWtvdiA8
bWF4QGtvc3Rpa292LmNvPokBVAQTAQgAPhYhBGkPSoE1zOCcQJY4oU6jN4e3e6a8
BQJZMoA9AhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEE6jN4e3
e6a8S0QH/2wpkU+yR9qf4XutGiB9rAyymRxEBXK0/wwg82KqB9qHEcLGQ2+f8Fka
ra6ynTLiLVRmpU/1VJifsPN3tGG/xvY0Zoop0BEdVI6T+eAGEtlXLafzCUO8UVkh
hRMBu4GphRcyJodqyjZ3DXTHlWky1MX8Yzfv9r8bzfqyYWp0LwrrDYQFCbugsJyJ
PzTI561Z5oBz31EV52VIz5fDxp7+lrmRMANqTTwZw1QsI+knXUsLpaRPWXP1dJRA
O3GIDLf6p14r89VElqWIAj1n6BHfJC7dC1Bmb+qiDvhPHcme5mftFgrvAkEDaaCJ
hQr17JYEcvMGq84fch+Lba2x62YTWsq5AQ0EWTKAPQEIAMvNsb+kjxXK7qQoXkVl
jvsluRLLw6f+q8XriQ/uetdaM4AhWJkMMqrCisarnaR9JcJFb3B1IcvNwFE94Isi
Ff7b+98DaF43gPCBmZ9//HYPaKJ6yyZnwK8/sBSrK/jPjAr6cD5lEW4dZ93+rTRD
kqKolUlWDYsS58bzWwj16Q5ctaqtFAkBrwGpXOIHMINkc0Jp4xmxLsJa1Z3rTepW
8w2hPJsiMOzrmRIFhVFRS6DIX+PU/Nvg+9qYYR9rF/OkI2Nm8oQ6kJNCsrFi7NKy
ozFV/JL2w0ppWRXYEmiaWcr+32K8Sku+0nu4PgwlyyMdIzjUoY/rK5QGId2Jv+pK
/REAEQEAAYkBPAQYAQgAJhYhBGkPSoE1zOCcQJY4oU6jN4e3e6a8BQJZMoA9AhsM
BQkDwmcAAAoJEE6jN4e3e6a8AqMH/jUTi8bcSqcBX1nBkE0TKPvkezRn34cC4e/A
lnu2wRGR93EP0HRWog6I2Y6VmsIQaY28ewgOINPuGyDoL/iklAuOMk/4+bpEz5bG
DHjPRUVQvaM6HIONUaIVAXQbCBnLDkmCwQ7IVJdv7X3sAbmSu7sV8u4md/gh5R8a
R/YYlut1ItDA6RX7x7xnwzGAmtnl+O+AhgMoftPC4lbBllYQIugX5u0qeoa0Lgtr
YpW6XjjgWFwvIVuZ7j2axdgum9pw9Gv73zpEZR1wPADAdzeMmvMEfwWVuxRWPJ02
7psxxdoH24Mn6JMv2m3zSWjfArk+ofePAFhfGSmBHzYBVEki560=
=y4kZ
-----END PGP PUBLIC KEY BLOCK-----

В результате после обработки введённых данных получим искомую DNS-запись.

9baf3a40312f39849f46dad1040f2f039f1cffa1238c41e9db675315._openpgpkey.kostikov.co. IN OPENPGPKEY (
                  mQENBFkygD0BCADxhcWx5IuOZEPM999nPrYCYEMoK9xKhsmpSzIhM39g/U82
                  uegiUSWW/ykt2yyvO8C5z2ud583jQb3v8LRaDtCsBveB8zbVarHkQg00EA1O
                  yg3fWxsYhmtRGJqipReU1nyVz/y41LGpUzc83DROdi2aywLcjen108WRQwAW
                  xzaAR3wOQsMflql6To8koyQQZDj7O7ltQPU13nwnX9ne/I5LfZSwCbeGhAcz
                  D+GLVLa7UsheejW31lk5R0qhylzbeaSVa66e4zX9+Fhd1RER3tXfjiDIuVNE
                  eNcyLWuPD4yCn3Q6uo8e//80+PwH7yayfFu/USAh0E9gTvLdq5+0bwVPABEB
                  AAG0Hk1heCBLb3N0aWtvdiA8bWF4QGtvc3Rpa292LmNvPokBVAQTAQgAPhYh
                  BGkPSoE1zOCcQJY4oU6jN4e3e6a8BQJZMoA9AhsDBQkDwmcABQsJCAcCBhUI
                  CQoLAgQWAgMBAh4BAheAAAoJEE6jN4e3e6a8S0QH/2wpkU+yR9qf4XutGiB9
                  rAyymRxEBXK0/wwg82KqB9qHEcLGQ2+f8Fkara6ynTLiLVRmpU/1VJifsPN3
                  tGG/xvY0Zoop0BEdVI6T+eAGEtlXLafzCUO8UVkhhRMBu4GphRcyJodqyjZ3
                  DXTHlWky1MX8Yzfv9r8bzfqyYWp0LwrrDYQFCbugsJyJPzTI561Z5oBz31EV
                  52VIz5fDxp7+lrmRMANqTTwZw1QsI+knXUsLpaRPWXP1dJRAO3GIDLf6p14r
                  89VElqWIAj1n6BHfJC7dC1Bmb+qiDvhPHcme5mftFgrvAkEDaaCJhQr17JYE
                  cvMGq84fch+Lba2x62YTWsq5AQ0EWTKAPQEIAMvNsb+kjxXK7qQoXkVljvsl
                  uRLLw6f+q8XriQ/uetdaM4AhWJkMMqrCisarnaR9JcJFb3B1IcvNwFE94Isi
                  Ff7b+98DaF43gPCBmZ9//HYPaKJ6yyZnwK8/sBSrK/jPjAr6cD5lEW4dZ93+
                  rTRDkqKolUlWDYsS58bzWwj16Q5ctaqtFAkBrwGpXOIHMINkc0Jp4xmxLsJa
                  1Z3rTepW8w2hPJsiMOzrmRIFhVFRS6DIX+PU/Nvg+9qYYR9rF/OkI2Nm8oQ6
                  kJNCsrFi7NKyozFV/JL2w0ppWRXYEmiaWcr+32K8Sku+0nu4PgwlyyMdIzjU
                  oY/rK5QGId2Jv+pK/REAEQEAAYkBPAQYAQgAJhYhBGkPSoE1zOCcQJY4oU6j
                  N4e3e6a8BQJZMoA9AhsMBQkDwmcAAAoJEE6jN4e3e6a8AqMH/jUTi8bcSqcB
                  X1nBkE0TKPvkezRn34cC4e/Alnu2wRGR93EP0HRWog6I2Y6VmsIQaY28ewgO
                  INPuGyDoL/iklAuOMk/4+bpEz5bGDHjPRUVQvaM6HIONUaIVAXQbCBnLDkmC
                  wQ7IVJdv7X3sAbmSu7sV8u4md/gh5R8aR/YYlut1ItDA6RX7x7xnwzGAmtnl
                  +O+AhgMoftPC4lbBllYQIugX5u0qeoa0LgtrYpW6XjjgWFwvIVuZ7j2axdgu
                  m9pw9Gv73zpEZR1wPADAdzeMmvMEfwWVuxRWPJ027psxxdoH24Mn6JMv2m3z
                  SWjfArk+ofePAFhfGSmBHzYBVEki560=
)

Как видно, имя хоста состоит из хэша, учитывающего локальную часть адреса электронной почты, специального ярлыка _openpgpkey и доменного имени e-mail. И вновь остаётся лишь включить полученную OPENPGPKEY запись в DNS-зону, сгенерировать серийный номер и подписать используя DNSSEC.

5. Удостоверение сертификатов S/MIME

Стандарт S/MIME предназначен для тех же целей, каким служит PGP, а именно цифровой подписи и шифрованию сообщений электронной почты на базе открытых ключей. Ключевым отличием S/MIME от PGP представляется способ получения ключей. Если пользователь PGP самостоятельно создаёт ключи цифровой подписи, то в случае с S/MIME используется аналогичный TLS метод обращения к удостоверяющему центру. Разумеется, при этом допускаются и самоподписанные сертификаты.

Для примера создадим такой сертификат для того же адреса max@kostikov.co. Для этого последуем стандартной процедуре создания собственного CA для дальнейшего выпуска самоподписанного клиентского сертификата.

Создаём закрытый ключ удостоверяющего центра ca.key и на его базе публичный ключ ca.crt. Последний должен быть добавлен в список доверенных на клиентах, которые будут работать с создаваемым сертификатом S/MIME, в том случае, если они не поддерживают технологию DANE.

root@beta:~ # openssl genrsa -out ca.key 4096
Generating RSA private key, 4096 bit long modulus
.............++
................................................++
e is 65537 (0x10001)
root@beta:~ # openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:Kaliningrad
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Max Kostikov
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:kostikov.co
Email Address []:max@kostikov.co

Далее создаём закрытый ключ клиента smime.key и на его базе CSR-сертификат smime.csr.

root@beta:~ # openssl genrsa -out smime.key 2048
Generating RSA private key, 2048 bit long modulus
..................................................+++
........................................+++
e is 65537 (0x10001)
root@beta:~ # openssl req -new -key smime.key -out smime.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:Kaliningrad
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Max Kostikov
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:max@kostikov.co
Email Address []:max@kostikov.co

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:12345
An optional company name []:

Обратите внимание, что в CSR-сертификате важно в качестве Common Name (CN=) указать e-mail адрес, для которого будет выписываеться сертификат.

Далее получаем собственно сам S/MIME сертификат smime.crt удостоверения для электронной почты и просмотрим его содержимое. Создаваемый попутно файл ca.srl хранит в себе счётчик серийных номеров сертификатов выдаваемых данным CA.

root@beta:~ # echo 01 > ca.srl
root@beta:~ # openssl x509 -sha256 -req -days 365 -in smime.csr -out smime.crt -CA ca.crt -CAkey ca.key -setalias "Self Signed S/MIME" -addtrust emailProtection -addreject clientAuth -addreject serverAuth -trustout
Signature ok
subject=/C=RU/ST=Kaliningrad/O=Max Kostikov/CN=max@kostikov.co/emailAddress=max@kostikov.co
Getting CA Private Key
root@beta:~ # openssl x509 -in smime.crt -noout -text
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 2 (0x2)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=RU, ST=Kaliningrad, O=Max Kostikov, CN=kostikov.co/emailAddress=max@kostikov.co
        Validity
            Not Before: May  30 15:09:17 2017 GMT
            Not After : May  30 15:09:17 2018 GMT
        Subject: C=RU, ST=Kaliningrad, O=Max Kostikov, CN=max@kostikov.co/emailAddress=max@kostikov.co
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b6:11:8c:a2:12:21:6b:2f:0d:53:40:6d:6b:d7:
                    0b:b6:d1:19:8c:b0:3e:88:46:43:da:8f:77:9e:d9:
                    34:40:ae:8c:25:34:55:08:0a:85:ce:a4:24:b8:ec:
                    21:57:13:82:e8:c7:58:97:9c:48:58:65:d2:57:1f:
                    79:85:08:fa:54:ae:cd:32:ec:0b:7c:69:f7:ac:81:
                    00:b2:ed:9e:f3:9b:04:1c:7b:ad:f3:de:f9:51:bf:
                    20:b8:be:17:54:2f:f5:7d:76:fc:43:e7:80:b8:d2:
                    5e:50:e3:1f:11:30:03:c5:cf:02:b4:54:3c:2a:30:
                    4f:3f:98:7d:83:cb:d1:39:79:64:2f:b5:b3:c4:b3:
                    52:11:9e:57:a4:20:35:fb:f4:92:9c:95:51:2b:d0:
                    ba:7a:71:fa:6f:cc:5b:f9:63:6e:71:e1:71:08:65:
                    ac:70:93:a0:f5:28:0f:70:39:d5:13:66:33:3a:b9:
                    90:6b:7f:fc:54:76:c4:a2:63:0b:9e:86:8b:f9:99:
                    29:4b:96:10:01:b7:63:4a:8b:37:28:bc:7d:4a:b6:
                    05:6b:3e:28:88:db:24:32:16:52:10:a5:99:55:2f:
                    a5:96:fe:2e:36:31:a3:6d:cc:75:3b:60:b7:1b:a8:
                    a7:85:09:40:a6:d0:2c:ca:9f:02:57:05:fc:70:cd:
                    54:ef
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         29:c2:cb:9f:62:38:81:46:8c:88:f7:ae:c0:05:4c:30:c6:2e:
         34:8b:eb:78:e8:94:c5:d7:52:f0:8c:76:46:fa:58:54:85:c8:
         43:fe:4e:16:97:08:d9:ae:7e:c3:f0:5f:93:d2:c5:da:e9:69:
         63:29:20:f1:3e:52:b5:ea:91:30:a9:b2:84:f2:3b:95:76:56:
         d4:b9:7b:71:58:04:6f:b6:17:de:1f:0c:5a:f2:99:5e:d0:f0:
         63:a2:88:ef:0d:df:e9:58:69:68:e0:c8:bb:65:eb:3c:c5:b6:
         ac:ba:84:f8:ec:a6:bd:db:c2:35:24:bc:93:5d:1e:c9:a6:37:
         39:c3:57:dd:5c:b2:85:b1:ec:1b:3a:60:87:54:a5:85:31:4f:
         a4:4a:97:35:74:e0:f5:8b:52:41:ca:e8:ab:41:5c:e4:8c:8a:
         2e:bd:aa:d6:44:09:13:ba:fb:3b:1e:68:74:17:8b:06:de:82:
         d8:b8:ae:da:8e:a3:e1:97:fc:94:e7:24:6e:cc:62:9b:05:4c:
         9b:d5:c2:a0:a1:4b:54:fb:9f:22:43:37:16:fd:6c:66:06:a7:
         83:4e:f4:87:9c:88:84:4d:8b:7b:96:e3:bb:ce:18:4d:31:6b:
         86:82:34:bb:4d:fd:b2:b5:ac:5b:18:c6:74:16:b9:c8:14:bb:
         ca:01:24:86:6f:24:7e:07:4c:1e:2d:ba:c3:20:81:f1:10:f5:
         90:e3:bb:b4:91:62:90:e3:64:85:61:39:aa:7d:02:e9:af:8e:
         8e:18:fd:c9:78:82:7f:bf:78:ad:da:54:4a:dc:7a:01:0f:a8:
         bd:31:ca:61:73:75:aa:d3:a1:7a:27:a0:1b:23:88:07:e6:f9:
         ac:d2:c0:a2:f6:c9:1d:20:bb:f8:9e:01:63:fc:3e:9e:d3:fa:
         65:1c:36:0d:b8:16:ba:b5:3b:0f:69:c6:23:99:3e:df:5b:f7:
         1d:34:3f:6d:d7:6c:63:be:dc:03:c0:77:e6:45:ba:46:26:01:
         9d:4d:fe:ed:8d:04:f6:c9:03:60:5e:27:fa:5a:38:fc:10:ef:
         a8:ce:35:ad:da:3b:9f:d0:dc:ee:58:df:cf:a0:92:2c:27:5e:
         0f:92:94:c7:7e:28:7d:34:8a:df:a6:1e:0f:ee:60:54:f4:77:
         7f:bb:1a:17:6e:e5:e4:86:3d:f6:30:5a:6a:aa:c8:39:36:63:
         b7:df:1b:67:7e:91:09:99:8a:94:bb:e6:9d:70:85:f0:51:86:
         20:8a:3b:48:8a:f5:2c:de:ab:a6:b6:34:8c:53:e4:48:c5:cf:
         eb:3c:09:df:1f:ac:83:6a:d0:85:c3:66:a7:3b:10:ac:a8:6f:
         a8:6b:61:a7:bc:29:24:37
Trusted Uses:
  E-mail Protection
Rejected Uses:
  TLS Web Client Authentication, TLS Web Server Authentication
Alias: Self Signed S/MIME

Как видно, он получил искомый статус E-mail Protection и запрет на использование в HTTP сервисах.

Для размещения отпечатка сертификата S/MIME черновым стандартом определена специальная ресурсная запись DNS SMIMEA. Её формат представляет собой сочетание форматов OPENPGPKEY и TLS. Из первого за образец взят формат доменного имени но с ключом _smimecert, а из второго — цифровые обозначения типа сертификата, указания данных, на основании которых был сформирован отпечаток и тип использованной для этого хэш-функции.

Ввиду того, что не удалось достойного инструмента для автоматизации формирования SMIMEA записи по предоставленному сертификату, автор разработал скрипт getsmimea.sh, который на основании введённых параметров и предоставленного S/MIME сертификата формирует готовую DNS-запись.

#!/bin/sh

# Creates SMIMEA DNS record from S/MIME certifiate
# v.20170606 (c)2017 by Max Kostikov http://kostikov.co e-mail: max@kostikov.co
#
# Usage: getsmimea.sh usage selector type /path/to/cert
#

# Read parameters
if [ $# -ne 4 ]
then
        echo "Insufficient arguments!"
        echo "$0 usage selector type /path/to/cert"
        exit 1
fi
if [ ! -f $4 ]
then
        echo "Certificate file '$4' not found!"
        exit 1
fi

# Detect certificate type
openssl x509 -in $4 -noout 2>/dev/null
if [ $? != 0 ]
then
        echo "Unsupported certificate type!"
        exit 1
fi

case $1 in
        0) echo "PKIX-TA not supported"; exit 1;;
        1) echo "PKIX-EE not supported"; exit 1;;
        2) ;;
        3) ;;
        *) echo "Wrong usage argument value '$1'!"; exit 1;;
esac
case $2 in
        0) c1=":"; c2="openssl x509 -in $4 -outform DER";;
        1) c1="openssl x509 -in $4 -noout -pubkey"; c2="openssl pkey -pubin -outform DER";;
        *) echo "Wrong selector argument value '$2'!"; exit 1;;
esac
case $3 in
        0) hash=`$c1 | $c2 | hexdump -ve '/1 "%02x"'`;;
        1) hash=`$c1 | $c2 | sha256`;;
        2) hash=`$c1 | $c2 | sha512`;;
        *) echo "Wrong type argument value '$3'!"; exit 1;;
esac

# Get e-mail address from certs CN=
email=`openssl x509 -noout -subject -nameopt multiline -in $4 | sed -n 's/ *commonName *= //p'`
local=`echo $email | cut -d '@' -f 1`
domain=`echo $email | cut -d '@' -f 2`
if [ "$local" = "$domain" ]
then
        echo "Wrong e-mail address <$email> in CN!"
        exit 1
fi

echo "`sha256 -s $local | cut -w -f 4 | cut -c 1-56`._smimecert.$domain     IN SMIMEA $1 $2 $3 ("
echo -n $hash | fold -w64 | sed 's/.*/  "&"/'
echo ") ; $email"

Воспользуемся им для получения искомой записи для нашего сертификата.

root@beta:~ # /bin/sh getsmimea.sh 3 0 1 smime.crt
9baf3a40312f39849f46dad1040f2f039f1cffa1238c41e9db675315._smimecert.kostikov.co IN SMIMEA 3 0 1 (
        "d424bdccfd3919a7b9a86af7220697a1c9bfee0c96225d3bdd2fb0c738be5de0" ); max@kostikov.co

6. Перспективы использования DANE

Внимательный читатель может обратить внимание на то, что автор, несмотря на упоминание факта возможности применения самоподписанных TLS сертификатов при использовании технологии DANE, сам не воспользовался этой, казалось бы, блестящей возможностью, оставшись приверженцем использования сертификатов, выданных удостоверяющим центром Let's Encrypt.

Причиной проблем с развёртыванием использования самоподписанных сертификатов через DANE и отказом от использования традиционных CA несколько.

Главнейшая их них — поддержка клиентским программным обеспечением, а говоря точнее, её отсутствие.

К примеру, на сегодняшний момент ни один (!) популярный браузер штатно не поддерживает аутентификацию TLS-сертификатов посредством DANE. Среди причин такого, казалось бы, странного отношения к этой технологии называется снижения время отклика при первом посещении страницы по протоколу HTTPS. Действительно, использование подписанных DNSSEC доменных зон заметно повышает премя разрешения адреса хоста в его IP-адрес. Это связано, во-первых, с в разы большим размером данных DNSSEC-зоны, во-вторых, с необходимостью проводить криптографические расчёты для подтверждения валидности цифовых подписей и, в-третьих, с потребностью при первичном доступе проходить всю цепочку DNS-серверов, начиная с корневой зоны через зону доменов первого уровня к непосредственно домену самого хоста. Кроме того, нельзя исключать сбоев на одном из этапов такой проверки, которые могут заблокировать доступ к валидируемым ресурсам. Традиционный метод аутентификации сертификатов через доверенные список CA, который уже загружен в браузер, разумеется, существенно быстрее и, в этом плане, надёжнее.

Также среди причин называется невысокий уровень распространения DNSSEC в сети Интернет. Несмотря на то, что по последним данным он достигает примерно 14% по миру, этот уровень, вероятно, представляется ещё недостаточным для того, чтобы стать стимулом для добавления связанного с DNSSEC в целом и DANE в частности в программное обеспечение.

На этом фоне неплохо выглядит сегмент SMTP-серверов, когда два доминирующих в почтовых сервера Exim и Postfix имеют поддержку технологии DANE.

Однако, можно надеяться, что по мере распространения механизма DNSSEC в системе DNS в среде разработчиков программного обеспечения будет расти и популярность использования технологии DANE, ведь её преимущества, как попытался показать автор в данной статье, очевидны.

7. PROFIT!

Статья была полезной? Тогда прошу не стесняться и поддерживать деньгами через PayPal или Яндекс.Деньги.


security  dev  shell  DNS  letsencrypt  SSL  DNSSEC  ssh