diff --git a/www/nginx/Makefile b/www/nginx/Makefile index 50233c3fc..0b14ed54a 100644 --- a/www/nginx/Makefile +++ b/www/nginx/Makefile @@ -1,6 +1,6 @@ PLUGIN_NAME= nginx PLUGIN_VERSION= 1.14 -PLUGIN_REVISION= 1 +PLUGIN_REVISION= 2 PLUGIN_COMMENT= Nginx HTTP server and reverse proxy PLUGIN_DEPENDS= nginx PLUGIN_MAINTAINER= franz.fabian.94@gmail.com diff --git a/www/nginx/src/opnsense/scripts/nginx/ngx_autoblock.php b/www/nginx/src/opnsense/scripts/nginx/ngx_autoblock.php index 8152dccce..0cd607499 100755 --- a/www/nginx/src/opnsense/scripts/nginx/ngx_autoblock.php +++ b/www/nginx/src/opnsense/scripts/nginx/ngx_autoblock.php @@ -29,6 +29,7 @@ require_once('config.inc'); require_once('IPv6.inc'); +require_once('util.inc'); use OPNsense\Firewall\Alias; use OPNsense\Nginx\AccessLogParser; @@ -69,6 +70,8 @@ function reopen_logs() $permanent_ban_file = '/var/log/nginx/permanentban.access.log'; $permanent_ban_file_work = $permanent_ban_file . '.work'; $autoblock_alias_name = 'nginx_autoblock'; +define('CRON_RUN_TEN_MINUTES', 10); +$is_ten_minutes = intval(date('i')) % CRON_RUN_TEN_MINUTES != 0; if (!file_exists($permanent_ban_file)) { @@ -80,7 +83,13 @@ if (!file_exists($permanent_ban_file)) { // move the file, and inform nginx that we deleted the file rename($permanent_ban_file, $permanent_ban_file_work); +if ($is_ten_minutes) { + rename('/var/log/nginx/tls_handshake.log', '/var/log/nginx/tls_handshake.log.work'); +} reopen_logs(); +if ($is_ten_minutes) { + mwexec_bg('/usr/local/opnsense/scripts/nginx/tls_ua_fingerprint.php'); +} $log_parser = new AccessLogParser($permanent_ban_file_work); diff --git a/www/nginx/src/opnsense/scripts/nginx/tls_ua_fingerprint.php b/www/nginx/src/opnsense/scripts/nginx/tls_ua_fingerprint.php index 154db06fe..1dc1c839c 100755 --- a/www/nginx/src/opnsense/scripts/nginx/tls_ua_fingerprint.php +++ b/www/nginx/src/opnsense/scripts/nginx/tls_ua_fingerprint.php @@ -25,11 +25,18 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +$tls_logfile = '/var/log/nginx/tls_handshake.log.work'; +$database_name = '/var/log/nginx/handshakes.json'; function parse_line($line) { $tmp = explode('"', trim($line)); - return array('ua' => $tmp[1], 'ciphers' => $tmp[3], 'curves' => $tmp[5] == '-' ? '' : $tmp[5], 'count' => 1); + return array( + 'ua' => $tmp[1], + 'ciphers' => $tmp[3], + 'curves' => $tmp[5] == '-' ? '' : $tmp[5], + 'count' => 1 + ); } function filter_ua($key) { @@ -37,9 +44,20 @@ function filter_ua($key) } +if (!file_exists($tls_logfile)) { + echo "logfile $tls_logfile does not exist\n"; + exit(0); +} + +$fingerprints_old = @json_decode(@file_get_contents($database_name), true); +if (!is_array($fingerprints_old)) { + $fingerprints_old = array(); +} + + // parse all finger prints and count them $fingerprints = array(); -$handle = @fopen('/var/log/nginx/tls_handshake.log', 'r'); +$handle = @fopen($tls_logfile, 'r'); if ($handle) { while (($buffer = fgets($handle)) !== false) { $md5line = md5($buffer); @@ -60,7 +78,7 @@ unset($handle); $fingerprints2 = array(); foreach ($fingerprints as $fingerprint) { $user_agent = $fingerprint['ua']; - if (!is_array($fingerprints2[$user_agent])) { + if (isset($fingerprints2[$user_agent]) && !is_array($fingerprints2[$user_agent])) { $fingerprints2[$user_agent] = array(); } $hashkey = md5($fingerprint['ciphers'] . $fingerprint['curves']); @@ -80,4 +98,26 @@ foreach ($fingerprints2 as $ua => $fingerprint_data) { unset($fingerprints2); -echo json_encode($fingerprints); +foreach ($fingerprints_old as $ua_old => $fingerprint_data_old) { + if (isset($fingerprints[$ua_old])) { + foreach ($fingerprint_data_old as &$fpdo) { + $changed = false; + foreach ($fingerprints[$ua_old] as &$fingerprint_new) { + if ($fpdo['ciphers'] == $fingerprint_new['ciphers'] && $fpdo['curves'] == $fingerprint_new['curves']) { + $changed = true; + $fingerprint_new['count'] = $fingerprint_new['count'] + $fpdo['count']; + break; + } + } + if (!$changed) { + $fingerprints[$ua_old][] = $fpdo; + } + } + } else { + // the new log does not have it, apply the old one + $fingerprints[$ua_old] = $fingerprint_data_old; + } +} + +file_put_contents($database_name, json_encode($fingerprints)); +unlink($tls_logfile); diff --git a/www/nginx/src/opnsense/service/conf/actions.d/actions_nginx.conf b/www/nginx/src/opnsense/service/conf/actions.d/actions_nginx.conf index 2a577b4a9..73cda1403 100644 --- a/www/nginx/src/opnsense/service/conf/actions.d/actions_nginx.conf +++ b/www/nginx/src/opnsense/service/conf/actions.d/actions_nginx.conf @@ -33,7 +33,7 @@ type:script_output message:restarting nginx [tls_handshakes] -command:/usr/local/opnsense/scripts/nginx/tls_ua_fingerprint.php +command:cat /var/log/nginx/handshakes.json parameters: type:script_output message:query TLS handshake information of nginx