#
# (c) Jan Gehring <jan.gehring@gmail.com>
#
# vim: set ts=2 sw=2 tw=0:
# vim: set expandtab:
package Rex::Resource::firewall::Provider::iptables;
use 5.010001;
use strict;
use warnings;
our $VERSION = '1.13.4'; # VERSION
use Rex::Commands::Iptables;
use Rex::Helper::Run;
use Data::Dumper;
use base qw(Rex::Resource::firewall::Provider::base);
sub new {
my $that = shift;
my $proto = ref($that) || $that;
my $self = $proto->SUPER::new(@_);
bless( $self, $proto );
return $self;
}
sub present {
my ( $self, $rule_config ) = @_;
my @iptables_rule = ();
$rule_config->{dport} ||= $rule_config->{port};
$rule_config->{proto} ||= 'tcp';
$rule_config->{chain} ||= 'INPUT';
$rule_config->{ip_version} ||= -4;
if ( $rule_config->{source}
&& $rule_config->{source} !~ m/\/(\d+)$/
&& $self->_version()->[0] >= 1
&& $self->_version()->[1] >= 4 )
{
$rule_config->{source} .= "/32";
}
push( @iptables_rule, t => $rule_config->{table} )
if ( defined $rule_config->{table} );
push( @iptables_rule, A => uc( $rule_config->{chain} ) )
if ( defined $rule_config->{chain} );
push( @iptables_rule, p => $rule_config->{proto} )
if ( defined $rule_config->{proto} );
push( @iptables_rule, m => $rule_config->{proto} )
if ( defined $rule_config->{proto} );
push( @iptables_rule, s => $rule_config->{source} )
if ( defined $rule_config->{source} );
push( @iptables_rule, d => $rule_config->{destination} )
if ( defined $rule_config->{destination} );
push( @iptables_rule, sport => $rule_config->{sport} )
if ( defined $rule_config->{sport} );
push( @iptables_rule, dport => $rule_config->{dport} )
if ( defined $rule_config->{dport} );
push( @iptables_rule, "tcp-flags" => $rule_config->{tcp_flags} )
if ( defined $rule_config->{tcp_flags} );
push( @iptables_rule, "i" => $rule_config->{iniface} )
if ( defined $rule_config->{iniface} );
push( @iptables_rule, "o" => $rule_config->{outiface} )
if ( defined $rule_config->{outiface} );
push( @iptables_rule, "reject-with" => $rule_config->{reject_with} )
if ( defined $rule_config->{reject_with} );
push( @iptables_rule, "log-level" => $rule_config->{log_level} )
if ( defined $rule_config->{log_level} );
push( @iptables_rule, "log-prefix" => $rule_config->{log_prefix} )
if ( defined $rule_config->{log_prefix} );
push( @iptables_rule, "state" => $rule_config->{state} )
if ( defined $rule_config->{state} );
push( @iptables_rule, j => uc( $rule_config->{action} ) )
if ( defined $rule_config->{action} );
if (
!Rex::Commands::Iptables::_rule_exists(
$rule_config->{ip_version},
@iptables_rule
)
)
{
iptables( $rule_config->{ip_version}, @iptables_rule );
return 1;
}
return 0;
}
sub absent {
my ( $self, $rule_config ) = @_;
my @iptables_rule = ();
$rule_config->{dport} ||= $rule_config->{port};
$rule_config->{proto} ||= 'tcp';
$rule_config->{chain} ||= 'INPUT';
$rule_config->{ip_version} ||= -4;
if ( $rule_config->{source}
&& $rule_config->{source} !~ m/\/(\d+)$/
&& $self->_version()->[0] >= 1
&& $self->_version()->[1] >= 4 )
{
$rule_config->{source} .= "/32";
}
push( @iptables_rule, t => $rule_config->{table} )
if ( defined $rule_config->{table} );
push( @iptables_rule, D => uc( $rule_config->{chain} ) )
if ( defined $rule_config->{chain} );
push( @iptables_rule, s => $rule_config->{source} )
if ( defined $rule_config->{source} );
push( @iptables_rule, p => $rule_config->{proto} )
if ( defined $rule_config->{proto} );
push( @iptables_rule, m => $rule_config->{proto} )
if ( defined $rule_config->{proto} );
push( @iptables_rule, d => $rule_config->{destination} )
if ( defined $rule_config->{destination} );
push( @iptables_rule, sport => $rule_config->{sport} )
if ( defined $rule_config->{sport} );
push( @iptables_rule, dport => $rule_config->{dport} )
if ( defined $rule_config->{dport} );
push( @iptables_rule, "tcp-flags" => $rule_config->{tcp_flags} )
if ( defined $rule_config->{tcp_flags} );
push( @iptables_rule, "i" => $rule_config->{iniface} )
if ( defined $rule_config->{iniface} );
push( @iptables_rule, "o" => $rule_config->{outiface} )
if ( defined $rule_config->{outiface} );
push( @iptables_rule, "reject-with" => $rule_config->{reject_with} )
if ( defined $rule_config->{reject_with} );
push( @iptables_rule, "log-level" => $rule_config->{log_level} )
if ( defined $rule_config->{log_level} );
push( @iptables_rule, "log-prefix" => $rule_config->{log_prefix} )
if ( defined $rule_config->{log_prefix} );
push( @iptables_rule, "state" => $rule_config->{state} )
if ( defined $rule_config->{state} );
push( @iptables_rule, j => uc( $rule_config->{action} ) )
if ( defined $rule_config->{action} );
if (
Rex::Commands::Iptables::_rule_exists(
$rule_config->{ip_version},
@iptables_rule
)
)
{
iptables( $rule_config->{ip_version}, @iptables_rule );
return 1;
}
return 0;
}
sub _version {
my ($self) = @_;
if ( exists $self->{__version__} ) { return $self->{__version__} }
my $version = i_run "iptables --version", fail_ok => 1;
$version =~ s/^.*\sv(\d+\.\d+\.\d+)/$1/;
$self->{__version__} = [ split( /\./, $version ) ];
Rex::Logger::debug(
"Got iptables version: " . join( ", ", @{ $self->{__version__} } ) );
return $self->{__version__};
}
1;