Difference between revisions of "Ns.fjfi.cvut.cz"

From NMS
Jump to: navigation, search
(Monitoring)
(DNSSEC)
 
(11 intermediate revisions by the same user not shown)
Line 36: Line 36:
 
===Automatické změny===
 
===Automatické změny===
  
 +
* některá DNS záznamy jsou automaticky updatovány v závislosti na aktuální dostupnosti služeb
 +
** změny jsou prováděny [https://gitlab.fjfi.cvut.cz/comp/scripts/blob/master/DnsHA.py DnsHA.py] skriptem běžícím na <tt>[[nms.fjfi.cvut.cz]]</tt>
 +
** ruční změny těchto záznamů budou do pěti minut znovu přepsány
 +
** automatické updaty lze [https://nms.fjfi.cvut.cz/user/?p=admin&sp=ddns disablovat] (viz. konfigurace DDNS HA)
 
*smtp.fjfi.cvut.cz -> směřuje na mailgw1.fjfi.cvut.cz resp. mailgw2.fjfi.cvut.cz dle dostupnosti
 
*smtp.fjfi.cvut.cz -> směřuje na mailgw1.fjfi.cvut.cz resp. mailgw2.fjfi.cvut.cz dle dostupnosti
 
*ldap[1-3].fjfi.cvut.cz, krb[1-3].fjfi.cvut.cz, wc[1-3].fjfi.cvut.cz -> směřuje na dostupné doménové kontrolery
 
*ldap[1-3].fjfi.cvut.cz, krb[1-3].fjfi.cvut.cz, wc[1-3].fjfi.cvut.cz -> směřuje na dostupné doménové kontrolery
 
* *.dhcp.fjfi.cvut.cz, *.7.32.147.in-addr.arpa, *.11.32.147.in-addr.arpa -> aktualizováno DHCP serverem při přidělení adresy síťovému zařízení
 
* *.dhcp.fjfi.cvut.cz, *.7.32.147.in-addr.arpa, *.11.32.147.in-addr.arpa -> aktualizováno DHCP serverem při přidělení adresy síťovému zařízení
 
* *.radvd.fjfi.cvut.cz -> aktualizováno na základě informací o registrovaném zařízení, týká se zařízení u nichž je uvedena IPv6 adresa "dynamic". Podle informací o umístění zařízení (Břehová, Trojanova, Trója, Mobilní) se generují různé záznamy pro všechny podsítě, kde se může zařízení vyskytovat. DNS jména pak mohou vypadat následujícím způsobem <tt>def-tjn-123-untrusted.radvd.fjfi.cvut.cz</tt>.
 
* *.radvd.fjfi.cvut.cz -> aktualizováno na základě informací o registrovaném zařízení, týká se zařízení u nichž je uvedena IPv6 adresa "dynamic". Podle informací o umístění zařízení (Břehová, Trojanova, Trója, Mobilní) se generují různé záznamy pro všechny podsítě, kde se může zařízení vyskytovat. DNS jména pak mohou vypadat následujícím způsobem <tt>def-tjn-123-untrusted.radvd.fjfi.cvut.cz</tt>.
 +
 +
# TODO - details about these DnsHA updated records
 +
ldap.fjfi.cvut.cz (resp. ldap1.fjfi.cvut.cz, ldap2.fjfi.cvut.cz, ldap3.fjfi.cvut.cz)
 +
krb.fjfi.cvut.cz (resp. krb1.fjfi.cvut.cz, krb2.fjfi.cvut.cz, krb3.fjfi.cvut.cz)
 +
imap.fjfi.cvut.cz
 +
mail.fjfi.cvut.cz resp. webmail.fjfi.cvut.cz
 +
ntp.fjfi.cvut.cz
 +
people.fjfi.cvut.cz
 +
kms.fjfi.cvut.cz
 +
_vlmcs._tcp.fjfi.cvut.cz
  
 
===DNSSEC===
 
===DNSSEC===
 +
 +
==== Quick start for ISC Bind ====
 +
* [[ns.fjfi.cvut.cz#Skript pro vygenerování prvních KSK/ZSK|vygenerujte ZSK+KSK pomocí níže uvedeného skriptu]]
 +
* přidejte <tt>key-directory</tt>, <tt>auto-dnssec</tt> a <tt>inline-signing</tt> do [[ns.fjfi.cvut.cz#Prvotní inicializace a konfigurace|konfigurace zóny]] a reloadněte konfiguraci
 +
* přidejte do cronu [[ns.fjfi.cvut.cz#Skript pro rotování posledních 3 ZSK|skript pro automatické rotování ZSK klíčů]]
 +
* zkonfigurujte si nějaký [[ns.fjfi.cvut.cz#Monitoring|monitoring]]
 +
* po otestování [[ns.fjfi.cvut.cz#Ukotvení DNSSEC|ukotvěte]] v DNS hierarchii
  
 
==== Prvotní inicializace a konfigurace ====
 
==== Prvotní inicializace a konfigurace ====
Line 178: Line 199:
 
  DELDATE=`date --date="$((2*${ZSK_VALID}+1)) months" +%Y%m%d`
 
  DELDATE=`date --date="$((2*${ZSK_VALID}+1)) months" +%Y%m%d`
 
   
 
   
  ZSK=`dnssec-keygen -r /dev/urandom -K ${KEYDIR_BACKUP} -I ${INADATE} -D ${DELDATE} -S ${KEYDIR_ZONE}/${ZSK} -L 18000`
+
  ZSK=`dnssec-keygen -r /dev/urandom -K ${KEYDIR_BACKUP} -I ${INADATE} -D ${DELDATE} -S ${KEYDIR_ZONE}/${ZSK}.key -L 18000`
 
  chown ${NUSER}:${NGROUP} ${KEYDIR_BACKUP}/${ZSK}.*
 
  chown ${NUSER}:${NGROUP} ${KEYDIR_BACKUP}/${ZSK}.*
 
  cp -a ${KEYDIR_BACKUP}/${ZSK}.key ${KEYDIR_ZONE}
 
  cp -a ${KEYDIR_BACKUP}/${ZSK}.key ${KEYDIR_ZONE}
Line 189: Line 210:
 
  echo "rndc signing -nsec3param 1 0 10 ${SEED} ${ZONE}"
 
  echo "rndc signing -nsec3param 1 0 10 ${SEED} ${ZONE}"
  
===== Skript pro rotování posledních 3 KSK =====
+
===== Skript pro rotování posledních 3 ZSK =====
 
  #!/bin/bash
 
  #!/bin/bash
  # This script can be used for simple DNSSEC KSK rotation using 3 keys (prev, curr, next)
+
  # This script can be used for simple DNSSEC ZSK rotation using 3 keys (prev, curr, next)
 
  # Update global configuration section at the beggining of this script.
 
  # Update global configuration section at the beggining of this script.
 
  # usage:
 
  # usage:
Line 284: Line 305:
 
  DELDATE=`date --date="$((2*${ZSK_VALID}+1)) months" +%Y%m%d`
 
  DELDATE=`date --date="$((2*${ZSK_VALID}+1)) months" +%Y%m%d`
 
   
 
   
  ZSK=`dnssec-keygen -r /dev/urandom -K ${KEYDIR_BACKUP} -I ${INADATE} -D ${DELDATE} -S ${KEYDIR_ZONE}/${ZSK_CURR} -L 18000 2> /dev/null`
+
  ZSK=`dnssec-keygen -r /dev/urandom -K ${KEYDIR_BACKUP} -I ${INADATE} -D ${DELDATE} -S ${KEYDIR_ZONE}/${ZSK_NEXT}.key -L 18000 2> /dev/null`
 
  if [ $? -ne 0 ]; then
 
  if [ $? -ne 0 ]; then
 
   MSG="ZONE[${ZONE}] ZSK not created, please investigate!"
 
   MSG="ZONE[${ZONE}] ZSK not created, please investigate!"
Line 298: Line 319:
 
  [ -f "${KEYDIR_ZONE}/${ZSK_PREV}.key" ] && rm -rf "${KEYDIR_ZONE}/${ZSK_PREV}.key"
 
  [ -f "${KEYDIR_ZONE}/${ZSK_PREV}.key" ] && rm -rf "${KEYDIR_ZONE}/${ZSK_PREV}.key"
 
  [ -f "${KEYDIR_ZONE}/${ZSK_PREV}.private" ] && rm -rf "${KEYDIR_ZONE}/${ZSK_PREV}.private"
 
  [ -f "${KEYDIR_ZONE}/${ZSK_PREV}.private" ] && rm -rf "${KEYDIR_ZONE}/${ZSK_PREV}.private"
 +
echo "# $(date)" >> ${KEYDIR_STATUS}
 
  echo "ZSK_PREV='${ZSK_CURR}'" >> ${KEYDIR_STATUS}
 
  echo "ZSK_PREV='${ZSK_CURR}'" >> ${KEYDIR_STATUS}
 
  echo "ZSK_CURR='${ZSK_NEXT}'" >> ${KEYDIR_STATUS}
 
  echo "ZSK_CURR='${ZSK_NEXT}'" >> ${KEYDIR_STATUS}
Line 303: Line 325:
  
 
==== Monitoring ====
 
==== Monitoring ====
* kritická součást nasazení DNSSEC, protože '''''při expiraci podepsaných záznamů nebude nic fungovat'''''
+
* kritická součást nasazení DNSSEC, protože '''''po expiraci podepsaných záznamů nebude nic fungovat'''''
 +
** musí být funkční automatický update podpisů v rámci ISC Bind viz. informace o [[ns.fjfi.cvut.cz#Poznámky|sig-validity-interval]]
 +
** musí fungovat rotování ZSK (případně KSK) klíčů resp. k tomu určený [[ns.fjfi.cvut.cz#Skript pro rotování posledních 3 ZSK|skrip spouštěný pravidelně z cronu]]
 +
*** uvedený skript byl psán tak aby něco nezničil - při neočekávaném/chybovém stavu se ukončí
 +
*** informaci o neúspěchu vypíše do logů a na stdout (při spouštění z cronu by měl správce dostat mail)
 +
*** stejně se ale předpokládá, že poběží další kontrola např. pomocí níže uvedené konfigurace Nagiosu
 
* aktuálně monitorován Nagiosem pomocí [https://github.com/pawal/dnssec-monitor pluginů pro validaci DNSSEC záznamů]
 
* aktuálně monitorován Nagiosem pomocí [https://github.com/pawal/dnssec-monitor pluginů pro validaci DNSSEC záznamů]
 
** umožňují základní validaci SOA záznamů ale i celé zóny při povoleném AXFR transferu zónových dat
 
** umožňují základní validaci SOA záznamů ale i celé zóny při povoleném AXFR transferu zónových dat
Line 346: Line 373:
 
** změna délky ZSK klíče je bezproblémová
 
** změna délky ZSK klíče je bezproblémová
 
** změna algoritmu ZSK (KSK) je komplikováná a v takovém případě je nutné si tuhle proceduru předem odzkoušet!!! Navíc se při různých klíčích bind 9.9.4 v jistý okamžik zbláznil, neustále načítal znovu klíče z disku, negeneroval nové podpisy v postižené zóně a přitom vytěžoval CPU na 100% (pomohlo až expirování starých klíčů pomocí <tt>dnssec-settime -D now <i>keyname</i></tt>)
 
** změna algoritmu ZSK (KSK) je komplikováná a v takovém případě je nutné si tuhle proceduru předem odzkoušet!!! Navíc se při různých klíčích bind 9.9.4 v jistý okamžik zbláznil, neustále načítal znovu klíče z disku, negeneroval nové podpisy v postižené zóně a přitom vytěžoval CPU na 100% (pomohlo až expirování starých klíčů pomocí <tt>dnssec-settime -D now <i>keyname</i></tt>)
 +
* algoritmy klíčů
 +
** délka DNSSEC podpisů závisí na použitém algoritmu a počtu bitů klíče
 +
** řešíme kompromis mezi délkou klíče a bezpečností (to je také důvod proč se rozlišují KSK a ZSK resp. jejich délka) s ohledem na potenciální problémy s velkými UDP pakety (fragmentace, EDNS, ...) resp. fallbackem na TCP
 +
** aktuálně jsou asi nejvhodnější eliptické křivky (s ohledem na velikosti podpisů při dané délce klíče), ale osobně s nimi zatím nemám praktické zkušenosti (tj. jestli je např. podporují všechny validující klienti)
 
* využití DNSSEC
 
* využití DNSSEC
 
** SSHFP (RFC 4255) - publikování SSH fingerprintu přes DNS - po zapnutí volby <tt>VerifyHostKeyDNS yes</tt> se nové SSH klíče automaticky ověří proti SSHFP záznamu v DNS
 
** SSHFP (RFC 4255) - publikování SSH fingerprintu přes DNS - po zapnutí volby <tt>VerifyHostKeyDNS yes</tt> se nové SSH klíče automaticky ověří proti SSHFP záznamu v DNS
 
** DANE (RFC 6698) standard a publikovani [https://ssl-tools.net/tlsa-generator TLSA zaznamu], viz. např. [http://blog.nic.cz/2014/01/23/postfix-dostal-podporu-pro-dane-protokol/ konfigurace postfixu]
 
** DANE (RFC 6698) standard a publikovani [https://ssl-tools.net/tlsa-generator TLSA zaznamu], viz. např. [http://blog.nic.cz/2014/01/23/postfix-dostal-podporu-pro-dane-protokol/ konfigurace postfixu]
 +
 +
===DNSSEC 2016 (ČVUT) ===
 +
 +
V souvislosti s podepsáním zóny <tt>cvut.cz</tt> bylo provedeno několik změn v konfiguraci DNSSEC pro subdoménu <tt>fjfi.cvut.cz</tt>. Vzhledem k tomu, že se správce nadřazené zóny rozhodl pro podpisy použít ECDSAP256SHA256 (alg-13), tak i naše lokální zóna byla podepsána stejným algoritmem. Navíc stejně jako v nadřazené zóně používáme CSK (Combined Signing Key), který výrazně zjednodušuje management DNSSEC klíčů oproti klasickému KSK/ZSK. CSK má oproti klasickému přístupu některé nevýhody hlavně s ohledem na prostředí, kde je vyžadován vysoký stupeň zabezpečení (např. KSK může být držen offline, při výměně ZSK není potřeba provádět změny DS záznamů v nadřazené zóně, ...). Vlastnosti a použití ECDSA s DNSSEC jsou pěkně shrunuty ve článku [http://www.sigcomm.org/sites/default/files/ccr/papers/2015/October/0000000-0000002.pdf Making the Case for Elliptic Curves in DNSSEC].
 +
 +
* zrychlení generování náhodných čísel používaných při podepisování zónových souborů
 +
yum install haveged
 +
systemctl enable haveged
 +
systemctl start haveged
 +
 +
* ECDSA Curve P-256 with SHA256 je v současnosti považována za dostatečně bezpečnou a tak se nebudeme vůbec zabývat rotací klíčů (předpokládám, že vždy při zásadním upgradu DNS infrastruktury bude přehodnocena i konfigurace DNSSEC)
 +
 +
dnssec-keygen -a ECDSAP256SHA256 -fK fjfi.cvut.cz
 +
chgrp named Kfjfi.cvut.cz.+013+38165.*
 +
chmod g+r Kfjfi.cvut.cz.+013+38165.private
 +
 +
* výměna klíče
 +
# vygenerování nového, viz. výše
 +
rndc sign fjfi.cvut.cz
 +
dnssec-settime -I now -D +35d Kfjfi.cvut.cz.+013+38165

Latest revision as of 00:51, 12 May 2016

Servery / Služby
Přístupné komukoliv
windows
srk
linux / unix
kmlinux
Omezený/individuální účet
linux / unix
bimbo · buon(KF) · km(KM) · lenochod(KJR) · linux · node(KM) · sunrise(KF) · unixlab(KFE) · vkstat(KM)
Služby
backup · DHCP · DNS · doména FJFI · eduroam · fileserver · IdM · forum · gitlab · lists · moodle · indico · mailgw · K4 · mailserver · NMS · openvpn · skolniftp · ssh · videokonference · VoIP · video · VPN · wififjfi · wiki · www
Učebny
e-sklipek · KFE unixlab · KFE pclab · PD1 · KM 105 · KM 115
Ostatní
Network · Blokované porty
[edit] · [view]

Základní informace

Správce 
Petr Vokáč
HW 
T1119 miniITX 1U Intel Atom 525 (dualcore), X7SPE-HF-D525 (PCI-E8,2GLAN,2SFF,front IO/C)
OS 
CentOS7
Využití 
nameserver pro doménu fjfi.cvut.cz
Konto 
-

Instalace a konfigurace

  • standardní (minimální) instalace operačního systému
  • standardní puppet konfigurace pro server (certifikáty, logging, monitoring, kerberos, ...)
  • konfigurace mailu - přeposílání mailů pro root účet pomocí /etc/aliases
  • specifický software a konfigurace
    • ISC bind
      • konfigurace v /etc/named.*, /etc/named
      • data uložena v /var/named
    • firewall
firewall-cmd --permanent --add-service=dns
firewall-cmd --pernament --add-rich-rule='rule family="ipv4" source address="mgmt.srv.ip.addr" port port="rndc" protocol="tcp" accept'
firewall-cmd --pernament --add-rich-rule='rule family="ipv6" source address="mgmt.srv.ip.addr" port port="rndc" protocol="tcp" accept'
# další specifická IP+porty pro monitoring, zálohování, ...
firewall-cmd --reload

Konfigurace

  • změny mohou provádět vybraní správci
  • informace ke konfiguraci ISC Bind
    • podpora GSS-TSIG DDNS update z Windows Serverů (je potřeba zkonfigurovat, aby se nepoužívali/nezkoušeli updaty bez GSS-TSIG)
    • nejsem si teď na 100% jist, jestli GSS-TSIG z Windows funguje při kompilaci s --disable-isc-spnego (standardně aplikováno ve RHEL)
  • v testování je clusterové řešení (postavené na RH cluster suite), ale pravděpodobně jen pro rekurzivní/cachovací DNS
  • v plánu je support pro DNSSEC (po podepsání nadřazené domény) - hotovo s prozatimním ukotvením přes DLV
  • v plánu jsou různá view pro vnitřní a externí sítě

Automatické změny

  • některá DNS záznamy jsou automaticky updatovány v závislosti na aktuální dostupnosti služeb
    • změny jsou prováděny DnsHA.py skriptem běžícím na nms.fjfi.cvut.cz
    • ruční změny těchto záznamů budou do pěti minut znovu přepsány
    • automatické updaty lze disablovat (viz. konfigurace DDNS HA)
  • smtp.fjfi.cvut.cz -> směřuje na mailgw1.fjfi.cvut.cz resp. mailgw2.fjfi.cvut.cz dle dostupnosti
  • ldap[1-3].fjfi.cvut.cz, krb[1-3].fjfi.cvut.cz, wc[1-3].fjfi.cvut.cz -> směřuje na dostupné doménové kontrolery
  • *.dhcp.fjfi.cvut.cz, *.7.32.147.in-addr.arpa, *.11.32.147.in-addr.arpa -> aktualizováno DHCP serverem při přidělení adresy síťovému zařízení
  • *.radvd.fjfi.cvut.cz -> aktualizováno na základě informací o registrovaném zařízení, týká se zařízení u nichž je uvedena IPv6 adresa "dynamic". Podle informací o umístění zařízení (Břehová, Trojanova, Trója, Mobilní) se generují různé záznamy pro všechny podsítě, kde se může zařízení vyskytovat. DNS jména pak mohou vypadat následujícím způsobem def-tjn-123-untrusted.radvd.fjfi.cvut.cz.
# TODO - details about these DnsHA updated records
ldap.fjfi.cvut.cz (resp. ldap1.fjfi.cvut.cz, ldap2.fjfi.cvut.cz, ldap3.fjfi.cvut.cz)
krb.fjfi.cvut.cz (resp. krb1.fjfi.cvut.cz, krb2.fjfi.cvut.cz, krb3.fjfi.cvut.cz)
imap.fjfi.cvut.cz
mail.fjfi.cvut.cz resp. webmail.fjfi.cvut.cz
ntp.fjfi.cvut.cz
people.fjfi.cvut.cz
kms.fjfi.cvut.cz
_vlmcs._tcp.fjfi.cvut.cz

DNSSEC

Quick start for ISC Bind

Prvotní inicializace a konfigurace

mkdir -p /etc/named/keys/fjfi.cvut.cz
cd /etc/named/keys/fjfi.cvut.cz
dnssec-keygen -r /dev/urandom -3 -a RSASHA512 -b 1024 fjfi.cvut.cz
dnssec-keygen -r /dev/urandom -3 -a RSASHA512 -b 2048 -f KSK fjfi.cvut.cz
chown named:named Kfjfi.cvut.cz.+*+*.key
chown named:named Kfjfi.cvut.cz.+*+*.private
  • upravení konfigurace pro automatické podepisování zóny
zone "fjfi.cvut.cz" {
  // ...
  # look for dnssec keys here
  key-directory "/etc/named/keys/fjfi.cvut.cz";
  # publish and activate dnssec keys
  auto-dnssec maintain;
  # use inline signing (bind 9.9)
  inline-signing yes;
  # change signature validity interval (default: 30 [24]; )
  //sig-validity-interval 60 30;
};
  • reloadnutí konfigurace
rndc reconfig
  • vygenerování NSEC3 seedu - způsobí přegenerování NSEC záznamů na NSEC3
rndc signing -nsec3param 1 0 10 $(printf "%04x%04x" $RANDOM $RANDOM) fjfi.cvut.cz
  • při používání dynamických updatů (a z minulosti existujících *.jnl souborů) přestal DDNS fungovat, opraveno zavoláním
rndc sync -clean

Otestování konfigurace

  • aplikace upravené konfigurace a par užitečných příkazů pro zjištění aktuálního stavu
rndc reconfig
# vylistování aktuálně načtených klíčů
rndc signing -list fjfi.cvut.cz
# kontrola podpisů v zóně
dig +dnssec +noall +answer @127.0.0.1 -t SOA fjfi.cvut.cz
dig @127.0.0.1 AXFR fjfi.cvut.cz
# čitelné vypsání zkompilované zóny
named-compilezone -f raw -F text -o - fjfi.cvut.cz data/fjfi.cvut.cz.zone.signed
named-checkzone -D -f raw -o - fjfi.cvut.cz data/fjfi.cvut.cz.zone.signed

Ukotvení DNSSEC

  • aby se DNS resolvery měli šanci důvěryhodně dozvědět, že používáme DNSSEC, je nutné vypropagovat DS záznamy a to buď to testovacího dlv.isc.org (ISC Bind, Unbound a asi i většina ostatních rekurzivní DNS používá i DLV jako důvěryhodný kořen) nebo přímo do rodičovské domény
# získání DS záznamů
dig @127.0.0.1 dnskey fjfi.cvut.cz | dnssec-dsfromkey -f - fjfi.cvut.cz
dnssec-dsfromkey -a SHA-1 Kexample.net.+008+50707.key
dnssec-dsfromkey -a SHA-256 Kexample.net.+008+50707.key
  • získané DS záznamy je nutné přidat do zóny rodičovské domény (mam pocit že by měl stačit ten "lepší" SHA-256 hash)
  • pro testovací DLV databázi na dlv.isc.org je postup dostatečně zřejmý z informací na webu (vkládají se přímo celé DSKEY misto DS hashů)
  • pro reverzní záznamy se informace zadávají přimo do RIPE databáze (pro ČVUT reverzy na to ma práva CESNET), ale reverzy nejsou pro bezpečnost DNSSEC tak kritické, protože nenesou informace (SSHFP, TLSA, ...), které bez DNSSEC zabezpeční nelze vůbec využít

Rotování klíčů

  • základní informace jsou v RFC 4641 a konkrétní informace k ISC Bind
  • standardní velikost klíčů je 1024 bitů pro ZSK a 2048 bitů pro KSK (velikost by měla odpovídat důležitosti domény resp. její postavení v hierarchii domén)
  • doporučená doba rotace ZSK klíčů je 90 dní a pro KSK klíče 2 roky (viz. pravidla pro .cz doménu)
    • pokud nedojde ke kompromitaci KSK nebo nejakému zásadnímu problému s použitým šifrováním tak rotování KSK není v principu potřeba (podepisují se jím pouze nové ZSK, tj. celá řada útoků vyžadující velký vzorek zašifrovaných dat není prakticky proveditelná)
  • výše vygenerované klíče nemají omezenou platnost a lze ji změnit pomocí
dnssec-settime -I 20141001 -D 20141101 Kfjfi.cvut.cz.+007+first.key
  • pro ZSK je asi nejvhodnější použít Pre-Publish Key Rollover
  • vždy budou publikovány dva ZSK klíče z nichž právě jeden bude aktivní
  • nový klíč se stejnými parametry a správnými hodnotami pro publikaci a aktivaci (pokud není změněno sig-validity-interval) lze vygenerovat
dnssec-keygen -r /dev/urandom -I 20141001 -D 20141101 -S Kfjfi.cvut.cz.+ZSK+current.key
Skript pro vygenerování prvních KSK/ZSK
#!/bin/bash
# This script can be used to create initial DNSSEC KSK/ZSK
# Update global configuration section at the beggining of this script.
# usage:
#   DNSSEC-CREATE fjfi.cvut.cz

# global configuration
KEYDIR='/etc/named/keys'
ZSK_VALID=3      # ZSK is valid for 3 months
KSK_VALID=120    # KSK is valid for 10 years
NUSER='named'    # user account for files with new keys
NGROUP='named'   # group for files with new keys


if [ $# -lt 1 ]; then
  echo "usage: $0 zone"
  echo "example: $0 fjfi.cvut.cz"
  exit 1
fi

SCRIPT_NAME=$0
ZONE=$1
KEYDIR_ZONE="${KEYDIR}/${ZONE}"
KEYDIR_BACKUP="${KEYDIR}/BACKUP/${ZONE}"
KEYDIR_STATUS="${KEYDIR}/${ZONE}.status"


# don't overwrite existing configuration
if [ -d ${KEYDIR_ZONE} -o -d ${KEYDIR_BACKUP} -o -f ${KEYDIR_STATUS} ]; then
  echo "Configuration for ${ZONE} already exists, exitting..."
  exit 1
fi

# create directories for our keys
mkdir -p ${KEYDIR_ZONE}
mkdir -p ${KEYDIR_BACKUP}
#chown ${NUSER}:${NGROUP} ${KEYDIR_ZONE}
#chown ${NUSER}:${NGROUP} ${KEYDIR_BACKUP}


# create first KSK (key signing key)
INADATE=`date --date="${KSK_VALID} months" +%Y%m%d`
DELDATE=`date --date="$((${KSK_VALID}+1)) months" +%Y%m%d`

KSK=`dnssec-keygen -r /dev/urandom -K ${KEYDIR_BACKUP} -I ${INADATE} -D ${DELDATE} -3 -a RSASHA512 -b 2048 -f KSK ${ZONE}`
chown ${NUSER}:${NGROUP} ${KEYDIR_BACKUP}/${KSK}.*
cp -a ${KEYDIR_BACKUP}/${KSK}.key ${KEYDIR_ZONE}
cp -a ${KEYDIR_BACKUP}/${KSK}.private ${KEYDIR_ZONE}
echo "KSK_CURR='${KSK}'" >> ${KEYDIR_STATUS}


# create first ZSK (zone signing key)
INADATE=`date --date="${ZSK_VALID} months" +%Y%m%d`
DELDATE=`date --date="$((${ZSK_VALID}+1)) months" +%Y%m%d`

ZSK=`dnssec-keygen -r /dev/urandom -K ${KEYDIR_BACKUP} -I ${INADATE} -D ${DELDATE} -3 -a RSASHA512 -b 1024 -L 18000 ${ZONE}`
chown ${NUSER}:${NGROUP} ${KEYDIR_BACKUP}/${ZSK}.*
cp -a ${KEYDIR_BACKUP}/${ZSK}.key ${KEYDIR_ZONE}
cp -a ${KEYDIR_BACKUP}/${ZSK}.private ${KEYDIR_ZONE}
echo "ZSK_CURR='${ZSK}'" >> ${KEYDIR_STATUS}


# create next ZSK (zone signing key), because script for key rotation relay on existing current+next key
INADATE=`date --date="$((2*${ZSK_VALID})) months" +%Y%m%d`
DELDATE=`date --date="$((2*${ZSK_VALID}+1)) months" +%Y%m%d`

ZSK=`dnssec-keygen -r /dev/urandom -K ${KEYDIR_BACKUP} -I ${INADATE} -D ${DELDATE} -S ${KEYDIR_ZONE}/${ZSK}.key -L 18000`
chown ${NUSER}:${NGROUP} ${KEYDIR_BACKUP}/${ZSK}.*
cp -a ${KEYDIR_BACKUP}/${ZSK}.key ${KEYDIR_ZONE}
cp -a ${KEYDIR_BACKUP}/${ZSK}.private ${KEYDIR_ZONE}
echo "ZSK_NEXT='${ZSK}'" >> ${KEYDIR_STATUS}

# show command that can be used to create NSEC3 seed
SEED=`printf '%04x%04x' $RANDOM $RANDOM`
echo "# if you want to use NSEC3 instead of NSEC, execute following command"
echo "rndc signing -nsec3param 1 0 10 ${SEED} ${ZONE}"
Skript pro rotování posledních 3 ZSK
#!/bin/bash
# This script can be used for simple DNSSEC ZSK rotation using 3 keys (prev, curr, next)
# Update global configuration section at the beggining of this script.
# usage:
#   echo "/path/to/this/script/DNSSEC-ROTATE fjfi.cvut.cz" >> /etc/cron.daily/DNSSEC-ROTATE-fjfi.cvut.cz

# global configuration
KEYDIR='/etc/named/keys'
ZSK_VALID=3      # ZSK is valid for 3 months
KSK_VALID=120    # KSK is valid for 10 years
NUSER='named'    # user account for files with new keys
NGROUP='named'   # group for files with new keys


# use command line arguments
if [ $# -lt 1 ]; then
  echo "usage: $0 zone"
  echo "example: $0 fjfi.cvut.cz"
  exit 1
fi

SCRIPT_NAME=$0
ZONE=$1
KEYDIR_ZONE="${KEYDIR}/${ZONE}"
KEYDIR_BACKUP="${KEYDIR}/BACKUP/${ZONE}"
KEYDIR_STATUS="${KEYDIR}/${ZONE}.status"


# check files required before running this key rolling script
if [ ! -f ${KEYDIR_STATUS} ]; then
  MSG="ZONE[${ZONE}] zone status file ${KEYDIR_STATUS} doesn't exist, use KEYS-FIRST to create keys and initial status file"
  logger -t ${SCRIPT_NAME} -p user.error "${MSG}"
  echo "${MSG}"
  exit 1
fi

. ${KEYDIR_STATUS}

if [ -z ${ZSK_CURR} ]; then
  MSG="ZONE[${ZONE}] ZSK current key not defined in ${KEYDIR_STATUS}"
  logger -t ${SCRIPT_NAME} -p user.error "${MSG}"
  echo "${MSG}"
  exit 1
fi
if [ -z ${ZSK_NEXT} ]; then
  MSG="ZONE[${ZONE}] ZSK next key not defined in ${KEYDIR_STATUS}"
  logger -t ${SCRIPT_NAME} -p user.error "${MSG}"
  echo "${MSG}"
  exit 1
fi
if [ ! -f "${KEYDIR_ZONE}/${ZSK_CURR}.key" -o ! -f "${KEYDIR_ZONE}/${ZSK_CURR}.private" ]; then
  MSG="ZONE[${ZONE}] ZSK current key file ${KEYDIR_ZONE}/${ZSK_CURR}.{key,private} doesn't exists"
  logger -t ${SCRIPT_NAME} -p user.error "${MSG}"
  echo "${MSG}"
  exit 1
fi
if [ ! -f "${KEYDIR_ZONE}/${ZSK_NEXT}.key" -o ! -f "${KEYDIR_ZONE}/${ZSK_NEXT}.private" ]; then
  MSG="ZONE[${ZONE}] ZSK current key file ${KEYDIR_ZONE}/${ZSK_NEXT}.{key,private} doesn't exists"
  logger -t ${SCRIPT_NAME} -p user.error "${MSG}"
  echo "${MSG}"
  exit 1
fi


# for safety check local time with NTP servers,
# because key validity depends on correct time setting
TIMESYNC=`ntpdate -q -s -p 2 tik.cesnet.cz tak.cesnet.cz | sed -e 's/.*offset //' -e 's/\..*//' | sort -n | tail -1`
#if [ $? -ne 0 -o "x${TIMESYNC}" == "x" -o "${TIMESYNC}" -gt 0 ]; then
if [ $? -ne 0 -o "${TIMESYNC}" -gt 0 ]; then
  MSG="ZONE[${ZONE}] ZSK can't be checked, because local time is not synchronized ${TIMESYNC}"
  logger -t ${SCRIPT_NAME} -p user.error "${MSG}"
  echo "${MSG}"
  exit 1
fi


# check validity of current keys
LASTDATE=`grep -E '^Inactive: [0-9]*$' ${KEYDIR_ZONE}/${ZSK_CURR}.private | sed 's/.*: //'`
if [ -z ${LASTDATE} ]; then
  logger -t ${SCRIPT_NAME} -p user.info "ZONE[${ZONE}] ZSK never expires"
  exit 0
fi
if [ `date +%Y%m%d%H%M%S` -lt ${LASTDATE} ]; then
  logger -t ${SCRIPT_NAME} -p user.info "ZONE[${ZONE}] ZSK inactivate date ${LASTDATE} is in future"
  exit 0
fi


# create next ZSK (zone signing key)
logger -t ${SCRIPT_NAME} -p user.info "ZONE[${ZONE}] ZSK current key is inactive from ${LASTDATE}, rotating keys"

INADATE=`date --date="$((2*${ZSK_VALID})) months" +%Y%m%d`
DELDATE=`date --date="$((2*${ZSK_VALID}+1)) months" +%Y%m%d`

ZSK=`dnssec-keygen -r /dev/urandom -K ${KEYDIR_BACKUP} -I ${INADATE} -D ${DELDATE} -S ${KEYDIR_ZONE}/${ZSK_NEXT}.key -L 18000 2> /dev/null`
if [ $? -ne 0 ]; then
  MSG="ZONE[${ZONE}] ZSK not created, please investigate!"
  logger -t ${SCRIPT_NAME} -p user.error "${MSG}"
  echo "${MSG}"
  exit 1
fi
chown ${NUSER}:${NGROUP} ${KEYDIR_BACKUP}/${ZSK}.*

# rotate old files and copy new files
cp -a ${KEYDIR_BACKUP}/${ZSK}.key ${KEYDIR_ZONE}
cp -a ${KEYDIR_BACKUP}/${ZSK}.private ${KEYDIR_ZONE}
[ -f "${KEYDIR_ZONE}/${ZSK_PREV}.key" ] && rm -rf "${KEYDIR_ZONE}/${ZSK_PREV}.key"
[ -f "${KEYDIR_ZONE}/${ZSK_PREV}.private" ] && rm -rf "${KEYDIR_ZONE}/${ZSK_PREV}.private"
echo "# $(date)" >> ${KEYDIR_STATUS}
echo "ZSK_PREV='${ZSK_CURR}'" >> ${KEYDIR_STATUS}
echo "ZSK_CURR='${ZSK_NEXT}'" >> ${KEYDIR_STATUS}
echo "ZSK_NEXT='${ZSK}'" >> ${KEYDIR_STATUS}

Monitoring

  • kritická součást nasazení DNSSEC, protože po expiraci podepsaných záznamů nebude nic fungovat
    • musí být funkční automatický update podpisů v rámci ISC Bind viz. informace o sig-validity-interval
    • musí fungovat rotování ZSK (případně KSK) klíčů resp. k tomu určený skrip spouštěný pravidelně z cronu
      • uvedený skript byl psán tak aby něco nezničil - při neočekávaném/chybovém stavu se ukončí
      • informaci o neúspěchu vypíše do logů a na stdout (při spouštění z cronu by měl správce dostat mail)
      • stejně se ale předpokládá, že poběží další kontrola např. pomocí níže uvedené konfigurace Nagiosu
  • aktuálně monitorován Nagiosem pomocí pluginů pro validaci DNSSEC záznamů
    • umožňují základní validaci SOA záznamů ale i celé zóny při povoleném AXFR transferu zónových dat
    • konfigurace Nagiosu
define command{
       command_name    check_dnssec
       command_line    $USER1$/nagios_dnssec.pl --nsec3 --zone $ARG1$ --kskwarning=$ARG2$ --kskcritical=$ARG3$ --zskwarning=$ARG2$ --zskcritical=$ARG3$ $HOSTADDRESS
}
define command{
       command_name    check_dnssec_zone
       command_line    $USER1$/nagios_zonecheck.pl --zone $ARG1$ --warning=$ARG2$ --critical=$ARG3$ $HOSTADDRESS
}
define service{
       name                            dnssec-service
       #use                             critical-service,linux-service,dnssec-service
       service_description             DNSSEC
       #servicegroups                   +dns
       check_command                   check_dnssec!fjfi.cvut.cz!16!20
}
define service{
       name                            dnssec-zone-service
       #use                             critical-service,linux-service,dnssec-service
       service_description             ZDNSSEC
       #servicegroups                   +dns
       check_command                   check_dnssec_zone!fjfi.cvut.cz!28!16
       # this check does whole AXFR zone transfer, check only once a day
       check_interval                  1440
}

Poznámky

  • SOA minimum TTL by měl být relativně krátký
    • význam této položky byl v historii různý
    • nyní je používána jako délka cachování negativních odpovědí (RFC 2308)
    • pokud něco uděláme špatně (zapomeneme publikovat nějaký důležitý záznam pro DNSSEC), tak je vhodné aby negativní cache expirovala relativně brzy
    • doporučený čas je v desítkách minut až jednotek hodin
  • sig-validity-interval
    • je standardně nastaven na 30 24 dní (vygenerovaný podpis je platný po 30 dní a bude přegenerován 6 dní před exprirací)
    • podle mě je vhodné aby interval mezi expirací a automatickým přepodepisováním pokryl dobu expirace zóny uvedené v SOA + dobu maximálního TTL uvedeného pro některý záznam v dané zóně
    • naše potřeby (expirace zóny 2 týdny + expirace záznamů 1 den) lze použít např. hodnoty 30 14 (nebo třeba 60 44)
  • změny vlastností klíčů
    • není problém prodloužit platnost klíče pomocí dnssec-settime, pokud je aktuální datum uvnitř intervalu (published, deleted) - např. pokud se blíží doba expirace KSK a ještě nejsme připraveni na jeho rotování
    • změna délky ZSK klíče je bezproblémová
    • změna algoritmu ZSK (KSK) je komplikováná a v takovém případě je nutné si tuhle proceduru předem odzkoušet!!! Navíc se při různých klíčích bind 9.9.4 v jistý okamžik zbláznil, neustále načítal znovu klíče z disku, negeneroval nové podpisy v postižené zóně a přitom vytěžoval CPU na 100% (pomohlo až expirování starých klíčů pomocí dnssec-settime -D now keyname)
  • algoritmy klíčů
    • délka DNSSEC podpisů závisí na použitém algoritmu a počtu bitů klíče
    • řešíme kompromis mezi délkou klíče a bezpečností (to je také důvod proč se rozlišují KSK a ZSK resp. jejich délka) s ohledem na potenciální problémy s velkými UDP pakety (fragmentace, EDNS, ...) resp. fallbackem na TCP
    • aktuálně jsou asi nejvhodnější eliptické křivky (s ohledem na velikosti podpisů při dané délce klíče), ale osobně s nimi zatím nemám praktické zkušenosti (tj. jestli je např. podporují všechny validující klienti)
  • využití DNSSEC
    • SSHFP (RFC 4255) - publikování SSH fingerprintu přes DNS - po zapnutí volby VerifyHostKeyDNS yes se nové SSH klíče automaticky ověří proti SSHFP záznamu v DNS
    • DANE (RFC 6698) standard a publikovani TLSA zaznamu, viz. např. konfigurace postfixu

DNSSEC 2016 (ČVUT)

V souvislosti s podepsáním zóny cvut.cz bylo provedeno několik změn v konfiguraci DNSSEC pro subdoménu fjfi.cvut.cz. Vzhledem k tomu, že se správce nadřazené zóny rozhodl pro podpisy použít ECDSAP256SHA256 (alg-13), tak i naše lokální zóna byla podepsána stejným algoritmem. Navíc stejně jako v nadřazené zóně používáme CSK (Combined Signing Key), který výrazně zjednodušuje management DNSSEC klíčů oproti klasickému KSK/ZSK. CSK má oproti klasickému přístupu některé nevýhody hlavně s ohledem na prostředí, kde je vyžadován vysoký stupeň zabezpečení (např. KSK může být držen offline, při výměně ZSK není potřeba provádět změny DS záznamů v nadřazené zóně, ...). Vlastnosti a použití ECDSA s DNSSEC jsou pěkně shrunuty ve článku Making the Case for Elliptic Curves in DNSSEC.

  • zrychlení generování náhodných čísel používaných při podepisování zónových souborů
yum install haveged
systemctl enable haveged
systemctl start haveged
  • ECDSA Curve P-256 with SHA256 je v současnosti považována za dostatečně bezpečnou a tak se nebudeme vůbec zabývat rotací klíčů (předpokládám, že vždy při zásadním upgradu DNS infrastruktury bude přehodnocena i konfigurace DNSSEC)
dnssec-keygen -a ECDSAP256SHA256 -fK fjfi.cvut.cz
chgrp named Kfjfi.cvut.cz.+013+38165.*
chmod g+r Kfjfi.cvut.cz.+013+38165.private 
  • výměna klíče
# vygenerování nového, viz. výše
rndc sign fjfi.cvut.cz
dnssec-settime -I now -D +35d Kfjfi.cvut.cz.+013+38165