86400,"path"=>"/","domain"=>".weval-consulting.com","secure"=>true,"httponly"=>true,"samesite"=>"Lax"]);
session_start();
require_once __DIR__ . '/authentik-trust.php'; // SSO gate
$VALID_USERS=['weval'=>"REDACTED_PWD",'yacine'=>"REDACTED_PWD",'admin'=>"REDACTED_PWD"];
if(isset($_POST['logout'])){session_destroy();header('Location:'.$_SERVER['PHP_SELF']);exit;}
if(isset($_POST['login_user'])){$lu=strtolower(trim($_POST['login_user']));if(isset($VALID_USERS[$lu])&&$_POST['login_pass']===$VALID_USERS[$lu]){$_SESSION['sess_auth']=true;$_SESSION['sess_ts']=time();session_regenerate_id(true);}else{$loginErr='Identifiants incorrects';}}
if(isset($_SESSION['sess_ts'])&&time()-$_SESSION['sess_ts']>14400){session_destroy();header('Location:'.$_SERVER['PHP_SELF']);exit;}
// ACTIONS (POST)
$actionMsg='';
if(!empty($_SESSION['sess_auth'])&&$_SERVER['REQUEST_METHOD']==='POST'){
$act=$_POST['action']??'';
$ip=$_POST['target_ip']??'';
if($act==='blacklist'&&$ip&&filter_var($ip,FILTER_VALIDATE_IP)){
// Add to CrowdSec ban list
$r=shell_exec("sudo cscli decisions add --ip ".escapeshellarg($ip)." --duration 24h --reason 'Manual ban from Sessions Monitor' --type ban 2>&1");
$actionMsg="🚫 IP $ip blacklistée 24h via CrowdSec";
}
if($act==='eject'&&$ip&&filter_var($ip,FILTER_VALIDATE_IP)){
// Drop connections with iptables temporary (5 min)
shell_exec("sudo iptables -I INPUT -s ".escapeshellarg($ip)." -j DROP 2>/dev/null");
shell_exec("(sleep 300 && sudo iptables -D INPUT -s ".escapeshellarg($ip)." -j DROP 2>/dev/null) &");
$actionMsg="⚡ IP $ip éjectée 5 min (iptables)";
}
if($act==='unban'&&$ip){
shell_exec("sudo cscli decisions delete --ip ".escapeshellarg($ip)." 2>&1");
$actionMsg="✅ IP $ip débloquée";
}
}
if(empty($_SESSION['sess_auth'])):
?>
WEVAL Sessions Monitor
'Local','code'=>'lo','city'=>'Serveur'];
$ch=curl_init("http://ip-api.com/json/$ip?fields=status,country,countryCode,city");curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>2,CURLOPT_CONNECTTIMEOUT=>1]);$r=curl_exec($ch);curl_close($ch);
if($r){$d=json_decode($r,true);if(($d['status']??'')==='success')return $geoCache[$ip]=['country'=>$d['country']??'?','code'=>strtolower($d['countryCode']??'xx'),'city'=>$d['city']??''];}
return $geoCache[$ip]=['country'=>'Inconnu','code'=>'xx','city'=>''];
}
function getFlag($code){
if($code==='lo')return '🖥️';if($code==='xx'||!$code)return '🌍';
return implode('',array_map(fn($c)=>mb_chr(ord($c)-ord('A')+0x1F1E6),str_split(strtoupper($code))));
}
// Parse nginx log
function parseLog($file,$minutes=10){
$visitors=[];$cutoff=time()-($minutes*60);
if(!file_exists($file))return $visitors;
$fp=@fopen($file,'r');if(!$fp)return $visitors;
fseek($fp,-min(filesize($file),500000),SEEK_END);fgets($fp);
while(!feof($fp)){
$line=fgets($fp);
if(preg_match('/^(\S+) \S+ \S+ \[([^\]]+)\] "(\S+) ([^"]+)" (\d+) \S+ "([^"]*)" "([^"]*)"/',$line,$m)){
$ip=$m[1];
// Cloudflare IPs: extract real IP from X-Forwarded-For if logged
if(preg_match('/^(162\.158\.|172\.(68|69|70|71)\.|173\.245\.|103\.21\.|103\.22\.|103\.31\.|104\.(16|17|18|19|20|21|22|23|24|25)\.|108\.162\.|131\.0\.72\.|141\.101\.|190\.93\.|197\.234\.|198\.41\.)/',$ip)){$ip=$ip." (CF)";}$path=preg_replace('/\?.*$/','',$m[4]);$ua=$m[7];$code=$m[5];
$date=DateTime::createFromFormat('d/M/Y:H:i:s O',$m[2]);
if(!$date||$date->getTimestamp()<$cutoff)continue;
if(preg_match('/\.(css|js|png|jpg|gif|ico|woff|svg|map|ttf|woff2)$/i',$path))continue;
if(!isset($visitors[$ip]))$visitors[$ip]=['ip'=>$ip,'hits'=>0,'last_path'=>'','last_ts'=>0,'ua'=>'','code'=>$code,'paths'=>[]];
$visitors[$ip]['hits']++;
if($date->getTimestamp()>$visitors[$ip]['last_ts']){$visitors[$ip]['last_path']=$path;$visitors[$ip]['last_ts']=$date->getTimestamp();$visitors[$ip]['ua']=substr($ua,0,60);$visitors[$ip]['code']=$code;}
}
}
fclose($fp);return $visitors;
}
$s204_visitors=parseLog('/var/log/nginx/access.log',10);
// Enrich with geo
foreach($s204_visitors as &$v){$geo=getGeo($v['ip']);$v['country']=$geo['country'];$v['code']=$geo['code'];$v['city']=$geo['city'];}unset($v);
$s204_fpm=trim(shell_exec('ps aux|grep php-fpm|grep -v grep|wc -l'));
$s204_docker_count=trim(shell_exec('sudo docker ps -q 2>/dev/null|wc -l'));
$s204_ssh=trim(shell_exec('who 2>/dev/null'));
$s204_ollama_ps=trim(shell_exec('sudo ollama ps 2>/dev/null'));
// CrowdSec bans
$cs_bans=trim(shell_exec('sudo cscli decisions list -o raw 2>/dev/null|tail -n+2|wc -l'));
$cs_list=trim(shell_exec('sudo cscli decisions list --limit 10 -o raw 2>/dev/null|tail -n+2'));
// S95 via sentinel
function sentinelCmd($cmd,$t=5){$ch=curl_init('http://10.1.0.3:5890/api/sentinel-brain.php?action=exec&cmd='.urlencode($cmd));curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>$t]);$r=curl_exec($ch);curl_close($ch);$d=json_decode($r,true);return $d['output']??'';}
$s95_raw=sentinelCmd('echo "A:$(ss -tnp 2>/dev/null|grep -c :5890)|PG:$(PGPASSWORD=admin123 psql -U admin -d adx_system -t -c \"SELECT count(*) FROM pg_stat_activity WHERE state=\'active\'\" 2>/dev/null|tr -d \" \")|SSH:$(who 2>/dev/null|wc -l)|CR:$(crontab -l 2>/dev/null|grep -v \"^#\"|grep -v \"^$\"|wc -l)"',6);
$s95=[];foreach(explode('|',$s95_raw) as $kv){$p=explode(':',$kv,2);if(count($p)==2)$s95[trim($p[0])]=trim($p[1]);}
$s95_tops=sentinelCmd('tail -500 /var/log/apache2/wevads_access.log 2>/dev/null|awk "{print \$1}"|sort|uniq -c|sort -rn|head -8',5);
$s151c=@file_get_contents('https://consent.wevup.app',false,stream_context_create(['http'=>['timeout'=>3]]))!==false;
$s151t=@file_get_contents('https://track.wevup.app',false,stream_context_create(['http'=>['timeout'=>3]]))!==false;
$total_http=count($s204_visitors);
?>
WEVAL Sessions Monitor
👁️ WEVAL Sessions Monitor v2
=$ts?> — 30s
=$actionMsg?>
=$total_http?>HTTP IPs (S204)
=$s204_fpm?>FPM Workers
=$s204_docker_count?>Docker
=intval($s95['A']??0)?>Apache S95
=intval($s95['PG']??0)?>PG Active
=intval($s95['CR']??0)?>Crons S95
=$cs_bans?>CrowdSec Bans
=$s151c&&$s151t?'UP':'❌'?>S151 DR
🌐 S204 — Visiteurs HTTP (=$total_http?> IPs, 10 min)
| IP / Pays | Ville | Server | Hits | Dernière page | Code | User-Agent | Activité | Actions |
$b['hits']-$a['hits']);
foreach(array_slice($s204_visitors,0,40) as $v):
$ago=time()-$v['last_ts'];$agoStr=$ago<60?$ago.'s':round($ago/60).'m';
$isLocal=$v['code']==='lo';
$isSuspect=$v['hits']>50&&!$isLocal;
?>
>
=getFlag($v['code'])?> =htmlspecialchars($v['ip'])?> =htmlspecialchars($v['country'])?> |
=htmlspecialchars($v['city'])?> |
=$isLocal?'LOCAL':'S204'?> |
=$v['hits']?> |
=htmlspecialchars($v['last_path'])?> |
=$v['code']?> |
=htmlspecialchars($v['ua'])?> |
il y a =$agoStr?> |
|
0):?>
🛡️ CrowdSec — IPs bannies (=$cs_bans?>)
| IP | Durée | Raison | Action |
| =htmlspecialchars($bip)?> | =htmlspecialchars($p[5]??'')?> | =htmlspecialchars(substr($p[6]??'',0,30))?> |
|
⚡ S95 — Top IPs Apache
| Hits | IP | Pays/Ville | Server |
| =htmlspecialchars($p[0])?> | =getFlag($geo['code'])?> =htmlspecialchars($sip)?> | =htmlspecialchars($geo['city'])?>, =htmlspecialchars($geo['country'])?> | S95 |
Pas de données Apache récentes
🔑 SSH S204
=htmlspecialchars($s204_ssh?:'Aucune session')?>
🧠 Ollama RAM
=htmlspecialchars($s204_ollama_ps?:'Aucun modèle chargé')?>
💻 Blade
ssh -p 49222 root@204.168.152.13 S204
ssh root@95.216.167.89 S95
ssh ubuntu@151.80.235.110 S151