summaryrefslogtreecommitdiff
path: root/frontends
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-03-20 10:09:26 +0200
committerPaul Buetow <paul@buetow.org>2024-03-20 10:09:26 +0200
commitc3c8a774d3a0947880f0416b3e3b1b877a86a7c6 (patch)
tree93864085a1fdb8febac0d44eb0252d6f1c9ee34e /frontends
parente14a5b471ab59b08d07f195778011ea68cb0e7d8 (diff)
failover script works, it's now ksh, btw.
Diffstat (limited to 'frontends')
-rw-r--r--frontends/Rexfile16
-rw-r--r--frontends/scripts/dns-failover.ksh88
-rw-r--r--frontends/scripts/dnsfailover.sh.tpl66
3 files changed, 102 insertions, 68 deletions
diff --git a/frontends/Rexfile b/frontends/Rexfile
index 0d9d184..4456755 100644
--- a/frontends/Rexfile
+++ b/frontends/Rexfile
@@ -1,6 +1,6 @@
# How to use:
#
-# rex commons nsd_master nsd_slaves
+# rex commons
#
# Why use Rex to automate my servers? Because Rex is KISS, Puppet, SALT and Chef
# are not. So, why not use Ansible then? To use Ansible correctly you should also
@@ -293,7 +293,7 @@ task 'smtpd', group => 'frontends',
};
desc 'Setup DNS server(s)';
-task 'nsd_master', group => 'frontends',
+task 'nsd', group => 'frontends',
sub {
my $restart = FALSE;
append_if_no_such_line '/etc/rc.conf.local', 'nsd_flags=';
@@ -338,6 +338,16 @@ task 'nsd_master', group => 'frontends',
service 'nsd', ensure => 'started';
};
+desc 'Setup DNS failover script(s)';
+task 'nsd_failover', group => 'frontends',
+ sub {
+ file '/usr/local/bin/dns-failover.sh',
+ source => './scripts/dns-failover.ksh',
+ owner => 'root',
+ group => 'wheel',
+ mode => '500';
+ };
+
desc 'Setup DTail';
task 'dtail', group => 'frontends',
sub {
@@ -501,6 +511,8 @@ task 'ircbouncer', group => 'ircbouncer',
desc 'Common configs of all hosts';
task 'commons', group => 'frontends', sub {
run_task 'base';
+ run_task 'nsd';
+ run_task 'nsd_failover';
run_task 'uptimed';
run_task 'httpd';
run_task 'gemtexter';
diff --git a/frontends/scripts/dns-failover.ksh b/frontends/scripts/dns-failover.ksh
new file mode 100644
index 0000000..0be63bf
--- /dev/null
+++ b/frontends/scripts/dns-failover.ksh
@@ -0,0 +1,88 @@
+#!/bin/ksh
+
+ZONES_DIR=/var/nsd/zones/master/
+DEFAULT_MASTER=fishfinger.buetow.org
+DEFAULT_STANDBY=blowfish.buetow.org
+
+MASTER=$DEFAULT_MASTER
+STANDBY=$DEFAULT_STANDBY
+
+MASTER_A=$(host $MASTER | awk '/has address/ { print $(NF) }')
+MASTER_AAAA=$(host $MASTER | awk '/has IPv6 address/ { print $(NF) }')
+STANDBY_A=$(host $STANDBY | awk '/has address/ { print $(NF) }')
+STANDBY_AAAA=$(host $STANDBY | awk '/has IPv6 address/ { print $(NF) }')
+
+transform () {
+ sed -E '
+ /IN A .*; Enable failover/ {
+ /^mirror/! {
+ s/^(.*) 300 IN A (.*) ; (.*)/\1 300 IN A '$MASTER_A' ; \3/;
+ }
+ /^mirror/ {
+ s/^(.*) 300 IN A (.*) ; (.*)/\1 300 IN A '$STANDBY_A' ; \3/;
+ }
+ }
+ /IN AAAA .*; Enable failover/ {
+ /^mirror/! {
+ s/^(.*) 300 IN AAAA (.*) ; (.*)/\1 300 IN AAAA '$MASTER_AAAA' ; \3/;
+ }
+ /^mirror/ {
+ s/^(.*) 300 IN AAAA (.*) ; (.*)/\1 300 IN AAAA '$STANDBY_AAAA' ; \3/;
+ }
+ }
+ / ; serial/ {
+ s/^( +) ([0-9]+) .*; (.*)/\1 '"$(date +%s)"' ; \3/;
+ }
+ '
+}
+
+zone_is_ok () {
+ local zone=$1
+ local domain=${zone%.zone}
+
+ echo "Testing zone $zone (if no NS output, then doesn't work)"
+ dig $domain @localhost | grep "$domain.*IN.*NS"
+}
+
+failover_zone () {
+ local zone_file=$1
+ local zone=$(basename $zone_file)
+
+ cat $zone_file | transform > $zone_file.new.tmp
+
+ grep -v ' ; serial' $zone_file.new.tmp > $zone_file.new.noserial.tmp
+ grep -v ' ; serial' $zone_file > $zone_file.old.noserial.tmp
+
+ if diff $zone_file.new.noserial.tmp $zone_file.old.noserial.tmp; then
+ echo "zone $zone_file hasn't changed"
+ rm $zone_file.*.tmp
+ return
+ fi
+
+ cp $zone_file $zone_file.bak
+ mv $zone_file.new.tmp $zone_file
+ rm $zone_file.*.tmp
+ nsd-control reload
+
+ if zone_is_ok $zone; then
+ if [ -f $zone_file.invalid ]; then
+ rm $zone_file.invalid
+ fi
+ echo "Failover of zone $zone completed"
+ return
+ fi
+
+ echo "Rolling back $zone_file changes"
+ cp $zone_file $zone_file.invalid
+ mv $zone_file.bak $zone_file
+ nsd-control reload
+ zone_is_ok $zone
+}
+
+main () {
+ for zone_file in $ZONES_DIR/*.zone; do
+ failover_zone $zone_file
+ done
+}
+
+main
diff --git a/frontends/scripts/dnsfailover.sh.tpl b/frontends/scripts/dnsfailover.sh.tpl
deleted file mode 100644
index 050d42b..0000000
--- a/frontends/scripts/dnsfailover.sh.tpl
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/sh
-
-ZONES_DIR=/var/nsd/zones/master/
-MASTER_A=master_a
-MASTER_AAAA=master_aaaa
-STANDBY_A=standby_a
-STANDBY_AAAA=standby_aaaa
-
-transform () {
- sed -E '
- /IN A .*; Enable failover/ {
- /^mirror/! {
- s/^(.*) 300 IN A (.*) ; (.*)/\1 300 IN A '$MASTER_A' ; \3/;
- }
- /^mirror/ {
- s/^(.*) 300 IN A (.*) ; (.*)/\1 300 IN A '$STANDBY_A' ; \3/;
- }
- }
- /IN AAAA .*; Enable failover/ {
- /^mirror/! {
- s/^(.*) 300 IN AAAA (.*) ; (.*)/\1 300 IN AAAA '$MASTER_AAAA' ; \3/;
- }
- /^mirror/ {
- s/^(.*) 300 IN AAAA (.*) ; (.*)/\1 300 IN AAAA '$STANDBY_AAAA' ; \3/;
- }
- }
- / ; serial/ {
- s/^( +) ([0-9]+) .*; (.*)/\1 '"`date +%s`"' ; \3/;
- }
- '
-}
-
-failover_zone () {
- zone=$1
- cat $zone | transform > $zone.new.tmp
-
- grep -v ' ; serial' $zone.new > $zone.new.noserial.tmp
- grep -v ' ; serial' $zone > $zone.old.noserial.tmp
-
- diff $zone.new.noserial.tmp $zone.old.noserial.tmp
- if [ $? -eq 0 ]; then
- echo "zone $zone hasn't changed"
- rm $zone.*.tmp
- return
- fi
-
- cp $zone $zone.bak
- mv $zone.new.tmp $zone
- rm $zone.*.tmp
- nsd-control reload $zone
-
- dig $zone @localhost
- # Todo: Use different return check, als ec may be 0 anyway
- if [ $? -eq 0 ]; then
- return
- fi
-
- echo "Rolling back $zone changes"
- cp $zone $zone.invalid
- mv $zone.bak $zone
- nsd-control reload $zone
-}
-
-for zone in $ZONES_DIR/snonux.foo.zone; do
- failover_zone $zone
-done