Le rôle de l’AS112
Cet AS est assez spécial, il sert de trou noir du DNS. C’est aussi l’une des premières utilisations de l’anycast.
En regardant la charge des serveurs racines du DNS, les administrateurs se
sont rendu compte qu’une quantité non négligeable de requêtes étaient des
demandes de PTR sur les adresses 1918. La parade est donc de créer une
délégation pour ces zones et d’avoir des serveurs qui répondent que le
domaine n’existe pas avec un très grand TTL. Ainsi, les serveurs racines
seront soulagés de ces requêtes le temps que le TTL expire.
Le serveur doit répondre sur cinq IPs différentes :
- prisoner.iana.org car c’est le serveur maître renseigné dans le SOA,
- blackhole-1.iana.org et blackhole-2.iana.org car les zones sont déléguées dessus,
- blackhole.as112.arpa afin de supporter les redirections DNAME,
- et bien sûr les IPs anycast du nœud.
Bien évidemment, un administrateur consciencieux ne devrait pas faire sortir ce genre de requêtes de son réseau ; mais nous savons tous que nous ne sommes pas entourés que de gens compétents.
Le projet est défini dans le RFC 6304 et le support d’IPv6 et du DNAME sont
ajoutés dans le RFC 7534.
Un brouillon est en cours de rédaction afin d’ajouter le support de la zone
home.arpa.
Mise en place du nœud
Pour ce nœud j’ai choisi d’utiliser FreeBSD (en 11.1 à l’heure où j’écris ces lignes) avec les implémentations NSD pour le DNS et OpenBGPd pour le BGP.
DNS
Je me suis très fortement inspiré du fichier de configuration donné par Stéphane Bortzmeyer. Je l’ai adapté pour respecter le nouveau nommage de zones et supporter l’IPv6 d’une part, puis pour supporter les statistiques ainsi que quelques autres fioritures d’autre part.
Par défaut, NSD n’est pas compilé avec le support des statistiques dans
FreeBSD, j’ai donc utilisé la version des ports en ajoutant les options
BIND8_STATS
et MUNIN_PLUGIN
. Cette dernière
servira à grapher les requêtes.
Voici les fichiers de configuration actuellement utilisés :
nsd.conf
# NSD configuration file for an AS112 name server. See RFC 6304 and
#
# Inspired from http://www.bortzmeyer.org/6304.html
server:
zonesdir: "/var/db/nsd"
# Replace both with the real name
# CH TXT queries
identity: "hostname.as112.net - grifon node"
# NSID (RFC 5011) queries. *Must* be in hex :-( Use for instance:
# echo -n "ns.example.net" | hexdump -v -e '/1 "%02X"'
nsid: "61733131322e677269666f6e2e6672"
# The default value is too small
tcp-count: 100
tcp-query-count: 10
tcp-timeout: 60
# localhost
ip-address: ::1
ip-address: 127.0.0.1
# Breizh-IX
ip-address: 2001:7f8:b1::12
ip-address: 185.1.89.16
# grifon
ip-address: 2a00:5884:0:100::1:10
ip-address: 89.234.186.134
# AS112
ip-address: 2620:4f:8000::1
ip-address: 2620:4f:8000::6
ip-address: 2620:4f:8000::42
ip-address: 2001:4:112::1
ip-address: 192.175.48.1
ip-address: 192.175.48.6
ip-address: 192.175.48.42
ip-address: 192.31.196.1
logfile: "/var/log/nsd.log"
statistics: 3600
username: nsd
remote-control:
control-enable: yes
# RFC 1918
zone:
name: "10.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "16.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "17.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "18.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "19.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "20.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "21.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "22.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "23.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "24.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "25.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "26.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "27.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "28.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "29.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "30.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "31.172.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
zone:
name: "168.192.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
# RFC 5735
zone:
name: "254.169.in-addr.arpa"
zonefile: "db.dd-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
# DNAME redirection AS112 Service
zone:
name: "empty.as112.arpa"
zonefile: "db.dr-empty"
provide-xfr: 0.0.0.0/0 BLOCKED
notify-retry: 0
# Also answer authoritatively for the HOSTNAME.AS112.NET and
# HOSTNAME.AS112.ARPA zones, which contain data of operational
# relevance.
zone:
name: "hostname.as112.net"
zonefile: "db.hostname.as112.net"
zone:
name: "hostname.as112.arpa"
zonefile: "db.hostname.as112.arpa"
# https://tools.ietf.org/html/draft-ietf-homenet-dot-14
zone:
name: "home.arpa"
zonefile: "db.dd-empty"
# Unlike the sample BIND configuration in RFC 6304, we do not log
# requests: NSD cannot do it and, anyway, it is better done outside of
# the name server, for instance with dnscap
# .
db.dd-empty
; db.empty
;
; Empty zone for AS112 server.
;
$TTL 1W
@ IN SOA prisoner.iana.org. hostmaster.root-servers.org. (
1 ; serial number
1W ; refresh
1M ; retry
1W ; expire
1W ) ; negative caching TTL
;
NS blackhole-1.iana.org.
NS blackhole-2.iana.org.
;
; There should be no other resource records included in this zone.
;
; Records that relate to RFC 1918-numbered resources within the
; site hosting this AS112 node should not be hosted on this
; nameserver.
db.dr-empty
; db.dr-empty
;
; Empty zone for DNAME redirection AS112 service.
;
$TTL 1W
@ IN SOA blackhole.as112.arpa. noc.dns.icann.org. (
1 ; serial number
1W ; refresh
1M ; retry
1W ; expire
1W ) ; negative caching TTL
;
NS blackhole.as112.arpa.
;
; There should be no other resource records included in this zone.
;
; Records that relate to RFC 1918-numbered resources within the
; site hosting this AS112 node should not be hosted on this
; nameserver.
db.hostname.as112.arpa
; db.hostname.as112.net
;
$TTL 1W
@ SOA as112.grifon.fr. adminsys.grifon.fr. (
1 ; serial number
1W ; refresh
1M ; retry
1W ; expire
1W ) ; negative caching TTL
;
NS blackhole-2.iana.org.
NS blackhole-1.iana.org.
;
TXT "grifon" "Rennes, FR"
TXT "See http://www.as112.net/ for more information."
;
LOC 48 51 29.520 N 2 20 19.320 E 0.00m 1m 10000m 10m
db.hostname.as112.net
; db.hostname.as112.net
;
$TTL 1W
@ SOA as112.grifon.fr. adminsys.grifon.fr. (
2017120900 ; serial number
1W ; refresh
1M ; retry
1W ; expire
1W ) ; negative caching TTL
;
NS blackhole-2.iana.org.
NS blackhole-1.iana.org.
;
TXT "grifon" "Rennes, FR"
TXT "See http://www.as112.net/ for more information."
TXT "See https://monitoring.grifon.fr/munin/grifon.fr/as112.grifon.fr/index.html#dns for statistics."
TXT "Unicast IP: 89.234.186.134"
;
LOC 48 51 29.520 N 2 20 19.320 E 0.00m 1m 10000m 10m
BGP
Le nœud est connecté aux deux routeurs de bordure de grifon afin
d’obtenir une vue complète d’Internet. Ces routeurs ne relaient pas
encore l’annonce, ça viendra sûrement un jour, quand je me serai fait
relire ;).
Le nœud est également connecté au serveur de routes de Breizh-IX afin
d’annoncer l’AS sur cet IX.
Les filtres d’AS sont commentés car ils contiennent des routes légitimes, comme 199.71.168.0/21 et 199.71.172.0/22.
root@as112:~ # bgpctl show rib transit-as 64500
flags: * = Valid, > = Selected, I = via IBGP, A = Announced, S = Stale
origin: i = IGP, e = EGP, ? = Incomplete
flags destination gateway lpref med aspath origin
*> 199.71.168.0/21 89.234.186.130 100 0 3.7484 174 19752 21992 64499 64500 3411 i
* 199.71.168.0/21 89.234.186.129 100 0 3.7484 174 19752 21992 64499 64500 3411 i
*> 199.71.168.0/23 89.234.186.130 100 0 3.7484 174 19752 21992 64499 64500 3411 i
* 199.71.168.0/23 89.234.186.129 100 0 3.7484 174 19752 21992 64499 64500 3411 i
*> 199.71.172.0/22 89.234.186.130 100 0 3.7484 174 19752 21992 64499 64500 3411 i
* 199.71.172.0/22 89.234.186.129 100 0 3.7484 174 19752 21992 64499 64500 3411 i
bgpd.conf
router-id 89.234.186.134
AS 112
fib-update yes
network 192.175.48.0/24
network 192.31.196.0/24
network 2620:4f:8000::/48
network 2001:4:112::/48
group "peering" {
softreconfig in yes
softreconfig out yes
announce all
neighbor 89.234.186.129 {
remote-as 204092
descr "Grifon nominoe IPv4"
}
neighbor 2a00:5884:0:100::1:1 {
remote-as 204092
descr "Grifon nominoe IPv6"
}
neighbor 89.234.186.130 {
remote-as 204092
descr "Grifon budic IPv4"
}
neighbor 2a00:5884:0:100::1:2 {
remote-as 204092
descr "Grifon budic IPv6"
}
neighbor 185.1.89.1 {
remote-as 206165
descr "Breizh-IX RS1"
enforce neighbor-as no
set localpref 150
}
neighbor 2001:7f8:b1::1 {
remote-as 206165
descr "Breizh-IX RS1"
enforce neighbor-as no
set localpref 150
}
}
# do not send or use routes from neighbors without further explicit
# configuration
deny from any
deny to any
# filter out prefixes longer than 24 or shorter than 8 bits for IPv4
# and longer than 48 or shorter than 16 bits for IPv6.
allow from any inet prefixlen 8 - 24
allow from any inet6 prefixlen 16 - 48
# filter bogus networks according to RFC5735
deny from any prefix 0.0.0.0/8 prefixlen >= 8 # 'this' network [RFC1122]
deny from any prefix 10.0.0.0/8 prefixlen >= 8 # private space [RFC1918]
deny from any prefix 100.64.0.0/10 prefixlen >= 10 # CGN Shared [RFC6598]
deny from any prefix 127.0.0.0/8 prefixlen >= 8 # localhost [RFC1122]
deny from any prefix 169.254.0.0/16 prefixlen >= 16 # link local [RFC3927]
deny from any prefix 172.16.0.0/12 prefixlen >= 12 # private space [RFC1918]
deny from any prefix 192.0.2.0/24 prefixlen >= 24 # TEST-NET-1 [RFC5737]
deny from any prefix 192.168.0.0/16 prefixlen >= 16 # private space [RFC1918]
deny from any prefix 198.18.0.0/15 prefixlen >= 15 # benchmarking [RFC2544]
deny from any prefix 198.51.100.0/24 prefixlen >= 24 # TEST-NET-2 [RFC5737]
deny from any prefix 203.0.113.0/24 prefixlen >= 24 # TEST-NET-3 [RFC5737]
deny from any prefix 224.0.0.0/4 prefixlen >= 4 # multicast
deny from any prefix 240.0.0.0/4 prefixlen >= 4 # reserved
# filter bogus IPv6 networks according to IANA
deny from any prefix ::/8 prefixlen >= 8
deny from any prefix 0100::/64 prefixlen >= 64 # Discard-Only [RFC6666]
deny from any prefix 2001:2::/48 prefixlen >= 48 # BMWG [RFC5180]
deny from any prefix 2001:10::/28 prefixlen >= 28 # ORCHID [RFC4843]
deny from any prefix 2001:db8::/32 prefixlen >= 32 # docu range [RFC3849]
deny from any prefix 3ffe::/16 prefixlen >= 16 # old 6bone
deny from any prefix fc00::/7 prefixlen >= 7 # unique local unicast
deny from any prefix fe80::/10 prefixlen >= 10 # link local unicast
deny from any prefix fec0::/10 prefixlen >= 10 # old site local unicast
deny from any prefix ff00::/8 prefixlen >= 8 # multicast
## filter bogon AS numbers
## http://www.iana.org/assignments/as-numbers/as-numbers.xhtml
#deny from any AS 23456 # AS_TRANS
#deny from any AS 64496 - 64511 # Reserved for use in docs and code RFC5398
#deny from any AS 64512 - 65534 # Reserved for Private Use RFC6996
#deny from any AS 65535 # Reserved RFC7300
#deny from any AS 65536 - 65551 # Reserved for use in docs and code RFC5398
#deny from any AS 65552 - 131071 # Reserved
#deny from any AS 4200000000 - 4294967294 # Reserved for Private Use RFC6996
#deny from any AS 4294967295 # Reserved RFC7300
allow to any prefix 2620:4f:8000::/48
allow to any prefix 2001:4:112::/48
allow to any prefix 192.175.48.0/24
allow to any prefix 192.31.196.0/24
Post-installation
Statistiques
Si on a compilé NSD avec le support des statistiques bind8 et que l’on a
configuré le support des dites statistiques et de nsd-control, on peut
utiliser un plugin munin qui nous fera de (presque) jolis graphes.
Pour cela, on l’active :
for i in hits memory by_type by_class by_opcode by_rcode zones; do ln -s
/usr/local/share/munin/plugins/nsd_munin_
/usr/local/etc/munin/plugins/nsd_munin_${i}; done
et on ajoute les lignes
demandées dans le code à
/usr/local/etc/munin/plugin-conf.d/plugins.conf
.
Les graphes de ce nœud sont visibles sur le munin de grifon.
J’ai également installé net-snmp afin de collecter les métriques SNMP depuis le LibreNMS et ainsi intégrer le nœud à la weathermap.
Monitoring
Je monitore ce nœud de deux façons : la résolution du SOA de
hostname.as112.arpa sur l’IP unicast de façon distante et la résolution du
SOA de toutes les zones en utilisant NRPE. Je ne peux pas monitorer les
IPs anycast de façon distante car l’icinga tourne chez hivane, je
monitorerais alors le nœud d’hivane et non celui que je mets en place.
Cela nous fait beaucoup trop de tests pour les écrire à la main, j’ai
généré le fichier de conf d’icinga qui va aller taper sur le NRPE avec un
onliner en parsant le fichier de conf de NSD : [root@as112 ~]# for
address in prisoner.iana.org blackhole-1.iana.org blackhole-2.iana.org
blackhole.as112.arpa; do awk -F '"' '/name:/ { print $2 }'
/usr/local/etc/nsd/nsd.conf | grep -v '^$' | while read zone; do printf
"object Service \"nrpe-as112-${zone}-${address}\" {\n\timport
\"generic-service\"\n\n\thost_name = \"as112.grifon.fr\"\n\tcheck_command
= \"nrpe\"\n\tvars.nrpe_command =
\"check_as112"\!"${zone}"\!"${address}\"\n\tvars.sla = \"24x7\"\n}\n\n";
done; done > nrpe.conf
. (et non, je n’ai même pas honte, j’ai pas
l’intention de réutiliser cette ligne un jour). Et j’ai écrit une bête
ligne dans le fichier de configuration du serveur NRPE :
command[check_as112]=/usr/local/libexec/nagios/check_dig -l '$ARG1$'
-H '$ARG2$' -T SOA
.
Annonces
Une fois que j’aurai reçu des retours sur cet article m’indiquant que je
n’ai rien raté, ce nœud sera d’abord mis en production uniquement chez
grifon afin de le tester. J’ai la main sur à peu près tout, ce sera donc
assez facile de débugguer. À ce moment je ferai une annonce sur as112-ops
en disant qu’il n’est pas visible d’Internet et sur la ML d’annonces de
grifon.
Ensuite, il sera mis en production sur Breizh-IX, une annonce sera alors
faite sur la ML de l’IX.
Enfin, si tout se passe bien, il sera peut-être annoncé publiquement, je
répondrai alors à mon premier mail sur as112-ops afin de prévenir du
changement de statut.
Remerciements
Merci à Pierre Emeriaud et à Stéphane Bortzmeyer pour leurs relectures.