--- a/Makefile Thu Jul 14 10:03:39 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-
-p = dns-autoslave
-SCRIPT = dns-autoslave
-RC = rc.dns-autoslave
-
-prefix = /usr/local
-sbindir = $(prefix)/stow/$p/sbin
-
-rcdir = /etc/init.d/
-
-all:
- @perl -c dns-autoslave
-
-stow:
- install -m 0755 -d $(sbindir)
- install -m 0755 -d $(rcdir)
- install -m 0755 $(SCRIPT) $(sbindir)/
- install -m 0755 $(RC) $(rcdir)/$(p)
- stow -d /usr/local/stow -vR $(p)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/README Thu Nov 09 14:56:03 2017 +0100
@@ -0,0 +1,1 @@
+Moved to git.schlittermann.de/user/heiko/dns-autoslave
--- a/dns-autoslave Thu Jul 14 10:03:39 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-#! /usr/bin/perl
-
-use strict;
-use warnings;
-use Unix::Syslog qw(:macros :subs);
-use File::Basename;
-use Net::Pcap;
-use Net::DNS::Packet;
-use Net::DNS::Resolver;
-use Fcntl ":flock";
-use AppConfig;
-use POSIX qw(SIGTERM);
-
-# Es kommen Zeilen
-# add slave domain.com
-use constant ME => basename $0;
-use constant CF_FILE => "/etc/".ME."/".ME.".conf";
-use constant LIB_DIR => "/etc/".ME;
-use constant PROMISC => 0;
-
-use constant CONFIG => (
- { CASE => 1 },
- dev => { ARGS => "=s", DEFAULT => "eth0", ALIAS => "interface" },
- filter => { ARGS => "=s", DEFAULT => "udp and src host (%accept) and dst port domain" },
- accept => { ARGS => "=s" },
- pid => { ARGS => "=s", DEFAULT => "/var/run/".ME.".pid" },
-);
-
-sub process($$$);
-
-openlog(ME, LOG_PERROR | LOG_NDELAY | LOG_PID, LOG_DAEMON);
-$SIG{__DIE__} = sub { die @_ if $^S; syslog(LOG_ERR, shift, @_); exit 1; };
-$SIG{__WARN__} = sub { syslog(LOG_WARNING, shift, @_); };
-
-my $Cf = new AppConfig CONFIG or die;
- $Cf->file(CF_FILE) or die if -f CF_FILE;
- $Cf->args or die;
-
-my %Seen;
-
-MAIN: {
-
- $_ = $Cf->filter;
- s/%accept/join " or ", split " ", $Cf->accept/e;
- $Cf->filter($_);
-
- require lib;
- import lib LIB_DIR;
- require "local.pm";
-
-
- my $err;
- my ($net, $mask);
- my ($pcap, $filter);
-
- Net::Pcap::lookupnet($Cf->dev, \($net, $mask, $err)) == 0 or die $err;
- $pcap = Net::Pcap::open_live($Cf->dev, 1500, PROMISC, 10, \$err) or die $err;
- Net::Pcap::compile($pcap, \$filter, $Cf->filter, 1, $mask) == 0 or die $@;
- Net::Pcap::setfilter($pcap, $filter);
-
- ##
- my $pidfile = $Cf->pid;
- my $pid;
- open(PID, "+>>$pidfile") or die "Can't open $pidfile: $!\n";
- flock(PID, LOCK_EX) or die "Can't flock $pidfile: $!\n";
- seek(PID, 0, 0) or die "Can't seek $pidfile: $!\n";
- if (defined ($pid = <PID>)) {
- chomp $pid;
- die "Process $pid is running\n" if kill 0, $pid;
- }
- seek(PID, 0, 0);
- truncate(PID, 0);
-
- $pid = fork;
- die "Can't fork: $!\n" if not defined $pid;
-
- if ($pid) {
- print PID "$pid\n";
- warn "Child pid: $pid\n";
- exit 0;
- }
-
- POSIX::sigaction(SIGTERM, POSIX::SigAction->new(sub { Net::Pcap::breakloop($pcap); } ))
- or die "Error setting SIGTERM Handler: $!\n";
- close(STDIN); close(STDOUT); close(STDERR); close(PID);
- $0 = ME." [capturing]";
- Net::Pcap::loop($pcap, -1, \&process, undef) == -1 and die Net::Pcap::geterr($pcap);
- warn "Exit.\n";
- unlink $Cf->pid;
- exit 0;
-}
-
-
-sub process($$$) {
- my (undef, $hdr, $data) = @_;
-
- {
- # Link-Level:
- # Dest 6 byte
- # Src 6 byte
- # type 2 byte
- my $type = unpack("x12 n", $data);
- if ($type != 0x800) {
- warn "unexpected link layer type: ", sprintf("0x%x", $type), "\n";
- return;
- }
- # Link layer abschneiden
- $data = substr($data, 14);
- }
-
- my $src;
- {
- # IP-Header
- # im ersten Byte stecken Version+Header-Länge
- @_ = unpack("C x11 C4", $data);
- my $hlen = ($_[0] & 0xf) * 4;
- $src = join ".",@_[1..4];
-
- # IP-Header abschneiden
- $data = substr($data, $hlen);
- }
-
- my $dns;
- {
- # UDP: SRC-Port 16 bit
- # DST-Port 16 bit
- # Len 16 bit
- # Chksum 16 bit => 8 byte
- $data = substr($data, 8);
- $dns = new Net::DNS::Packet(\$data) or do {
- warn "Can't decode packet\n";
- return;
- }
- }
-
- # Das, was wir bekommen, ist eine SOA-Query mit dem Opcode "NOTIFY",
- #
- # Sollen wir jetzt annehmen, daß der NS in der SOA (MNAME) der Master ist,
- # oder sollen wir annehmen, daß die IP, von der es kommt, die des Masters
- # ist? Beides kann falsch sein.
- #
- # Bei "hidden" Masters ist der Master höchstwahrscheinlich der interne (und damit
- # nicht erreichbare) Name des Masters, das würde uns also nichts nützen. Wir könnten
- # natürlich jetzt eine komplizierte Logik versuchen:
- # DNS-Anfrage an den, von dem das NOTIFY kam über die IP des MNAME,
- # wenn die OK ist, dann ... aber woher wissen wir, daß die OK ist.
- #
- # Wir gehen also einfach mal davon aus, daß der Master derjenige ist,
- # welcher uns das NOTIFY geschickt hat. Und haben in der Konfig-Datei ein
- # Mapping, damit wir die Fälle, wo der Master eine falsche Absender-IP
- # nutzt (HA-Cluster) auch ordentlich behandeln können.
-
- return unless $dns->header->opcode =~ /^(?:NS_)?NOTIFY(?:_OP)?$/;
-
- # Das, was dort kommt, hat eine QUESTION und eine ANSWER, in der ANSWER steckt
- foreach my $q ($dns->question) {
- next unless $q->qtype eq "SOA";
-
- my $domain = $q->qname;
- my $msg = "NOTIFY from $src about $domain:";
-
- if (exists $Seen{$domain} && (time - $Seen{$domain} < 60) ) {
- warn "$msg OK(seen)\n";
- next;
- }
-
- if ($_ = (new Net::DNS::Resolver (nameservers => ['127.0.0.1'], recurse => 0))->query($domain, "SOA")
- and $_->header->aa) {
- $Seen{$domain} = time;
- warn "$msg OK(soa checked)\n";
- next;
- }
-
- if (local::addZone($domain, $src)) {
- warn "$msg ADDED", $@ ? "($@)" : "", "\n";
- next;
- }
-
- warn "ERROR ", $@ ? "($@)" : "", "\n";
-
- }
-}
-
-# vim:sts=4 sw=4 aw ai sm:
--- a/dns-autoslave.conf.ex Thu Jul 14 10:03:39 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-accept = 192.168.7.2 \
- 192.168.7.3
--- a/gen-dep-deb Thu Jul 14 10:03:39 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-#!/usr/bin/equivs-build
-
-Section: perl
-Priority: optional
-Standards-Version: 3.6.2
-
-Package: dns-autoslave-deps
-Depends: perl-modules, libunix-syslog-perl, libnet-pcap-perl, libnet-dns-perl, libappconfig-perl
-Description: dns-autoslave Dependencies
- Installing this package will pull all Dependencies for dns-autoslave
--- a/ius/local.pm Thu Jul 14 10:03:39 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-# Example
-# $Id$
-# $URL$
-
-# remove the next line if you know, what you're doing
-#die "Sure? You should adapt this file to your needs!";
-
-package local;
-
-# in: zone name
-# src ip
-# out: 0 failure ($@ contains message)
-# !0 ok ($@ may contain message)
-sub addZone($$) {
- my ($zone, $src) = @_;
- my $hdns = '84.19.194.5';
-
- # Filename ist für das File selbst und auch für die Konfig
- (my $file = $zone) =~ s/[\/&|]/_/g;
-
- my $txt = <<__;
-// Autoadded %time by $0
-zone "$zone" IN {
- type slave;
- file "/etc/bind/s/$file";
- masters { %masters; };
- allow-query { any; };
- allow-transfer { %transferees; };
-};
-
-__
-
- # 84.19.194.5 ist die ip unseres hidden master
- my $transferees = $src eq $hdns ? 'localhost; key hh.schlittermann.de' : 'none';
-
- $txt =~ s/%time/scalar localtime/eg;
- $txt =~ s/%masters/$src/g;
- $txt =~ s/%transferees/$transferees/g;
-
- if (-f ($_ = "/etc/bind/zones.auto/$file")) {
- $@ = "$_ already exists";
- return 0;
- }
-
- if (-f ($_ = "/etc/bind/zones.auto/.removed/$file")) {
- $@ = "$_ removed";
- return 0;
- }
-
- s/\.removed\///;
-
- open(OUT, $_ = ">$_") or die "Can't open $_: $!\n";
- print OUT $txt;
-
- open(OUT, $_ = ">>/etc/bind/zones.all") or die "Can't open $_: $!\n";
- print OUT $txt;
-
- close OUT;
-
- # return 0 == system("rndc reload");
- local @ARGV = qw(/var/run/named/named.pid);
- chomp($_ = <>);
- warn "Sending HUP to $_\n";
- $@ = "Nameserver reloaded (HUP sent)";
- kill "HUP", $_ and return 1;
-
- $@ = "No process $_";
- return 0;
-}
-
-
-1;
-# vim:sts=4 sw=4 aw ai sm:
--- a/local.pm.ex-1 Thu Jul 14 10:03:39 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-# Example
-# $Id$
-# $URL$
-
-# remove the next line if you know, what you're doing
-die "Sure? You should adapt this file to your needs!";
-
-package local;
-
-# in: zone name
-# src ip
-# out: 0 failure ($@ contains message)
-# !0 ok ($@ may contain message)
-sub addZone($$) {
- my ($zone, $src) = @_;
-
- # Filename ist für das File selbst und auch für die Konfig
- (my $file = $zone) =~ s/[\/&|]/_/g;
-
- my $txt = <<__;
-// Autoadded %time by $0
-zone "$zone" IN {
- type slave;
- file "/etc/bind/s/$file";
- masters { %masters; };
- allow-query { any; };
- allow-transfer { none; };
-};
-
-__
-
- $txt =~ s/%time/scalar localtime/eg;
- $txt =~ s/%masters/$src/g;
-
- if (-f ($_ = "/etc/bind/zones.d/$file")) {
- $@ = "$_ already exists";
- return 0;
- }
-
- open(OUT, $_ = ">$_") or die "Can't open $_: $!\n";
- print OUT $txt;
-
- open(OUT, $_ = ">>/etc/bind/zones.all") or die "Can't open $_: $!\n";
- print OUT $txt;
-
- close OUT;
-
- # return 0 == system("rndc reload");
- local @ARGV = qw(/var/run/bind/run/named.pid);
- chomp($_ = <>);
- warn "Sending HUP to $_\n";
- $@ = "Nameserver reloaded (HUP sent)";
- kill "HUP", $_ and return 1;
-
- $@ = "No process $_";
- return 0;
-}
-
-
-1;
-# vim:sts=4 sw=4 aw ai sm:
--- a/local.pm.ex-2 Thu Jul 14 10:03:39 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-# Example
-
-# remove the next line if you know, what you're doing
-#die "Sure? You should adapt this file to your needs!";
-
-package local;
-
-# in: zone name
-# src ip
-# out: 0 failure ($@ contains message)
-# !0 ok ($@ may contain message)
-sub addZone($$) {
- my ($zone, $src) = @_;
- my $hdns = '84.19.194.5';
-
- # Filename ist für das File selbst und auch für die Konfig
- (my $file = $zone) =~ s/[\/&|]/_/g;
-
- # 84.19.194.5 ist die ip unseres hidden master
- my $transferees = $src eq $hdns ? 'localhost; key hh.schlittermann.de' : 'none';
-
- my $txt = <<__;
-{
- type slave;
- file "/etc/cache/bind/slave/$file";
- masters { $src; };
- allow-query { any; };
- allow-transfer { $transferees; };
-};
-
-__
-
- # set
- # allow-new-zones yes;
- # in /etc/bind/named.conf.options
- system rndc => (
- addzone => $zone,
- $txt
- );
-
- if ($?) {
- warn "rndc addzone $zone failed\n";
- return 0;
- }
-
- $@ = "zone $zone added via rndc addzone\n";
- return 1;
-
-}
-
-1;
-# vim:sts=4 sw=4 aw ai sm:
--- a/rc.dns-autoslave Thu Jul 14 10:03:39 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-#! /bin/sh
-
-### BEGIN INIT INFO
-# Provides: dns-autoslave
-# Required-Start: $local_fs $remote_fs $syslog $named $network $time
-# Required-Stop: $local_fs $remote_fs $syslog $named $network
-# Should-Start:
-# Should-Stop:
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: Start/Stop the dns-autoslave daemon
-### END INIT INFO
-
-DAEMON=/usr/local/sbin/dns-autoslave
-PIDFILE=/var/run/`basename $DAEMON`.pid
-
-case $1 in
-
- start)
- start-stop-daemon -v --start --pidfile $PIDFILE --startas $DAEMON
- ;;
-
- stop)
- start-stop-daemon -v --stop --retry 30 --pidfile $PIDFILE
- ;;
-
- restart) echo "Restarting $NAME..."
- $0 stop
- $0 start
- ;;
-
- *)
- echo "Usage: $0 {start|stop|restart}" >&2
- exit 1
- ;;
-esac
-
-exit 0