From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 29EDB6EB87 for ; Wed, 25 Aug 2021 12:32:03 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 144F510345 for ; Wed, 25 Aug 2021 12:31:33 +0200 (CEST) Received: from kerio.tuxis.nl (alrami.saas.tuxis.net [31.3.111.57]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 7B6561032E for ; Wed, 25 Aug 2021 12:31:28 +0200 (CEST) X-Footer: dHV4aXMubmw= Received: from [2a03:7900:64::1000] ([2a03:7900:64::1000]) (authenticated user mark@tuxis.nl) by kerio.tuxis.nl (Kerio Connect 9.3.1 patch 1) with ESMTPSA for pve-devel@lists.proxmox.com; Wed, 25 Aug 2021 12:01:20 +0200 Date: Wed, 25 Aug 2021 12:01:20 +0200 X-Mailer: Kerio Connect 9.3.1 patch 1/Kerio Connect Client X-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Firefox/91.0 Message-ID: <2092979696-10734@kerio.tuxis.nl> X-Priority: 3 Importance: Normal In-Reply-To: <20210825094703.374025-1-o.bektas@proxmox.com> MIME-Version: 1.0 From: Mark Schouten To: Proxmox VE development discussion X-SPAM-LEVEL: Spam detection results: 0 AWL 0.323 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% HTML_MESSAGE 0.001 HTML included in message KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [proxmox.com, tuxis.nl, firewall.pm] Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.29 Subject: Re: [pve-devel] [PATCH firewall] implement fail2ban backend X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Aug 2021 10:32:03 -0000 Hi, Few comments: * I'd say you would enable this on a cluster-level, for all nodes * Please allow a whitelist to be added * Feature request: When fail2ban on a node bans an IP, also add it to a blo= cklist used by VM's with a Proxmox firewall enabled. --=C2=A0 Mark Schouten=20 CTO, Tuxis B.V. | https://www.tuxis.nl/=20 | +31 318 200208 From: Oguz Bektas =20 To: =20 Sent: 2021-08-25 11:47=20 Subject: [pve-devel] [PATCH firewall] implement fail2ban backend=20 adds a section "[FAIL2BAN]" in the hostfw configuration, which allows=20 the properties 'maxretry' and 'bantime' (in minutes) for the GUI ports.=20 =20 Signed-off-by: Oguz Bektas =20 ---=20 RFC->PATCH:=20 =20 * better parser regex to allow comments in hostfw=20 * use heredoc for multiline file contents=20 * check if filter file exists, and if the jail configuration has changed=20 before writing it out=20 * removed the unrelated empty lines that i forgot, and the debug print :D=20 * error out if we can't parse an option=20 =20 =20 debian/control =C2=A0 =C2=A0 =C2=A0| =C2=A01 +=20 src/PVE/Firewall.pm | 79 ++++++++++++++++++++++++++++++++++++++++++++-=20 2 files changed, 79 insertions(+), 1 deletion(-)=20 =20 diff --git a/debian/control b/debian/control=20 index 4684c5b..377c9ae 100644=20 --- a/debian/control=20 +++ b/debian/control=20 @@ -17,6 +17,7 @@ Package: pve-firewall=20 Architecture: any=20 Conflicts: ulogd,=20 Depends: ebtables,=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 fail2ban,=20 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ipset,=20 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0iptables,=20 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0libpve-access-control,=20 diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm=20 index edc5336..ed13ca5 100644=20 --- a/src/PVE/Firewall.pm=20 +++ b/src/PVE/Firewall.pm=20 @@ -1347,6 +1347,26 @@ our $host_option_properties =3D {=20 =C2=A0 =C2=A0 },=20 };=20 =20 +our $fail2ban_option_properties =3D {=20 + =C2=A0 =C2=A0 enable =3D> {=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 description =3D> "Enable or disable fail2ban = on a node.",=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 type =3D> 'boolean',=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 default =3D> 1,=20 + =C2=A0 =C2=A0 },=20 + =C2=A0 =C2=A0 maxretry =3D> {=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 description =3D> "Amount of failed tries to b= an after.",=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 type =3D> 'integer',=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 minimum =3D> 1,=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 default =3D> 3,=20 + =C2=A0 =C2=A0 },=20 + =C2=A0 =C2=A0 bantime =3D> {=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 description =3D> "Minutes to ban suspicious I= Ps.",=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 type =3D> 'integer',=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 minimum =3D> 1,=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 default =3D> 5,=20 + =C2=A0 =C2=A0 },=20 +};=20 +=20 our $vm_option_properties =3D {=20 =C2=A0 =C2=A0 enable =3D> {=20 =C2=A0 =C2=A0 =C2=A0description =3D> "Enable/disable firewall rules.",=20 @@ -2407,6 +2427,39 @@ sub ruleset_generate_vm_rules {=20 =C2=A0 =C2=A0 }=20 }=20 =20 +sub generate_fail2ban_config {=20 + =C2=A0 =C2=A0my ($maxretry, $bantime) =3D @_;=20 +=20 + =C2=A0 =C2=A0my $bantime_seconds =3D $bantime * 60;=20 +=20 + =C2=A0 =C2=A0my $fail2ban_filter =3D < user=3D= .* msg=3D.*=20 +ignoreregex =3D=20 +CONFIG=20 + =C2=A0 =C2=A0my $filter_path =3D '/etc/fail2ban/filter.d/proxmox.conf';=20 + =C2=A0 =C2=A0PVE::Tools::file_set_contents($filter_path, $fail2ban_filter= ) unless -f $filter_path;=20 +=20 +=20 + =C2=A0 =C2=A0my $fail2ban_jail =3D <{$1}->{defau= lt});=20 + =C2=A0 =C2=A0} else {=20 + =C2=A0 =C2=A0 die "error parsing fail2ban options: $line";=20 + =C2=A0 =C2=A0}=20 +}=20 +=20 sub generic_fw_config_parser {=20 =C2=A0 =C2=A0 my ($filename, $cluster_conf, $empty_conf, $rule_env) =3D @_= ;=20 =20 @@ -2965,6 +3028,11 @@ sub generic_fw_config_parser {=20 =20 =C2=A0 =C2=A0 =C2=A0my $prefix =3D "$filename (line $linenr)";=20 =20 + =C2=A0 =C2=A0 if ($empty_conf->{fail2ban} && ($line =3D~ m/^\[fail2ban\]$= /i)) {=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 $section =3D 'fail2ban';=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 next;=20 + =C2=A0 =C2=A0 }=20 +=20 =C2=A0 =C2=A0 =C2=A0if ($empty_conf->{options} && ($line =3D~ m/^\[options= \]$/i)) {=20 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0$section =3D 'options';=20 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0next;=20 @@ -3046,6 +3114,13 @@ sub generic_fw_config_parser {=20 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 $res->{aliases}->{lc($data->{name})} = =3D $data;=20 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0};=20 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0warn "$prefix: $@" if $@;=20 + =C2=A0 =C2=A0 } elsif ($section eq 'fail2ban') {=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 my ($opt, $value) =3D eval { parse_fail2ban_o= ption($line) };=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (my $err =3D $@) {=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0warn "fail2ban parsing error: $err";=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0next;=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 }=20 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 $res->{fail2ban}->{$opt} =3D $value;=20 =C2=A0 =C2=A0 =C2=A0} elsif ($section eq 'rules') {=20 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0my $rule;=20 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0eval { $rule =3D parse_fw_rule($prefix, = $line, $cluster_conf, $res, $rule_env); };=20 @@ -3620,7 +3695,7 @@ sub load_hostfw_conf {=20 =20 =C2=A0 =C2=A0 $filename =3D $hostfw_conf_filename if !defined($filename);=20 =20 - =C2=A0 =C2=A0my $empty_conf =3D { rules =3D> [], options =3D> {}};=20 + =C2=A0 =C2=A0my $empty_conf =3D { rules =3D> [], options =3D> {}, fail2ba= n =3D> {}};=20 =C2=A0 =C2=A0 return generic_fw_config_parser($filename, $cluster_conf, $e= mpty_conf, 'host');=20 }=20 =20 @@ -4590,6 +4665,8 @@ sub update {=20 =C2=A0 =C2=A0 =C2=A0}=20 =20 =C2=A0 =C2=A0 =C2=A0my $hostfw_conf =3D load_hostfw_conf($cluster_conf);=20 + =C2=A0 =C2=A0 my $fail2ban_opts =3D $hostfw_conf->{fail2ban};=20 + =C2=A0 =C2=A0 generate_fail2ban_config($fail2ban_opts->{maxretry}, $fail2= ban_opts->{bantime});=20 =20 =C2=A0 =C2=A0 =C2=A0my ($ruleset, $ipset_ruleset, $rulesetv6, $ebtables_ru= leset) =3D compile($cluster_conf, $hostfw_conf);=20 =20 -- =20 2.30.2=20 =20 =20 =20 _______________________________________________=20 pve-devel mailing list=20 pve-devel@lists.proxmox.com=20 https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel=20 =20 =