From patchwork Fri Jun 18 17:24:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Peter_M=C3=BCller?= X-Patchwork-Id: 4441 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 4G65QZ58ylz3x6s for ; Fri, 18 Jun 2021 17:24:54 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "R3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 4G65QY73sXz1fH; Fri, 18 Jun 2021 17:24:53 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4G65QY6ZT5z2xcT; Fri, 18 Jun 2021 17:24:53 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4G65QX0qPVz2xbB for ; Fri, 18 Jun 2021 17:24:52 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by mail01.ipfire.org (Postfix) with ESMTPSA id 4G65QW1ljnz13j for ; Fri, 18 Jun 2021 17:24:51 +0000 (UTC) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003ed25519; t=1624037091; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Xv99GGn6VBM9V6A3dc2VxiO175hOdIP3g06va8k+svw=; b=atiNFCE4Pp+3ZU4yo8V+cd4g3uAkHNiuKUgD4G42Vpuw5UGG7Uq4Dej83WXI3Q6mDNo5+f Opvy3uHG6nWd7HCw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003rsa; t=1624037091; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Xv99GGn6VBM9V6A3dc2VxiO175hOdIP3g06va8k+svw=; b=GezhStc18AHqjxHVQ8TQ5EGjQlyCPfJYXHfvag6zL5nAo2JeWhIeJ6SV7c5S1JjyiZ30Cy qk2u7tU/53L6qsgnGlClT0IQgHYMi/2vsXUPJOq6iOrPM+MhKum7C++e+jSGCONNjnmCgi Xum/vJ2h6re14d1P1p5oMMswSvCT+WnaNZu4BAFNzHY14NjOlQuAJ2nsML4OPZiKrNQ4PS kfvz0ZftKSs1NzQCjBghe/mcOn+EI7LcefIfj5VAbsa2nwWjlrwKaeprd1uCBiZ6eorVdy 4rkbxufs/DQAHFt1lRRiymc38LNAP1Deqr4TlesjEsmdECdhSiTGvHL8TAr4vw== Subject: [PATCH 2/3] proxy.cgi: Implement proactive Fast Flux detection and detection for selectively announced destinations To: development@lists.ipfire.org References: <243ade9e-d013-089b-7189-d4752689af72@ipfire.org> <57f76aed-f963-e152-098a-3ca705cf3995@ipfire.org> From: =?utf-8?q?Peter_M=C3=BCller?= Message-ID: <461409ad-7b86-8744-b66d-1a36279dcc42@ipfire.org> Date: Fri, 18 Jun 2021 19:24:50 +0200 MIME-Version: 1.0 In-Reply-To: <57f76aed-f963-e152-098a-3ca705cf3995@ipfire.org> Content-Language: en-US X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" This patch adds two new features to IPFire's web proxy: (a) Proactive Fast Flux detection FQDNs are resolved to their IP addresses, which are then resolved to corresponding Autonomous System Numbers using IPFire's location database. Most destinations will scatter across a very low number of ASNs (not to be confused with IP addresses!). FQDNs hosted on Fast Flux setups have a significantly higher ASN diversity (5 is usually a good threshold), so they can be proactively detected. (b) Detection for selectively announced destinations Especially in targeted operations, miscreants host FQDNs for exfiltrating data or malware distributions on ASNs not announced globally, but only to the intended victim or it's upstream ISPs. That way, security researchers located in other parts of the internet have no insights into these attacks, hence not being able to publish listings or send take down notices for the domains used. While RPKI made this attack harder, it can still be observed every now and then. This feature also protects against accessing FQDNs resolving to IP addresses not being globally routeable, hence providing a trivial mitigation for so-called "rebound attacks" - which we cannot filter at DNS level currently. Signed-off-by: Peter Müller --- html/cgi-bin/proxy.cgi | 89 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/html/cgi-bin/proxy.cgi b/html/cgi-bin/proxy.cgi index 78ad33ad2..b7227deaf 100644 --- a/html/cgi-bin/proxy.cgi +++ b/html/cgi-bin/proxy.cgi @@ -21,6 +21,7 @@ use strict; use Apache::Htpasswd; +use Scalar::Util qw(looks_like_number); # enable only the following on debugging purpose #use warnings; @@ -225,6 +226,9 @@ $proxysettings{'THROTTLING_GREEN_TOTAL'} = 'unlimited'; $proxysettings{'THROTTLING_GREEN_HOST'} = 'unlimited'; $proxysettings{'THROTTLING_BLUE_TOTAL'} = 'unlimited'; $proxysettings{'THROTTLING_BLUE_HOST'} = 'unlimited'; +$proxysettings{'ASNBL_FASTFLUX_DETECTION'} = 'off'; +$proxysettings{'ASNBL_FASTFLUX_THRESHOLD'} = '5'; +$proxysettings{'ASNBL_SELECANN_DETECTION'} = 'off'; $proxysettings{'ENABLE_MIME_FILTER'} = 'off'; $proxysettings{'AUTH_METHOD'} = 'none'; $proxysettings{'AUTH_REALM'} = ''; @@ -414,6 +418,21 @@ if (($proxysettings{'ACTION'} eq $Lang::tr{'save'}) || ($proxysettings{'ACTION'} $errormessage = $Lang::tr{'invalid maximum incoming size'}; goto ERROR; } + if (($proxysettings{'ASNBL_FASTFLUX_DETECTION'} eq 'on') || ($proxysettings{'ASNBL_SELECANN_DETECTION'} eq 'on')) + { + if (-z $proxysettings{'ASNBL_FASTFLUX_THRESHOLD'}) { + $errormessage = $Lang::tr{'advproxy fastflux no threshold given'}; + goto ERROR; + } + if (! looks_like_number($proxysettings{'ASNBL_FASTFLUX_THRESHOLD'})) { + $errormessage = $Lang::tr{'advproxy fastflux threshold invalid'}; + goto ERROR; + } + if (($proxysettings{'ASNBL_FASTFLUX_THRESHOLD'} < 2) || ($proxysettings{'ASNBL_FASTFLUX_THRESHOLD'} > 10)) { + $errormessage = $Lang::tr{'advproxy fastflux threshold out of bounds'}; + goto ERROR; + } + } if (!($proxysettings{'AUTH_METHOD'} eq 'none')) { unless (($proxysettings{'AUTH_METHOD'} eq 'ident') && @@ -797,6 +816,14 @@ $selected{'THROTTLING_GREEN_HOST'}{$proxysettings{'THROTTLING_GREEN_HOST'}} = "s $selected{'THROTTLING_BLUE_TOTAL'}{$proxysettings{'THROTTLING_BLUE_TOTAL'}} = "selected='selected'"; $selected{'THROTTLING_BLUE_HOST'}{$proxysettings{'THROTTLING_BLUE_HOST'}} = "selected='selected'"; +$checked{'ASNBL_FASTFLUX_DETECTION'}{'off'} = ''; +$checked{'ASNBL_FASTFLUX_DETECTION'}{'on'} = ''; +$checked{'ASNBL_FASTFLUX_DETECTION'}{$proxysettings{'ASNBL_FASTFLUX_DETECTION'}} = "checked='checked'"; + +$checked{'ASNBL_SELECANN_DETECTION'}{'off'} = ''; +$checked{'ASNBL_SELECANN_DETECTION'}{'on'} = ''; +$checked{'ASNBL_SELECANN_DETECTION'}{$proxysettings{'ASNBL_SELECANN_DETECTION'}} = "checked='checked'"; + $checked{'ENABLE_MIME_FILTER'}{'off'} = ''; $checked{'ENABLE_MIME_FILTER'}{'on'} = ''; $checked{'ENABLE_MIME_FILTER'}{$proxysettings{'ENABLE_MIME_FILTER'}} = "checked='checked'"; @@ -1627,6 +1654,24 @@ END print < +
+ + + + + + + + + + + + + + + +
$Lang::tr{'advproxy asbased anomaly detection'}
$Lang::tr{'advproxy fastflux detection'}:$Lang::tr{'advproxy fastflux detection threshold'}:
$Lang::tr{'advproxy selectively announcements detection'}:
+
END ; @@ -3507,6 +3552,50 @@ if (@ssl_ports) { print FILE "http_access deny CONNECT !SSL_ports\n"; } + if ((($proxysettings{'ASNBL_FASTFLUX_DETECTION'} eq 'on') && (!-z $proxysettings{'ASNBL_FASTFLUX_THRESHOLD'})) || ($proxysettings{'ASNBL_SELECANN_DETECTION'} eq 'on')) { + print FILE "external_acl_type asnblhelper children-max=10 children-startup=2 ttl=86400 %DST /usr/bin/asnbl-helper.py /var/ipfire/proxy/asnbl-helper.conf\n"; + print FILE "acl asnbl external asnblhelper\n"; + print FILE "http_access deny asnbl\n\n"; + + # Write ASNBL helper configuration file... + open(ASNBLFILE, ">${General::swroot}/proxy/asnbl-helper.conf"); + flock(ASNBLFILE, 2); + + print ASNBLFILE<