📄 makezones
字号:
#! /bin/perl$version_number = "0.06a [22-Sep-93]";######################################################################### MAKEZONES ########################################################################## Copyright (c), University of Cambridge, 1993.# # The University retains the copyright and all other legal rights# to this software and makes it available non-exclusively. All users# must ensure that the software in all its derivations carries a# copyright notice as above. No warranty is expressed or implied.# This file is available for anonymous ftp from# # ftp.cus.cam.ac.uk:/pub/software/programs/DNS/makezones## Enquires to Philip Hazel <ph10@cus.cam.ac.uk>.######################################################################### CONFIGURATION VARIABLES## These are put at the top for ease of changing. See below for general# specification of the script.# Makezones checks the characters used in the components of names. Different# sites may have different local standards in this respect. The variable# $name_pattern is used to contain a regular expression pattern that# matches valid components of domain names. Change it to suit your# requirements. Note that:## (a) The variable contains only the pattern characters, NOT the delimiting# slashes.# (b) This pattern is for one component only, so should not contain things# that match full stops.# (c) The start and end of string metacharacters (^ and $) should not be# included; makezones uses this variable to build up a larger pattern# to match complete domain names, and it puts in ^ and $ itself.# (d) Because it is being constructed as a Perl string, any backslash# characters in the pattern must be doubled.# This pattern specifies that names must start with a letter, contain only # letters, digits, and hyphens, and not end with a hyphen.$name_pattern = '[a-zA-Z]([a-zA-Z\\-\\d]*[a-zA-Z\\d]+|)';# Possible variations:## $name_pattern = '[a-zA-Z\\d]([a-zA-Z\\-\\d]*[a-zA-Z\\d]+|)'; # digit at start# $name_pattern = '[a-z]([a-z\\-\\d]*[a-z\\d]+|)'; # all lower case## Note that, in addition to this, "*" is permitted as the first component of# names on MX records, to allow MX wildcarding. Names for PTR records must# always consist of four numeric components; $name_pattern is not used. Also,# names on NS records may consist of numeric components - this is necessary# in order to specify devolved reverse subzones.# To disable the checking of new zone file lengths against the previous# versions, set $opt_short = 1 here. This forces the -short option for# all runs. $opt_short = 0;# If you want fields in WKS records to be checked against the contents# of a file for validity, then set $services to the name of the file, # and $grep to your favourite grep command. The values below will be# typical. The program searches for the service name followed by a space# or a tab at the start of a line. If you don't want this check, set# $services to the null string.$services = "/etc/services";$grep = "/usr/bin/egrep";# If you want makezones to output some commentary as it goes along,# to let you know it is making some progress, then set the $chatty# variable to 1.$chatty = 1;######################################################################### UNIX DEPENDENCIES## The Unix "date" command is used to obtain the current date and time# in a particular format.## Perl's "stat" function is used to obtain the lengths of files; this may# differ for other operating systems.## Anything else I've forgotten?######################################################################### # Makezones is a perl script for processing a source file for a DNS zone# and producing the relevant operational DNS zone files. It does a lot of # checking to ensure that the data is not bad, and it also ensures that# the forward and reverse zone information is in step.## Makezones handles the updating of the serial number automatically. It# does this by updating the SOURCE FILE before generating the zone files.# >>>>> NB NB NB NB <<<<<# The source file therefore has to be writeable. Makezones insists that# the format of the serial number be <year><month><day><version> and that# the year be four digits long, so that this code will continue to work # after then end of 1999.## Makezones handles Class B and Class C networks, because those are the# ones that are around here in Cambridge, UK. It would not be hard to # extend it to handle a Class A if that were required.## Because the file should normally be correct, makezones makes no attempt# attempt to continue if it finds a serious error. It just reports it and # stops. However, syntax errors in the general records don't prevent it# going on to check further records, so you can get more than one error# message in a run. However, if it finds too many errors it says so, and# gives up. "Too many" is currently more than ten.## The input file looks like a normal DNS zone file, with the addition of# the following rules, which impose additional restrictions. Some of these# rules are to make it easy for makezones; some of them impose conventions# that we use in Cambridge which might not be liked elsewhere. The code is# well commented, and should be easy to modify.## . The class field ("IN") and the type fields ("A", "CNAME", etc.) must# be specified in upper case, as must "TCP" and "UDP" in WKS records.## . With the exception of the SOA & WKS records, all records must be # complete on one line of input. That is, continuation is not supported# in general.## . The SOA record must be right at the start of the file, and must be# set up so that each numeric parameter is on a separate line. For# example:## @ IN SOA cus.cam.ac.uk. hostmaster.ucs.cam.ac.uk. (# 1993080601 ; Serial# 10800 ; Refresh 3 hours# 3600 ; Retry 1 hour# 604800 ; Expire after a week# 86400 ) ; Minimum ttl## Note that the serial number begins with the full year number, not just# the last two digits. The SOA record is expected to have the "IN" class# field; subsequent records may omit it.## . The NS records for the zone must appear at the top of the file, just# after the SOA record. These will be copied into the forward and the# reverse zone files. That is, the assumption is that the nameservers# are the same for the forward and reverse zones. These NS records must# NOT have anything in the name field. The copying stops on reaching# the first record with a name field or the first non-NS record.## . NS records must always refer to fully qualified names. Makezones checks# for the final dot, because it is so easy to overlook this.# # . Comments are not normally copied into the working zone files. They# can, however, be forced into them by the following syntax:# # ;F copy this comment (without the F) into the forward file# ;R copy this comment (without the R) into the reverse file# # . All records except PTR records are normally copied to the forward file. # However, A records can be marked as "reverse only" by preceding them# with ">R " at the start. In this case, no A record is written to the# forward file, but a PTR record is constructed for the appropriate# reverse zone file. There should be exactly one space after the ">R";# three characters are removed from the start of the record. If ">R" is# followed by a tab, the tab is not removed (i.e. it acts as more than# one space).# # . PTR records and A records are the only ones used when generating the # reverse zone files. "A" records can be marked "forwards only" by preced- # ing them with ">F " at the start. This suppresses generation of a PTR # record for the reverse zone. It does not, however, suppress the check that# the address is in one of the networks being handled (see next item for# external networks). If more than one A record has the same IP address,# then all but one must have the ">F " flag, to ensure that only one PTR# record is generated (for the canonical name). Again, there must be# exactly one space or a tab after ">F".# # . We want to be able to check that all IP addresses are in one of the # networks that we are processing for. However, occasionally a record must# specify an external network (glue records are the prime example). Such # records must be flagged by ">E " at their start to override the error # that would otherwise occur. (They naturally won't get into any reverse # zones.) The special local address 127.0.0.1 is recognized and treated as# though ">E " is always present. The ">E " flag can be used on WKS # records as well as on A records.## . The name given for PTR records must be a complete, reversed IP address# that corresponds to one of the reverse zones. The network portion of# the "name" is removed when generating the PTR record for the reverse# zone. PTR records have to be used instead of A records flagged with# ">R " ("reverse only") when the name concerned is not in the domain# of the forward zone, because of the following rule.## . The names on all records must not end with . as we conventionally# specify them as partial domains for the forward zone. This means that,# if you want a record with the name of the zone as its domain, you must# use the "@" notation, which is supported.## . Makezones assumes that names consist of letters and digits, and start# with a letter. You can, however, override this by enclosing a name# in quotes. For example:## "3cpu" A 134.232.45.69## I didn't want to allow these through normally, as in my zone they are# more likely to be typos. You can change the rules for what characters# are allowed in names (without quoting) by editing the variable # $name_pattern (see under CONFIGURATION VARIABLES at the head of this # file).## . CNAME records must point to fully qualified names. Makezones checks# that if a name appears on a CNAME, it does not appear on any other# record.## . MX records must point to fully qualified names.# ## Makezones is run by a command of the following form:## makezones [options] <source> <forward-zone> <forward-zone-file> \# [<reverse-zone-file>]*## For example:# # makezones DBsource cam.ac.uk db.cam db.131.111 db.192.153.213# # The source file is specified as the first argument. The second and third# arguments specify the name of the zone and the file into which the records# for that zone are to be written. The name is required so that fully# qualified names can be generated in the reverse zone files. The remaining# arguments specify the networks for which reverse zone files are to be # written, and the corresponding files. There need not be any if there are # no PTR or non-forwards-only A records in the source file. Each of these # final arguments is the name of a zone file. The first part of the name can # be anything you like - the only requirement is that the name must end with # a valid Class B or Class C network number.## [This combining of network number and zone file name is done for convenience.# To change makezones so that the numbers and file names are given as separate# arguments would not be difficult; the changes would affect only the sub-# routine that unpicks the arguments.]## It is intended that makezones will normally be run as part of a "make" # sequence which will also install the files and reload the nameserver(s)# after makezones has run successfully. Thus, the command to run it will# normally be stored in a file and not typed each time.# # The output files are actually written to temporary files whose names are the # same as the final ones with ".new" appended. If the processing succeeds,# these files are renamed; if it fails, they are deleted.## Normally no options are required. There is currently only one option:## -short Used when a new zone file is more than 5% shorter than the # previous version. If not given, the processing will fail if# a new file is that much shorter. This guards against the case# of accidental loss of large portions of the source file. Setting# -short disables the length checking for all zones. You need to# set this option if the previous versions of the files do not# exist. The script can be configured to default to -short; see# "configuration options" above.# # The input file must be writable. The first thing the script does is to update # the serial number in the original file. This forms a permanent record and # ensures that all the created zones have the same number. The form of the# serial number must be <year><month><day><sequence>, as in the example SOA# record shown above. The code will continue to work after December 31, 1999.# If more than 99 updates are done in one day, the failure is soft in that a # valid serial number is still generated, though it no longer contains that# day's date.## # Written by Philip Hazel <ph10@cus.cam.ac.uk># University Computing Service# Computer Laboratory# New Museums Site# Cambridge CB2 3QG # United Kingdom# +44 223 334714## Started: August 1993# Running: September 1993## Update history:# 0.03 07-Sep-93 I'd forgotten to allow TTLs on SOA records.# 0.04 08-Sep-93 Allow comments before the SOA record.# In several places, " " appeared in calls to split(),# where "\s" should have appeared.# Allow non-standard names in quotes. This lets in# names like "3cpu" and "*.something".# Treat tabs after >F etc as multiple spaces.# Allow the name "@"; replace by zone name + dot.# Allow omission of class field except on the SOA record.# Check WKS address is in known network unless >E given.# Fail broadcast addresses.# 0.05 09-Sep-93 Use $name_pattern to check names.# Permit "*" as first name component on MX records.# 0.06 10-Sep-93 Failed if trailing spaces followed 127.0.0.1# 0.06a 22-Sep-93 Updated the specification comments.################################################### Print error message and die #################################################### Ensure any temporary files are removed first. If reading the main file,# $nline will be set non-zero and the current line will be in $_.sub give_up {do remove_temps();print "\n** Makezones: $_[0]\n";if ($nline > 0) { print " At line $nline of $source_file:\n"; print " $_"; } die "** Processing abandoned.\n\n";}################################################### Print error message and continue #################################################### After too many errors, give up. Setting $nline to 0# stops it reflecting the input line again.sub error {print "\n** Makezones: $_[0]\n";if ($nline > 0) { print " At line $nline of $source_file:\n"; print " $_"; } if (++$errors > 10) { do remove_temps(); die "\n** Makezones: too many errors - processing abandoned.\n\n"; } }################################################### Print line to all reverse zone files ###################################################sub print_reverse {local($i);for ($i = 0; $i < $rzone_count; $i++) { local($handle) = "REVERSE$i"; print $handle $_[0]; }} ################################################### Unpick the argument list #################################################### Exit from the whole program on failure. sub unpick_args {$rzone_count = 0;# Handle optionswhile ($#ARGV >= 0 && substr($ARGV[0], 0, 1) eq '-') { if ($ARGV[0] eq "-short") { $opt_short = 1; } else { do give_up("unknown option \"$ARGV[0]\""); } shift ARGV; } # Now we should be left with at least four arguments do give_up("at least three arguments are needed") if $#ARGV < 2;# The first argument is the source file$source_file = $ARGV[0]; shift ARGV;# The second argument is the zone name; remove the trailing dot# if present.$zone_name = $ARGV[0]; shift ARGV;chop($zone_name) if (substr($zone_name, -1, 1) eq ".");# The third argument is the forwards zone file$forward_file = $ARGV[0]; shift ARGV;# We now have zero or more reverse zone fileswhile ($#ARGV >= 0) { local($rzone) = $ARGV[0]; shift ARGV; $rzone_file[$rzone_count] = $rzone; # Check explicitly for a class B or a class C number. I couldn't # find a cunning way of writing a single regular expression that # handled this. Anyway, we need to differentiate in order to check # the values. local($a,$b,$c) = $rzone =~ /^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; if ("$a" eq "") { ($a,$b) = $rzone =~ /^.*\.(\d{1,3})\.(\d{1,3})$/; do give_up("\"$rzone\" does not end with a class B or C ". "network number") if $a eq ""; do give_up("bad class B network $a.$b") if ($a < 128 || $a > 191); $rzone_number[$rzone_count++] = ($a << 24) + ($b << 16); } else { do give_up("bad class C network $a.$b.$c") if ($a < 192 || $a > 223); $rzone_number[$rzone_count++] = ($a << 24) + ($b << 16) + ($c << 8); } } }################################################## # Verify what we are going to do ###################################################sub verify {print "\nMakezones $version_number\n";print "Generating DNS zone files for $zone_name from $source_file.\n";print " Forward zone file: $forward_file\n";printf " Reverse zone file%s ", ($rzone_count == 1)? ": " : "s:";if ($rzone_count > 0) { for ($i = 0; $i < $rzone_count; $i++) { print " "x22 if $i != 0; print "$rzone_file[$i]\n";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -