#! /usr/bin/perl use strict ; use warnings ; my $DEF_JAIL = 'recidive' ; my $PAT_IP = qr{^(\d{1,3}(\.\d{1,3}){3})$} ; my $prog = substr $0, rindex ( $0, '/' ) + 1 ; my $Usage = < ################################################################ 1. $prog adds argument to jail ; default '$DEF_JAIL' 2. $prog shows the status of jail ; default : all jails ################################################################ USAGE sub Usage { die "$_[0]$Usage" ; } sub Error { die "[error] $prog: $_[0]\n" ; } sub Warn { warn "[warn] $prog: $_[0]\n" ; } # usage: &GetOptions(ARG,ARG,..) defines $opt_ID as 1 or user spec'ed value # usage: &GetOptions(\%opt,ARG,ARG,..) defines $opt{ID} as 1 or user value # ARG = 'ID' | 'ID=SPC' | 'ID:SPC' for no-arg, required-arg or optional-arg # ID = perl identifier # SPC = i|f|s for integer, fixedpoint real or string argument use Getopt::Long ; Getopt::Long::config ( 'no_ignore_case' ) ; my %opt = () ; Usage '' unless GetOptions ( \%opt, qw(v q d f u) ) ; Usage("Arg count\n") if @ARGV > 2 ; $opt{v} ||= $opt{d} ; if ( $< ) { my $usr = getpwuid ( $< ) || "uid $<" ; Error "must run as root ; not $usr" ; } sub System { my $cmd = shift ; printf "running [$cmd] ...\n" if $opt{d} ; system $cmd ; } sub show_exit { my $JAIL = shift ; my $CMD = 'fail2ban-client -v status' ; my $pat = 'Jail list' ; printf "running [$CMD] ...\n" if $opt{d} ; open CMD, "$CMD|" or Error "can't popen $CMD ($!)" ; my @CMD = ; close CMD ; print "@CMD" if $opt{d} ; my $list ; for my $line ( @CMD ) { $list = $' if $line =~ /$pat:\s+/ ; } print "$pat : $list\n" ; chomp $list ; Error "no '$pat' found" unless defined $list ; my @list = split /,\s*/, $list ; Error "no jail '$JAIL' found" if $JAIL and ! grep $_ eq $JAIL, @list ; for my $jail ( $JAIL ? ( $JAIL ) : @list ) { System "$CMD $jail" ; } exit ; } my $ARG = shift ; my $JAIL = shift ; show_exit $ARG unless defined $ARG and $ARG =~ $PAT_IP ; $JAIL ||= $DEF_JAIL ; my $TAG = $opt{f} ? 'DID' : 'WOULD' ; my $sub = qr/\d{1,3}/ ; my $pat = qr/^$sub(\.$sub){3}$/ ; System "fail2ban-client -v status $JAIL" if $opt{v} ; Error "bad ip ($ARG) ; should match $pat" unless $ARG =~ $pat ; my $act = 'banip' ; $act = "un$act" if $opt{u} ; my $cmd = "fail2ban-client set $JAIL $act $ARG" ; print "$TAG $cmd\n" ; System $cmd if $opt{f} ; printf "*** THIS IS A DRY-RUN ***\n" unless $opt{f} ;