forked from extern/shorewall_code
762 lines
18 KiB
Perl
762 lines
18 KiB
Perl
|
#! /usr/bin/perl -w
|
||
|
#
|
||
|
# The Shoreline Firewall4 (Shorewall-perl) Packet Filtering Firewall Compiler - V4.0
|
||
|
#
|
||
|
# This program is under GPL [http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt]
|
||
|
#
|
||
|
# (c) 2007 - Tom Eastep (teastep@shorewall.net)
|
||
|
#
|
||
|
# Complete documentation is available at http://shorewall.net
|
||
|
#
|
||
|
# This program is free software; you can redistribute it and/or modify
|
||
|
# it under the terms of Version 2 of the GNU General Public License
|
||
|
# as published by the Free Software Foundation.
|
||
|
#
|
||
|
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
#
|
||
|
|
||
|
package Shorewall::Compiler;
|
||
|
require Exporter;
|
||
|
use Shorewall::Config;
|
||
|
use Shorewall::Chains;
|
||
|
use Shorewall::Zones;
|
||
|
use Shorewall::Policy;
|
||
|
use Shorewall::Tc;
|
||
|
use Shorewall::Tunnels;
|
||
|
use Shorewall::Actions;
|
||
|
use Shorewall::Accounting;
|
||
|
use Shorewall::Rules;
|
||
|
use Shorewall::Proc;
|
||
|
|
||
|
our @ISA = qw(Exporter);
|
||
|
our @EXPORT = qw( compiler EXPORT TIMESTAMP DEBUG );
|
||
|
our @EXPORT_OK = qw( $export );
|
||
|
our $VERSION = '4.04';
|
||
|
|
||
|
our $export;
|
||
|
|
||
|
our $reused = 0;
|
||
|
|
||
|
use constant { EXPORT => 0x01 ,
|
||
|
TIMESTAMP => 0x02 ,
|
||
|
DEBUG => 0x04 };
|
||
|
|
||
|
#
|
||
|
# Reinitilize the package-globals in the other modules
|
||
|
#
|
||
|
sub reinitialize() {
|
||
|
Shorewall::Config::initialize;
|
||
|
Shorewall::Chains::initialize;
|
||
|
Shorewall::Zones::initialize;
|
||
|
Shorewall::Policy::initialize;
|
||
|
Shorewall::Tc::initialize;
|
||
|
Shorewall::Actions::initialize;
|
||
|
Shorewall::Accounting::initialize;
|
||
|
Shorewall::Rules::initialize;
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# First stage of script generation.
|
||
|
#
|
||
|
# Copy the prog.header to the generated script.
|
||
|
# Generate the various user-exit jacket functions.
|
||
|
# Generate the 'initialize()' function.
|
||
|
#
|
||
|
# Note: This function is not called when $command eq 'check'. So it must have no side effects other
|
||
|
# than those related to writing to the object file.
|
||
|
|
||
|
sub generate_script_1() {
|
||
|
|
||
|
my $date = localtime;
|
||
|
|
||
|
emit "#!/bin/sh\n#\n# Compiled firewall script generated by Shorewall-perl $globals{VERSION} - $date\n#";
|
||
|
|
||
|
copy $globals{SHAREDIRPL} . 'prog.header';
|
||
|
|
||
|
for my $exit qw/init isusable start tcclear started stop stopped clear refresh refreshed/ {
|
||
|
emit "\nrun_${exit}_exit() {";
|
||
|
push_indent;
|
||
|
append_file $exit or emit 'true';
|
||
|
pop_indent;
|
||
|
emit '}';
|
||
|
}
|
||
|
|
||
|
emit ( '',
|
||
|
'#',
|
||
|
'# This function initializes the global variables used by the program',
|
||
|
'#',
|
||
|
'initialize()',
|
||
|
'{',
|
||
|
' #',
|
||
|
' # These variables are required by the library functions called in this script',
|
||
|
' #'
|
||
|
);
|
||
|
|
||
|
push_indent;
|
||
|
|
||
|
if ( $export ) {
|
||
|
emit ( 'SHAREDIR=/usr/share/shorewall-lite',
|
||
|
'CONFDIR=/etc/shorewall-lite',
|
||
|
'PRODUCT="Shorewall Lite"'
|
||
|
);
|
||
|
} else {
|
||
|
emit ( 'SHAREDIR=/usr/share/shorewall',
|
||
|
'CONFDIR=/etc/shorewall',
|
||
|
'PRODUCT=\'Shorewall\'',
|
||
|
);
|
||
|
}
|
||
|
|
||
|
emit( '[ -f ${CONFDIR}/vardir ] && . ${CONFDIR}/vardir' );
|
||
|
|
||
|
if ( $export ) {
|
||
|
emit ( 'CONFIG_PATH="/etc/shorewall-lite:/usr/share/shorewall-lite"' ,
|
||
|
'[ -n "${VARDIR:=/var/lib/shorewall-lite}" ]' );
|
||
|
} else {
|
||
|
emit ( qq(CONFIG_PATH="$config{CONFIG_PATH}") ,
|
||
|
'[ -n "${VARDIR:=/var/lib/shorewall}" ]' );
|
||
|
}
|
||
|
|
||
|
emit 'TEMPFILE=';
|
||
|
|
||
|
propagateconfig;
|
||
|
|
||
|
emit ( '[ -n "${COMMAND:=restart}" ]',
|
||
|
'[ -n "${VERBOSE:=0}" ]',
|
||
|
qq([ -n "\${RESTOREFILE:=$config{RESTOREFILE}}" ]),
|
||
|
'[ -n "$LOGFORMAT" ] || LOGFORMAT="Shorewall:%s:%s:"',
|
||
|
qq(VERSION="$globals{VERSION}") ,
|
||
|
qq(PATH="$config{PATH}") ,
|
||
|
'TERMINATOR=fatal_error' ,
|
||
|
''
|
||
|
);
|
||
|
|
||
|
if ( $config{IP6TABLES} ) {
|
||
|
emit( qq(IP6TABLES="$config{IP6TABLES}"),
|
||
|
'[ -x "$IP6TABLES" ] || startup_error "IP6TABLES=$IP6TABLES does not exist or is not executable"',
|
||
|
);
|
||
|
} else {
|
||
|
emit( '[ -z "$IP6TABLES" ] && IP6TABLES=$(mywhich ip6tables) # /sbin/shorewall6 exports IP6TABLES',
|
||
|
'[ -n "$IP6TABLES" -a -x "$IP6TABLES" ] || startup_error "Can\'t find ip6tables executable"'
|
||
|
);
|
||
|
}
|
||
|
|
||
|
emit( 'IP6TABLES_RESTORE=${IP6TABLES}-restore',
|
||
|
'[ -x "$IP6TABLES_RESTORE" ] || startup_error "$IP6TABLES_RESTORE does not exist or is not executable"' );
|
||
|
|
||
|
append_file 'params' if $config{EXPORTPARAMS};
|
||
|
|
||
|
emit ( '',
|
||
|
"STOPPING=",
|
||
|
'',
|
||
|
'#',
|
||
|
'# The library requires that ${VARDIR} exist',
|
||
|
'#',
|
||
|
'[ -d ${VARDIR} ] || mkdir -p ${VARDIR}'
|
||
|
);
|
||
|
|
||
|
emit ( '',
|
||
|
'#',
|
||
|
'# Recent kernels are difficult to configure -- we see state match omitted a lot so we check for it here',
|
||
|
'#',
|
||
|
'qt $IP6TABLES -N foox1234',
|
||
|
'qt $IP6TABLES -A foox1234 -m state --state ESTABLISHED,RELATED -j ACCEPT',
|
||
|
'result=$?',
|
||
|
'qt $IP6TABLES -F foox1234',
|
||
|
'qt $IP6TABLES -X foox1234',
|
||
|
'[ $result = 0 ] || startup_error "Your kernel/ip6tables do not include state match support. No version of Shorewall6 will run on this system"',
|
||
|
'' );
|
||
|
|
||
|
pop_indent;
|
||
|
|
||
|
emit "}\n"; # End of initialize()
|
||
|
|
||
|
}
|
||
|
|
||
|
sub compile_stop_firewall() {
|
||
|
|
||
|
emit <<'EOF';
|
||
|
#
|
||
|
# Stop/restore the firewall after an error or because of a 'stop' or 'clear' command
|
||
|
#
|
||
|
stop_firewall() {
|
||
|
|
||
|
deletechain() {
|
||
|
qt $IP6TABLES -L $1 -n && qt $IP6TABLES -F $1 && qt $IP6TABLES -X $1
|
||
|
}
|
||
|
|
||
|
deleteallchains() {
|
||
|
$IP6TABLES -F
|
||
|
$IP6TABLES -X
|
||
|
}
|
||
|
|
||
|
setcontinue() {
|
||
|
$IP6TABLES -A $1 -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||
|
}
|
||
|
|
||
|
case $COMMAND in
|
||
|
stop|clear|restore)
|
||
|
;;
|
||
|
*)
|
||
|
set +x
|
||
|
|
||
|
case $COMMAND in
|
||
|
start)
|
||
|
logger -p kern.err "ERROR:$PRODUCT start failed"
|
||
|
;;
|
||
|
restart)
|
||
|
logger -p kern.err "ERROR:$PRODUCT restart failed"
|
||
|
;;
|
||
|
restore)
|
||
|
logger -p kern.err "ERROR:$PRODUCT restore failed"
|
||
|
;;
|
||
|
esac
|
||
|
|
||
|
if [ "$RESTOREFILE" = NONE ]; then
|
||
|
COMMAND=clear
|
||
|
clear_firewall
|
||
|
echo "$PRODUCT Cleared"
|
||
|
|
||
|
kill $$
|
||
|
exit 2
|
||
|
else
|
||
|
RESTOREPATH=${VARDIR}/$RESTOREFILE
|
||
|
|
||
|
if [ -x $RESTOREPATH ]; then
|
||
|
echo Restoring ${PRODUCT:=Shorewall6}...
|
||
|
|
||
|
if $RESTOREPATH restore; then
|
||
|
echo "$PRODUCT restored from $RESTOREPATH"
|
||
|
set_state "Started"
|
||
|
else
|
||
|
set_state "Unknown"
|
||
|
fi
|
||
|
|
||
|
kill $$
|
||
|
exit 2
|
||
|
fi
|
||
|
fi
|
||
|
;;
|
||
|
esac
|
||
|
|
||
|
set_state "Stopping"
|
||
|
|
||
|
STOPPING="Yes"
|
||
|
|
||
|
TERMINATOR=
|
||
|
|
||
|
deletechain shorewall
|
||
|
|
||
|
run_stop_exit;
|
||
|
|
||
|
EOF
|
||
|
|
||
|
if ( $capabilities{MANGLE_ENABLED} ) {
|
||
|
emit <<'EOF';
|
||
|
run_iptables -t mangle -F
|
||
|
run_iptables -t mangle -X
|
||
|
for chain in PREROUTING INPUT FORWARD POSTROUTING; do
|
||
|
qt $IP6TABLES -t mangle -P $chain ACCEPT
|
||
|
done
|
||
|
|
||
|
EOF
|
||
|
}
|
||
|
|
||
|
if ( $capabilities{RAW_TABLE} ) {
|
||
|
emit <<'EOF';
|
||
|
run_ip6tables -t raw -F
|
||
|
run_ip6tables -t raw -X
|
||
|
for chain in PREROUTING OUTPUT; do
|
||
|
qt $IP6TABLES -t raw -P $chain ACCEPT
|
||
|
done
|
||
|
|
||
|
EOF
|
||
|
}
|
||
|
|
||
|
push_indent;
|
||
|
|
||
|
emit 'delete_tc1' if $config{CLEAR_TC};
|
||
|
|
||
|
my $criticalhosts = process_criticalhosts;
|
||
|
|
||
|
if ( @$criticalhosts ) {
|
||
|
if ( $config{ADMINISABSENTMINDED} ) {
|
||
|
emit ( 'for chain in INPUT OUTPUT; do',
|
||
|
' setpolicy $chain ACCEPT',
|
||
|
'done',
|
||
|
'',
|
||
|
'setpolicy FORWARD DROP',
|
||
|
'',
|
||
|
'deleteallchains',
|
||
|
''
|
||
|
);
|
||
|
|
||
|
for my $hosts ( @$criticalhosts ) {
|
||
|
my ( $interface, $host ) = ( split /:/, $hosts );
|
||
|
my $source = match_source_net $host;
|
||
|
my $dest = match_dest_net $host;
|
||
|
|
||
|
emit( "\$IP6TABLES -A INPUT -i $interface $source -j ACCEPT",
|
||
|
"\$IP6TABLES -A OUTPUT -o $interface $dest -j ACCEPT"
|
||
|
);
|
||
|
}
|
||
|
|
||
|
emit( '',
|
||
|
'for chain in INPUT OUTPUT; do',
|
||
|
' setpolicy $chain DROP',
|
||
|
"done\n"
|
||
|
);
|
||
|
} else {
|
||
|
emit( '',
|
||
|
'for chain in INPUT OUTPUT; do',
|
||
|
' setpolicy \$chain ACCEPT',
|
||
|
'done',
|
||
|
'',
|
||
|
'setpolicy FORWARD DROP',
|
||
|
'',
|
||
|
"deleteallchains\n"
|
||
|
);
|
||
|
|
||
|
for my $hosts ( @$criticalhosts ) {
|
||
|
my ( $interface, $host ) = ( split /:/, $hosts );
|
||
|
my $source = match_source_net $host;
|
||
|
my $dest = match_dest_net $host;
|
||
|
|
||
|
emit( "\$IP6TABLES -A INPUT -i $interface $source -j ACCEPT",
|
||
|
"\$IP6TABLES -A OUTPUT -o $interface $dest -j ACCEPT"
|
||
|
);
|
||
|
}
|
||
|
|
||
|
emit( "\nsetpolicy INPUT DROP",
|
||
|
'',
|
||
|
'for chain in INPUT FORWARD; do',
|
||
|
' setcontinue $chain',
|
||
|
"done\n"
|
||
|
);
|
||
|
}
|
||
|
} elsif ( $config{ADMINISABSENTMINDED} ) {
|
||
|
emit( 'for chain in INPUT FORWARD; do',
|
||
|
' setpolicy $chain DROP',
|
||
|
'done',
|
||
|
'',
|
||
|
'setpolicy OUTPUT ACCEPT',
|
||
|
'',
|
||
|
'deleteallchains',
|
||
|
'',
|
||
|
'for chain in INPUT FORWARD; do',
|
||
|
' setcontinue $chain',
|
||
|
"done\n",
|
||
|
);
|
||
|
} else {
|
||
|
emit( 'for chain in INPUT OUTPUT FORWARD; do',
|
||
|
' setpolicy $chain DROP',
|
||
|
'done',
|
||
|
'',
|
||
|
"deleteallchains\n"
|
||
|
);
|
||
|
}
|
||
|
|
||
|
process_routestopped;
|
||
|
|
||
|
emit( '$IP6TABLES -A INPUT -i lo -j ACCEPT',
|
||
|
'$IP6TABLES -A OUTPUT -o lo -j ACCEPT'
|
||
|
);
|
||
|
|
||
|
emit '$IP6TABLES -A OUTPUT -o lo -j ACCEPT' unless $config{ADMINISABSENTMINDED};
|
||
|
|
||
|
my $interfaces = find_interfaces_by_option 'dhcp';
|
||
|
|
||
|
for my $interface ( @$interfaces ) {
|
||
|
emit "\$IP6TABLES -A INPUT -p udp -i $interface --dport 67:68 -j ACCEPT";
|
||
|
emit "\$IP6TABLES -A OUTPUT -p udp -o $interface --dport 67:68 -j ACCEPT" unless $config{ADMINISABSENTMINDED};
|
||
|
#
|
||
|
# This might be a bridge
|
||
|
#
|
||
|
emit "\$IP6TABLES -A FORWARD -p udp -i $interface -o $interface --dport 67:68 -j ACCEPT";
|
||
|
}
|
||
|
|
||
|
emit '';
|
||
|
|
||
|
if ( $config{IP_FORWARDING} eq 'on' ) {
|
||
|
emit( 'echo 1 > /proc/sys/net/ipv4/ip_forward',
|
||
|
'progress_message2 IP Forwarding Enabled' );
|
||
|
} elsif ( $config{IP_FORWARDING} eq 'off' ) {
|
||
|
emit( 'echo 0 > /proc/sys/net/ipv4/ip_forward',
|
||
|
'progress_message2 IP Forwarding Disabled!'
|
||
|
);
|
||
|
}
|
||
|
|
||
|
emit 'run_stopped_exit';
|
||
|
|
||
|
pop_indent;
|
||
|
|
||
|
emit '
|
||
|
set_state "Stopped"
|
||
|
|
||
|
logger -p kern.info "$PRODUCT Stopped"
|
||
|
|
||
|
case $COMMAND in
|
||
|
stop|clear)
|
||
|
;;
|
||
|
*)
|
||
|
#
|
||
|
# The firewall is being stopped when we were trying to do something
|
||
|
# else. Kill the shell in case we\'re running in a subshell
|
||
|
#
|
||
|
kill $$
|
||
|
;;
|
||
|
esac
|
||
|
}
|
||
|
';
|
||
|
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# Second Phase of Script Generation
|
||
|
#
|
||
|
# copies the 'prog.functions' file into the script, generates
|
||
|
# clear_routing_and_traffic_shaping() and the first part of
|
||
|
# 'setup_routing_and_traffic_shaping()'
|
||
|
#
|
||
|
# The bulk of that function is produced by the various config file
|
||
|
# parsing routines that are called directly out of 'compiler()'.
|
||
|
#
|
||
|
# We create two separate functions rather than one so that the
|
||
|
# define_firewall() shell can set global IP configuration variables
|
||
|
# after the old config has been cleared and before we start instantiating
|
||
|
# the new config. That way, the variables reflect the way that the
|
||
|
# distribution's tools have configured IP without any Shorewall
|
||
|
# modifications.
|
||
|
#
|
||
|
# Note: This function is not called when $command eq 'check'. So it must have no side effects other
|
||
|
# than those related to writing to the object file.
|
||
|
#
|
||
|
sub generate_script_2 () {
|
||
|
|
||
|
copy $globals{SHAREDIRPL} . 'prog.functions';
|
||
|
|
||
|
emit( '',
|
||
|
'#',
|
||
|
'# Clear Routing and Traffic Shaping',
|
||
|
'#',
|
||
|
'clear_routing_and_traffic_shaping() {'
|
||
|
);
|
||
|
|
||
|
push_indent;
|
||
|
|
||
|
save_progress_message 'Initializing...';
|
||
|
|
||
|
if ( $export ) {
|
||
|
my $fn = find_file 'modules';
|
||
|
|
||
|
if ( $fn ne "$globals{SHAREDIR}/modules" && -f $fn ) {
|
||
|
emit 'echo MODULESDIR="$MODULESDIR" > ${VARDIR}/.modulesdir';
|
||
|
emit 'cat > ${VARDIR}/.modules << EOF';
|
||
|
open_file $fn;
|
||
|
while ( read_a_line ) {
|
||
|
emit_unindented $currentline;
|
||
|
}
|
||
|
emit_unindented 'EOF';
|
||
|
emit 'reload_kernel_modules < ${VARDIR}/.modules';
|
||
|
} else {
|
||
|
emit 'load_kernel_modules Yes';
|
||
|
}
|
||
|
} else {
|
||
|
emit 'load_kernel_modules Yes';
|
||
|
}
|
||
|
|
||
|
emit '';
|
||
|
|
||
|
emit ( '[ "$COMMAND" = refresh ] && run_refresh_exit || run_init_exit',
|
||
|
'',
|
||
|
);
|
||
|
|
||
|
emit "delete_tc1\n" if $config{CLEAR_TC};
|
||
|
|
||
|
pop_indent;
|
||
|
|
||
|
emit "}\n";
|
||
|
|
||
|
emit( '#',
|
||
|
'# Setup Routing and Traffic Shaping',
|
||
|
'#',
|
||
|
'setup_routing_and_traffic_shaping() {'
|
||
|
);
|
||
|
|
||
|
push_indent;
|
||
|
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# Third (final) stage of script generation.
|
||
|
#
|
||
|
# Generate the end of 'setup_routing_and_traffic_shaping()':
|
||
|
# Generate code for loading the various files in /var/lib/shorewall6[-lite]
|
||
|
#
|
||
|
# Generate the 'setup_netfilter()' function that runs ip6tables-restore.
|
||
|
# Generate the 'define_firewall()' function.
|
||
|
#
|
||
|
# Note: This function is not called when $command eq 'check'. So it must have no side effects other
|
||
|
# than those related to writing to the object file.
|
||
|
#
|
||
|
sub generate_script_3($) {
|
||
|
|
||
|
emit( '',
|
||
|
'if [ "$COMMAND" != refresh ]; then' );
|
||
|
|
||
|
push_indent;
|
||
|
|
||
|
emit 'cat > ${VARDIR}/chains << __EOF__';
|
||
|
dump_rule_chains;
|
||
|
emit_unindented '__EOF__';
|
||
|
|
||
|
emit 'cat > ${VARDIR}/zones << __EOF__';
|
||
|
dump_zone_contents;
|
||
|
emit_unindented '__EOF__';
|
||
|
|
||
|
pop_indent;
|
||
|
|
||
|
emit "fi\n";
|
||
|
|
||
|
add_addresses;
|
||
|
|
||
|
pop_indent;
|
||
|
|
||
|
emit "}\n";
|
||
|
|
||
|
progress_message2 "Creating ip6tables-restore input...";
|
||
|
create_netfilter_load;
|
||
|
create_chainlist_reload( $_[0] );
|
||
|
|
||
|
emit "#\n# Start/Restart the Firewall\n#";
|
||
|
emit 'define_firewall() {';
|
||
|
push_indent;
|
||
|
|
||
|
emit "\nclear_routing_and_traffic_shaping";
|
||
|
|
||
|
set_global_variables;
|
||
|
|
||
|
emit '';
|
||
|
|
||
|
emit<<'EOF';
|
||
|
setup_routing_and_traffic_shaping
|
||
|
|
||
|
if [ $COMMAND = restore ]; then
|
||
|
ip6tables_save_file=${VARDIR}/$(basename $0)-ip6tables
|
||
|
if [ -f $ip6tables_save_file ]; then
|
||
|
cat $ip6tables_save_file | $IP6TABLES_RESTORE # Use this nonsensical form to appease SELinux
|
||
|
else
|
||
|
fatal_error "$ip6tables_save_file does not exist"
|
||
|
fi
|
||
|
set_state "Started"
|
||
|
else
|
||
|
if [ $COMMAND = refresh ]; then
|
||
|
chainlist_reload
|
||
|
run_refreshed_exit
|
||
|
$IP6TABLES -N shorewall
|
||
|
set_state "Started"
|
||
|
else
|
||
|
setup_netfilter
|
||
|
restore_dynamic_rules
|
||
|
run_start_exit
|
||
|
$IP6TABLES -N shorewall
|
||
|
set_state "Started"
|
||
|
run_started_exit
|
||
|
fi
|
||
|
|
||
|
cp -f $(my_pathname) ${VARDIR}/.restore
|
||
|
fi
|
||
|
|
||
|
date > ${VARDIR}/restarted
|
||
|
|
||
|
case $COMMAND in
|
||
|
start)
|
||
|
logger -p kern.info "$PRODUCT started"
|
||
|
;;
|
||
|
restart)
|
||
|
logger -p kern.info "$PRODUCT restarted"
|
||
|
;;
|
||
|
refresh)
|
||
|
logger -p kern.info "$PRODUCT refreshed"
|
||
|
;;
|
||
|
restore)
|
||
|
logger -p kern.info "$PRODUCT restored"
|
||
|
;;
|
||
|
esac
|
||
|
EOF
|
||
|
|
||
|
pop_indent;
|
||
|
|
||
|
emit "}\n";
|
||
|
|
||
|
copy $globals{SHAREDIRPL} . 'prog.footer';
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# The Compiler.
|
||
|
#
|
||
|
# If the first argument is non-null, it names the script file to generate.
|
||
|
# Otherwise, this is a 'check' command and no script is produced.
|
||
|
#
|
||
|
sub compiler( $$$$$ ) {
|
||
|
|
||
|
my ( $objectfile, $directory, $verbosity, $options , $chains ) = @_;
|
||
|
|
||
|
$export = 0;
|
||
|
|
||
|
reinitialize if $reused++;
|
||
|
|
||
|
if ( $directory ne '' ) {
|
||
|
fatal_error "$directory is not an existing directory" unless -d $directory;
|
||
|
set_shorewall_dir( $directory );
|
||
|
}
|
||
|
|
||
|
set_verbose( $verbosity ) unless $verbosity eq '';
|
||
|
$export = 1 if $options & EXPORT;
|
||
|
set_timestamp( 1 ) if $options & TIMESTAMP;
|
||
|
set_debug( 1 ) if $options & DEBUG;
|
||
|
#
|
||
|
# Get shorewall.conf and capabilities.
|
||
|
#
|
||
|
get_configuration( $export );
|
||
|
|
||
|
report_capabilities;
|
||
|
|
||
|
require_capability( 'MULTIPORT' , "Shorewall6 $globals{VERSION}" , 's' );
|
||
|
require_capability( 'RECENT_MATCH' , 'MACLIST_TTL' , 's' ) if $config{MACLIST_TTL};
|
||
|
require_capability( 'XCONNMARK' , 'HIGH_ROUTE_MARKS=Yes' , 's' ) if $config{HIGH_ROUTE_MARKS};
|
||
|
require_capability( 'MANGLE_ENABLED' , 'Traffic Shaping' , 's' ) if $config{TC_ENABLED};
|
||
|
|
||
|
set_command( 'check', 'Checking', 'Checked' ) unless $objectfile;
|
||
|
|
||
|
initialize_chain_table;
|
||
|
|
||
|
unless ( $command eq 'check' ) {
|
||
|
create_temp_object( $objectfile );
|
||
|
generate_script_1;
|
||
|
}
|
||
|
|
||
|
#
|
||
|
# Process the zones file.
|
||
|
#
|
||
|
determine_zones;
|
||
|
#
|
||
|
# Process the interfaces file.
|
||
|
#
|
||
|
validate_interfaces_file ( $export );
|
||
|
#
|
||
|
# Process the hosts file.
|
||
|
#
|
||
|
validate_hosts_file;
|
||
|
#
|
||
|
# Report zone contents
|
||
|
#
|
||
|
zone_report;
|
||
|
#
|
||
|
# Do action pre-processing.
|
||
|
#
|
||
|
process_actions1;
|
||
|
#
|
||
|
# Process the Policy File.
|
||
|
#
|
||
|
validate_policy;
|
||
|
#
|
||
|
# Compile the 'stop_firewall()' function
|
||
|
#
|
||
|
compile_stop_firewall;
|
||
|
#
|
||
|
# Start Second Part of script
|
||
|
#
|
||
|
generate_script_2 unless $command eq 'check';
|
||
|
#
|
||
|
# Set up MSS rules
|
||
|
#
|
||
|
setup_mss;
|
||
|
#
|
||
|
# Do all of the zone-independent stuff
|
||
|
#
|
||
|
add_common_rules;
|
||
|
#
|
||
|
# /proc stuff
|
||
|
#
|
||
|
setup_arp_filtering;
|
||
|
setup_route_filtering;
|
||
|
setup_martian_logging;
|
||
|
setup_source_routing;
|
||
|
setup_forwarding;
|
||
|
#
|
||
|
# Handle MSS setings in the zones file
|
||
|
#
|
||
|
setup_zone_mss;
|
||
|
#
|
||
|
# TOS
|
||
|
#
|
||
|
process_tos;
|
||
|
#
|
||
|
# ECN
|
||
|
#
|
||
|
setup_ecn;
|
||
|
#
|
||
|
# MACLIST Filtration
|
||
|
#
|
||
|
setup_mac_lists 1;
|
||
|
#
|
||
|
# Process the rules file.
|
||
|
#
|
||
|
process_rules;
|
||
|
#
|
||
|
# Add Tunnel rules.
|
||
|
#
|
||
|
setup_tunnels;
|
||
|
#
|
||
|
# Post-rules action processing.
|
||
|
#
|
||
|
process_actions2;
|
||
|
process_actions3;
|
||
|
#
|
||
|
# MACLIST Filtration again
|
||
|
#
|
||
|
setup_mac_lists 2;
|
||
|
#
|
||
|
# Apply Policies
|
||
|
#
|
||
|
apply_policy_rules;
|
||
|
#
|
||
|
# TCRules and Traffic Shaping
|
||
|
#
|
||
|
setup_tc;
|
||
|
#
|
||
|
# Accounting.
|
||
|
#
|
||
|
setup_accounting;
|
||
|
#
|
||
|
# We generate the matrix even though we don't write out the rules. That way, we insure that
|
||
|
# a compile of the script won't blow up during that step.
|
||
|
#
|
||
|
generate_matrix;
|
||
|
|
||
|
if ( $command eq 'check' ) {
|
||
|
progress_message3 "Shorewall configuration verified";
|
||
|
} else {
|
||
|
#
|
||
|
# Finish the script.
|
||
|
#
|
||
|
generate_script_3( $chains );
|
||
|
finalize_object ( $export );
|
||
|
#
|
||
|
# And generate the auxilary config file
|
||
|
#
|
||
|
generate_aux_config if $export;
|
||
|
}
|
||
|
|
||
|
1;
|
||
|
}
|
||
|
|
||
|
1;
|