Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| user:gp68:unbound [2024-09-02T16:53:38Z] – created gp68 | user:gp68:unbound [2024-09-03T11:03:59Z] (current) – gp68 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Unbound Howto ====== | ====== Unbound Howto ====== | ||
| + | This setup is build as an example to work as tier1 or tier2 server. \\ | ||
| + | There is an update script which sets up all slave zones and does an tier1 anmd tiar2 server test after update. \\ | ||
| + | The update script also checks dnssec basics and updates the files in git. \\ | ||
| + | /// | ||
| + | |||
| ===== Base setup ===== | ===== Base setup ===== | ||
| + | |||
| + | <file txt unbound.conf> | ||
| + | server: | ||
| + | verbosity: 1 | ||
| + | log-queries: | ||
| + | port: 53 | ||
| + | # ---------------------- | ||
| + | # optimizations https:// | ||
| + | # adjust for your needs | ||
| + | # ---------------------- | ||
| + | num-threads: | ||
| + | msg-cache-slabs: | ||
| + | rrset-cache-slabs: | ||
| + | infra-cache-slabs: | ||
| + | key-cache-slabs: | ||
| + | so-reuseport: | ||
| + | key-cache-size: | ||
| + | neg-cache-size: | ||
| + | rrset-cache-size: | ||
| + | msg-cache-size: | ||
| + | # depends on number of cores: 1024/cores - 50 | ||
| + | outgoing-range: | ||
| + | num-queries-per-thread: | ||
| + | so-rcvbuf: 4m | ||
| + | so-sndbuf: 4m | ||
| + | outgoing-num-tcp: | ||
| + | incoming-num-tcp: | ||
| + | stream-wait-size: | ||
| + | # ---------------------- | ||
| + | # can be set to 0 if you don't need | ||
| + | # | ||
| + | statistics-interval: | ||
| + | # ---------------------- | ||
| + | port: 53 | ||
| + | interface: 0.0.0.0 | ||
| + | interface: ::0 | ||
| + | # | ||
| + | # tls setup get ssl keys from letsencrypt | ||
| + | # | ||
| + | interface: 0.0.0.0@853 | ||
| + | interface: ::0@853 | ||
| + | tls-service-key: | ||
| + | tls-service-pem: | ||
| + | # i don't like files :-) | ||
| + | use-syslog: | ||
| + | # ------------------------------------- | ||
| + | # for the first start update files | ||
| + | # named.cache.opennic and opennic.dnskey | ||
| + | # manually | ||
| + | # ------------------------------------- | ||
| + | # drill . ns @161.97.219.84 > named.cache.opennic | ||
| + | # dig -t DNSKEY . @161.97.219.84 | dnssec-dsfromkey -1 -f - . > opennic.dnskey | ||
| + | # dig -t DNSKEY . @161.97.219.84 | dnssec-dsfromkey -2 -f - . > opennic.dnskey | ||
| + | root-hints: | ||
| + | trust-anchor-file: | ||
| + | # -------------------------------------------------- | ||
| + | # dnssec not working at the moment for all domains | ||
| + | # -------------------------------------------------- | ||
| + | harden-dnssec-stripped: | ||
| + | harden-glue: | ||
| + | aggressive-nsec: | ||
| + | # access control for everyone ai and ipv6 | ||
| + | access-control: | ||
| + | access-control: | ||
| + | # no identity needed | ||
| + | hide-identity: | ||
| + | identity: " | ||
| + | hide-version: | ||
| + | version: | ||
| + | tls-system-cert: | ||
| + | # DOS protection | ||
| + | # | ||
| + | # | ||
| + | ratelimit: 100 | ||
| + | # --------------------------------------- | ||
| + | # for start make am empty file | ||
| + | # will be updated by refresh script | ||
| + | # | ||
| + | include: / | ||
| + | # | ||
| + | # enable control via locahhost | ||
| + | remote-control: | ||
| + | control-enable: | ||
| + | |||
| + | include: / | ||
| + | </ | ||
| ===== Refresh script ===== | ===== Refresh script ===== | ||
| + | Gets the opennic root nameserver from the web | ||
| + | |||
| + | <file perl getroot_opennic.pl> | ||
| + | # | ||
| + | |||
| + | use strict; | ||
| + | use warnings; | ||
| + | use XML:: | ||
| + | use Data:: | ||
| + | |||
| + | my @bla = `wget --no-check-certificate -q -O - https:// | ||
| + | |||
| + | my $done=0; | ||
| + | my $res=""; | ||
| + | |||
| + | while ( @bla ) { | ||
| + | my $l = shift @bla; | ||
| + | unless ($done) { | ||
| + | if ( $l =~ / | ||
| + | $done++; | ||
| + | $res = $l; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | $res =~ s/ | ||
| + | $res =~ s/ | ||
| + | $res =~ s/ | ||
| + | $res =~ s/ | ||
| + | $res =~ s/ | ||
| + | $res =~ s/ | ||
| + | $res =~ s/ | ||
| + | if ( $res =~ / | ||
| + | print $1 . " | ||
| + | } | ||
| + | if ( $res =~ / | ||
| + | print $1 . " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Refreshes the files | ||
| + | * opennic.dnskey | ||
| + | * named.cache.opennic | ||
| + | * opennic_server.conf | ||
| + | * opennic_domains.conf | ||
| + | |||
| + | The script locks for single usage and checks the serial of the root zone for changes. | ||
| + | |||
| + | <file bash refresh_base.sh> | ||
| + | #!/bin/bash | ||
| + | |||
| + | # arch linux packets needed: | ||
| + | # - ldns | ||
| + | # - unbound | ||
| + | # - gawk | ||
| + | # - coreutils | ||
| + | # - grep | ||
| + | |||
| + | AWK=/ | ||
| + | CUT=/ | ||
| + | DIG="/ | ||
| + | GREP=/ | ||
| + | PRINTF=/ | ||
| + | SED=/ | ||
| + | KF=opennic.dnskey | ||
| + | CF=named.cache.opennic | ||
| + | SF=opennic_server.conf | ||
| + | DF=opennic_domains.conf | ||
| + | MYIP='< | ||
| + | |||
| + | if [ " | ||
| + | echo "set varieble MYIP in this script" | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | cd `dirname $0` | ||
| + | |||
| + | # Make sure only one copy runs at a time | ||
| + | LOCK=" | ||
| + | r=$($PRINTF %05d $RANDOM) | ||
| + | sleep ${r: | ||
| + | if [ -f $LOCK ]; then | ||
| + | last_serial=$(cat $LOCK) | ||
| + | dt=$((`date +%s` - `date -r $LOCK +%s`)) | ||
| + | if [ $dt -lt 600 ]; then | ||
| + | echo "Last run ${dt}s < 600s left" | ||
| + | exit 0; | ||
| + | else | ||
| + | echo "Last run ${dt}s" | ||
| + | fi | ||
| + | fi | ||
| + | |||
| + | touch $LOCK | ||
| + | |||
| + | # first get any tier1 server to start | ||
| + | NS=( $(./ | ||
| + | |||
| + | echo -n " | ||
| + | |||
| + | for ns in " | ||
| + | echo -n "$ns " | ||
| + | soa=$($DIG -Q SOA . @$ns) | ||
| + | if [ " | ||
| + | done | ||
| + | if [ ! " | ||
| + | echo "No Opennic tier1 server could not be reached -- aborting!" | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | echo | ||
| + | |||
| + | # get master server | ||
| + | NS0=$(echo $NS0 | awk ' | ||
| + | |||
| + | echo -n " | ||
| + | |||
| + | # get ip from master server | ||
| + | NS=( $(drill -Q @$ns ns0.opennic.glue.) ) | ||
| + | for ns in " | ||
| + | if [ " | ||
| + | done | ||
| + | if [ ! " | ||
| + | echo "could not be reached -- aborting!" | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | echo " | ||
| + | |||
| + | soa=$($DIG -Q SOA . @$NS0) | ||
| + | serial=$(echo $soa | awk '{ print $3}') | ||
| + | refresh=$(echo $soa | awk '{ print $4}') | ||
| + | |||
| + | echo " | ||
| + | echo " | ||
| + | |||
| + | echo $serial > $LOCK | ||
| + | |||
| + | if [ -z " | ||
| + | last_serial=0 | ||
| + | fi | ||
| + | |||
| + | if [ $last_serial == $serial ]; then | ||
| + | echo "No Update needed serial not changed" | ||
| + | exit 0 | ||
| + | fi | ||
| + | |||
| + | dig . ns @${NS0} > $CF | ||
| + | echo " | ||
| + | |||
| + | dig -t DNSKEY . @${NS0} | dnssec-dsfromkey -1 -f - . > $KF | ||
| + | dig -t DNSKEY . @${NS0} | dnssec-dsfromkey -2 -f - . >> $KF | ||
| + | cp $KF / | ||
| + | echo " | ||
| + | |||
| + | # Start printing the new file | ||
| + | ifs=$IFS | ||
| + | |||
| + | # Collect list of TLDs | ||
| + | TXT=(dns.opennic.glue $($DIG -Q @$NS0 TXT tlds.opennic.glue | tr -d '"' | ||
| + | IFS=$' | ||
| + | IFS=$ifs | ||
| + | if [ " | ||
| + | echo " | ||
| + | rm -f $LOCK | ||
| + | exit 1 | ||
| + | else | ||
| + | echo "TLDS: ${TLDS[*]}" | ||
| + | fi | ||
| + | |||
| + | echo "#" | ||
| + | echo "# OpenNIC zone config - file created by $HOSTNAME" | ||
| + | echo "# Generated on `date '+%A, %d %b %Y at %T' | ||
| + | echo "#" | ||
| + | |||
| + | echo "#" | ||
| + | echo "# OpenNIC server config for opennic - file created by $HOSTNAME" | ||
| + | echo "# Generated on `date '+%A, %d %b %Y at %T' | ||
| + | echo "#" | ||
| + | |||
| + | |||
| + | for TLD in " | ||
| + | if [ $TLD != ' | ||
| + | echo -n ' | ||
| + | echo -n $TLD >> $SF | ||
| + | echo '"' | ||
| + | fi | ||
| + | # Check if this zone is mastered by this server | ||
| + | zone=" | ||
| + | if [ " | ||
| + | zone="" | ||
| + | fi | ||
| + | master=($($DIG -Q TXT $zone. @$NS0 | sed ' | ||
| + | |||
| + | echo "TLD $TLD master = ${master[*]}" | ||
| + | | ||
| + | # Begin printing the zone config | ||
| + | echo >> $DF | ||
| + | echo " | ||
| + | echo " | ||
| + | if [ $TLD == ' | ||
| + | echo " | ||
| + | else | ||
| + | echo " | ||
| + | fi | ||
| + | echo " | ||
| + | # Collect a list of master nameservers for the zone | ||
| + | for mm in " | ||
| + | mm=$(echo $mm | $SED ' | ||
| + | ns=$(echo $mm | $CUT -d. -f1 | $SED ' | ||
| + | AT=" | ||
| + | if [ " | ||
| + | if [ " | ||
| + | |||
| + | # If this is an unknown NS, query its IPs | ||
| + | if [ ! " | ||
| + | A4=$($DIG -Q A $mm $AT) | ||
| + | A6=$($DIG -Q AAAA $mm $AT) | ||
| + | RES[$ns]=" | ||
| + | fi | ||
| + | read -a IP <<< | ||
| + | |||
| + | # Print all IPs for all nameservers | ||
| + | for addr in " | ||
| + | echo " | ||
| + | done | ||
| + | done | ||
| + | echo >> $DF | ||
| + | done | ||
| + | echo " | ||
| + | |||
| + | unbound-control reload_keep_cache | ||
| + | echo " | ||
| + | |||
| + | sleep 10 | ||
| + | |||
| + | wget -q --no-check-certificate -O test.txt " | ||
| + | if [ $(cat test.txt | perl -n -e 'if ( $p == 1 ) { /Passed/ && print " | ||
| + | echo " | ||
| + | rm -f test.txt | ||
| + | exit 1 | ||
| + | else | ||
| + | echo " | ||
| + | rm -f test.txt | ||
| + | fi | ||
| + | |||
| + | sleep 10 | ||
| + | |||
| + | wget -q --no-check-certificate -O test.txt " | ||
| + | if [ $(cat test.txt | perl -n -e '/ | ||
| + | echo " | ||
| + | rm -f test.txt | ||
| + | exit 1 | ||
| + | else | ||
| + | echo " | ||
| + | rm -f test.txt | ||
| + | fi | ||
| + | |||
| + | if [ -z " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | else | ||
| + | echo " | ||
| + | fi | ||
| + | git commit -am " | ||
| + | </ | ||