Respektovat X-Forwarded-For za reverzní proxí (Nginx Proxy Manager)
Bez TRUST_PROXY_HEADERS=true by rate limiting viděl u každého požadavku IP proxy místo skutečného návštěvníka a limit by se sdílel napříč všemi uživateli. Přidán i návod na zapojení do Nginx Proxy Manageru v README.
This commit is contained in:
@@ -30,3 +30,10 @@ REG_PASSWORD_MAX=16
|
||||
# Kolik pokusů o registraci povolit z jedné IP v daném časovém okně (vteřiny)
|
||||
REG_RATE_LIMIT_MAX=5
|
||||
REG_RATE_LIMIT_WINDOW=3600
|
||||
|
||||
# --- Reverzní proxy (Nginx Proxy Manager, Cloudflare, ...) ---
|
||||
# Nastav na "true" JEN pokud je tenhle web dostupný z internetu výhradně
|
||||
# přes reverzní proxy (Apache/PHP-FPM port není veřejně dosažitelný přímo).
|
||||
# Jinak si útočník IP jednoduše vymyslí přes hlavičku a rate limiting/logy
|
||||
# přestanou dávat smysl.
|
||||
TRUST_PROXY_HEADERS=false
|
||||
|
||||
@@ -54,14 +54,16 @@ salt/verifierem, takže se hráč může rovnou přihlásit ve hře.
|
||||
3. Nastav webserver tak, aby **DocumentRoot mířil na `public/`**, ne na kořen
|
||||
projektu — `includes/`, `data/` a `.env` tak nebudou z webu dostupné vůbec.
|
||||
|
||||
Příklad Apache vhost:
|
||||
Příklad Apache vhost (port 80 — HTTPS řeší reverzní proxy před tímhle
|
||||
serverem, viz sekce níže; pokud Apache vystavuješ na internet přímo bez
|
||||
proxy, dej sem `*:443` a přidej SSL certifikát):
|
||||
|
||||
```apache
|
||||
<VirtualHost *:443>
|
||||
<VirtualHost *:80>
|
||||
ServerName wow.minkey.cz
|
||||
DocumentRoot /cesta/k/wow-registrace/public
|
||||
DocumentRoot /var/www/wow-registrace/public
|
||||
|
||||
<Directory /cesta/k/wow-registrace/public>
|
||||
<Directory /var/www/wow-registrace/public>
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
@@ -73,9 +75,9 @@ salt/verifierem, takže se hráč může rovnou přihlásit ve hře.
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen 80;
|
||||
server_name wow.minkey.cz;
|
||||
root /cesta/k/wow-registrace/public;
|
||||
root /var/www/wow-registrace/public;
|
||||
index index.php;
|
||||
|
||||
location / {
|
||||
@@ -120,6 +122,33 @@ salt/verifierem, takže se hráč může rovnou přihlásit ve hře.
|
||||
6. Otevři stránku v prohlížeči, vyzkoušej registraci, ověř že se v `account`
|
||||
tabulce objevil nový řádek a že se přihlásíš herním klientem.
|
||||
|
||||
## Nasazení za reverzní proxy (Nginx Proxy Manager, Cloudflare, ...)
|
||||
|
||||
Pokud HTTPS řeší proxy před tímto serverem (např. Nginx Proxy Manager),
|
||||
Apache/Nginx tady běží jen na HTTP (viz vhosty výše) a proxy dotazy
|
||||
předává dál. Je potřeba:
|
||||
|
||||
1. V Nginx Proxy Manageru přidat nový **Proxy Host**:
|
||||
- Domain Names: `wow.minkey.cz`
|
||||
- Forward Hostname/IP + Port: adresa a port `80`, na kterém poslouchá
|
||||
Apache/Nginx s tímhle vhostem (stejně, jak už máš nastavené pro
|
||||
PlayerMap, jen jiná doména)
|
||||
- Na záložce SSL: **Request a new SSL Certificate** (Let's Encrypt) +
|
||||
zapnout **Force SSL**
|
||||
|
||||
2. V `.env` nastavit:
|
||||
|
||||
```
|
||||
TRUST_PROXY_HEADERS=true
|
||||
```
|
||||
|
||||
Bez tohohle by aplikace u každého požadavku viděla jako "IP klienta"
|
||||
IP samotné proxy, a rate limiting proti spamu by tak omylem počítal
|
||||
všechny návštěvníky jako jednoho. **Zapínej to jen tehdy, když Apache
|
||||
port 80 na tomhle serveru není z internetu dostupný přímo** (jen skrz
|
||||
tu proxy) — jinak si útočník IP adresu v hlavičce jednoduše vymyslí a
|
||||
rate limiting/logy přestanou dávat smysl.
|
||||
|
||||
## Aktualizace
|
||||
|
||||
```bash
|
||||
|
||||
+17
-4
@@ -3,10 +3,23 @@ declare(strict_types=1);
|
||||
|
||||
function client_ip(): string
|
||||
{
|
||||
// Uprav podle své infrastruktury: pokud web běží za reverzní proxy
|
||||
// (nginx proxy_pass, Cloudflare, ...), musíš X-Forwarded-For nastavit
|
||||
// a validovat důvěryhodně na úrovni proxy, jinak si ji klient může
|
||||
// vymyslet sám. Bez proxy je REMOTE_ADDR spolehlivý zdroj.
|
||||
// Za reverzní proxy (Nginx Proxy Manager, Cloudflare, ...) je
|
||||
// REMOTE_ADDR vždy IP proxy, ne návštěvníka — rate limiting by tak
|
||||
// omylem sdílel jeden limit pro úplně všechny. TRUST_PROXY_HEADERS=true
|
||||
// v .env zapíná čtení X-Forwarded-For; zapínej ho JEN pokud je tenhle
|
||||
// web dostupný z internetu výhradně přes tu proxy (Apache port 80 by
|
||||
// neměl být veřejně dosažitelný přímo), jinak si klient IP jednoduše
|
||||
// vymyslí a rate limiting úplně obejde.
|
||||
if (env('TRUST_PROXY_HEADERS', 'false') === 'true') {
|
||||
$forwardedFor = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? '';
|
||||
if ($forwardedFor !== '') {
|
||||
$first = trim(explode(',', $forwardedFor)[0]);
|
||||
if (filter_var($first, FILTER_VALIDATE_IP)) {
|
||||
return $first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
|
||||
return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : '0.0.0.0';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user