From 5de6b807942a0f79b90e305bc9af08a851b452bb Mon Sep 17 00:00:00 2001 From: sld-admin Date: Thu, 12 Feb 2026 14:36:29 +0000 Subject: [PATCH] Fixed Generate Script --- assets/css/style.css | 4 +- assets/js/main.js | 20 ++- functions/main.php | 25 +++ generate-report.php | 278 ++++++++++++++++++++++++++++++ process/ajax-refresh.php | 8 + process/generate-report.php | 104 ----------- scripts-backup/generate-report.pl | 240 ++++++++++++++++++++++++++ scripts-backup/generate-report.sh | 63 +++++++ template/footer.php | 7 + template/header.php | 2 +- web_check.json | 92 +++++----- web_check_backup.json | 52 ++++++ web_list.json | 35 +++- 13 files changed, 764 insertions(+), 166 deletions(-) create mode 100644 generate-report.php create mode 100644 process/ajax-refresh.php delete mode 100644 process/generate-report.php create mode 100755 scripts-backup/generate-report.pl create mode 100755 scripts-backup/generate-report.sh create mode 100644 web_check_backup.json diff --git a/assets/css/style.css b/assets/css/style.css index 9bddd66..d8e0293 100755 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -19,7 +19,7 @@ header{ } .main-container{ - padding:50px 20px 20px 20px ; + padding:50px 20px 50px 20px ; background-color: #363636; width:100vw; height:100vh; @@ -75,7 +75,7 @@ header{ margin:5px; background-color: rgba(255, 255, 255, 0.774); color:black; - + flex-direction: column; justify-content: space-between; flex-wrap: wrap; diff --git a/assets/js/main.js b/assets/js/main.js index c19754b..88dbe83 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -8,4 +8,22 @@ function show_details(){ }) }) -} \ No newline at end of file +} + +function aggiornaDati() { + fetch('/process/ajax-refresh.php') + .then(response => response.text()) + .then(html => { + const container = document.getElementById('main-container'); + if (container) { + container.innerHTML = html; + + // Se hai funzioni tipo show_details() + if (typeof show_details === "function") { + show_details(); + } + } + }) + .catch(error => console.error('Errore AJAX:', error)); +} + diff --git a/functions/main.php b/functions/main.php index 5fc29ed..bf5f24f 100644 --- a/functions/main.php +++ b/functions/main.php @@ -51,17 +51,40 @@ use function PHPSTORM_META\type; function get_checked_list(){ global $webcheck_json; + + // Ordina: problemi prima + usort($webcheck_json, function($a, $b) { + + $a_problem = ($a['sslcheck_ok'] != 1 || $a['wordcheck_ok'] != 1); + $b_problem = ($b['sslcheck_ok'] != 1 || $b['wordcheck_ok'] != 1); + + // Se A ha problema e B no → A prima + if ($a_problem && !$b_problem) return -1; + + // Se B ha problema e A no → B prima + if (!$a_problem && $b_problem) return 1; + + // Se entrambi uguali → mantieni ordine + return 0; + }); + foreach($webcheck_json as $check_element){ //VARIABLES $host=$check_element['host']; $domain=$check_element['domain']; + $path=$check_element['path']; $checkword_ok=$check_element['wordcheck_ok']; $sslcheck_ok=$check_element['sslcheck_ok']; $wordtocheck=$check_element['wordtocheck']; $ssl_released=$check_element['ssl-released']; $ssl_expiry=$check_element['ssl-expiry']; $ssl_company=$check_element['ssl-company']; + $http_error=$check_element['content_http_code']; + + if ($path == ""){ + $path = "/"; + } ?>
@@ -76,6 +99,8 @@ use function PHPSTORM_META\type;
SSL RELEASED:
SSL EXPIRY:
SSL COMPANY:
+
PATH:
+
ERROR CODE:
diff --git a/generate-report.php b/generate-report.php new file mode 100644 index 0000000..1a0465c --- /dev/null +++ b/generate-report.php @@ -0,0 +1,278 @@ + $v) { + if (!is_numeric($k)) $vals[] = "$k=$v"; + else $vals[] = $v; + } + return $vals ? implode(', ', $vals) : null; +} + +function extractIssuerCN(array $cert_info): ?string { + if (empty($cert_info['issuer']) || !is_array($cert_info['issuer'])) return null; + $issuer = $cert_info['issuer']; + + // prima prova CN (Common Name) + $keys = ['CN', 'commonName', 'O', 'o', 'OU', 'organizationName']; + foreach ($keys as $k) { + if (isset($issuer[$k]) && !empty($issuer[$k])) { + return $issuer[$k]; + } + } + + // fallback: unisci tutti + $vals = []; + foreach ($issuer as $k => $v) { + if (!is_numeric($k)) $vals[] = "$k=$v"; + else $vals[] = $v; + } + return $vals ? implode(', ', $vals) : null; +} + +// Ottieni informazioni certificato via stream_socket_client (SNI) +function getCertInfo(string $host, int $port = 443, int $timeout = 10): array { + $result = [ + 'status' => 0, + 'issued' => null, + 'expiry' => null, + 'company' => null, + 'error' => null + ]; + + $ctx = stream_context_create([ + 'ssl' => [ + 'capture_peer_cert' => true, + 'verify_peer' => false, // non forziamo la verifica CA per garantire il fetch del cert + 'verify_peer_name' => false, + 'peer_name' => $host, + 'SNI_enabled' => true, + ] + ]); + + $address = "ssl://{$host}:{$port}"; + $client = @stream_socket_client($address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $ctx); + if ($client !== false) { + $params = stream_context_get_params($client); + @fclose($client); + if (!empty($params['options']['ssl']['peer_certificate'])) { + $cert = $params['options']['ssl']['peer_certificate']; + $cert_info = @openssl_x509_parse($cert); + if ($cert_info !== false) { + $issued = isset($cert_info['validFrom_time_t']) ? date('d/m/Y', $cert_info['validFrom_time_t']) : null; + $expiry = isset($cert_info['validTo_time_t']) ? date('d/m/Y', $cert_info['validTo_time_t']) : null; + $company = extractIssuerCN($cert_info) ?? null; + $isValid = (isset($cert_info['validTo_time_t']) && time() < $cert_info['validTo_time_t']) ? 1 : 0; + + $result = [ + 'status' => $isValid, + 'issued' => $issued, + 'expiry' => $expiry, + 'company' => $company, + 'error' => null + ]; + return $result; + } else { + $result['error'] = 'openssl_x509_parse failed'; + return $result; + } + } else { + $result['error'] = 'no peer_certificate found'; + return $result; + } + } + + // fallback: prova con openssl s_client se disponibile (solo se exec abilitato) + $escHost = escapeshellarg($host); + $cmd = sprintf("timeout %d openssl s_client -connect %s:443 -servername %s -showcerts /dev/null | openssl x509 -noout -dates -issuer", $timeout, $escHost, $escHost); + @exec($cmd, $out, $ret); + if ($ret === 0 && !empty($out)) { + $joined = implode("\n", $out); + // notBefore / notAfter + if (preg_match('/notBefore=(.+)/i', $joined, $m1)) { + $issuedRaw = trim($m1[1]); + $issuedTs = strtotime($issuedRaw); + $issued = $issuedTs ? date('d/m/Y', $issuedTs) : $issuedRaw; + } else { + $issued = null; + } + if (preg_match('/notAfter=(.+)/i', $joined, $m2)) { + $expiryRaw = trim($m2[1]); + $expiryTs = strtotime($expiryRaw); + $expiry = $expiryTs ? date('d/m/Y', $expiryTs) : $expiryRaw; + } else { + $expiry = null; + } + if (preg_match('/issuer=.*O=([^,\/]+)/i', $joined, $m3)) { + $company = trim($m3[1]); + } elseif (preg_match('/issuer=.*CN=([^,\/]+)/i', $joined, $m4)) { + $company = trim($m4[1]); + } else { + $company = null; + } + $isValid = 0; + if ($expiry) { + $dt = DateTime::createFromFormat('d/m/Y', $expiry); + if ($dt) $isValid = (time() < $dt->getTimestamp()) ? 1 : 0; + } + return [ + 'status' => $isValid, + 'issued' => $issued, + 'expiry' => $expiry, + 'company' => $company, + 'error' => null + ]; + } + + $result['error'] = "stream_socket_client failed: $errstr ($errno)"; + return $result; +} + +// Fetch content con cURL (supporta basic auth), ritorna array con body, http_code, error +function fetchWithCurl(string $url, ?string $user, ?string $pass, int $timeout = 10) { + if (!function_exists('curl_init')) return ['ok' => false, 'error' => 'curl missing']; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); + + // se vuoi abilitare la verifica CA, metti true e assicurati che PHP abbia CA bundle + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + + if ($user !== null && $pass !== null) { + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + curl_setopt($ch, CURLOPT_USERPWD, $user . ':' . $pass); + } + + $body = curl_exec($ch); + $err = curl_error($ch); + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($body === false) return ['ok' => false, 'error' => $err, 'http_code' => $code]; + return ['ok' => true, 'body' => $body, 'http_code' => $code]; +} + +// Controlla presenza stringa (1/0) e ritorna anche eventuale debug +function checkContentMatch(string $url, string $match, ?string $user, ?string $pass, int $timeout = 10): array { + $resp = fetchWithCurl($url, $user, $pass, $timeout); + if (!$resp['ok']) { + return ['ok' => 0, 'http_code' => $resp['http_code'] ?? null, 'error' => $resp['error'] ?? 'fetch failed']; + } + $found = (strpos($resp['body'], $match) !== false) ? 1 : 0; + return ['ok' => $found, 'http_code' => $resp['http_code'] ?? null, 'error' => null]; +} + +// --- Leggi input JSON --- +if (!file_exists($inputFile)) { + echo "File $inputFile non trovato\n"; + exit(1); +} +$raw = file_get_contents($inputFile); +$domains = json_decode($raw, true); +if ($domains === null) { + echo "Errore parsing JSON di input\n"; + exit(1); +} + +$results = []; +$totalSSLok = 0; +$totalContentOk = 0; + +foreach ($domains as $entry) { + $host = $entry['host'] ?? null; + $domain = $entry['domain'] ?? null; // es. wiki.sld-server.org + $path = $entry['path'] ?? ''; // es. /doku.php?id=start oppure "" + $word = $entry['word-to-check'] ?? ''; + $basicAuth = $entry['basic_auth'] ?? false; + + // supporta sia basic_auth_password che basic_auth_pass (tolleranza nomi) + $user = ($basicAuth && !empty($entry['basic_auth_name'])) ? $entry['basic_auth_name'] : null; + $pass = null; + if ($basicAuth) { + if (!empty($entry['basic_auth_password'])) $pass = $entry['basic_auth_password']; + elseif (!empty($entry['basic_auth_pass'])) $pass = $entry['basic_auth_pass']; + elseif (!empty($entry['basic_auth_passwd'])) $pass = $entry['basic_auth_passwd']; + } + + // costruisci URL (https://domain + path). se path vuoto -> '/' + $domainClean = preg_replace('#^https?://#i', '', rtrim($domain, '/')); + $pathClean = $path === '' ? '/' : (strpos($path, '/') === 0 ? $path : '/' . $path); + $url = 'https://' . $domainClean . $pathClean; + + // estrai host per SSL (rimuove eventuale port/path) + $sslHost = normalizeDomainHost($domain); + + // --- SSL info --- + $sslInfo = getCertInfo($sslHost, 443, $timeout); + + // --- content check --- + $contentCheck = checkContentMatch($url, $word, $user, $pass, $timeout); + + $word_ok = $contentCheck['ok']; + $http_code = $contentCheck['http_code'] ?? null; + $content_error = $contentCheck['error'] ?? null; + + if ($sslInfo['status'] === 1) $totalSSLok++; + if ($word_ok === 1) $totalContentOk++; + + $results[] = [ + 'host' => $host, + 'domain' => $domain, + 'path' => $path, + 'wordtocheck' => $word, + 'wordcheck_ok' => $word_ok, + 'sslcheck_ok' => $sslInfo['status'], + 'ssl-released' => $sslInfo['issued'], + 'ssl-expiry' => $sslInfo['expiry'], + 'ssl-company' => $sslInfo['company'], + // campi di debug utili per capire perché auth/content falliscono + 'content_http_code' => $http_code, + 'content_error' => $content_error, + 'ssl_error' => $sslInfo['error'] ?? null + ]; +} + +// salva output (unescaped slashes) +file_put_contents($outputFile, json_encode($results, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + +// stampa sommario +echo "Check completato. Risultati salvati in $outputFile\n"; +echo "Totali: SSL ok = $totalSSLok, Content ok = $totalContentOk\n"; +?> diff --git a/process/ajax-refresh.php b/process/ajax-refresh.php new file mode 100644 index 0000000..1fa0519 --- /dev/null +++ b/process/ajax-refresh.php @@ -0,0 +1,8 @@ + ["capture_peer_cert" => true, "verify_peer" => true, "verify_peer_name" => true] - ]); - - $client = @stream_socket_client("ssl://$host:443", $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $streamContext); - - if (!$client) { - return ["status" => false, "expiry" => null, "error" => $errstr]; - } - - $params = stream_context_get_params($client); - $cert = $params["options"]["ssl"]["peer_certificate"]; - $cert_info = openssl_x509_parse($cert); - $expiry = date('Y-m-d H:i:s', $cert_info['validTo_time_t']); - - // Controllo se scaduto - $isValid = time() < $cert_info['validTo_time_t']; - - return ["status" => $isValid, "expiry" => $expiry, "error" => null]; -} - -function checkContent($host, $match, $user = null, $pass = null, $timeout = 10) { - $opts = ['http' => ['timeout' => $timeout]]; - if ($user && $pass) { - $opts['http']['header'] = "Authorization: Basic " . base64_encode("$user:$pass"); - } - $context = stream_context_create($opts); - $content = @file_get_contents("https://$host", false, $context); - - if ($content === false) return false; - return strpos($content, $match) !== false; -} - -// --- Leggi lista domini --- -if (!file_exists($inputFile)) { - die("File $inputFile non trovato.\n"); -} -$domains = json_decode(file_get_contents($inputFile), true); - -$results = []; -$totalSSLok = 0; -$totalContentOk = 0; - -foreach ($domains as $entry) { - $host = $entry[0]; - $domain = $entry[1]; - $match = $entry[2]; - $checkContentFlag = $entry[3]; - - // Leggi user/pass solo se flag true - $user = null; - $pass = null; - if ($checkContentFlag) { - $user = $entry[4] ?? null; - $pass = $entry[5] ?? null; - } - - // --- SSL --- - $ssl = checkSSL($host, $timeout); - if ($ssl['status']) $totalSSLok++; - - // --- Content --- - $contentOk = true; - if ($checkContentFlag) { - $contentOk = checkContent($host, $match, $user, $pass, $timeout); - if ($contentOk) $totalContentOk++; - } - - // --- Tutto OK? --- - $allOk = $ssl['status'] && $contentOk; - - // --- Salva risultato --- - $results[] = [ - "host" => $host, - "domain" => $domain, - "ssl_status" => $ssl['status'], - "ssl_expiry" => $ssl['expiry'], - "content_match" => $contentOk, - "all_ok" => $allOk - ]; -} - -// --- Salva JSON output --- -$output = [ - "results" => $results, - "summary" => [ - "total_ssl_ok" => $totalSSLok, - "total_content_ok" => $totalContentOk, - "total_checked" => count($domains) - ] -]; - -file_put_contents($outputFile, json_encode($output, JSON_PRETTY_PRINT)); - -echo "Check completato. Risultati salvati in $outputFile\n"; -?> diff --git a/scripts-backup/generate-report.pl b/scripts-backup/generate-report.pl new file mode 100755 index 0000000..28362a7 --- /dev/null +++ b/scripts-backup/generate-report.pl @@ -0,0 +1,240 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use JSON::MaybeXS; +use LWP::UserAgent; +use HTTP::Request; +use MIME::Base64 qw(encode_base64); +use Date::Parse qw(str2time); +use POSIX qw(strftime); +use File::Spec; +use File::Basename; +use HTTP::Cookies; + +# CONFIG +my $basedir = dirname(__FILE__); +my $input_file = File::Spec->catfile($basedir, 'web_list.json'); +my $output_file = File::Spec->catfile($basedir, 'web_check.json'); +my $false_html = File::Spec->catfile($basedir, 'sld-check-false.html'); +my $timeout = 10; # timeout secondi +my $openssl_timeout_bin = (-x '/usr/bin/timeout' ? '/usr/bin/timeout' : + -x '/bin/timeout' ? '/bin/timeout' : ''); + +# ===== helpers ===== +sub read_json_file { + my ($path) = @_; + open my $fh, '<', $path or die "Cannot open $path: $!\n"; + local $/; + my $json = <$fh>; + close $fh; + return decode_json($json); +} + +sub write_json_file { + my ($path, $data) = @_; + open my $out, '>', $path or die "Cannot write $path: $!\n"; + print $out encode_json($data); + close $out; +} + +sub format_date_from_string { + my ($raw) = @_; + return undef unless defined $raw && $raw ne ''; + my $ts = str2time($raw); + return undef unless $ts; + return strftime("%d/%m/%Y", gmtime($ts)); +} + +# Run openssl s_client -> parse notBefore notAfter issuer +sub get_cert_info_openssl { + my ($host, $timeout_sec) = @_; + my $result = { + status => 0, + issued => undef, + expiry => undef, + company => undef, + error => undef, + }; + + # escape host for shell + my $esc_host = $host; + $esc_host =~ s/'/'\\''/g; # basic escape if used in single quotes + my $cmd = sprintf("openssl s_client -connect %s:443 -servername %s -showcerts /dev/null | openssl x509 -noout -dates -issuer", $host, $host); + if ($openssl_timeout_bin) { + $cmd = join(' ', $openssl_timeout_bin, $timeout_sec, $cmd); + } + + my $out = qx{$cmd}; + my $exit = $? >> 8; + + if ($exit != 0 || $out eq '') { + $result->{error} = "openssl failed or timed out (exit=$exit)"; + return $result; + } + + my ($notBefore) = $out =~ /notBefore=(.+)/i; + my ($notAfter) = $out =~ /notAfter=(.+)/i; + my ($issuer) = $out =~ /issuer\s*=\s*(.+)/i; + + my $issued_fmt = defined $notBefore ? format_date_from_string($notBefore) : undef; + my $expiry_fmt = defined $notAfter ? format_date_from_string($notAfter) : undef; + + # extract company from issuer: try O= then CN= else whole issuer + my $company = undef; + if (defined $issuer) { + if ($issuer =~ /O=([^,\/]+)/) { + $company = $1; + } elsif ($issuer =~ /CN=([^,\/]+)/) { + $company = $1; + } else { + $company = $issuer; + } + $company =~ s/^\s+|\s+$//g; + } + + my $is_valid = 0; + if ($expiry_fmt) { + my $ts = str2time($notAfter); + $is_valid = ($ts && time() < $ts) ? 1 : 0; + } + + $result->{status} = $is_valid; + $result->{issued} = $issued_fmt; + $result->{expiry} = $expiry_fmt; + $result->{company} = $company; + $result->{error} = undef; + return $result; +} + +# build URL from domain + path; ensure https:// prefix +sub build_url { + my ($domain, $path) = @_; + $domain =~ s{^https?://}{}i; + $domain =~ s{/$}{}; # remove trailing slash + $path = '' unless defined $path; + $path = '/' if $path eq ''; + $path = "/$path" unless $path =~ m{^/}; + return 'https://' . $domain . $path; +} + +# basic sanitize host (remove scheme and path) +sub normalize_host { + my ($domain) = @_; + return undef unless defined $domain; + $domain =~ s{^https?://}{}i; + $domain =~ s{/.*$}{}; # remove path + $domain =~ s/:\d+$//; # remove port if any + return $domain; +} + +# ===== prepare LWP client ===== +my $ua = LWP::UserAgent->new(timeout => $timeout); +# Browser-like user agent to avoid bot blocking +$ua->agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ". + "(KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"); +$ua->default_header('Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'); +$ua->cookie_jar(HTTP::Cookies->new()); # maintain cookies +$ua->max_redirect(7); + +# ===== main ===== +die "Input file $input_file not found\n" unless -f $input_file; +my $domains = read_json_file($input_file); +die "Input JSON must be an array\n" unless ref($domains) eq 'ARRAY'; + +my @results; +my $any_fail = 0; +my $total_ssl_ok = 0; +my $total_content_ok = 0; + +foreach my $entry (@$domains) { + # read fields (tolleranza nomi) + my $host = $entry->{host} // ''; + my $domain = $entry->{domain} // ''; + my $path = exists $entry->{path} ? $entry->{path} : ''; + my $word = $entry->{'word-to-check'} // ''; + my $basic_auth = $entry->{basic_auth} ? 1 : 0; + my $user = $entry->{basic_auth_name} // undef; + my $pass = $entry->{basic_auth_pass} // $entry->{basic_auth_password} // $entry->{basic_auth_passwd} // undef; + + # build url & ssl host + my $url = build_url($domain, $path); + my $ssl_host = normalize_host($domain) || $host || ''; + + # get cert info (openssl s_client) + my $ssl_info = get_cert_info_openssl($ssl_host, $timeout); + + # content check via LWP::UserAgent + my $word_ok = 0; + my $http_code = undef; + my $content_err = undef; + + # prepare request + my $req = HTTP::Request->new(GET => $url); + # add headers that often avoid 403 + $req->header('Accept-Language' => 'en-US,en;q=0.9'); + + if ($basic_auth && defined $user && defined $pass) { + my $b64 = encode_base64("$user:$pass", ''); + $req->header('Authorization' => "Basic $b64"); + } + + my $res = eval { $ua->request($req) }; + if ($@ or !defined $res) { + $content_err = $@ || 'request failed'; + $word_ok = 0; + } else { + $http_code = $res->code; + if ($res->is_success) { + my $body = $res->decoded_content(charset => 'none'); + $word_ok = (index($body, $word) >= 0) ? 1 : 0; + } else { + $content_err = "HTTP $http_code - " . ($res->message // ''); + $word_ok = 0; + } + } + + $total_ssl_ok++ if $ssl_info->{status} == 1; + $total_content_ok++ if $word_ok == 1; + $any_fail = 1 if ($ssl_info->{status} == 0 || $word_ok == 0); + + push @results, { + host => $host, + domain => $domain, + path => ($path eq '' ? '/' : $path), + wordtocheck => $word, + wordcheck_ok => $word_ok, + sslcheck_ok => $ssl_info->{status} // 0, + 'ssl-released' => $ssl_info->{issued}, + 'ssl-expiry' => $ssl_info->{expiry}, + 'ssl-company' => $ssl_info->{company}, + # debug fields + content_http_code => defined $http_code ? "$http_code" : undef, + content_error => $content_err, + ssl_error => $ssl_info->{error}, + }; +} + +# write output +open my $outfh, '>', $output_file or die "Cannot write $output_file: $!\n"; +print $outfh encode_json(\@results); +close $outfh; + +# manage sld-check-false.html +if ($any_fail) { + if (open my $fh, '>', $false_html) { + print $fh "

WARNING: some checks failed

\n"; + print $fh "

Generated by check_web_final.pl

\n"; + print $fh "\n"; + close $fh; + } else { + warn "Cannot write $false_html: $!\n"; + } +} else { + unlink $false_html if -f $false_html; +} + +# summary +print "Check completato. Risultati salvati in $output_file\n"; +print "Totali: SSL ok = $total_ssl_ok, Content ok = $total_content_ok\n"; + +exit 0; diff --git a/scripts-backup/generate-report.sh b/scripts-backup/generate-report.sh new file mode 100755 index 0000000..cd877e4 --- /dev/null +++ b/scripts-backup/generate-report.sh @@ -0,0 +1,63 @@ +#!/bin/bash +input="web_list.json" +output="web_check.json" +tmpfile=$(mktemp) + +jq -c '.[]' "$input" | while read -r entry; do + host=$(echo "$entry" | jq -r '.host') + domain=$(echo "$entry" | jq -r '.domain') + path=$(echo "$entry" | jq -r '.path') + word=$(echo "$entry" | jq -r '.["word-to-check"]') + basic_auth=$(echo "$entry" | jq -r '.basic_auth') + user=$(echo "$entry" | jq -r '.basic_auth_name // empty') + pass=$(echo "$entry" | jq -r '.basic_auth_pass // empty') + + [[ -z "$path" ]] && path="/" + + # --- SSL check --- + ssl_info=$(echo | openssl s_client -servername "$domain" -connect "$domain:443" 2>/dev/null | openssl x509 -noout -dates -issuer) + ssl_released=$(echo "$ssl_info" | grep 'notBefore' | cut -d= -f2) + ssl_expiry=$(echo "$ssl_info" | grep 'notAfter' | cut -d= -f2) + ssl_company=$(echo "$ssl_info" | grep 'issuer' | sed -n 's/.*O=\([^,]*\).*/\1/p') + ssl_ok=0 + if [[ $(date -d "$ssl_expiry" +%s) -gt $(date +%s) ]]; then ssl_ok=1; fi + + # --- Content check --- + url="https://$domain$path" + if [[ "$basic_auth" == "true" ]]; then + content=$(curl -s -u "$user:$pass" "$url") + else + content=$(curl -s "$url") + fi + word_ok=0 + [[ "$content" == *"$word"* ]] && word_ok=1 + + # --- Scrivi in tmp JSON --- + jq -n \ + --arg host "$host" \ + --arg domain "$domain" \ + --arg path "$path" \ + --arg word "$word" \ + --argjson wordcheck_ok "$word_ok" \ + --argjson sslcheck_ok "$ssl_ok" \ + --arg ssl_released "$ssl_released" \ + --arg ssl_expiry "$ssl_expiry" \ + --arg ssl_company "$ssl_company" \ + '{ + host: $host, + domain: $domain, + path: $path, + wordtocheck: $word, + wordcheck_ok: $wordcheck_ok, + sslcheck_ok: $sslcheck_ok, + "ssl-released": $ssl_released, + "ssl-expiry": $ssl_expiry, + "ssl-company": $ssl_company + }' >> "$tmpfile" +done + +# --- Combina in array JSON --- +jq -s '.' "$tmpfile" > "$output" +rm "$tmpfile" + +echo "Check completato. Output salvato in $output" diff --git a/template/footer.php b/template/footer.php index 9b927a6..a26585a 100644 --- a/template/footer.php +++ b/template/footer.php @@ -16,6 +16,13 @@ \ No newline at end of file diff --git a/template/header.php b/template/header.php index b2914fe..e657986 100644 --- a/template/header.php +++ b/template/header.php @@ -14,4 +14,4 @@

SLD WEB HEALTH CHECK

-
\ No newline at end of file +
\ No newline at end of file diff --git a/web_check.json b/web_check.json index e2fa405..db2cbb2 100644 --- a/web_check.json +++ b/web_check.json @@ -1,52 +1,44 @@ [ - { - "host" : "sld-gw", - "domain" : "sld-server.org", - "wordtocheck" : "proxmox", - "wordcheck_ok" : 1, - "sslcheck_ok" : 1, - "ssl-released" : "10/01/2025", - "ssl-expiry" : "13/03/2025", - "ssl-company" : "Let's Encrypt" - }, - { - "host" : "sld-nextcloud", - "domain" : "nextcloud.sld-server.org", - "wordtocheck" : "login", - "wordcheck_ok" : 1, - "sslcheck_ok" : 1, - "ssl-released" : "10/01/2025", - "ssl-expiry" : "13/03/2025", - "ssl-company" : "Let's Encrypt" - }, - { - "host" : "sld-app-a", - "domain" : "wiki.sld-app-a", - "wordtocheck" : "welcome", - "wordcheck_ok" : 1, - "sslcheck_ok" : 1, - "ssl-released" : "10/01/2025", - "ssl-expiry" : "13/03/2025", - "ssl-company" : "Let's Encrypt" - }, - { - "host" : "sld-app-a", - "domain" : "sld-server.org", - "wordtocheck" : "proxmox", - "wordcheck_ok" : 0, - "sslcheck_ok" : 0, - "ssl-released" : "10/01/2025", - "ssl-expiry" : "13/03/2025", - "ssl-company" : "Let's Encrypt" - }, - { - "host" : "sld-test", - "domain" : "test.org", - "wordtocheck" : "test", - "wordcheck_ok" : 1, - "sslcheck_ok" : 0, - "ssl-released" : "10/01/2025", - "ssl-expiry" : "13/03/2025", - "ssl-company" : "Let's Encrypt" - } + { + "host": "sld-app-a", + "domain": "sld-server.org", + "path": "", + "wordtocheck": "proxmox", + "wordcheck_ok": 1, + "sslcheck_ok": 1, + "ssl-released": "24/12/2025", + "ssl-expiry": "24/03/2026", + "ssl-company": "Cloudflare TLS Issuing ECC CA 3", + "content_http_code": 200, + "content_error": null, + "ssl_error": null + }, + { + "host": "sld-nextcloud", + "domain": "nextcloud.sld-server.org", + "path": "/index.php/login", + "wordtocheck": "nextcloud", + "wordcheck_ok": 1, + "sslcheck_ok": 1, + "ssl-released": "24/12/2025", + "ssl-expiry": "24/03/2026", + "ssl-company": "Cloudflare TLS Issuing ECC CA 3", + "content_http_code": 200, + "content_error": null, + "ssl_error": null + }, + { + "host": "sld-app-a", + "domain": "wiki.sld-server.org", + "path": "/doku.php?id=start", + "wordtocheck": "Benvenuto", + "wordcheck_ok": 1, + "sslcheck_ok": 1, + "ssl-released": "24/12/2025", + "ssl-expiry": "24/03/2026", + "ssl-company": "Cloudflare TLS Issuing ECC CA 3", + "content_http_code": 200, + "content_error": null, + "ssl_error": null + } ] \ No newline at end of file diff --git a/web_check_backup.json b/web_check_backup.json new file mode 100644 index 0000000..e2fa405 --- /dev/null +++ b/web_check_backup.json @@ -0,0 +1,52 @@ +[ + { + "host" : "sld-gw", + "domain" : "sld-server.org", + "wordtocheck" : "proxmox", + "wordcheck_ok" : 1, + "sslcheck_ok" : 1, + "ssl-released" : "10/01/2025", + "ssl-expiry" : "13/03/2025", + "ssl-company" : "Let's Encrypt" + }, + { + "host" : "sld-nextcloud", + "domain" : "nextcloud.sld-server.org", + "wordtocheck" : "login", + "wordcheck_ok" : 1, + "sslcheck_ok" : 1, + "ssl-released" : "10/01/2025", + "ssl-expiry" : "13/03/2025", + "ssl-company" : "Let's Encrypt" + }, + { + "host" : "sld-app-a", + "domain" : "wiki.sld-app-a", + "wordtocheck" : "welcome", + "wordcheck_ok" : 1, + "sslcheck_ok" : 1, + "ssl-released" : "10/01/2025", + "ssl-expiry" : "13/03/2025", + "ssl-company" : "Let's Encrypt" + }, + { + "host" : "sld-app-a", + "domain" : "sld-server.org", + "wordtocheck" : "proxmox", + "wordcheck_ok" : 0, + "sslcheck_ok" : 0, + "ssl-released" : "10/01/2025", + "ssl-expiry" : "13/03/2025", + "ssl-company" : "Let's Encrypt" + }, + { + "host" : "sld-test", + "domain" : "test.org", + "wordtocheck" : "test", + "wordcheck_ok" : 1, + "sslcheck_ok" : 0, + "ssl-released" : "10/01/2025", + "ssl-expiry" : "13/03/2025", + "ssl-company" : "Let's Encrypt" + } +] \ No newline at end of file diff --git a/web_list.json b/web_list.json index a3eda6b..8afe606 100644 --- a/web_list.json +++ b/web_list.json @@ -1,10 +1,29 @@ [ - [ - "host", - "domain", - "word-to-check", - true, - "basic_auth_name", - "basic_auth_password" - ] + { + "host":"sld-app-a", + "domain":"sld-server.org", + "path":"", + "word-to-check":"proxmox", + "basic_auth":false, + "basic_auth_name":"basic_auth_name", + "basic_auth_password":"basic_auth_pass" + }, + { + "host":"sld-nextcloud", + "domain":"nextcloud.sld-server.org", + "path":"/index.php/login", + "word-to-check":"nextcloud", + "basic_auth":false, + "basic_auth_name":"basic_auth_name", + "basic_auth_pass":"basic_auth_pass" + }, + { + "host":"sld-app-a", + "domain":"wiki.sld-server.org", + "path":"/doku.php?id=start", + "word-to-check":"Benvenuto", + "basic_auth":true, + "basic_auth_name":"sld-admin", + "basic_auth_pass":"Angela" + } ] \ No newline at end of file