česky | english
Ověření "otisků prstů" pomocí DNSSEC
K ověření, zda jsou "otisky prstů" (fingerprints) stažených kořenových certifikátů správné, lze použít TXT záznamy v DNS domény cacert.org, chráněné zabezpečením DNSSEC.
Informace o "otiscích prstů" (fingerprints) jsou uloženy v zóně DNS s názvem _fp.cacert.org - znak podtržítko indikuje ne-hostitelskou informaci. Pro každou generaci kořenových certifikátů bude vytvořen nový podadresář. Ten současný se nazývá "g1". K získání seznamu všech dostupných certifikátů určité generace se můžete dotázat návěstí _certs onoho podadresáře dotazem na DNS pro _certs.g1._fp.cacert.org, což poskytne dva názvy certifikátů "root_X0F class3_X0E". Každý z těchto odkazů zase poskytne jak URL ("_url"), tak sadu "otisků prstů" (algoritmy _md5, _sha1, _sha256) potřebnou pro ověřené stažení příslušného certifikátu. Ke stažení současného (g1) kořenového certifikátu byste tedy měli vyhledat URL pro stažení na _url.root_X0F.g1._fp.cacert.org a ověřit "otisk prstu" SHA2-256 na _sha256.root_X0F.g1._fp.cacert.org. "Otisky prstů" jsou vždy psány písmeny velké abecedy a bez oddělovačů.
Při používání příkazů a skriptů vždy začínejte záznamem záhlaví _certs.g1._fp.cacert.org, který v současné době dává „root_X0F class3_X0E“. Pokud materiál místo toho používá „root class3“, je zastaralý a měl by být implementován první dotaz.
Pro krátký test v Linuxu provede kontrolu následující kód. Pro použití v provozu zajistěte, aby byly odpovědi DNS ověřeny. Toho lze dosáhnout instalací ověřovacího vyhodnocovače (resolveru) [1, 2]. Pro správné nastavení DNSSEC v případě potřeby jednejte podle pokynů k distribucím.
- [Po znaku $ je vždy uveden příkaz, ostatní řádky jsou odpovědi.]
$ host -t TXT _url.root_X0F.g1._fp.cacert.org. _url.root_X0F.g1._fp.cacert.org descriptive text "http://www.cacert.org/certs/root_X0F.crt" $ host -t TXT _sha256.root_X0F.g1._fp.cacert.org. _sha256.root_X0F.g1._fp.cacert.org descriptive text "07EDBD824A4988CFEF4215DA20D48C2B41D71529D7C900F570926F277CC230C5" $ wget -O root_X0F.crt 'http://www.cacert.org/certs/root_X0F.crt' $ openssl x509 -in root_X0F.crt -noout -fingerprint -sha256 | tr -d : SHA256 Fingerprint=07EDBD824A4988CFEF4215DA20D48C2B41D71529D7C900F570926F277CC230C5
V systému Windows lze tytéž údaje zjistit programem "nslookup":
>nslookup Default Server: my.dnssrv.eu Address: 2001:470:6f:458:c56d:5931:992:4708 > set type=TXT > _url.root_X0F.g1._fp.cacert.org. Server: my.dnssrv.eu Address: 2001:470:6f:458:c56d:5931:992:4708 Non-authoritative answer: _url.root_X0F.g1._fp.cacert.org text = "http://www.cacert.org/certs/root_X0F.crt" > _sha256.root_X0F.g1._fp.cacert.org. Server: my.dnssrv.eu Address: 2001:470:6f:458:c56d:5931:992:4708 Non-authoritative answer: _sha256.root_X0F.g1._fp.cacert.org text = "07EDBD824A4988CFEF4215DA20D48C2B41D71529D7C900F570926F277CC230C5" > _url.class3_X0E.g1._fp.cacert.org. Server: my.dnssrv.eu Address: 2001:470:6f:458:c56d:5931:992:4708 Non-authoritative answer: _url.class3_X0E.g1._fp.cacert.org text = "http://www.cacert.org/certs/class3_X0E.crt" > _sha256.class3_X0E.g1._fp.cacert.org. Server: my.dnssrv.eu Address: 2001:470:6f:458:c56d:5931:992:4708 Non-authoritative answer: _sha256.class3_X0E.g1._fp.cacert.org text = "F6873D70D67596C2ACBA34401E69738B52701DD6AB06B49749BC55150936D544" > exit
Níže je vypsán malý skript pro Linux, který provede ověření (je-li systémový resolver [součást operačního systému, řešící převod názvu DNS na IP-adresy a výpis záznamů DNS] správně konfigurován). Návratový stav je 0 při úspěšném ověření, jinak je nenulový (chyby 3, 4 a 5 mohou indikovat, že systémový resolver nepracuje se záznamy DNSSEC).
Skript není funkční, alespoň na Ubuntu 15.10 - končí kódem 3 na řádku 8.
Upravený skript s původními řádky v poznámce bezprostředně před upravenými: CAcert-roots-fingerprint-test.sh. V původním skriptu vypsaném níže jsou to řádky: 8, 10, 24, 26, 33, 35.
- Příčiny:
- Ve výpisu se (již?) nevyskytuje flag "ad" - nahrazen "rd".
- Ve výpisu se nevyskytují žádné řádky obsahující " RRSIG".
1 #!/bin/bash
2
3 # Ziskam seznam dostupnych korenovych certifikatu (nazvy)
4 TMP_RESPONSE=___root___$$.tmp
5 dig +nocmd +comments +nostats +norrcomments +dnssec IN TXT _certs.g1._fp.cacert.org. > ${TMP_RESPONSE} || exit 1
6
7 grep -q '^;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ' ${TMP_RESPONSE} || exit 2
8 grep '^;; flags:' ${TMP_RESPONSE} | cut '-d;' -f3 | cut -d: -f2 | grep -q ad || exit 3
9 grep '^; EDNS:' ${TMP_RESPONSE} | tr ";," "\n\n" | grep flags | cut -d: -f2 | grep -q do || exit 4
10 grep -v '^;' ${TMP_RESPONSE} | grep -q RRSIG || exit 5
11
12 ROOTS=$(grep -v '^;' "${TMP_RESPONSE}" | grep -v " RRSIG " | grep TXT | cut '-d"' -f2 | head -1)
13 printf "Nalezeny koreny: %s\n\n" "$ROOTS"
14
15 rm -f -- "${TMP_RESPONSE}"
16
17 for a in $ROOTS; do
18 printf "Stahuji %s ...\n" "$a"
19
20 # Ziskam URL pro stazeni kazdeho certifikatu v seznamu ROOTS
21 TMP_ROOT=___root___$$.tmp
22 dig +nocmd +comments +nostats +norrcomments +dnssec IN TXT "_url.$a.g1._fp.cacert.org." > ${TMP_ROOT} || exit 11
23 grep -q '^;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ' ${TMP_ROOT} || exit 12
24 grep '^;; flags:' ${TMP_ROOT} | cut '-d;' -f3 | cut -d: -f2 | grep -q ad || exit 13
25 grep '^; EDNS:' ${TMP_ROOT} | tr ";," "\n\n" | grep flags | cut -d: -f2 | grep -q do || exit 14
26 grep -v '^;' ${TMP_ROOT} | grep -q RRSIG || exit 15
27 CRT_URL=$(grep -v '^;' ${TMP_ROOT} | grep -v " RRSIG " | grep TXT | cut '-d"' -f2 | head -1)
28
29 # Ziskam otisk SHA2-256 kazdeho certifikatu v seznamu ROOTS
30 TMP_ROOT_FP=___root___$$.tmp
31 dig +nocmd +comments +nostats +norrcomments +dnssec IN TXT "_sha256.$a.g1._fp.cacert.org." > ${TMP_ROOT_FP} || exit 21
32 grep -q '^;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ' ${TMP_ROOT_FP} || exit 22
33 grep '^;; flags:' ${TMP_ROOT_FP} | cut '-d;' -f3 | cut -d: -f2 | grep -q ad || exit 23
34 grep '^; EDNS:' ${TMP_ROOT_FP} | tr ";," "\n\n" | grep flags | cut -d: -f2 | grep -q do || exit 24
35 grep -v '^;' ${TMP_ROOT_FP} | grep -q RRSIG || exit 25
36 CRT_FP=$(grep -v '^;' ${TMP_ROOT_FP} | grep -v " RRSIG " | grep TXT | cut '-d"' -f2 | head -1)
37
38 # Ze ziskaneho URL stahnu certifikat
39 wget --quiet -O "___CRT___$a.crt" "$CRT_URL" || exit 31
40
41 # Spocitam otisk ze stazeneho souboru certifikatu
42 DL_FP=$(openssl x509 -in "___CRT___$a.crt" -noout -fingerprint -sha256 | cut -d= -f2 | tr -d :)
43
44 printf "Nalezen certifikat pro koren \"%s\":\n- CRT URL:\t%s\n- CRT FP:\t%s\n- DL FP:\t%s\n\n" "$a" "$CRT_URL" "$CRT_FP" "$DL_FP"
45
46 # Porovnam otisk stazeneho certifikatu s hodnotou získanou z DNS
47 if [ ! "$CRT_FP" == "$DL_FP" ]; then
48 printf 'Verification Failed!'
49 exit 32
50 fi
51
52 rm -f -- "$TMP_ROOT" "$TMP_ROOT_FP"
53 done
Výstup z upraveného skriptu:
_certs.g1._fp.cacert.org. 21599 IN TXT "root_X0F class3_X0E" Nalezeny koreny: root_X0F class3_X0E Stahuji root_X0F ... _url.root_X0F.g1._fp.cacert.org. 20558 IN TXT "http://www.cacert.org/certs/root_X0F.crt" _sha256.root_X0F.g1._fp.cacert.org. 20632 IN TXT "07EDBD824A4988CFEF4215DA20D48C2B41D71529D7C900F570926F277CC230C5" Nalezen certifikat pro koren "root_X0F": - CRT URL: http://www.cacert.org/certs/root_X0F.crt - CRT FP: 07EDBD824A4988CFEF4215DA20D48C2B41D71529D7C900F570926F277CC230C5 - DL FP: 07EDBD824A4988CFEF4215DA20D48C2B41D71529D7C900F570926F277CC230C5 Stahuji class3_X0E ... _url.class3_X0E.g1._fp.cacert.org. 20651 IN TXT "http://www.cacert.org/certs/class3_X0E.crt" _sha256.class3_X0E.g1._fp.cacert.org. 20680 IN TXT "F6873D70D67596C2ACBA34401E69738B52701DD6AB06B49749BC55150936D544" Nalezen certifikat pro koren "class3_X0E": - CRT URL: http://www.cacert.org/certs/class3_X0E.crt - CRT FP: F6873D70D67596C2ACBA34401E69738B52701DD6AB06B49749BC55150936D544 - DL FP: F6873D70D67596C2ACBA34401E69738B52701DD6AB06B49749BC55150936D544