# Secure By Rayor — secure.rayor.fr > Base de réputation d'adresses IP, libre et française. Alternative gratuite à AbuseIPDB : > score de confiance d'abus 0–100 par IP, blocklists téléchargeables (texte / CSV / JSON), > API JSON publique, signalement communautaire adossé aux comptes Rayor Connect. > Ce fichier est un guide d'INSTALLATION : il donne tout ce qu'il faut pour brancher > Secure By Rayor sur un serveur, un pare-feu ou une application, sans lire le site. Toutes les URL sont sur `https://secure.rayor.fr`. Tout ce qui est décrit ici est gratuit. Aucune inscription n'est nécessaire pour LIRE (feeds + API en lecture) ; un compte gratuit (Rayor Connect) est nécessaire pour SIGNALER et pour lever les quotas de lecture. ## Modèle de données - `abuseConfidenceScore` : 0 à 100. **≥ 75 = malveillante** (présente dans les blocklists), **≥ 25 = suspecte**, `whitelisted` = jamais publiée ni bloquée. - Le score décroît avec le temps (demi-vie des signalements : 45 jours) : une IP qui cesse d'attaquer redescend toute seule. Ne mettez donc jamais en cache un verdict plus de 24 h. - Les IP privées/réservées (RFC 1918/4193…) ne sont ni suivies ni renvoyées (HTTP 422). ## Choisir son mode d'intégration | Besoin | Solution | Compte requis | |---|---|---| | Bloquer au pare-feu, en masse | Feeds statiques `/feeds/*.txt` | non | | Vérifier une IP à la volée dans une app | `GET /api/v2/check` avec clé | oui (gratuit) | | Vérifier ponctuellement, dépannage | `GET /api/v2/check` sans clé (1 req/min/IP) | non | | Alimenter la base depuis fail2ban/WAF | `POST /api/v2/report` | oui | | Liste filtrée à la demande | `GET /api/v2/blacklist` | recommandé | Règle d'or : **pour du volume, utilisez les feeds** (fichiers statiques, aucun quota) ; l'API `check` sert au cas par cas. ## 1. Feeds — blocklists prêtes à l'emploi Régénérées automatiquement (~toutes les 15 min). Format texte = 1 IP par ligne, 3 lignes de commentaire `#` en tête, prêtes pour ipset / iptables / fail2ban / pfSense. - `https://secure.rayor.fr/feeds/blocklist.txt` — score ≥ 75 (recommandé par défaut) - `https://secure.rayor.fr/feeds/blocklist-strict.txt` — score ≥ 90 (quasi zéro faux positif) - `https://secure.rayor.fr/feeds/suspects.txt` — score ≥ 25 (large : à réserver au log/tarpit, pas au blocage sec) - `https://secure.rayor.fr/feeds/blocklist.csv` — `ip,score,country,total_reports,last_reported_at,is_tor` - `https://secure.rayor.fr/feeds/blocklist.json` — `{meta:{…}, data:[{ipAddress,abuseConfidenceScore,countryCode,lastReportedAt,isTor}]}` - `https://secure.rayor.fr/feeds/tor-exits.txt` — nœuds de sortie Tor uniquement - `https://secure.rayor.fr/feeds/` — index lisible avec le décompte de chaque liste ### Installation ipset + iptables (Debian/Ubuntu) ```bash apt-get install -y ipset curl cat >/usr/local/sbin/sbr-update <<'EOF' #!/bin/bash # Secure By Rayor — recharge la blocklist dans un ipset, sans coupure. set -euo pipefail SET=sbr; TMP=sbr_tmp URL=https://secure.rayor.fr/feeds/blocklist.txt ipset create $SET hash:ip -exist maxelem 500000 ipset create $TMP hash:ip -exist maxelem 500000 ipset flush $TMP curl -fsS --retry 3 "$URL" | grep -v '^#' | grep -v '^$' | \ while read -r ip; do ipset add $TMP "$ip" -exist; done ipset swap $TMP $SET # bascule atomique ipset destroy $TMP iptables -C INPUT -m set --match-set $SET src -j DROP 2>/dev/null || \ iptables -I INPUT -m set --match-set $SET src -j DROP EOF chmod +x /usr/local/sbin/sbr-update && /usr/local/sbin/sbr-update echo "17 * * * * root /usr/local/sbin/sbr-update >/dev/null 2>&1" >/etc/cron.d/sbr ``` ⚠️ Whitelistez toujours vos propres réseaux AVANT la règle DROP : `iptables -I INPUT -s -j ACCEPT`. Sinon un faux positif vous enferme dehors. ### Installation nftables ```bash curl -fsS https://secure.rayor.fr/feeds/blocklist.txt | grep -v '^#' | paste -sd, - \ > /etc/nftables.d/sbr.list nft add table inet filter nft add set inet filter sbr '{ type ipv4_addr; flags interval; }' nft add element inet filter sbr "{ $(cat /etc/nftables.d/sbr.list) }" nft add rule inet filter input ip saddr @sbr drop ``` ### Nginx — refuser les IP de la liste ```bash curl -fsS https://secure.rayor.fr/feeds/blocklist-strict.txt | grep -v '^#' \ | sed 's/$/ 1;/' > /etc/nginx/sbr.map ``` ```nginx geo $sbr_blocked { default 0; include /etc/nginx/sbr.map; } server { if ($sbr_blocked) { return 403; } } ``` ### Apache 2.4 ```bash curl -fsS https://secure.rayor.fr/feeds/blocklist-strict.txt | grep -v '^#' \ | sed 's/^/Require not ip /' > /etc/apache2/conf-available/sbr.conf ``` puis dans le vhost : ` Require all granted \n Include conf-available/sbr.conf ` ### fail2ban — importer la liste `/etc/fail2ban/filter.d/` n'est pas concerné : passez par ipset (ci-dessus) et laissez fail2ban gérer vos propres bans. Les deux cohabitent sans conflit. ## 2. Clé API 1. Aller sur `https://secure.rayor.fr/login` — connexion par **Rayor Connect** (SSO, gratuit). 2. La clé est affichée sur `https://secure.rayor.fr/dashboard`, au format `rsk_<40 hex>`. 3. Elle se régénère depuis la même page (l'ancienne est invalidée immédiatement). Quotas à l'inscription : **1000 requêtes/min en lecture**, **50/min en écriture**. Ils augmentent automatiquement avec la « confiance » du compte (signalements validés, ancienneté). Sans clé : **1 requête/min et par IP cliente**, lecture seule. ## 3. API JSON — `https://secure.rayor.fr/api/v2` Authentification : en-tête `Key: rsk_…` (alias `X-Api-Key`, ou `?key=` en dernier recours). CORS ouvert (`Access-Control-Allow-Origin: *`). Réponses `{"data":…}` ou `{"errors":[{status,detail}]}`. En-têtes sur chaque réponse : `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-Api-Tier` (`anonymous` ou `key`) ; en cas de dépassement : `429` + `Retry-After: 60`. ### GET /api/v2/check ```bash curl -s "https://secure.rayor.fr/api/v2/check?ipAddress=122.161.49.171" -H "Key: rsk_votrecle" ``` ```json {"data":{"ipAddress":"122.161.49.171","abuseConfidenceScore":48,"countryCode":"IN", "usageType":null,"isp":"Bharti Airtel Ltd.","isTor":false,"isWhitelisted":false, "totalReports":1,"numDistinctUsers":1,"lastReportedAt":"2026-08-01T10:00:00+00:00", "categories":{"18":1},"abuseipdbSeed":48,"source":"community","malicious":false, "reportUrl":"https://secure.rayor.fr/ip/122.161.49.171"}} ``` Codes : `400` ipAddress invalide · `401` clé fournie mais invalide · `422` IP privée · `429` quota. Note : sans clé, la réponse vient de la base locale seule ; une IP inconnue est mise en file d'enrichissement et sera renseignée plus tard (le quota AbuseIPDB amont est partagé). ### POST /api/v2/report — clé obligatoire ```bash curl -s https://secure.rayor.fr/api/v2/report -H "Key: rsk_votrecle" \ -d "ipAddress=203.0.113.10" -d "categories=18,22" -d "comment=Brute-force SSH" ``` ```json {"data":{"ipAddress":"203.0.113.10","abuseConfidenceScore":49,"message":"Signalement enregistré."}} ``` Un compte ne pèse qu'**une fois par IP** : re-signaler met à jour, ne cumule pas. Le signalement anonyme est refusé par conception (résistance Sybil). ### GET /api/v2/blacklist ```bash curl -s "https://secure.rayor.fr/api/v2/blacklist?confidenceMinimum=90&limit=5000" \ -H "Key: rsk_votrecle" ``` `confidenceMinimum` (défaut 75, 1–100), `limit` (max 100 000 avec clé, 1 000 sans). Renvoie `{meta:{generatedAt,confidenceMinimum,count,limit,tier},data:[…]}`. ## 4. Signalement automatique depuis fail2ban `/etc/fail2ban/action.d/secure-rayor.conf` : ```ini [Definition] actionban = curl -sS --max-time 10 https://secure.rayor.fr/api/v2/report \ -H "Key: " \ --data-urlencode "ipAddress=" \ --data-urlencode "categories=" \ --data-urlencode "comment=fail2ban échecs" >/dev/null [Init] sbrkey = rsk_votrecle cats = 18 ``` Puis dans `jail.local` : `action = %(action_)s\n secure-rayor[name=%(__name__)s, cats=22]` (`cats=22` pour SSH, `18` brute-force générique, `21` attaque web, `14` scan de ports). Gardez `50 bans/min` en tête : au-delà, l'API répond 429 (le ban local, lui, reste appliqué). ## 5. Extraits d'intégration applicative PHP : ```php function sbr_score(string $ip): int { $ctx = stream_context_create(['http' => ['header' => "Key: rsk_votrecle\r\n", 'timeout' => 3]]); $j = @file_get_contents("https://secure.rayor.fr/api/v2/check?ipAddress=" . urlencode($ip), false, $ctx); return (int) (json_decode((string)$j, true)['data']['abuseConfidenceScore'] ?? 0); } if (sbr_score($_SERVER['REMOTE_ADDR']) >= 75) { http_response_code(403); exit; } ``` Python : ```python import requests def sbr_score(ip, key="rsk_votrecle"): r = requests.get("https://secure.rayor.fr/api/v2/check", params={"ipAddress": ip}, headers={"Key": key}, timeout=3) return r.json().get("data", {}).get("abuseConfidenceScore", 0) ``` Node : ```js const sbrScore = async (ip) => { const r = await fetch(`https://secure.rayor.fr/api/v2/check?ipAddress=${ip}`, { headers: { Key: 'rsk_votrecle' } }); return (await r.json())?.data?.abuseConfidenceScore ?? 0; }; ``` Dans les trois cas : **échouez en mode ouvert** (`fail-open`). Si Secure By Rayor est injoignable, laissez passer le trafic — une base de réputation ne doit jamais devenir un point de panne pour votre service. ## 6. CAPTCHA — protéger un formulaire (script + balise) Secure By Rayor fournit aussi un CAPTCHA à **kinématogramme** : le mot n'existe que dans le mouvement des points. Une image figée n'est que du bruit uniforme, donc une capture d'écran ou un OCR naïf échoue. Clés : créez-les sur `https://secure.rayor.fr/dashboard#captcha`. La **sitekey** (`sbk_…`) est publique et vit dans la page ; le **secret** (`sbs_…`) reste sur votre serveur. Côté page — un script, une balise. Le widget est monté dans une iframe servie par secure.rayor.fr : la réponse ne transite jamais par le DOM de votre page. ```html
``` Le script injecte dans le formulaire un champ caché `sbr-captcha-response`. Attributs : `data-theme` (`auto`|`light`|`dark`), `data-callback`, `data-expired-callback`. API JS : `sbrCaptcha.render(el[,opts])`, `.reset([el])`, `.getResponse([el])` ; l'élément émet aussi `sbr-captcha-solved`. Côté serveur — **obligatoire**. Ce que reçoit le navigateur ne prouve rien ; la preuve est ce contrôle serveur-à-serveur : ```bash curl -s https://secure.rayor.fr/captcha/siteverify \ -d "secret=sbs_votre_secret" \ -d "response=$SBR_CAPTCHA_RESPONSE" # → {"success":true,"challenge_ts":"2026-08-30T10:48:34+00:00","hostname":"exemple.fr"} ``` ```php $resp = $_POST['sbr-captcha-response'] ?? ''; $r = @file_get_contents('https://secure.rayor.fr/captcha/siteverify', false, stream_context_create(['http' => ['method' => 'POST', 'timeout' => 5, 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => http_build_query(['secret' => SBR_SECRET, 'response' => $resp])]])); if (!$r || !(json_decode($r, true)['success'] ?? false)) { http_response_code(400); exit; } ``` Le jeton est à **usage unique** et vaut 300 s. Codes d'erreur : `invalid-input-secret`, `invalid-input-response`, `timeout-or-duplicate`, `remoteip-mismatch`. Paramètre optionnel `remoteip` : ne l'envoyez que si vous maîtrisez votre chaîne de proxys (sinon vous rejetterez des humains légitimes). Épinglage de domaine : renseignez les hôtes autorisés sur la clé (`exemple.fr, *.exemple.fr`). C'est un garde-fou contre la réutilisation opportuniste de votre sitekey, pas une barrière : il repose sur le Referer du navigateur. ⚠️ **Ce que ça vaut** : une couche de friction, pas une serrure. Un attaquant qui reconstruit le mouvement (flux optique) lit le mot. Combinez-le avec la réputation d'IP ci-dessus, un honeypot et une limitation de débit — jamais seul. ## 6. Catégories de signalement (identifiants) `3` fraude · `4` DDoS · `5` brute-force FTP · `7` phishing · `9` proxy ouvert · `10` spam web · `11` spam e-mail · `13` VPN/anonymiseur abusif · `14` scan de ports · `15` piratage/intrusion · `16` injection SQL · `17` spoofing · `18` brute-force identifiants · `19` robot malveillant · `20` hôte compromis · `21` attaque applicative web · `22` attaque SSH · `23` ciblage IoT · `99` autre. Plusieurs identifiants séparés par des virgules. ## 7. Précautions - **IP dynamiques et CGNAT** : une IP « malveillante » hier peut appartenir à un particulier aujourd'hui. Préférez `blocklist-strict.txt` (≥ 90) pour du DROP sec, et `blocklist.txt` (≥ 75) avec un journal pour pouvoir revenir en arrière. - **Ne bloquez jamais sur `suspects.txt`** sans supervision : cette liste sert au scoring, au tarpit ou au challenge (CAPTCHA), pas au blocage. - **Tor** : `tor-exits.txt` est informatif. Bloquer Tor est un choix politique, pas un choix de sécurité — assumez-le explicitement. - **Retrait** : toute IP peut être retirée sur demande motivée — `https://secure.rayor.fr/retrait` (procédure RGPD, traitement humain). Aucun blocage n'est définitif. - **Attribution** : usage libre des feeds. Un lien vers `https://secure.rayor.fr` est apprécié. ## Pages - Accueil et recherche d'IP : https://secure.rayor.fr/ - Fiche d'une IP : https://secure.rayor.fr/ip/ - Documentation API : https://secure.rayor.fr/api - Feeds : https://secure.rayor.fr/feeds/ - Signaler une IP (compte requis) : https://secure.rayor.fr/report - Espace membre / clé API : https://secure.rayor.fr/dashboard - CAPTCHA : démo, intégration et clés : https://secure.rayor.fr/captcha - Script du widget : https://secure.rayor.fr/captcha.js - Demande de retrait (RGPD) : https://secure.rayor.fr/retrait - Confidentialité : https://secure.rayor.fr/confidentialite - CGU : https://secure.rayor.fr/cgu - Éditeur : Rayor — https://rayor.fr