Support for arptables.

Signed-off-by: Tom Eastep <teastep@mint14.(none)>
This commit is contained in:
Tom Eastep 2013-01-04 09:17:57 -08:00
parent 90e0c8b717
commit 38657d9f98
15 changed files with 921 additions and 26 deletions

View File

@ -25,7 +25,7 @@
# loaded after this one and replaces some of the functions declared here.
#
SHOREWALL_CAPVERSION=40509
SHOREWALL_CAPVERSION=40512
[ -n "${g_program:=shorewall}" ]
@ -329,11 +329,30 @@ logwatch() # $1 = timeout -- if negative, prompt each time that
done
}
#
# Try to find the arptables binary -- sets the variable 'arptables'
#
resolve_arptables() {
arptables="$ARPTABLES"
[ -n "${arptables:=arptables}" ]
case $arptables in
*/*)
;;
*)
arptables=$(mywhich "$arptables")
;;
esac
}
#
# Save currently running configuration
#
do_save() {
local status
local arptables
status=0
if [ -f ${VARDIR}/firewall ]; then
@ -353,6 +372,42 @@ do_save() {
status=1
fi
case ${SAVE_ARPTABLES:=No} in
[Yy]es)
resolve_arptables
if [ -n "$arptables" ]; then
#
# 'sed' command is a hack to work around broken arptables_jf
#
if ${arptables}-save | sed 's/-p[[:space:]]\+0\([[:digit:]]\)00\/ffff/-p 000\1\/ffff/' > ${VARDIR}/restore-$$; then
if grep -q '^-A' ${VARDIR}/restore-$$; then
mv -f ${VARDIR}/restore-$$ ${g_restorepath}-arptables
else
rm -f ${VARDIR}/restore-$$
fi
fi
else
case "$ARPTABLES" in
*/*)
error_message "ERROR: ARPTABLES=$ARPTABLES does not exist or is not executable - arptables not saved"
;;
*)
error_message "ERROR: The arptables utility cannot be located - arptables not saved"
;;
esac
rm -f ${g_restorepath}-arptables
fi
;;
[Nn]o)
rm -f ${g_restorepath}-arptables
;;
*)
error_message "WARNING: Invalid value ($SAVE_ARPTABLES) for SAVE_ARPTABLES"
;;
esac
case ${SAVE_IPSETS:=No} in
[Yy]es)
case ${IPSET:=ipset} in
@ -683,6 +738,7 @@ show_command() {
table_given=
local output_filter
output_filter=cat
local arptables
show_macro() {
foo=`grep 'This macro' $macro | sed 's/This macro //'`
@ -999,6 +1055,17 @@ show_command() {
echo
show_nfacct
;;
arptables)
[ $# -gt 1 ] && usage 1
resolve_arptables
if [ -n "$arptables" -a -x $arptables ]; then
echo "$g_product $SHOREWALL_VERSION arptables at $g_hostname - $(date)"
echo
$arptables -L -n -v
else
error_message "Cannot locate the arptables executable"
fi
;;
*)
case "$g_program" in
*-lite)
@ -1156,6 +1223,9 @@ dump_filter() {
do_dump_command() {
local finished
finished=0
local arptables
resolve_arptables
while [ $finished -eq 0 -a $# -gt 0 ]; do
option=$1
@ -1230,6 +1300,11 @@ do_dump_command() {
host=$(echo $g_hostname | sed 's/\..*$//')
$g_tool -L $g_ipt_options
if [ -n "$arptables" -a -x "$arptables" ]; then
heading "ARP rules"
$arptables -L -n -v
fi
heading "Log ($LOGFILE)"
packet_log 20
@ -2035,6 +2110,7 @@ determine_capabilities() {
local tool
local chain
local chain1
local arptables
if [ -z "$g_tool" ]; then
[ $g_family -eq 4 ] && tool=iptables || tool=ip6tables
@ -2125,6 +2201,7 @@ determine_capabilities() {
RPFILTER_MATCH=
NFACCT_MATCH=
CHECKSUM_TARGET=
ARPTABLESJF=
AMANDA_HELPER=
FTP_HELPER=
FTP0_HELPER=
@ -2141,6 +2218,12 @@ determine_capabilities() {
TFTP_HELPER=
TFTP0_HELPER=
resolve_arptables
if [ -n "$arptables" -a -x $arptables ]; then
qt $arptables -L OUT && ARPTABLESJF=Yes
fi
chain=fooX$$
if [ -n "$NAT_ENABLED" ]; then
@ -2524,6 +2607,7 @@ report_capabilities_unsorted() {
report_capability "RPFilter match" $RPFILTER_MATCH
report_capability "NFAcct match" $NFACCT_MATCH
report_capability "Checksum Target" $CHECKSUM_TARGET
report_capability "Arptables JF" $ARPTABLESJF
report_capability "Amanda Helper" $AMANDA_HELPER
report_capability "FTP Helper" $FTP_HELPER
@ -2641,6 +2725,7 @@ report_capabilities_unsorted1() {
report_capability1 RPFILTER_MATCH
report_capability1 NFACCT_MATCH
report_capability1 CHECKSUM_TARGET
report_capability1 ARPTABLESJF
report_capability1 AMANDA_HELPER
report_capability1 FTP_HELPER
@ -2784,6 +2869,7 @@ forget_command() {
rm -f $g_restorepath
rm -f ${g_restorepath}-iptables
rm -f ${g_restorepath}-ipsets
rm -f ${g_restorepath}-arptables
echo " $g_restorepath removed"
elif [ -f $g_restorepath ]; then
echo " $g_restorepath exists and is not a saved $g_product configuration"
@ -3215,6 +3301,7 @@ usage() # $1 = exit status
echo " save [ <file name> ]"
echo " show [ -b ] [ -x ] [ -t {filter|mangle|nat} ] [ {chain [<chain> [ <chain> ... ]"
echo " show [ -f ] capabilities"
echo " show arptables"
echo " show classifiers"
echo " show config"
echo " show connections"

View File

@ -0,0 +1,294 @@
#
# Shorewall 4.5 -- /usr/share/shorewall/Shorewall/ARP.pm
#
# This program is under GPL [http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt]
#
# (c) 2013 - 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.
#
# This file is responsible for Shorewall's arptables support
#
package Shorewall::ARP;
require Exporter;
use Shorewall::Config qw(:DEFAULT :internal);
use Shorewall::Zones;
use Shorewall::IPAddrs;
use strict;
our @ISA = qw(Exporter);
our @EXPORT = ( qw( process_arprules create_arptables_load preview_arptables_load ) );
our %arp_table;
our $arp_input;
our $arp_output;
our $arp_forward;
our $sourcemac;
our $destmac;
our @builtins;
our $arptablesjf;
our @map = ( qw( 0 Request Reply Request_Reverse Reply_Reverse DRARP_Request DRARP_Reply DRARP_Error InARP_Request ARP_NAK ) );
sub match_arp_net( $$$ ) {
my ( $net, $mac, $source ) = @_;
my $return = '';
if ( supplied $net ) {
my ( $addr , $mask ) = split( $net , '/', 2 );
my $invert = ( $addr =~ s/^!// ) ? '! ' : '';
validate_net $net, 0;
$return = $source ? "-s $net " : "-d $net ";
}
if ( supplied $mac ) {
my ( $addr , $mask ) = split( $mac , '/', 2 );
my $invert = ( $addr =~ s/^!// ) ? '! ' : '';
fatal_error "Invalid MAC address ($net)" unless $addr =~ /^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$/;
if ( supplied $mask ) {
fatal_error "Invalid MAC Mask ($mask)" unless $mask =~ /^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$/;
$return .= $source ? "$sourcemac $invert$addr/$mask " : "$destmac $invert$addr/mask ";
} else {
$return .= $source ? "$sourcemac $invert$addr " : "$destmac $invert$addr ";
}
}
$return;
}
sub process_arprule() {
my ( $originalaction, $source, $dest, $opcode ) = split_line( 'arprules file entry', {action => 0, source => 1, dest => 2, opcode => 3 } );
my $chainref;
my $iiface;
my $diface;
my $saddr;
my $smac;
my $daddr;
my $dmac;
my $rule = '';
fatal_error "ACTION must be specified" if $originalaction eq '-';
my ( $action, $newaddr ) = split( ':', $originalaction, 2 );
my %functions = ( DROP => sub() { $rule .= "-j DROP" },
ACCEPT => sub() { $rule .= "-j ACCEPT" },
SNAT => sub() { validate_address $newaddr, 0;
$rule .= "-j mangle --mangle-ip-s $newaddr"; },
DNAT => sub() { validate_address $newaddr, 0;
$rule .= "-j mangle --mangle-ip-d $newaddr"; },
SMAT => sub() { fatal_error "Invalid MAC address ($newaddr)" unless $newaddr =~ /^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$/;
$rule .= "-j mangle --mangle-mac-s $newaddr"; },
DMAT => sub() { fatal_error "Invalid MAC address ($newaddr)" unless $newaddr =~ /^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$/;
$rule .= "-j mangle --mangle-mac-d $newaddr"; },
SNATC => sub() { validate_address $newaddr, 0;
$rule .= "-j mangle --mangle-ip-s $newaddr--mangle-target CONTINUE"; },
DNATC => sub() { validate_address $newaddr, 0;
$rule .= "-j mangle --mangle-ip-d $newaddr--mangle-target CONTINUE"; },
SMATC => sub() { fatal_error "Invalid MAC address ($newaddr)" unless $newaddr =~ /^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$/;
$rule .= "-j mangle --mangle-mac-s $newaddr--mangle-target CONTINUE"; },
DMATC => sub() { fatal_error "Invalid MAC address ($newaddr)" unless $newaddr =~ /^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$/;
$rule .= "-j mangle --mangle-mac-d $newaddr --mangle-target CONTINUE"; },
);
if ( supplied $newaddr ) {
fatal_error "The $action ACTION does not allow a new address" unless $action =~ /^SNAT|DNAT|SMAT|DMAT$/;
} else {
fatal_error "Invalid ACTION ($action)" unless $action =~ /^DROP|ACCEPT$/;
}
if ( $source ne '-' ) {
if ( $source =~ /^(.+?):(.*)(?::(.*))?/ ) {
$iiface = $1;
$saddr = $2;
$smac = $3;
} else {
$iiface = $source;
}
$iiface = find_interface( $iiface )->{physical};
fatal_error "Wildcard Interfaces ( $iiface )may not be used in this context" if $iiface =~ /\+$/;
$rule .= "-i $iiface ";
$rule .= match_arp_net( $saddr , $smac, 1 ) if supplied( $saddr );
$chainref = $arp_input;
}
if ( $dest ne '-' ) {
if ( $dest =~ /^(.+?):(.*)(?::(.*))?/ ) {
$diface = $1;
$daddr = $2;
$dmac = $3;
} else {
$diface = $dest;
}
$diface = find_interface( $diface )->{physical};
fatal_error "A wildcard interfaces ( $diface) may not be used in this context" if $diface =~ /\+$/;
if ( $iiface ) {
fatal_error "When both SOURCE and DEST are given, the interfaces must be ports on the same bridge"
if $iiface->{bridge} ne $diface->{bridge};
$chainref = $arp_forward;
} else {
$chainref = $arp_output;
}
$rule .= "-o $diface ";
$rule .= match_arp_net( $daddr , $dmac, 0 ) if supplied( $daddr );
}
if ( $opcode ne '-' ) {
my $invert = ( $opcode =~ s/^!// ) ? '! ' : '';
fatal_error "Invalid ARP OPCODE ($opcode)" unless $opcode =~ /^\d$/ && $opcode;
$rule .= $arptablesjf ? " --arpop ${invert}$map[$opcode] " : "--opcode $opcode ";
}
$functions{$action} ->();
fatal_error "Either SOURCE or DEST must be specified" unless $chainref;
push @$chainref, $rule;
}
sub process_arprules() {
my $result = 0;
if ( $arptablesjf = have_capability 'ARPTABLESJF' ) {
$arp_input = $arp_table{IN} = [];
$arp_output = $arp_table{OUT} = [];
$arp_forward = $arp_table{FORWARD} = [];
@builtins = qw( IN OUT FORWARD );
$sourcemac = '-z';
$destmac = '-y';
} else {
$arp_input = $arp_table{INPUT} = [];
$arp_output = $arp_table{OUTPUT} = [];
$arp_forward = $arp_table{FORWARD} = [];
@builtins = qw( INPUT OUTPUT FORWARD );
$sourcemac = '--source-mac';
$destmac = '--dest-mac';
}
my $fn = open_file 'arprules';
if ( $fn ) {
first_entry( sub() {
$result = 1;
progress_message2 "$doing $fn..."; }
);
process_arprule while read_a_line( NORMAL_READ );
}
$result;
}
sub create_arptables_load( $ ) {
my $test = shift;
emit ( '#',
'# Create the input to arptables-restore and pass that input to the utility',
'#',
'setup_arptables()',
'{'
);
push_indent;
save_progress_message "Preparing arptables-restore input...";
emit '';
emit "exec 3>\${VARDIR}/.arptables-input";
my $date = localtime;
unless ( $test ) {
emit_unindented '#';
emit_unindented "# Generated by Shorewall $globals{VERSION} - $date";
emit_unindented '#';
}
emit '';
emit 'cat >&3 << __EOF__';
emit_unindented "*filter";
emit_unindented ":$_ ACCEPT" for @builtins;
for ( @builtins ) {
my $rules = $arp_table{$_};
while ( my $rule = shift @$rules ) {
emit_unindented "-A $_ $rule";
}
}
emit_unindented "COMMIT\n" if $arptablesjf;
emit_unindented "__EOF__";
#
# Now generate the actual ip[6]tables-restore command
#
emit( 'exec 3>&-',
'',
'progress_message2 "Running $ARPTABLES_RESTORE..."',
'',
'cat ${VARDIR}/.arptables-input | $ARPTABLES_RESTORE # Use this nonsensical form to appease SELinux',
'if [ $? != 0 ]; then',
qq( fatal_error "arptables-restore Failed. Input is in \${VARDIR}/.arptables-input"),
"fi\n"
);
pop_indent;
emit "}\n";
}
sub preview_arptables_load() {
my $date = localtime;
print "#\n# Generated by Shorewall $globals{VERSION} - $date\n#\n";
print "*filter\n";
print ":$_ ACCEPT\n" for qw( INPUT OUTPUT FORWARD );
for ( @builtins ) {
my $rules = $arp_table{$_};
while ( my $rule = shift @$rules ) {
print "-A $rule\n";
}
}
print "COMMIT\n" if $arptablesjf;
print "\n";
}
1;

View File

@ -36,6 +36,7 @@ use Shorewall::Proc;
use Shorewall::Proxyarp;
use Shorewall::Raw;
use Shorewall::Misc;
use Shorewall::ARP;
use strict;
@ -50,6 +51,8 @@ our $test;
our $family;
our $have_arptables;
#
# Initilize the package-globals in the other modules
#
@ -226,6 +229,22 @@ sub generate_script_2() {
set_chain_variables;
my $need_arptables = $have_arptables || $config{SAVE_ARPTABLES};
if ( my $arptables = $config{ARPTABLES} ) {
emit( qq(ARPTABLES="$arptables"),
'[ -x "$ARPTABLES" ] || startup_error "ARPTABLES=$ARPTABLES does not exist or is not executable"',
);
} elsif ( $need_arptables ) {
emit( '[ -z "$ARPTABLES" ] && ARPTABLES=$(mywhich arptables)',
'[ -n "$ARPTABLES" -a -x "$ARPTABLES" ] || startup_error "Can\'t find arptables executable"' );
}
if ( $need_arptables ) {
emit( 'ARPTABLES_RESTORE=${ARPTABLES}-restore',
'[ -x "$ARPTABLES_RESTORE" ] || startup_error "$ARPTABLES_RESTORE does not exist or is not executable"' );
}
if ( $config{EXPORTPARAMS} ) {
append_file 'params';
} else {
@ -323,6 +342,7 @@ sub generate_script_3($) {
}
create_netfilter_load( $test );
create_arptables_load( $test ) if $have_arptables;
create_chainlist_reload( $_[0] );
emit "#\n# Start/Restart the Firewall\n#";
@ -450,16 +470,25 @@ sub generate_script_3($) {
' if [ -f $iptables_save_file ]; then' );
if ( $family == F_IPV4 ) {
emit ' cat $iptables_save_file | $IPTABLES_RESTORE # Use this nonsensical form to appease SELinux'
emit( ' cat $iptables_save_file | $IPTABLES_RESTORE # Use this nonsensical form to appease SELinux' );
emit( '',
' arptables_save_file=${VARDIR}/$(basename $0)-arptables',
' if [ -f $arptables_save_file ]; then',
' cat $arptables_save_file | $ARPTABLES_RESTORE',
' fi')
if $config{SAVE_ARPTABLES};
} else {
emit ' cat $iptables_save_file | $IP6TABLES_RESTORE # Use this nonsensical form to appease SELinux'
}
emit<<'EOF';
else
fatal_error "$iptables_save_file does not exist"
fi
EOF
emit( ' else',
' fatal_error "$iptables_save_file does not exist"',
' fi',
''
);
push_indent;
setup_load_distribution;
setup_forwarding( $family , 1 );
@ -489,6 +518,7 @@ EOF
' setup_netfilter'
);
push_indent;
emit 'setup_arptables' if $have_arptables;
setup_load_distribution;
pop_indent;
@ -544,8 +574,9 @@ sub compiler {
my ( $scriptfilename, $directory, $verbosity, $timestamp , $debug, $chains , $log , $log_verbosity, $preview, $confess , $update , $annotate , $convert, $config_path, $shorewallrc , $shorewallrc1 , $directives ) =
( '', '', -1, '', 0, '', '', -1, 0, 0, 0, 0, , 0 , '' , '/usr/share/shorewall/shorewallrc', '' , 0 );
$export = 0;
$test = 0;
$export = 0;
$test = 0;
$have_arptables = 0;
sub validate_boolean( $ ) {
my $val = numeric_value( shift );
@ -754,6 +785,8 @@ sub compiler {
emit "}\n"; # End of setup_routing_and_traffic_shaping()
}
$have_arptables = process_arprules if $family == F_IPV4;
disable_script;
#
# N E T F I L T E R
@ -837,7 +870,7 @@ sub compiler {
generate_script_2;
#
# N E T F I L T E R L O A D
# (Produces setup_netfilter(), chainlist_reload() and define_firewall() )
# (Produces setup_netfilter(), setup_arptables(), chainlist_reload() and define_firewall() )
#
generate_script_3( $chains );
#
@ -850,7 +883,7 @@ sub compiler {
# S T O P _ F I R E W A L L
# (Writes the stop_firewall() function to the compiled script)
#
compile_stop_firewall( $test, $export );
compile_stop_firewall( $test, $export , $have_arptables );
#
# U P D O W N
# (Writes the updown() function to the compiled script)
@ -898,7 +931,10 @@ sub compiler {
generate_script_2 if $debug;
preview_netfilter_load if $preview;
if ( $preview ) {
preview_netfilter_load;
preview_arptables_load if $have_arptables;
}
}
#
# Re-initialize the chain table so that process_routestopped() has the same
@ -908,7 +944,7 @@ sub compiler {
initialize_chain_table(0);
if ( $debug ) {
compile_stop_firewall( $test, $export );
compile_stop_firewall( $test, $export, $have_arptables );
disable_script;
} else {
#

View File

@ -350,6 +350,7 @@ our %capdesc = ( NAT_ENABLED => 'NAT',
RPFILTER_MATCH => 'RPFilter Match',
NFACCT_MATCH => 'NFAcct Match',
CHECKSUM_TARGET => 'Checksum Target',
ARPTABLESJF => 'Arptables JF',
AMANDA_HELPER => 'Amanda Helper',
FTP_HELPER => 'FTP Helper',
FTP0_HELPER => 'FTP-0 Helper',
@ -636,7 +637,7 @@ sub initialize( $;$$) {
KLUDGEFREE => '',
STATEMATCH => '-m state --state',
VERSION => "4.5.12-Beta3",
CAPVERSION => 40509 ,
CAPVERSION => 40512 ,
);
#
# From shorewall.conf file
@ -722,6 +723,7 @@ sub initialize( $;$$) {
MACLIST_TABLE => undef,
MACLIST_TTL => undef,
SAVE_IPSETS => undef,
SAVE_ARPTABLES => undef,
MAPOLDACTIONS => undef,
FASTACCEPT => undef,
IMPLICIT_CONTINUE => undef,
@ -880,6 +882,7 @@ sub initialize( $;$$) {
RPFILTER_MATCH => undef,
NFACCT_MATCH => undef,
CHECKSUM_TARGET => undef,
ARPTABLESJF => undef,
AMANDA_HELPER => undef,
FTP_HELPER => undef,
@ -1015,12 +1018,14 @@ sub initialize( $;$$) {
$globals{CONFDIR} = "$shorewallrc{CONFDIR}/shorewall";
$globals{PRODUCT} = 'shorewall';
$config{IPTABLES} = undef;
$config{ARPTABLES} = undef;
$validlevels{ULOG} = 'ULOG';
} else {
$globals{SHAREDIR} = "$shorewallrc{SHAREDIR}/shorewall6";
$globals{CONFDIR} = "$shorewallrc{CONFDIR}/shorewall6";
$globals{PRODUCT} = 'shorewall6';
$config{IP6TABLES} = undef;
delete $config{ARPTABLES};
}
%shorewallrc1 = %shorewallrc unless $shorewallrc1;
@ -3911,9 +3916,21 @@ sub Checksum_Target() {
have_capability 'MANGLE_ENABLED' && qt1( "$iptables -t mangle -A $sillyname -j CHECKSUM --checksum-fill" );
}
sub Arptables_JF() {
my $arptables = $config{ARPTABLES};
$arptables = which( 'arptables' ) unless supplied $arptables;
if ( $arptables && -f $arptables && -x _ ) {
$config{ARPTABLES} = $arptables;
qt( "$arptables -L OUT" );
}
}
our %detect_capability =
( ACCOUNT_TARGET =>\&Account_Target,
AMANDA_HELPER => \&Amanda_Helper,
ARPTABLESJF => \&Arptables_JF,
AUDIT_TARGET => \&Audit_Target,
ADDRTYPE => \&Addrtype,
BASIC_FILTER => \&Basic_Filter,
@ -4986,6 +5003,7 @@ sub get_configuration( $$$$ ) {
unsupported_yes_no_warning 'RFC1918_STRICT';
default_yes_no 'SAVE_IPSETS' , '';
default_yes_no 'SAVE_ARPTABLES' , '';
default_yes_no 'STARTUP_ENABLED' , 'Yes';
default_yes_no 'DELAYBLACKLISTLOAD' , '';
default_yes_no 'MAPOLDACTIONS' , 'Yes';
@ -5496,7 +5514,7 @@ sub generate_aux_config() {
emit "#\n# Shorewall auxiliary configuration file created by Shorewall version $globals{VERSION} - $date\n#";
for my $option ( qw(VERBOSITY LOGFILE LOGFORMAT IPTABLES IP6TABLES IP TC IPSET PATH SHOREWALL_SHELL SUBSYSLOCK LOCKFILE RESTOREFILE) ) {
for my $option ( qw(VERBOSITY LOGFILE LOGFORMAT ARPTABLES IPTABLES IP6TABLES IP TC IPSET PATH SHOREWALL_SHELL SUBSYSLOCK LOCKFILE RESTOREFILE) ) {
conditionally_add_option $option;
}

View File

@ -2317,8 +2317,8 @@ sub setup_mss( ) {
#
# Compile the stop_firewall() function
#
sub compile_stop_firewall( $$ ) {
my ( $test, $export ) = @_;
sub compile_stop_firewall( $$$ ) {
my ( $test, $export, $have_arptables ) = @_;
my $input = $filter_table->{INPUT};
my $output = $filter_table->{OUTPUT};
@ -2523,6 +2523,8 @@ EOF
create_stop_load $test;
if ( $family == F_IPV4 ) {
emit( '$ARPTABLES -F',
'' ) if $have_arptables;
if ( $config{IP_FORWARDING} eq 'on' ) {
emit( 'echo 1 > /proc/sys/net/ipv4/ip_forward',
'progress_message2 IPv4 Forwarding Enabled' );

View File

@ -55,6 +55,8 @@ TCP_FLAGS_LOG_LEVEL=info
# L O C A T I O N O F F I L E S A N D D I R E C T O R I E S
###############################################################################
ARPTABLES=
CONFIG_PATH=${CONFDIR}/shorewall:${SHAREDIR}/shorewall
GEOIPDIR=/usr/share/xt_geoip/LE
@ -194,6 +196,8 @@ RETAIN_ALIASES=No
ROUTE_FILTER=No
SAVE_ARPTABLES=No
SAVE_IPSETS=No
TC_ENABLED=Internal

View File

@ -66,6 +66,8 @@ TCP_FLAGS_LOG_LEVEL=info
# L O C A T I O N O F F I L E S A N D D I R E C T O R I E S
###############################################################################
ARPTABLES=
CONFIG_PATH=${CONFDIR}/shorewall:${SHAREDIR}/shorewall
GEOIPDIR=/usr/share/xt_geoip/LE
@ -205,6 +207,8 @@ RETAIN_ALIASES=No
ROUTE_FILTER=No
SAVE_ARPTABLES=No
SAVE_IPSETS=No
TC_ENABLED=Internal

View File

@ -64,6 +64,8 @@ TCP_FLAGS_LOG_LEVEL=info
# L O C A T I O N O F F I L E S A N D D I R E C T O R I E S
###############################################################################
ARPTABLES=
CONFIG_PATH=${CONFDIR}/shorewall:${SHAREDIR}/shorewall
GEOIPDIR=/usr/share/xt_geoip/LE
@ -203,6 +205,8 @@ RETAIN_ALIASES=No
ROUTE_FILTER=No
SAVE_ARPTABLES=No
SAVE_IPSETS=No
TC_ENABLED=Internal

View File

@ -67,6 +67,8 @@ TCP_FLAGS_LOG_LEVEL=info
# L O C A T I O N O F F I L E S A N D D I R E C T O R I E S
###############################################################################
ARPTABLES=
CONFIG_PATH=${CONFDIR}/shorewall:${SHAREDIR}/shorewall
GEOIPDIR=/usr/share/xt_geoip/LE
@ -206,6 +208,8 @@ RETAIN_ALIASES=No
ROUTE_FILTER=No
SAVE_ARPTABLES=No
SAVE_IPSETS=No
TC_ENABLED=Internal

View File

@ -0,0 +1,8 @@
#
# Shorewall version 4 - arprules File
#
# For information about entries in this file, type "man shorewall-arprules"
#
##############################################################################################################
#ACTION SOURCE DEST ARP
# OPCODE

View File

@ -55,6 +55,8 @@ TCP_FLAGS_LOG_LEVEL=info
# L O C A T I O N O F F I L E S A N D D I R E C T O R I E S
###############################################################################
ARPTABLES=
CONFIG_PATH="${CONFDIR}/shorewall:${SHAREDIR}/shorewall"
GEOIPDIR=/usr/share/xt_geoip/LE
@ -194,6 +196,8 @@ RETAIN_ALIASES=No
ROUTE_FILTER=No
SAVE_ARPTABLES=No
SAVE_IPSETS=No
TC_ENABLED=Internal

View File

@ -641,6 +641,19 @@ if [ -f masq ]; then
echo "Masquerade file installed as ${DESTDIR}${CONFDIR}/$PRODUCT/masq"
fi
fi
if [ -f arprules ]; then
#
# Install the ARP rules file
#
run_install $OWNERSHIP -m 0644 arprules ${DESTDIR}${SHAREDIR}/$PRODUCT/configfiles
run_install $OWNERSHIP -m 0644 arprules.annotated ${DESTDIR}${SHAREDIR}/$PRODUCT/configfiles
if [ -z "$SPARSE" -a ! -f ${DESTDIR}${CONFDIR}/$PRODUCT/arprules ]; then
run_install $OWNERSHIP -m 0600 arprules${suffix} ${DESTDIR}${CONFDIR}/$PRODUCT/arprules
echo "ARP rules file installed as ${DESTDIR}${CONFDIR}/$PRODUCT/arprules"
fi
fi
#
# Install the Conntrack file
#

View File

@ -0,0 +1,378 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<refentry>
<refmeta>
<refentrytitle>shorewall-arprules</refentrytitle>
<manvolnum>5</manvolnum>
</refmeta>
<refnamediv>
<refname>arprules</refname>
<refpurpose>Shorewall ARP rules file</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>/etc/shorewall/arprules</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>This file was added in Shorwall 4.5.12 and is used to describe
low-level rules managed by arptables (8). These rules only affect Address
Resolution Protocol (ARP), Reverse Address Resolution Protocol (RARP) and
Dynamic Reverse Address Resolution Protocol (DRARP) frames.</para>
<para>The columns in the file are as shown below. MAC addresses are
specified normally (6 hexidecimal numbers separated by colons).</para>
<variablelist>
<varlistentry>
<term><emphasis role="bold">ACTION</emphasis></term>
<listitem>
<para>Describes the action to take when a frame matches the criteria
in the other columns. Possible values are:</para>
<variablelist>
<varlistentry>
<term><emphasis role="bold">ACCEPT</emphasis></term>
<listitem>
<para>This is the default action if no rules matches a frame;
it lets the frame go through.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">DROP</emphasis></term>
<listitem>
<para>Causes the frame to be dropped.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role="bold">SNAT:</emphasis><replaceable>ip-address</replaceable></term>
<listitem>
<para>Modifies the source IP address to the specified
<replaceable>ip-address</replaceable>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role="bold">DNAT:</emphasis><replaceable>ip-address</replaceable></term>
<listitem>
<para>Modifies the destination IP address to the specified
<replaceable>ip-address</replaceable>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role="bold">SMAT:</emphasis><replaceable>mac-address</replaceable></term>
<listitem>
<para>Modifies the source MAC address to the specified
<replaceable>mac-address</replaceable>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role="bold">DMAT:</emphasis><replaceable>mac-address</replaceable></term>
<listitem>
<para>Modifies the destination MAC address to the specified
<replaceable>mac-address</replaceable>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role="bold">SNATC:</emphasis><replaceable>ip-address</replaceable></term>
<listitem>
<para>Like SNAT except that the frame is then passed to the
next rule.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role="bold">DNAC:</emphasis><replaceable>ip-address</replaceable></term>
<listitem>
<para>Like DNAT except that the frame is then passed to the
next rule.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role="bold">SMATC:</emphasis><replaceable>mac-address</replaceable></term>
<listitem>
<para>Like SMAT except that the frame is then passed to the
next rule.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role="bold">DMATC:</emphasis><replaceable>mac-address</replaceable></term>
<listitem>
<para>Like DMAT except that the frame is then passed to the
next rule.</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">SOURCE</emphasis> - <emphasis
role="bold">[<replaceable>interface</replaceable>[:[!]<replaceable>ipaddress</replaceable>[/ip<replaceable>mask</replaceable>][:[!]<replaceable>macaddress</replaceable>[/<replaceable>macmask</replaceable>]]]]</emphasis></term>
<listitem>
<para>Where </para>
<variablelist>
<varlistentry>
<term><replaceable>interface</replaceable></term>
<listitem>
<para>Is an interface defined in
shorewall-interfaces(5).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>ipaddress</replaceable></term>
<listitem>
<para>is an IPv4 address.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>ipmask</replaceable></term>
<listitem>
<para>specifies a mask to be applied to
<replaceable>ipaddress</replaceable>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>macaddress</replaceable></term>
<listitem>
<para>The source MAC address.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>macmask</replaceable></term>
<listitem>
<para>Mask for MAC address; must be specified as 6 hexidecimal
numbers separated by colons.</para>
</listitem>
</varlistentry>
</variablelist>
<para>When '!' is specified, the test is inverted.</para>
<para>If not specified, matches only frames originating on the
firewall itself.</para>
<caution>
<para>Either SOURCE or DEST must be specified.</para>
</caution>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">DEST</emphasis> - <emphasis
role="bold">[<replaceable>interface</replaceable>[:[!]<replaceable>ipaddress</replaceable>[/ip<replaceable>mask</replaceable>][:[!]<replaceable>macaddress</replaceable>[/<replaceable>macmask</replaceable>]]]]</emphasis></term>
<listitem>
<para>Where</para>
<variablelist>
<varlistentry>
<term><replaceable>interface</replaceable></term>
<listitem>
<para>Is an interface defined in
shorewall-interfaces(5).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>ipaddress</replaceable></term>
<listitem>
<para>is an IPv4 address or a MAC address.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>ipmask</replaceable></term>
<listitem>
<para>specifies a mask to be applied to frame
addresses.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>macaddress</replaceable></term>
<listitem>
<para>The destination MAC address.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>macmask</replaceable></term>
<listitem>
<para>Mask for MAC address; must be specified as 6 hexidecimal
numbers separated by colons.</para>
</listitem>
</varlistentry>
</variablelist>
<para>When '!' is specified, the test is inverted and the rule
matches frames which do not match the specified address/mask.</para>
<para>If not specified, matches only frames originating on the
firewall itself.</para>
<para>If both SOURCE and DEST are specified, then both interfaces
must be bridge ports on the same bridge.</para>
<caution>
<para>Either SOURCE or DEST must be specified.</para>
</caution>
</listitem>
</varlistentry>
<varlistentry>
<term>ARP OPCODE - [[!]<replaceable>opcode</replaceable>]</term>
<listitem>
<para>Optional. Describes the type of frame. Possible
<replaceable>opcode</replaceable> values are:</para>
<variablelist>
<varlistentry>
<term>1</term>
<listitem>
<para>ARP Request</para>
</listitem>
</varlistentry>
<varlistentry>
<term>2</term>
<listitem>
<para>ARP Reply</para>
</listitem>
</varlistentry>
<varlistentry>
<term>3</term>
<listitem>
<para>RARP Request</para>
</listitem>
</varlistentry>
<varlistentry>
<term>4</term>
<listitem>
<para>RARP Reply</para>
</listitem>
</varlistentry>
<varlistentry>
<term>5</term>
<listitem>
<para>Dynamic RARP Request</para>
</listitem>
</varlistentry>
<varlistentry>
<term>6</term>
<listitem>
<para>Dynamic RARP Reply</para>
</listitem>
</varlistentry>
<varlistentry>
<term>7</term>
<listitem>
<para>Dynamic RARP Error</para>
</listitem>
</varlistentry>
<varlistentry>
<term>8</term>
<listitem>
<para>InARP Request</para>
</listitem>
</varlistentry>
<varlistentry>
<term>9</term>
<listitem>
<para>ARP NAK</para>
</listitem>
</varlistentry>
</variablelist>
<para>When '!' is specified, the test is inverted and the rule
matches frames which do not match the specifed
<replaceable>opcode</replaceable>.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Example</title>
<para>The eth1 interface has both a pubiic IP address and a private
address (10.1.10.11/24). When sending ARP requests to 10.1.10.0/24, use
the private address as the IP source:</para>
<programlisting>#ACTION SOURCE DEST ARP OPCODE
SNAT:10.1.10.11 - eth1:10.1.10.0/24 1</programlisting>
</refsect1>
<refsect1>
<title>FILES</title>
<para>/etc/shorewall/arprules</para>
</refsect1>
</refentry>

View File

@ -282,16 +282,18 @@
<varlistentry>
<term><emphasis
role="bold">IGNOREUNKNOWNVARIABLES=</emphasis>[<emphasis
role="bold">Yes</emphasis>|<emphasis role="bold">No</emphasis>]</term>
role="bold">ARPTABLES=</emphasis>[<emphasis>pathname</emphasis>]</term>
<listitem>
<para>Added in Shorewall 4.5.11. Normally, if an unknown shell
variable is encountered in a configuration file (except in ?IF and
?ELSIF directives), the compiler raises a fatal error. If
IGNOREUNKNOWNVARIABLES is set to <emphasis
role="bold">Yes</emphasis>, then such variables simply expand to an
empty string. Default is <emphasis role="bold">No</emphasis>.</para>
<para>Added in Shorewall 4.5.12. This parameter names the arptables
executable to be used by Shorewall. If not specified or if specified
as a null value, then the arptables executable located using the
PATH option is used.</para>
<para>Regardless of how the arptables utility is located (specified
via arptables= or located via PATH), Shorewall uses the
arptables-restore and arptables-save utilities from that same
directory.</para>
</listitem>
</varlistentry>
@ -867,6 +869,21 @@ net all DROP info</programlisting>then the chain name is 'net2all'
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role="bold">IGNOREUNKNOWNVARIABLES=</emphasis>[<emphasis
role="bold">Yes</emphasis>|<emphasis role="bold">No</emphasis>]</term>
<listitem>
<para>Added in Shorewall 4.5.11. Normally, if an unknown shell
variable is encountered in a configuration file (except in ?IF and
?ELSIF directives), the compiler raises a fatal error. If
IGNOREUNKNOWNVARIABLES is set to <emphasis
role="bold">Yes</emphasis>, then such variables simply expand to an
empty string. Default is <emphasis role="bold">No</emphasis>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">IMPLICIT_CONTINUE=</emphasis>{<emphasis
role="bold">Yes</emphasis>|<emphasis role="bold">No</emphasis>}</term>
@ -1012,7 +1029,7 @@ net all DROP info</programlisting>then the chain name is 'net2all'
the iptables executable located using the PATH option is
used.</para>
<para>Regardless of how the IPTABLES utility is located (specified
<para>Regardless of how the iptables utility is located (specified
via IPTABLES= or located via PATH), Shorewall uses the
iptables-restore and iptables-save utilities from that same
directory.</para>
@ -2058,6 +2075,19 @@ net all DROP info</programlisting>then the chain name is 'net2all'
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">SAVE_ARPTABLES=</emphasis>{<emphasis
role="bold">Yes</emphasis>|<emphasis role="bold">No</emphasis>}</term>
<listitem>
<para>Added in Shorewall 4.5.12. If SAVE_ARPTABLES=Yes, then the
current arptables contents will be saved by <emphasis
role="bold">shorewall save</emphasis> command and restored by
<emphasis role="bold">shorewall restore</emphasis> command. Default
value is No.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">SAVE_IPSETS=</emphasis>{<emphasis
role="bold">Yes</emphasis>|<emphasis role="bold">No</emphasis>}</term>

View File

@ -26,6 +26,12 @@
<year>2010</year>
<year>2011</year>
<year>2012</year>
<year>2013</year>
<holder>Thomas M. Eastep</holder>
</copyright>
@ -66,6 +72,9 @@
<member><ulink url="manpages/shorewall-actions.html">actions</ulink> -
Declare user-defined actions.</member>
<member><ulink url="manpages/shorewall-arprules.html">arprules</ulink>
- (Added in Shorewall 4.5.12) Define arpfilter rules.</member>
<member><ulink
url="manpages/shorewall-blacklist.html">blacklist</ulink> - Static
blacklisting.</member>