#!/usr/bin/perl -w # # make-data # jms1 2003-05-27 # # Builds a tinydns "data" file from one or more input files. Some changes are # made to the records in the input files: # - "Z" lines are updated to use the current timestamp as the serial number. # Doing this guarantees that if the output is sent to multiple servers, they # will all have the same serial numbers in the SOA records they serve. Using # the unix timestamp as the serial number ensures that each run of this # script will produce data with higher serial numbers than the previous run, # so other caching nameservers will be aware of updates more quickly. # - "." lines are converted to "Z", so that the serial numbers can be # controlled. # - "3" lines are converted to ":" records containing an AAAA record. # - "6" lines are converted to ":" records containing an AAAA record, along # with a "^" (PTR) line with the appropriate name. (You still need to # declare the appropriate "Z" and "&" records for the "xxx.ip6.arpa." # domain in order for tinydns to serve the records. # # Last updated: 2020-01-01 jms1 # - Cleaning up for public release. # - Automatically injects a consistent serial number in all "Z" lines. # - Converts "." lines to "Z" lines with consistent serial numbers, along # with "&" and "+" lines as appropriate. # - Converts "3" and "6" to the appropriate "normal" lines. # - Clarified that the license is GPLv2 or GPLv3, but not any unknown future # version of the GPL (I'm not willing to trust a license that I haven't # seen yet.) # ############################################################ # # Since https://www.fefe.de/dns/ doesn't really document the format to use # for IPv6 records, they are: # # 3fqdn:addr:ttl:timestamp:lo # - AAAA record only # # 6fqdn:addr:ttl:timestamp:lo # - AAAA and PTR (in the "ip6.arpa." domain) # # In both lines, 'addr' should be exactly 32 hex digits, so the address # '2001:db8::c0:ffee' would be written as '20010db800000000000000c0ffee'. # # Also, don't forget to include the appropriate "Z" and "&" lines for the # "ip6.arpa." domain(s), otherwise tinydns won't actually serve these PTR # records. # ############################################################################### # # Copyright (C) 2003-2020 John Simpson. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 or version 3 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # or visit http://www.gnu.org/licenses/gpl.txt # ############################################################################### require 5.003 ; use strict ; # djb's defaults for SOA records my $ref = 16384 ; # refresh time (16384) my $ret = 2048 ; # retry time (2048) my $exp = 1048576 ; # expire time (1048576) my $min = 2560 ; # minimum time (2560) my $rcrypto = < ) { next unless ( $line =~ /[^\s]/ ) ; next if ( $line =~ /^#/ ) ; ############################################################ # "Z" - Force the serial number to be the current timestamp. if ( $line =~ /^Z/ ) { my @w = split ( /\:/ , $line ) ; $w[3] = $t ; $line = join ( ":" , @w ) ; } if ( $line =~ /^Z/ ) { chomp $line ; my @w = split ( /\:/ , $line ) ; die "ERROR: 'Z' line missing fqdn\n$line\n$rcrypto" unless ( $w[0] ) ; die "ERROR: 'Z' line missing mname\n$line\n$rcrypto" unless ( $w[1] ) ; die "ERROR: 'Z' line missing rname\n$line\n$rcrypto" unless ( $w[2] ) ; $w[3] = $t ; $w[4] ||= $ref ; $w[5] ||= $ret ; $w[6] ||= $exp ; $w[7] ||= $min ; $line = join ( ":" , @w ) . "\n" ; } ############################################################ # "." - Convert to "Z" and "&" lines, and possibly a "+" line if needed. # Uses default values for timeouts, nameserver names, and responsible # party emails. If these default values are not correct, you should # change the input files and specify the "Z", "&", and maybe "+" lines # the way you want them. if ( $line =~ s/^\.// ) { chomp $line ; my @w = split ( /\:/ , $line ) ; push ( @w , "" , "" , "" , "" , "" ) ; die "ERROR: '.' line missing fqdn\n$line\n$rcrypto" unless ( $w[0] ) ; my $nsname = $w[2] ? ( ( $w[2] =~ /\./ ) ? $w[2] : "$w[2].ns.$w[0]" ) : "ns.$w[0]" ; my $rname = "hostmaster.$w[0]" ; makeline ( "Z$w[0]" , $nsname , $rname , $t , $ref , $ret , $exp , $min , $w[3] , $w[4] , $w[5] ) ; makeline ( "&$w[0]" , $w[1] , $nsname , $w[3] , $w[4] , $w[5] ) ; if ( $w[1] ) { makeline ( "+$nsname" , $w[1] , $w[3] , $w[4] , $w[5] ) ; } next ; } if ( $line =~ s/^\.// ) { chomp $line ; my @w = split ( /\:/ , $line ) ; push ( @w , "" , "" , "" , "" , "" ) ; my $nsname = "ns.$w[0]" ; if ( $w[2] ) { $nsname = ( $w[2] =~ /\./ ) ? $w[2] : "$w[2].ns.$w[0]" ; } my $rname = "hostmaster.$w[0]" ; makeline ( "Z$w[0]" , $nsname , $rname , $t , $ref , $ret , $exp , $min , $w[3] , $w[4] , $w[5] ) ; makeline ( "&$w[0]" , $w[1] , $nsname , $w[3] , $w[4] , $w[5] ) ; if ( $w[1] ) { makeline ( "+$nsname" , $w[1] , $w[3] , $w[4] , $w[5] ) ; } next ; } ############################################################ # "3" or "6" - Convert to ":28:" line (AAAA record), and possibly add # a "^" line (PTR record) in the "ip6.arpa." domain. if ( $line =~ s/^([36])// ) { my $type = $1 ; chomp $line ; my @w = split( /\:/ , $line ) ; my $fqdn = ( ( shift @w ) || '' ) ; my $astring = ( ( shift @w ) || '' ) ; die "ERROR: '$type' line missing fqdn\n$type$line\n$rfefe" unless ( $fqdn ) ; die "ERROR: '$astring' is not a valid IPv6 address string\n$type$line\n$rfefe" unless ( $astring =~ /^[0-9a-fA-F]{32}$/ ) ; ######################################## # Build AAAA record my $x = $astring ; my $y = '' ; while ( $x =~ s/^(..)// ) { $y .= sprintf( '\\%03o' , hex($1) ) ; } makeline( ":$fqdn" , 28 , $y , @w ) ; ######################################## # Maybe build PTR record if ( $type eq '6' ) { $y = join( '.' , reverse split( // , $astring ) ) ; makeline( "^$y.ip6.arpa" , $fqdn , @w ) ; } next ; } print $line ; }