mkfwrules.in 5.57 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
#!/usr/bin/perl -w
#
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file 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 Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
#
use Getopt::Std;
use Socket;

#
# Convert the ipfw rule template files into actual rule files. If you want
# to run these rules on your boss and/or ops, you will need to make
# sure you have the ipfw modules built or an ipfw enabled kernel already
# running. More info on this is in the "ipfirewall" man page. Then, you
# need to change /etc/rc.conf:
#
#  firewall_enable="YES"
#  firewall_flags="-f"
#  firewall_type="/etc/myrules"
#
# where /etc/myrules is the appropriate rule file from the build
# directory. 
#
sub usage {
	print "Usage: $0 <templatefile>\n";
}

#
# Configure variables
#
my $OURDOMAIN                = "@OURDOMAIN@";
my $ELABINELAB		     = @ELABINELAB@;
my ($BOSSTOKEN)              = ("@BOSSNODE@" =~ /^([-\w]+).*$/);
my ($USERTOKEN)              = ("@USERNODE@" =~ /^([-\w]+).*$/);
my ($FSTOKEN)                = ("@FSNODE@" =~ /^([-\w]+).*$/);
my $TESTBED_NETWORK          = "@TESTBED_NETWORK@";
my $TESTBED_NETMASK          = "@TESTBED_NETMASK@";
my $EXTERNAL_TESTBED_NETWORK = "@EXTERNAL_TESTBED_NETWORK@";
my $EXTERNAL_TESTBED_NETMASK = "@EXTERNAL_TESTBED_NETMASK@";
my $BOSSNODE_IP              = "@BOSSNODE_IP@";
my $USERNODE_IP              = "@USERNODE_IP@";
my $FSNODE_IP                = "@FSNODE_IP@";
my $NTPSERVER                = "@NTPSERVER@";
my $EXTERNAL_BOSSNODE_IP     = "@EXTERNAL_BOSSNODE_IP@";
my $EXTERNAL_USERNODE_IP     = "@EXTERNAL_USERNODE_IP@";
my $EXTERNAL_FSNODE_IP       = "@EXTERNAL_FSNODE_IP@";
my $CONTROL_ROUTER_IP        = "@CONTROL_ROUTER_IP@";
my $CONTROL_NETWORK          = "@CONTROL_NETWORK@";
my $CONTROL_NETMASK          = "@CONTROL_NETMASK@";
my $PRIVATE_NETWORK          = "@PRIVATE_NETWORK@";
my $PRIVATE_ROUTER           = "@PRIVATE_ROUTER@";
my $PRIVATE_NETMASK          = "@PRIVATE_NETMASK@";
my $PUBLIC_NETWORK           = "@PUBLIC_NETWORK@";
my $PUBLIC_ROUTER            = "@PUBLIC_ROUTER@";
my $PUBLIC_NETMASK           = "@PUBLIC_NETMASK@";
my $NAMED_FORWARDERS         = "@NAMED_FORWARDERS@";
74 75 76
my $GREP		     = "/usr/bin/grep";
my $FIREWALL_BOSS_LOCALRULETMPL = "@FIREWALL_BOSS_LOCALRULETMPL@";
my $FIREWALL_OPS_LOCALRULETMPL  = "@FIREWALL_OPS_LOCALRULETMPL@";
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

# Simple is good. I stole this out of a google search.
my @NETMASKS =
    (0x10000000,                                             # 0
     0x80000000, 0xC0000000, 0xE0000000, 0xF0000000,         #  1 -  4
     0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000,         #  5 -  8
     0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000,         #  9 - 12
     0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000,         # 13 - 16
     0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000,         # 17 - 20
     0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00,         # 21 - 24
     0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0,         # 25 - 28
     0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF          # 29 - 32
);

my %SUB = (
    "alltestbed"        => "$TESTBED_NETWORK:$TESTBED_NETMASK",
    "publicnetwork"     => "$PUBLIC_NETWORK:$PUBLIC_NETMASK",
    "controlnetwork"    => "$CONTROL_NETWORK:$CONTROL_NETMASK",
    "jailnetwork"	=> "172.16.0.0/12",
    "multicast"         => "$TESTBED_NETWORK:$TESTBED_NETMASK,172.16.0.0/12",
);

#
# Ug, for elabinelab, it is easier to just set the multicast rule
101
# to "any" to avoid problems. 
102 103 104 105 106
#
if ($ELABINELAB) {
    $SUB{"multicast"} = "any";
}

107 108 109 110 111
#
# Natd is optional. 
#
my $NATDRULE = "add divert natd ip4 from any to any";

112 113 114 115 116 117 118 119
# Testbed libraries.
use lib "@prefix@/lib";

usage()
    if (@ARGV != 1);

my $infile = $ARGV[0];

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140

#
# Look to see if natd is enabled in /etc/rc.conf and what the
# natd interface is. Might be easier to just read in the shell
# variables and process them. 
#

system("$GREP '^natd_enable' /etc/rc.conf | $GREP -q -i yes");
if (!$?) {
    my $natd_interface = `$GREP '^natd_interface' /etc/rc.conf`;
    if (!$? && $natd_interface =~ /=\"(.*)\"$/) {
	$NATDRULE = "$NATDRULE via $1";
    }
    else {
	die("natd is enabled in /etc/rc.conf, but no natd_interface!\n");
    }
}
else {
    $NATDRULE = "";
}

141 142 143 144
open(IF,"<$infile") or
    die("Unable to open $infile for reading\n");

while (<IF>) {
145
    if (/^(.*)\%([-\w]*)\%\s*(.*)$/) {
146
	if ($2 eq "localrules") {
147 148 149 150 151 152 153 154 155 156 157
	    my $which = $3;
	    my $filename;

	    if ($which eq "ops" && $FIREWALL_OPS_LOCALRULETMPL ne "") {
		$filename .= "${FIREWALL_OPS_LOCALRULETMPL}.ipfw";
	    }
	    elsif ($which eq "boss" && $FIREWALL_BOSS_LOCALRULETMPL ne "") {
		$filename .= "${FIREWALL_BOSS_LOCALRULETMPL}.ipfw";
	    }
	    next
		if (! defined($filename));
158 159 160 161
	    
	    if (-e $filename) {
		system("cat $filename");
	    }
162 163 164 165 166 167
	    else {
		die("Local template file for $which does not exist\n");
	    }
	}
	elsif ($2 eq "natdrules") {
	    print "$NATDRULE\n";
168 169
	}
	elsif (exists($SUB{$2})) {
170
	    print "$1" . $SUB{$2} . " $3\n";
171 172 173 174 175 176 177 178 179 180 181 182
	}
	else {
	    die("No substitution for '$2'\n");
	}
	next;
    }
    print $_;
}
close(IF);

exit(0);