Home | History | Annotate | Line # | Download | only in perl
ipfmeta.pl revision 1.1.1.1.2.2
      1  1.1.1.1.2.2  yamt #!/usr/bin/perl -w
      2  1.1.1.1.2.2  yamt #
      3  1.1.1.1.2.2  yamt # Written by Camiel Dobbelaar <cd (at] sentia.nl>, Aug-2000
      4  1.1.1.1.2.2  yamt # ipfmeta is in the Public Domain.
      5  1.1.1.1.2.2  yamt #
      6  1.1.1.1.2.2  yamt 
      7  1.1.1.1.2.2  yamt use strict;
      8  1.1.1.1.2.2  yamt use Getopt::Std;
      9  1.1.1.1.2.2  yamt 
     10  1.1.1.1.2.2  yamt ## PROCESS COMMANDLINE
     11  1.1.1.1.2.2  yamt our($opt_v); $opt_v=1;
     12  1.1.1.1.2.2  yamt getopts('v:') || die "usage: ipfmeta [-v verboselevel] [objfile]\n";
     13  1.1.1.1.2.2  yamt my $verbose = $opt_v + 0;
     14  1.1.1.1.2.2  yamt my $objfile = shift || "ipf.objs";
     15  1.1.1.1.2.2  yamt my $MAXRECURSION = 10;
     16  1.1.1.1.2.2  yamt 
     17  1.1.1.1.2.2  yamt ## READ OBJECTS
     18  1.1.1.1.2.2  yamt open(FH, "$objfile") || die "cannot open $objfile: $!\n";
     19  1.1.1.1.2.2  yamt my @tokens;
     20  1.1.1.1.2.2  yamt while (<FH>) {
     21  1.1.1.1.2.2  yamt 	chomp;
     22  1.1.1.1.2.2  yamt 	s/#.*$//;	# remove comments
     23  1.1.1.1.2.2  yamt 	s/^\s+//;	# compress whitespace
     24  1.1.1.1.2.2  yamt 	s/\s+$//;
     25  1.1.1.1.2.2  yamt 	next if m/^$/;	# skip empty lines
     26  1.1.1.1.2.2  yamt 	push (@tokens, split);
     27  1.1.1.1.2.2  yamt }
     28  1.1.1.1.2.2  yamt close(FH) || die "cannot close $objfile: $!\n";
     29  1.1.1.1.2.2  yamt # link objects with their values
     30  1.1.1.1.2.2  yamt my $obj="";
     31  1.1.1.1.2.2  yamt my %objs;
     32  1.1.1.1.2.2  yamt while (@tokens) {
     33  1.1.1.1.2.2  yamt 	my $token = shift(@tokens);
     34  1.1.1.1.2.2  yamt 	if ($token =~ m/^\[([^]]*)\]$/) {
     35  1.1.1.1.2.2  yamt 		# new object
     36  1.1.1.1.2.2  yamt 		$obj = $1;
     37  1.1.1.1.2.2  yamt 	} else {
     38  1.1.1.1.2.2  yamt 		# new value
     39  1.1.1.1.2.2  yamt 		push(@{$objs{$obj}}, $token) unless ($obj eq "");
     40  1.1.1.1.2.2  yamt 	}
     41  1.1.1.1.2.2  yamt }
     42  1.1.1.1.2.2  yamt 
     43  1.1.1.1.2.2  yamt # sort objects: longest first
     44  1.1.1.1.2.2  yamt my @objs = sort { length($b) <=> length($a) } keys %objs;
     45  1.1.1.1.2.2  yamt 
     46  1.1.1.1.2.2  yamt ## SUBSTITUTE OBJECTS WITH THEIR VALUES FROM STDIN
     47  1.1.1.1.2.2  yamt foreach (<STDIN>) {
     48  1.1.1.1.2.2  yamt 	foreach (expand($_, 0)) {
     49  1.1.1.1.2.2  yamt 		print;
     50  1.1.1.1.2.2  yamt 	}
     51  1.1.1.1.2.2  yamt }
     52  1.1.1.1.2.2  yamt 
     53  1.1.1.1.2.2  yamt ## END
     54  1.1.1.1.2.2  yamt 
     55  1.1.1.1.2.2  yamt sub expand {
     56  1.1.1.1.2.2  yamt 	my $line = shift;
     57  1.1.1.1.2.2  yamt 	my $level = shift;
     58  1.1.1.1.2.2  yamt 	my @retlines = $line;
     59  1.1.1.1.2.2  yamt 	my $obj;
     60  1.1.1.1.2.2  yamt 	my $val;
     61  1.1.1.1.2.2  yamt 
     62  1.1.1.1.2.2  yamt 	# coarse protection
     63  1.1.1.1.2.2  yamt 	if ($level > $MAXRECURSION) {
     64  1.1.1.1.2.2  yamt 		print STDERR "ERR: recursion exceeds $MAXRECURSION levels\n";
     65  1.1.1.1.2.2  yamt 		return;
     66  1.1.1.1.2.2  yamt 	}
     67  1.1.1.1.2.2  yamt 
     68  1.1.1.1.2.2  yamt 	foreach $obj (@objs) {
     69  1.1.1.1.2.2  yamt 		if ($line =~ m/$obj/) {
     70  1.1.1.1.2.2  yamt 			@retlines = "";
     71  1.1.1.1.2.2  yamt 			if ($level < $verbose) {
     72  1.1.1.1.2.2  yamt 				# add metarule as a comment
     73  1.1.1.1.2.2  yamt 				push(@retlines, "# ".$line);
     74  1.1.1.1.2.2  yamt 			}
     75  1.1.1.1.2.2  yamt 			foreach $val (@{$objs{$obj}}) {
     76  1.1.1.1.2.2  yamt 				my $newline = $line;
     77  1.1.1.1.2.2  yamt 				$newline =~ s/$obj/$val/;
     78  1.1.1.1.2.2  yamt 				push(@retlines, expand($newline, $level+1));
     79  1.1.1.1.2.2  yamt 			}
     80  1.1.1.1.2.2  yamt 			last;
     81  1.1.1.1.2.2  yamt 		}
     82  1.1.1.1.2.2  yamt 	}
     83  1.1.1.1.2.2  yamt 
     84  1.1.1.1.2.2  yamt 	return @retlines;
     85  1.1.1.1.2.2  yamt }
     86  1.1.1.1.2.2  yamt 
     87  1.1.1.1.2.2  yamt __END__
     88  1.1.1.1.2.2  yamt 
     89  1.1.1.1.2.2  yamt =head1 NAME
     90  1.1.1.1.2.2  yamt 
     91  1.1.1.1.2.2  yamt B<ipfmeta> - use objects in IP filter files
     92  1.1.1.1.2.2  yamt 
     93  1.1.1.1.2.2  yamt =head1 SYNOPSIS
     94  1.1.1.1.2.2  yamt 
     95  1.1.1.1.2.2  yamt B<ipfmeta> [F<options>] [F<objfile>]
     96  1.1.1.1.2.2  yamt 
     97  1.1.1.1.2.2  yamt =head1 DESCRIPTION
     98  1.1.1.1.2.2  yamt 
     99  1.1.1.1.2.2  yamt B<ipfmeta> is used to simplify the maintenance of your IP filter
    100  1.1.1.1.2.2  yamt ruleset. It does this through the use of 'objects'.  A matching
    101  1.1.1.1.2.2  yamt object gets replaced by its values at runtime.  This is similar to
    102  1.1.1.1.2.2  yamt what a macro processor like m4 does.
    103  1.1.1.1.2.2  yamt 
    104  1.1.1.1.2.2  yamt B<ipfmeta> is specifically geared towards IP filter. It is line
    105  1.1.1.1.2.2  yamt oriented, if an object has multiple values, the line with the object
    106  1.1.1.1.2.2  yamt is duplicated and substituted for each value. It is also recursive,
    107  1.1.1.1.2.2  yamt an object may have another object as a value.
    108  1.1.1.1.2.2  yamt 
    109  1.1.1.1.2.2  yamt Rules to be processed are read from stdin, output goes to stdout.
    110  1.1.1.1.2.2  yamt 
    111  1.1.1.1.2.2  yamt The verbose option allows for the inclusion of the metarules in the
    112  1.1.1.1.2.2  yamt output as comments.
    113  1.1.1.1.2.2  yamt 
    114  1.1.1.1.2.2  yamt Definition of the objects and their values is done in a separate
    115  1.1.1.1.2.2  yamt file, the filename defaults to F<ipf.objs>.  An object is delimited
    116  1.1.1.1.2.2  yamt by square brackets. A value is delimited by whitespace.  Comments
    117  1.1.1.1.2.2  yamt start with '#' and end with a newline. Empty lines and extraneous
    118  1.1.1.1.2.2  yamt whitespace are allowed.  A value belongs to the first object that
    119  1.1.1.1.2.2  yamt precedes it.
    120  1.1.1.1.2.2  yamt 
    121  1.1.1.1.2.2  yamt It is recommended that you use all caps or another distinguishing
    122  1.1.1.1.2.2  yamt feature for object names. You can use B<ipfmeta> for NAT rules also,
    123  1.1.1.1.2.2  yamt for instance to keep them in sync with filter rules.  Combine
    124  1.1.1.1.2.2  yamt B<ipfmeta> with a Makefile to save typing.
    125  1.1.1.1.2.2  yamt 
    126  1.1.1.1.2.2  yamt =head1 OPTIONS
    127  1.1.1.1.2.2  yamt 
    128  1.1.1.1.2.2  yamt =over 4
    129  1.1.1.1.2.2  yamt 
    130  1.1.1.1.2.2  yamt =item B<-v> I<verboselevel>
    131  1.1.1.1.2.2  yamt 
    132  1.1.1.1.2.2  yamt Include metarules in output as comments. Default is 1, the top level
    133  1.1.1.1.2.2  yamt metarules. Higher levels cause expanded metarules to be included.
    134  1.1.1.1.2.2  yamt Level 0 does not add comments at all.
    135  1.1.1.1.2.2  yamt 
    136  1.1.1.1.2.2  yamt =back
    137  1.1.1.1.2.2  yamt 
    138  1.1.1.1.2.2  yamt =head1 BUGS
    139  1.1.1.1.2.2  yamt 
    140  1.1.1.1.2.2  yamt A value can not have whitespace in it.
    141  1.1.1.1.2.2  yamt 
    142  1.1.1.1.2.2  yamt =head1 EXAMPLE
    143  1.1.1.1.2.2  yamt 
    144  1.1.1.1.2.2  yamt (this does not look good, formatted)
    145  1.1.1.1.2.2  yamt 
    146  1.1.1.1.2.2  yamt I<ipf.objs>
    147  1.1.1.1.2.2  yamt 
    148  1.1.1.1.2.2  yamt [PRIVATE] 10.0.0.0/8 127.0.0.0/8 172.16.0.0/12 192.168.0.0/16
    149  1.1.1.1.2.2  yamt 
    150  1.1.1.1.2.2  yamt [MULTICAST] 224.0.0.0/4
    151  1.1.1.1.2.2  yamt 
    152  1.1.1.1.2.2  yamt [UNWANTED] PRIVATE MULTICAST
    153  1.1.1.1.2.2  yamt 
    154  1.1.1.1.2.2  yamt [NOC] xxx.yy.zz.1/32 xxx.yy.zz.2/32
    155  1.1.1.1.2.2  yamt 
    156  1.1.1.1.2.2  yamt [WEBSERVERS] 192.168.1.1/32 192.168.1.2/32
    157  1.1.1.1.2.2  yamt 
    158  1.1.1.1.2.2  yamt [MGMT-PORTS] 22 23
    159  1.1.1.1.2.2  yamt 
    160  1.1.1.1.2.2  yamt I<ipf.metarules>
    161  1.1.1.1.2.2  yamt 
    162  1.1.1.1.2.2  yamt block in from UNWANTED to any
    163  1.1.1.1.2.2  yamt 
    164  1.1.1.1.2.2  yamt pass  in from NOC to WEBSERVERS port = MGMT-PORTS
    165  1.1.1.1.2.2  yamt 
    166  1.1.1.1.2.2  yamt pass  out all
    167  1.1.1.1.2.2  yamt 
    168  1.1.1.1.2.2  yamt I<Run>
    169  1.1.1.1.2.2  yamt 
    170  1.1.1.1.2.2  yamt ipfmeta ipf.objs <ipf.metarules >ipf.rules
    171  1.1.1.1.2.2  yamt 
    172  1.1.1.1.2.2  yamt I<Output>
    173  1.1.1.1.2.2  yamt 
    174  1.1.1.1.2.2  yamt # block in from UNWANTED to any
    175  1.1.1.1.2.2  yamt 
    176  1.1.1.1.2.2  yamt block in from 10.0.0.0/8 to any
    177  1.1.1.1.2.2  yamt 
    178  1.1.1.1.2.2  yamt block in from 127.0.0.0/8 to any
    179  1.1.1.1.2.2  yamt 
    180  1.1.1.1.2.2  yamt block in from 172.16.0.0/12 to any
    181  1.1.1.1.2.2  yamt 
    182  1.1.1.1.2.2  yamt block in from 192.168.0.0/16 to any
    183  1.1.1.1.2.2  yamt 
    184  1.1.1.1.2.2  yamt block in from 224.0.0.0/4 to any
    185  1.1.1.1.2.2  yamt 
    186  1.1.1.1.2.2  yamt # pass  in from NOC to WEBSERVERS port = MGMT-PORTS
    187  1.1.1.1.2.2  yamt 
    188  1.1.1.1.2.2  yamt pass  in from xxx.yy.zz.1/32 to 192.168.1.1/32 port = 22
    189  1.1.1.1.2.2  yamt 
    190  1.1.1.1.2.2  yamt pass  in from xxx.yy.zz.1/32 to 192.168.1.1/32 port = 23
    191  1.1.1.1.2.2  yamt 
    192  1.1.1.1.2.2  yamt pass  in from xxx.yy.zz.1/32 to 192.168.1.2/32 port = 22
    193  1.1.1.1.2.2  yamt 
    194  1.1.1.1.2.2  yamt pass  in from xxx.yy.zz.1/32 to 192.168.1.2/32 port = 23
    195  1.1.1.1.2.2  yamt 
    196  1.1.1.1.2.2  yamt pass  in from xxx.yy.zz.2/32 to 192.168.1.1/32 port = 22
    197  1.1.1.1.2.2  yamt 
    198  1.1.1.1.2.2  yamt pass  in from xxx.yy.zz.2/32 to 192.168.1.1/32 port = 23
    199  1.1.1.1.2.2  yamt 
    200  1.1.1.1.2.2  yamt pass  in from xxx.yy.zz.2/32 to 192.168.1.2/32 port = 22
    201  1.1.1.1.2.2  yamt 
    202  1.1.1.1.2.2  yamt pass  in from xxx.yy.zz.2/32 to 192.168.1.2/32 port = 23
    203  1.1.1.1.2.2  yamt 
    204  1.1.1.1.2.2  yamt pass  out all
    205  1.1.1.1.2.2  yamt 
    206  1.1.1.1.2.2  yamt =head1 AUTHOR
    207  1.1.1.1.2.2  yamt 
    208  1.1.1.1.2.2  yamt Camiel Dobbelaar <cd@sentia.nl>. B<ipfmeta> is in the Public Domain.
    209  1.1.1.1.2.2  yamt 
    210  1.1.1.1.2.2  yamt =cut
    211