mirror of
https://github.com/webmin/webmin.git
synced 2026-03-20 08:40:24 +00:00
Add jails status and actions 2/2 #1623
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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), " <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', "e_escape($_))]}\" onmouseover=\"this.style.textDecoration='line-through'\" onmouseout=\"this.style.textDecoration='none'\""
|
||||
) . " " .
|
||||
&ui_link("unblock_jail.cgi?permblock=1&jips-@{[&urlize($jail)]}=@{[&urlize($_)]}&jail=@{[&urlize($jail)]}", "∅", undef,
|
||||
"title=\"@{[&text('status_jail_permblock_ip', "e_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
54
fail2ban/unblock_jail.cgi
Executable 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");
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user