Add jails status and actions 2/2 #1623

This commit is contained in:
Ilia
2022-04-11 01:10:27 +03:00
parent 916600aa6d
commit 1c7a18f08f
5 changed files with 149 additions and 1 deletions

View File

@@ -178,9 +178,16 @@ status_head_total_failed=Total failed
status_head_currently_banned=Currently banned
status_head_total_banned=Total banned
status_head_banned_ip_list=Banned IP list
status_jail_unblock_ip=Remove $1 from banned list
status_jail_permblock_ip=Permanently block this IP
status_jail_unblock=Unblock All IPs for Selected Jails
status_jail_block=Permanently Block All IPs in Banned List for Selected Jails
status_jail_noactive=There are no active jails enabled yet.
status_err_set=Failed set action
status_err_unblock=Failed to unblock action
status_err_nojail=No jails has been selected
status_err_unban=Cannot un-ban $1 IP address
status_err_ban=Cannot ban $1 IP address
syslog_logtarget=Fail2Ban action log

View File

@@ -16,12 +16,14 @@ if (@jails) {
my @links = ( &select_all_link("jail"),
&select_invert_link("jail") );
my $head;
my @jipsall;
foreach my $jail (@jails) {
my $fh = 'cmdjail';
my $cmd = "$config{'client_cmd'} status ".quotemeta($jail);
my $jcmd = "$cmd 2>&1 </dev/null";
my @head = (undef, $text{"status_head_jail_name"});
my @body = (&ui_link("edit_jail.cgi?name=".urlize($jail), "&nbsp;<tt>".&html_escape($jail)."</tt>"));
my $jips;
&open_execute_command($fh, $jcmd, 1);
while(<$fh>) {
if (/-\s+(.*):\s*(.*)/) {
@@ -32,8 +34,17 @@ if (@jails) {
if ($col !~ /journal_matches/) {
push(@head, $text{"status_head_$col"});
if ($col =~ /banned_ip_list/) {
$jips = $val;
my @ips = split(/\s+/, $val);
$val =~ s/\s+/<br>/g;
@ips = map { &ui_link("unblock_jail.cgi?unblock=1&jips-@{[&urlize($jail)]}=@{[&urlize($_)]}&jail=@{[&urlize($jail)]}", $_, undef,
"title=\"@{[&text('status_jail_unblock_ip', &quote_escape($_))]}\" onmouseover=\"this.style.textDecoration='line-through'\" onmouseout=\"this.style.textDecoration='none'\""
) . "&nbsp;&nbsp; " .
&ui_link("unblock_jail.cgi?permblock=1&jips-@{[&urlize($jail)]}=@{[&urlize($_)]}&jail=@{[&urlize($jail)]}", "&empty;", undef,
"title=\"@{[&text('status_jail_permblock_ip', &quote_escape($_))]}\" onmouseover=\"this.style.opacity='1';this.style.filter='grayscale(0)'\" onmouseout=\"this.style.opacity='0.25';this.style.filter='grayscale(100%)'\" style=\"font-size: 125%; filter: grayscale(100%); opacity: .25\""
) } @ips;
$val = "<br>" if ($val);
$val .= join('<br>', @ips);
$val .= "<br><br>" if ($val);
}
push(@body, $val);
}
@@ -46,10 +57,14 @@ if (@jails) {
print &ui_columns_start(\@head);
}
print &ui_checked_columns_row(\@body, ['width=5', undef, $tdc, $tdc, $tdc, $tdc], "jail", $jail);
push(@jipsall, ["$jail" => $jips]);
}
if ($head) {
print &ui_columns_end();
print &ui_links_row(\@links);
foreach my $j (@jipsall) {
print &ui_hidden("jips-$j->[0]", "$j->[1]");
}
print &ui_form_end([ [ 'unblock', $text{'status_jail_unblock'} ],
[ 'permblock', $text{'status_jail_block'} ] ]);
};

54
fail2ban/unblock_jail.cgi Executable file
View File

@@ -0,0 +1,54 @@
#!/usr/local/bin/perl
# Create, update or delete a action
use strict;
use warnings;
require './fail2ban-lib.pl';
our (%in, %text, %config);
&ReadParse();
&error_setup($text{'status_err_set'});
my @jails = split(/\0/, $in{'jail'});
my $action = $in{'permblock'} ? 'block' : $in{'unblock'} ? 'unblock' : undef;
# Error checks
!$action || $in{'jail'} || &error($text{'status_err_nojail'});
# Unblock given IP in given jail
my $unblock_jailed_ip = sub {
my ($jail, $ip) = @_;
my $cmd = "$config{'client_cmd'} set ".quotemeta($jail)." unbanip ".quotemeta($ip)." 2>&1 </dev/null";
my $out = &backquote_logged($cmd);
if ($?) {
&error(&text('status_err_unban', &html_escape($ip)) . " : $out");
}
};
# Processes jails actions
foreach my $jail (@jails) {
my @jailips = split(/\s+/, $in{"jips-$jail"});
if (@jailips) {
foreach my $ip (@jailips) {
# Blocking permanently IP from given jail
if ($action eq 'block') {
# Add permanent block first
&foreign_require('firewalld');
my $out = &firewalld::add_ip_ban($ip);
if ($out) {
&error(&text('status_err_ban', &html_escape($ip)) . " : $out");
}
# Remove from fail2ban now
&$unblock_jailed_ip($jail, $ip);
}
# Unblocking IP from given jail
elsif ($action eq 'unblock') {
# Just unblock
&$unblock_jailed_ip($jail, $ip);
}
}
}
}
# Log and redirect
&webmin_log('update', 'jail', join(", ", @jails));
&redirect("list_status.cgi");

View File

@@ -353,4 +353,73 @@ else {
}
}
# add_ip_ban(ip, [zone])
# Ban given IP address in given or default zone
sub add_ip_ban
{
my ($ip, $zone) = @_;
return create_rich_rule('add', $ip, $zone);
}
# remove_ip_ban(ip, [zone])
# Un-ban given IP address in given or default zone
sub remove_ip_ban
{
my ($ip, $zone) = @_;
return create_rich_rule('remove', $ip, $zone);
}
# create_rich_rule(action, ip, [zone], [opts])
# Add or remove rich rule for given IP in given or default zone
sub create_rich_rule
{
my ($action, $ip, $zone, $opts) = @_;
my $ip_validate = sub {
return &check_ipaddress($_[0]) || &check_ip6address($_[0]);
};
# Default action for permanent ban is 'drop'
my $action_type = "drop";
# Override defaults
if (ref($opts)) {
# Override default action
$action_type = lc($opts->{'action'})
if ($opts->{'action'} &&
$opts->{'action'} =~ /^accept|reject|drop|mark$/);
}
# Default zone
if (!$zone) {
my @zones = &list_firewalld_zones();
($zone) = grep { $_->{'default'} } @zones;
}
my $zone_name = $zone->{'name'};
$zone_name =~ tr/A-Za-z0-9\-\_//cd;
# Validate action
$action eq 'add' || $action eq 'remove' || &error($text{'richrule_actionerr'});
# Validate IP
&$ip_validate($ip) || &error($text{'richrule_iperr'});
# Set family
my $family = $ip =~ /:/ ? 'ipv6' : 'ipv4';
# Apply block (you cannot quotemeta IP address and
# other params, i.e. must be validated manually)
my $get_cmd = sub {
my ($rtype) = @_;
my $type;
$type = " --permanent" if ($rtype eq 'permanent');
return "$config{'firewall_cmd'} --zone=".$zone_name."$type --$action-rich-rule=\"rule family='$family' source address='$ip' $action_type\"";
};
my $out = &backquote_logged(&$get_cmd()." 2>&1 </dev/null");
return $out if ($?);
$out = &backquote_logged(&$get_cmd('permanent')." 2>&1 </dev/null");
return $? ? $out : undef;
}
1;

View File

@@ -93,6 +93,9 @@ delzone_rusure=Are you sure you want to delete the zone $1, which contains $2 po
defzone_err=Failed to make zone the default
richrule_iperr=Invalid IP address
richrule_actionerr=Invalid action
restart_err=Failed to apply configuration
stop_err=Failed to stop FirewallD
start_err=Failed to start FirewallD