First cut at IPSEC support in the accounting file.

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2010-08-19 11:46:26 -07:00
parent 4322d7b2af
commit d997ef1653
3 changed files with 94 additions and 56 deletions

View File

@ -52,7 +52,7 @@ sub process_accounting_rule( ) {
our $jumpchainref;
my ($action, $chain, $source, $dest, $proto, $ports, $sports, $user, $mark ) = split_line1 1, 9, 'Accounting File';
my ($action, $chain, $source, $dest, $proto, $ports, $sports, $user, $mark, $ipsec ) = split_line1 1, 10, 'Accounting File';
if ( $action eq 'COMMENT' ) {
process_comment;
@ -84,7 +84,7 @@ sub process_accounting_rule( ) {
$ports = '' if $ports eq 'any' || $ports eq 'all';
$sports = '' if $sports eq 'any' || $sports eq 'all';
my $rule = do_proto( $proto, $ports, $sports ) . do_user ( $user ) . do_test ( $mark, $globals{TC_MASK} );
my $rule = do_proto( $proto, $ports, $sports ) . do_user ( $user ) . do_test ( $mark, $globals{TC_MASK} ) . do_ipsec( $ipsec );
my $rule2 = 0;
unless ( $action eq 'COUNT' ) {

View File

@ -149,6 +149,8 @@ our %EXPORT_TAGS = (
match_orig_dest
match_ipsec_in
match_ipsec_out
do_ipsec_options
do_ipsec
log_rule
expand_rule
addnatjump
@ -2615,6 +2617,92 @@ sub match_ipsec_out( $$ ) {
$match;
}
#
# Handle a unidirectional IPSEC Options
#
sub do_ipsec_options($$$)
{
my %validoptions = ( strict => NOTHING,
next => NOTHING,
reqid => NUMERIC,
spi => NUMERIC,
proto => IPSECPROTO,
mode => IPSECMODE,
"tunnel-src" => NETWORK,
"tunnel-dst" => NETWORK,
);
my ( $dir, $policy, $list ) = @_;
my $options = "-m policy --pol $policy --dir $dir ";
my $fmt;
for my $e ( split_list $list, 'IPSEC option' ) {
my $val = undef;
my $invert = '';
if ( $e =~ /([\w-]+)!=(.+)/ ) {
$val = $2;
$e = $1;
$invert = '! ';
} elsif ( $e =~ /([\w-]+)=(.+)/ ) {
$val = $2;
$e = $1;
}
$fmt = $validoptions{$e};
fatal_error "Invalid IPSEC Option ($e)" unless $fmt;
if ( $fmt eq NOTHING ) {
fatal_error "Option \"$e\" does not take a value" if defined $val;
} else {
fatal_error "Missing value for option \"$e\"" unless defined $val;
fatal_error "Invalid value ($val) for option \"$e\"" unless $val =~ /^($fmt)$/;
}
$options .= $invert;
$options .= "--$e ";
$options .= "$val " if defined $val;
}
$options;
}
#
# Handle a bi-directional IPSEC column
#
sub do_ipsec($) {
my $ipsec = $_[0];
if ( $ipsec eq '-' ) {
return '';
}
fatal_error "Non-empty IPSEC column requires policy match support in your kernel and iptables" unless have_capability( 'POLICY_MATCH' );
if ( $ipsec eq 'in' ) {
do_ipsec_options 'in', 'ipsec', '';
} elsif ( $ipsec eq 'out' ) {
do_ipsec_options 'out', 'ipsec', '';
} else {
my @options = split_list $ipsec, 'IPSEC options';
my $dir = shift @options;
fatal_error q(First IPSEC option must be 'in' or 'out') unless $dir =~ /^(?:in|out)$/;
if ( @options == 1 ) {
if ( lc( $options[0] ) =~ /^(yes|ipsec)$/ ) {
return do_ipsec_option $dir, 'ipsec', '';
}
if ( lc( $options[0] ) =~ /^(no|none)$/ ) {
return do_ipsec_option $dir, 'ipsec', '';
}
}
do_ipsec_options $dir, 'ipsec', join( ',', @options );
}
}
#
# Generate a log message
#

View File

@ -36,7 +36,7 @@ use strict;
our @ISA = qw(Exporter);
our @EXPORT = qw( setup_masq setup_nat setup_netmap add_addresses );
our @EXPORT_OK = ();
our $VERSION = '4.4_11';
our $VERSION = '4.4_13';
our @addresses_to_add;
our %addresses_to_add;
@ -49,56 +49,6 @@ sub initialize() {
%addresses_to_add = ();
}
#
# Handle IPSEC Options in a masq record
#
sub do_ipsec_options($)
{
my %validoptions = ( strict => NOTHING,
next => NOTHING,
reqid => NUMERIC,
spi => NUMERIC,
proto => IPSECPROTO,
mode => IPSECMODE,
"tunnel-src" => NETWORK,
"tunnel-dst" => NETWORK,
);
my $list=$_[0];
my $options = '-m policy --pol ipsec --dir out ';
my $fmt;
for my $e ( split_list $list, 'option' ) {
my $val = undef;
my $invert = '';
if ( $e =~ /([\w-]+)!=(.+)/ ) {
$val = $2;
$e = $1;
$invert = '! ';
} elsif ( $e =~ /([\w-]+)=(.+)/ ) {
$val = $2;
$e = $1;
}
$fmt = $validoptions{$e};
fatal_error "Invalid Option ($e)" unless $fmt;
if ( $fmt eq NOTHING ) {
fatal_error "Option \"$e\" does not take a value" if defined $val;
} else {
fatal_error "Missing value for option \"$e\"" unless defined $val;
fatal_error "Invalid value ($val) for option \"$e\"" unless $val =~ /^($fmt)$/;
}
$options .= $invert;
$options .= "--$e ";
$options .= "$val " if defined $val;
}
$options;
}
#
# Process a single rule from the the masq file
#
@ -153,11 +103,11 @@ sub process_one_masq( )
fatal_error "Non-empty IPSEC column requires policy match support in your kernel and iptables" unless have_capability( 'POLICY_MATCH' );
if ( $ipsec =~ /^yes$/i ) {
$baserule .= '-m policy --pol ipsec --dir out ';
$baserule .= do_ipsec_options 'out', 'ipsec', '';
} elsif ( $ipsec =~ /^no$/i ) {
$baserule .= '-m policy --pol none --dir out ';
$baserule .= do_ipsec_options 'out', 'none', '';
} else {
$baserule .= do_ipsec_options $ipsec;
$baserule .= do_ipsec_options 'out', 'ipsec', $ipsec;
}
} elsif ( have_ipsec ) {
$baserule .= '-m policy --pol none --dir out ';