Files
html/api/port-protection.php
2026-04-16 02:28:32 +02:00

33 lines
1.7 KiB
PHP

<?php
header('Content-Type: application/json');
$start=microtime(true);
$PORT_MAP=[80=>'nginx',443=>'nginx-ssl',2024=>'DeerFlow',2026=>'DeerFlow-UI',3088=>'Kuma',3100=>'Langfuse',3200=>'Paperclip',3900=>'GPT-Runner',5001=>'MiroFish',5432=>'PostgreSQL',5678=>'n8n',6333=>'Qdrant',8000=>'Plausible',8065=>'Mattermost',8080=>'SearXNG',8222=>'Vaultwarden',11434=>'Ollama'];
$SACRED=[80,443,5432,11434,49222];
$NGINX=['paperclip.weval-consulting.com'=>3200,'langfuse.weval-consulting.com'=>3100];
$pass=$fail=0;$conflicts=[];$checks=[];
foreach($PORT_MAP as $port=>$svc){
$up=!empty(trim(shell_exec("ss -tlnp sport = :$port 2>/dev/null|grep LISTEN")));
if($up){$pass++;$checks[]=['port'=>$port,'svc'=>$svc,'s'=>'UP'];}
else{
if(in_array($port,$SACRED)){$fail++;$conflicts[]="SACRED :$port ($svc) DOWN";}
$checks[]=['port'=>$port,'svc'=>$svc,'s'=>'DOWN'];
}
}
foreach($NGINX as $dom=>$exp){
$cf="/etc/nginx/sites-enabled/$dom";
if(file_exists($cf)){
$c=file_get_contents($cf);
if(preg_match('/proxy_pass\s+https?:\/\/.*?:(\d+)\s*;/',$c,$m)){
$act=(int)$m[1];
if($act!==$exp){$fail++;$conflicts[]="NGINX $dom -> :$act should be :$exp";}
else{$pass++;}
}
}
}
if(count($conflicts)>0){
$msg="PORT PROTECTION: ".implode(", ",$conflicts);
@file_get_contents("https://api.telegram.org/bot8544624912/sendMessage?chat_id=7605775322&text=".urlencode($msg));
}
$total=$pass+$fail;
echo json_encode(['score'=>$total>0?round($pass/$total*100,1):0,'pass'=>$pass,'fail'=>$fail,'ports'=>count($PORT_MAP),'conflicts'=>$conflicts,'checks'=>$checks,'elapsed_ms'=>round((microtime(true)-$start)*1000),'rule'=>'EACH APP = 1 PORT. NEVER REUSE.'],JSON_PRETTY_PRINT);