diff --git a/clean.pl b/clean.pl index 6fab844..24d5916 100755 --- a/clean.pl +++ b/clean.pl @@ -1,5 +1,19 @@ #!/usr/bin/env perl # +# Copyright (c) 2023 Mischa Peters +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# use 5.024; use strict; use warnings; diff --git a/parse.pl b/parse.pl index 36b4792..da283d3 100755 --- a/parse.pl +++ b/parse.pl @@ -1,5 +1,19 @@ #!/usr/bin/env perl # +# Copyright (c) 2023 Mischa Peters +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# use 5.024; use strict; use warnings; diff --git a/ptrd.pl b/ptrd.pl index d0ce4c0..abb30c7 100755 --- a/ptrd.pl +++ b/ptrd.pl @@ -1,5 +1,19 @@ #!/usr/bin/perl # +# Copyright (c) 2023 Mischa Peters +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# use 5.024; use strict; use warnings; diff --git a/reset.pl b/reset.pl new file mode 100755 index 0000000..3164208 --- /dev/null +++ b/reset.pl @@ -0,0 +1,115 @@ +#!/usr/bin/env perl +# +# Copyright (c) 2023 Mischa Peters +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +use 5.024; +use strict; +use warnings; +use autodie; +use Fcntl qw(:flock); +use File::Basename; +use File::Copy; +use POSIX qw(strftime); +use Net::IP; + +my $ipv4_range = new Net::IP("46.23.80.0/20"); +my $ipv6_range = new Net::IP("2a03:6000::/29"); +my $nsd = "/var/nsd/zones/reverse"; +my $v6_zone = "2a03.6000"; +my $default_ptr = "powered-by.openbsd.amsterdam"; +my $workdir = dirname($0); +my $serial; +my $serial_prev; +my $zonefile; +my $match; +my $replace; + +if (! $ARGV[0]) { + print STDERR "usage: $0 \n"; + exit 1; +} +my $client_ip = $ARGV[0]; +my $ip = new Net::IP($client_ip); + +if ($ip->overlaps($ipv4_range)) { + ($zonefile = $client_ip) =~ s/^((\d{1,3}\.){3})\d+$/${1}0/; + $match = substr($client_ip, rindex($client_ip, '.')+1); + +} elsif ($ip->overlaps($ipv6_range)) { + $zonefile = $v6_zone; + $match = substr($ip->reverse_ip(), 0, 47); +} +$replace = "${match}\t\tIN\tPTR\t${default_ptr}."; + +if (qx(rlog ${nsd}/${zonefile} | grep 'locked by') =~ m/locked by/) { + _log("$client_ip zone file locked, trying again later..."); + next; +} else { + open my $fh_in, '<', "${nsd}/$zonefile"; + open my $fh_out, '>', "${workdir}/zonefiles/$zonefile"; + while (my $row = <$fh_in>) { + chomp $row; + if ($row =~ m/^\s*(\d+)\s*; serial$/) { + $serial = $serial_prev = $1; + my $timestamp = strftime ("%Y%m%d", localtime()) . "01"; + if ($serial < $timestamp) { + $serial = $timestamp; + } else { + $serial++; + } + $row =~ s/${serial_prev}/${serial}/; + } + + if ($row =~ m/^${match}\s+IN\s+PTR\s+\S+( ;.*)?$/) { + if ($1) { + my $comment = $1; + $row =~ s/^${match}\s+.*$/${replace}${comment}/; + } else { + $row =~ s/^${match}\s+.*$/${replace}/; + } + } + print $fh_out "$row\n"; + } + close $fh_in; + close $fh_out; + + (my $diff = qx(diff ${nsd}/${zonefile} ${workdir}/zonefiles/${zonefile} | wc -l)) =~ s/^\s*(.*?)\s*$/$1/; + if ($diff == 8) { + _log("$client_ip diff within limits ($diff), $serial_prev -> $serial"); + copy("${nsd}/${zonefile}", "${workdir}/zonefiles-archive/${zonefile}-${serial}"); + qx(co -q -l ${nsd}/${zonefile}); + copy("${workdir}/zonefiles/${zonefile}", "${nsd}/${zonefile}"); + qx(ci -q -u -m"updated for ${client_ip}" ${nsd}/${zonefile}); + + qx(rcctl reload nsd); + qx(rdist -f /etc/Distfile) if (-r '/etc/Distfile'); + + my $protect = qx(pfctl -t protected -T delete $client_ip 2>&1); + chomp $protect; + qx(pfctl -t protected -T show > /etc/pf.protected); + _log("$client_ip protected $protect"); + + } else { + _log("$client_ip diff is outside limits ($diff)"); + } +} + +sub _log { + my ($msg) = @_; + open my $fh, '>>', '/var/log/ptrd.log'; + flock $fh, LOCK_EX; + print $fh sprintf("%s %s: %s \n", strftime("%b %d %H:%M:%S", localtime), basename($0), $msg); + close $fh; +}