# BEGIN Security - Shared rules for all sites # Last updated: 2026-05-22 # Block known attacker ranges (VPS/hosting providers used for brute force) RewriteEngine On # FranTech / PonyNET / BuyVM RewriteCond %{REMOTE_ADDR} ^107\.189\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^209\.141\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^104\.244\.73\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^198\.98\. RewriteRule .* - [F,L] # WatchComm / FNI RewriteCond %{REMOTE_ADDR} ^205\.185\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^45\.61\.18[4-8]\. RewriteRule .* - [F,L] # AltunHOST / hosting providers RewriteCond %{REMOTE_ADDR} ^5\.83\.135\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^192\.109\.200\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^103\.60\.12\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^185\.198\.240\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^173\.239\.240\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^104\.234\.53\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^104\.238\.222\. RewriteRule .* - [F,L] # TECHOFF SRV LIMITED (scraper) RewriteCond %{REMOTE_ADDR} ^195\.178\.110\. RewriteRule .* - [F,L] # Brute force attackers (May 11) RewriteCond %{REMOTE_ADDR} ^103\.59\.161\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^185\.153\.151\. RewriteRule .* - [F,L] # F.N.S. HOLDINGS LIMITED RewriteCond %{REMOTE_ADDR} ^216\.73\.160\. RewriteRule .* - [F,L] # DigitalOcean brute force RewriteCond %{REMOTE_ADDR} ^143\.198\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^146\.190\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^142\.93\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^170\.64\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^134\.209\. RewriteRule .* - [F,L] # Cipher Operations (Serbia) RewriteCond %{REMOTE_ADDR} ^62\.60\.130\. RewriteRule .* - [F,L] # UK Dedicated Servers RewriteCond %{REMOTE_ADDR} ^185\.192\.7[0-1]\. RewriteRule .* - [F,L] # GSL Networks RewriteCond %{REMOTE_ADDR} ^85\.203\.2[1-3]\. RewriteRule .* - [F,L] # Argon Data Communication RewriteCond %{REMOTE_ADDR} ^157\.66\.56\. RewriteRule .* - [F,L] # Pfcloud UG RewriteCond %{REMOTE_ADDR} ^217\.60\.241\. RewriteRule .* - [F,L] # Omegatech LTD RewriteCond %{REMOTE_ADDR} ^158\.94\.210\. RewriteRule .* - [F,L] # Individual attackers RewriteCond %{REMOTE_ADDR} ^94\.26\.106\.111$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^176\.65\.132\.166$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^37\.120\.217\.182$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^8\.210\.170\.233$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^120\.24\.67\.156$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^140\.245\.111\.5$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^20\.9\.82\.33$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^45\.156\.87\.222$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^31\.57\.184\.107$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^92\.205\.109\.21$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^72\.167\.150\.128$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^165\.154\.38\.157$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^50\.6\.207\.27$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^141\.98\.11\.117$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^136\.243\.176\.166$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^123\.30\.233\.1[2-3]$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^91\.227\.37\.60$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^78\.142\.18\.172$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^66\.116\.235\.214$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^149\.88\.110\.49$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^35\.227\.109\.86$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^103\.253\.27\.44$ RewriteRule .* - [F,L] # Contabo (individual IP) RewriteCond %{REMOTE_ADDR} ^85\.239\.235\.108$ RewriteRule .* - [F,L] # xmlrpc + brute force attackers (May 22) RewriteCond %{REMOTE_ADDR} ^105\.184\.79\.191$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^45\.94\.31\.119$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^138\.2\.98\.238$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^20\.89\.64\.143$ RewriteRule .* - [F,L] # Vulnerability scanners (May 22-23) RewriteCond %{REMOTE_ADDR} ^143\.92\.32\.30$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^194\.26\.192\.219$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^38\.99\.81\.38$ RewriteRule .* - [F,L] # Massive brute force (May 23) RewriteCond %{REMOTE_ADDR} ^193\.26\.115\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^51\.79\.177\.162$ RewriteRule .* - [F,L] # ALFA shell scanners / 2ipcore crawler RewriteCond %{REMOTE_ADDR} ^185\.213\.154\.185$ RewriteRule .* - [F,L] # Vulnerability scanners (May 23 evening) # Microsoft Azure — shell/backdoor scanner RewriteCond %{REMOTE_ADDR} ^20\.151\.117\.104$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^4\.228\.100\.214$ RewriteRule .* - [F,L] # 2ipcore ALFA shell scanners (expand to /24) RewriteCond %{REMOTE_ADDR} ^2\.58\.56\. RewriteRule .* - [F,L] # DigitalOcean scanners RewriteCond %{REMOTE_ADDR} ^157\.230\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^139\.59\. RewriteRule .* - [F,L] # Directory enumeration scanner RewriteCond %{REMOTE_ADDR} ^91\.199\.118\.57$ RewriteRule .* - [F,L] # ALFA shell scanners (expand to /24) RewriteCond %{REMOTE_ADDR} ^45\.92\.1\. RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^45\.154\.98\. RewriteRule .* - [F,L] # Google Cloud spammer RewriteCond %{REMOTE_ADDR} ^34\.42\.34\.237$ RewriteRule .* - [F,L] # Azure vulnerability scanners (May 24) RewriteCond %{REMOTE_ADDR} ^20\.48\.233\.234$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^20\.63\.100\.211$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^20\.226\.23\.23$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^20\.9\.81\.163$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^20\.63\.46\.176$ RewriteRule .* - [F,L] # Persistent brute force (Hetzner) RewriteCond %{REMOTE_ADDR} ^168\.119\.26\.89$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^173\.249\.4\.57$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^216\.251\.35\.201$ RewriteRule .* - [F,L] # File enumeration scanner (May 25) RewriteCond %{REMOTE_ADDR} ^158\.158\.44\.35$ RewriteRule .* - [F,L] # Reconnaissance bots / Tor (May 25) RewriteCond %{REMOTE_ADDR} ^149\.102\.230\.133$ RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^82\.102\.18\.116$ RewriteRule .* - [F,L] # Directory scanner (May 25) RewriteCond %{REMOTE_ADDR} ^195\.3\.220\.7$ RewriteRule .* - [F,L] # Azure shell scanner (May 25) RewriteCond %{REMOTE_ADDR} ^20\.226\.59\.228$ RewriteRule .* - [F,L] # WP installer scanner (May 26) RewriteCond %{REMOTE_ADDR} ^194\.26\.192\.75$ RewriteRule .* - [F,L] # Azure webshell scanner (May 26) RewriteCond %{REMOTE_ADDR} ^104\.43\.242\.179$ RewriteRule .* - [F,L] # Block non-existent plugin/theme probes (saves PHP workers) RewriteRule ^ALFA_DATA/ - [F,L] RewriteRule ^alfacgiapi/ - [F,L] # Block xmlrpc.php Require all denied # END Security # --- Security headers --- Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "DENY" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()" Header always set Cross-Origin-Opener-Policy "same-origin" Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # CSP en observation (ne bloque rien pour l'instant) # --- CSP (global) : autorise Matomo + CDNs --- Header always set Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data: https: https://staging.uslugi.fr/matomo/; script-src 'self' 'unsafe-inline' https://staging.uslugi.fr/matomo/ https://cdn.jsdelivr.net https://www.googletagmanager.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https:; frame-ancestors 'none'" # Reduce attack surface Options -Indexes -MultiViews # --- Rewrite & HTTPS --- RewriteEngine On # Force HTTPS (behind proxy/Varnish) RewriteCond %{HTTPS} !=on RewriteCond %{HTTP:X-Forwarded-Proto} !https RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] # Let's Encrypt RewriteRule ^\.well-known/acme-challenge/ - [L] # --- Sensitive paths & files --- # Block VCS RewriteRule ^(\.git|\.svn|\.hg)(/|$) - [F] # Block dotfiles (except .well-known) RewriteRule ^\.(?!well-known/) - [F] # Block sensitive extensions RewriteRule \.(env|ini|log|bak|old|sql|zip|tar|gz|7z)$ - [F] # Block backup files *~ RewriteRule ^(.*/)?[^/]+~$ - [F] # Block specific filenames Require all denied # No scripts in /uploads RewriteRule ^(?:public/)?uploads/.*\.(php|phtml|phar|phps|cgi|pl|py|sh|rb)$ - [F,NC] # --- Application routing --- # 0) Serve existing files/dirs RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] # 1) Normalize trailing slash (except /) RewriteCond %{REQUEST_URI} !^/$ RewriteCond %{REQUEST_URI} (.+)/$ RewriteRule ^ %1 [R=301,L] # 2) Clean URLs -> router.php RewriteRule ^([^.]+)$ router.php?slug=$1 [L,QSA] # 2bis) Unknown PHP files => 404 RewriteCond %{REQUEST_URI} \.php$ [NC] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ - [R=404,L] # 3) General fallback RewriteRule ^ index.php [L,QSA] # --- PWA / Types & SW cache --- AddType application/manifest+json .webmanifest Header set Cache-Control "no-cache, no-store, must-revalidate" Header set Pragma "no-cache" Header set Expires "0" # Visio-specific headers for /visio/join.php SetEnvIf Request_URI "^/visio/join\.php$" IS_VISIO=1 Header always unset Permissions-Policy env=IS_VISIO Header always unset Feature-Policy env=IS_VISIO Header always set Permissions-Policy "camera=(self 'https://meet.uslugi.fr'), microphone=(self 'https://meet.uslugi.fr'), display-capture=(self 'https://meet.uslugi.fr'), fullscreen=(self 'https://meet.uslugi.fr')" env=IS_VISIO Header always set Feature-Policy "camera 'self' https://meet.uslugi.fr; microphone 'self' https://meet.uslugi.fr" env=IS_VISIO Header always set Content-Security-Policy "default-src 'self'; frame-src https://meet.uslugi.fr; script-src 'self' 'unsafe-inline' https://meet.uslugi.fr; connect-src 'self' https://meet.uslugi.fr wss://meet.uslugi.fr; img-src 'self' data: https://meet.uslugi.fr; style-src 'self' 'unsafe-inline' https://meet.uslugi.fr" env=IS_VISIO DirectoryIndex index.php index.html