$l,'msg'=>$m,'ts'=>date('c')];lg("[$l] $m");} function fx($t){global $fixes;$fixes[]=['title'=>$t,'ts'=>date('c')];lg("[FIX] $t");} // 1. OUTPOST $c=@fsockopen('127.0.0.1',9090,$e,$er,3); if($c){fclose($c);$checks['outpost']='UP';} else{al('critical','Outpost DOWN 9090');$checks['outpost']='DOWN'; shell_exec("docker restart authentik-server authentik-worker 2>/dev/null");fx('Restart authentik'); sleep(5);$c2=@fsockopen('127.0.0.1',9090,$e,$er,3); if($c2){fclose($c2);$checks['outpost']='RECOVERED';fx('Outpost recovered');} else{al('critical','Outpost STILL DOWN');}} // 2. AUTH FLOW $doms=['weval-consulting.com','monitor.weval-consulting.com','wevads.weval-consulting.com', 'ethica.weval-consulting.com','n8n.weval-consulting.com','crm.weval-consulting.com', 'mm.weval-consulting.com','analytics.weval-consulting.com','deerflow.weval-consulting.com']; $ok=0;$fail=0; foreach($doms as $d){ $ch=curl_init("https://$d/"); curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>1,CURLOPT_NOBODY=>1,CURLOPT_TIMEOUT=>5,CURLOPT_SSL_VERIFYPEER=>0,CURLOPT_FOLLOWLOCATION=>0]); curl_exec($ch);$code=curl_getinfo($ch,CURLINFO_HTTP_CODE);$loc=curl_getinfo($ch,CURLINFO_REDIRECT_URL);curl_close($ch); if($d==='weval-consulting.com'){if($code==200){$ok++;$checks["flow:$d"]='OK';}else{$fail++;al('warning',"Main $d: $code");$checks["flow:$d"]="FAIL:$code";}} else{if($code==302){$ok++;$checks["flow:$d"]='OK';} else{$fail++;al('warning',"Auth flow $d: $code");$checks["flow:$d"]="FAIL:$code";}}} // 3. CALLBACK CONFIG $nx=@file_get_contents('/etc/nginx/sites-enabled/weval-consulting'); if($nx){ $hcb=strpos($nx,'outpost.goauthentik.io/callback')!==false; $checks['callback_location']=$hcb?'OK':'MISSING'; if(!$hcb){al('warning','Callback location missing in nginx'); $old=' location /outpost.goauthentik.io {'; $new=" location /outpost.goauthentik.io/callback { proxy_pass http://127.0.0.1:9090/outpost.goauthentik.io/callback; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Host \$host; proxy_set_header X-Forwarded-Proto https; } location /outpost.goauthentik.io {"; shell_exec("chattr -i /etc/nginx/sites-enabled/weval-consulting 2>/dev/null"); $nx=str_replace($old,$new,$nx);file_put_contents('/etc/nginx/sites-enabled/weval-consulting',$nx); shell_exec("chattr +i /etc/nginx/sites-enabled/weval-consulting 2>/dev/null"); $t=shell_exec("nginx -t 2>&1");if(strpos($t,'successful')!==false){shell_exec("systemctl reload nginx");fx('Callback location auto-added');}}} // 4. COOKIE DOMAIN $pg=@pg_connect("host=127.0.0.1 port=5434 dbname=authentik user=authentik password=authentik_pg_2026"); if($pg){$r=pg_query($pg,"SELECT oauth2provider_ptr_id,cookie_domain,mode FROM authentik_providers_proxy_proxyprovider WHERE mode='forward_domain'"); while($row=pg_fetch_assoc($r)){$cd=$row['cookie_domain'];$checks['cookie_domain']=$cd; if($cd!=='.weval-consulting.com'){al('warning',"Cookie domain=$cd should be .weval-consulting.com"); pg_query($pg,"UPDATE authentik_providers_proxy_proxyprovider SET cookie_domain='.weval-consulting.com' WHERE oauth2provider_ptr_id=".$row['oauth2provider_ptr_id']);fx('Cookie domain fixed');}}pg_close($pg);} // 5. SSL foreach(['weval-consulting.com','auth.weval-consulting.com'] as $d){ $exp=trim(shell_exec("echo|timeout 3 openssl s_client -connect $d:443 -servername $d 2>/dev/null|openssl x509 -noout -enddate 2>/dev/null|cut -d= -f2")); $days=$exp?(int)((strtotime($exp)-time())/86400):-1;$checks["ssl:$d"]="{$days}d"; if($days>=0&&$days<3){al('critical',"SSL $d expires in {$days}d");fx('SSL renewal triggered');}} // 6. CONTAINERS foreach(['authentik-server','authentik-worker','authentik-db','authentik-redis'] as $cn){ $st=trim(shell_exec("docker inspect --format='{{.State.Status}}' $cn 2>/dev/null"));$checks["docker:$cn"]=$st?:'NOT_FOUND'; if($st&&$st!=='running'){al('warning',"$cn is $st");shell_exec("docker restart $cn 2>/dev/null");fx("Restart $cn");}} // 7. PORTS $ports=explode(" ",trim(shell_exec("ss -tlnp|grep -oP ':\K[0-9]+'|sort -nu|tr '\n' ' '"))); $checks['open_ports']=count($ports); // 8. NGINX OK $t=trim(shell_exec("nginx -t 2>&1"));$checks['nginx']=strpos($t,'successful')!==false?'OK':'ERROR'; // SAVE $status=['timestamp'=>date('Y-m-d H:i:s'),'healthy'=>empty($alerts),'checks'=>$checks, 'flow_ok'=>$ok,'flow_fail'=>$fail,'alerts_count'=>count($alerts),'fixes_count'=>count($fixes), 'alerts'=>$alerts,'fixes'=>$fixes]; file_put_contents($SF,json_encode($status,JSON_PRETTY_PRINT)); // EMAIL $crit=array_filter($alerts,fn($a)=>$a['level']==='critical'); if(!empty($crit)){$b="WEVIA AUTH AGENT - ".date('Y-m-d H:i')." "; foreach($alerts as $a)$b.="[{$a['level']}] {$a['msg']} "; @mail('ymahboub@weval-consulting.com','[WEVIA AUTH] '.$crit[0]['msg'],$b,"From: wevia@weval-consulting.com");} lg("Auth:$ok/".($ok+$fail)." Out:{$checks['outpost']} A:".count($alerts)." F:".count($fixes)); echo "$ts Auth:$ok/".($ok+$fail)." Out:{$checks['outpost']} A:".count($alerts)." F:".count($fixes)." ";