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