b1d3e255e0
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.
183 lines
6.8 KiB
Markdown
183 lines
6.8 KiB
Markdown
# Registrace účtů — AzerothCore
|
||
|
||
Jednoduchá PHP registrační stránka pro AzerothCore server. Vytváří účet
|
||
přímo v `acore_auth`.`account` tabulce se správně spočítaným SRP6
|
||
salt/verifierem, takže se hráč může rovnou přihlásit ve hře.
|
||
|
||
## Ochrana proti spamu/botům
|
||
|
||
- **Cloudflare Turnstile** — captcha ověřená server-side (volitelná: pokud
|
||
necháš `TURNSTILE_SITE_KEY`/`TURNSTILE_SECRET_KEY` prázdné, widget se
|
||
nezobrazí a ověření se přeskočí — pro produkci ale doporučuji vyplnit).
|
||
- **Honeypot pole** — skryté pole `website`, které boti často vyplní;
|
||
formulář pak předstírá úspěch, ale nic se nezapíše.
|
||
- **Rate limiting** — max. N registračních pokusů z jedné IP za časové
|
||
okno (výchozí 5 / hodinu), ukládá se do lokální SQLite (`data/ratelimit.sqlite`),
|
||
nezasahuje do AzerothCore databáze.
|
||
- **CSRF token** na formuláři.
|
||
|
||
## Požadavky na serveru
|
||
|
||
- PHP 8.1+
|
||
- PHP rozšíření: `pdo_mysql`, `pdo_sqlite`, `gmp`, `session`, `openssl`
|
||
- Webserver (Apache s `mod_php`/PHP-FPM, nebo nginx + PHP-FPM)
|
||
- Síťový/lokální přístup k MySQL, kde běží `acore_auth`
|
||
|
||
## Instalace
|
||
|
||
0. Naklonuj repozitář na server, mimo webroot ostatních webů (např. vedle
|
||
PlayerMap):
|
||
|
||
```bash
|
||
git clone https://gitea.minkey.cz/vojta/wow-registrace.git
|
||
cd wow-registrace
|
||
```
|
||
|
||
1. Zkopíruj `.env.example` do `.env` a vyplň:
|
||
- `SITE_NAME`, `REALMLIST_ADDRESS` (`wow.minkey.cz`), `CLIENT_VERSION`,
|
||
případně `CLIENT_DOWNLOAD_URL` — zobrazují se na úvodní stránce
|
||
- `DB_HOST`, `DB_PORT`, `DB_DATABASE` (typicky `acore_auth`), `DB_USERNAME`, `DB_PASSWORD`
|
||
- `TURNSTILE_SITE_KEY` / `TURNSTILE_SECRET_KEY` z Cloudflare dashboardu
|
||
|
||
`.env` se **negituje** (je v `.gitignore`) — na serveru ho vytváříš ručně,
|
||
nikdy ho nepushuj do repozitáře.
|
||
|
||
2. Vytvoř v MySQL **dedikovaného uživatele** jen s právy na tabulku `account`
|
||
(neházej tam root přístup):
|
||
|
||
```sql
|
||
CREATE USER 'acore_reg'@'localhost' IDENTIFIED BY 'silne-nahodne-heslo';
|
||
GRANT SELECT, INSERT ON acore_auth.account TO 'acore_reg'@'localhost';
|
||
FLUSH PRIVILEGES;
|
||
```
|
||
|
||
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 (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 *:80>
|
||
ServerName wow.minkey.cz
|
||
DocumentRoot /var/www/wow-registrace/public
|
||
|
||
<Directory /var/www/wow-registrace/public>
|
||
AllowOverride All
|
||
Require all granted
|
||
</Directory>
|
||
</VirtualHost>
|
||
```
|
||
|
||
Příklad Nginx + PHP-FPM (uprav `fastcgi_pass` podle svého PHP-FPM socketu,
|
||
stejně jako to máš u PlayerMap):
|
||
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name wow.minkey.cz;
|
||
root /var/www/wow-registrace/public;
|
||
index index.php;
|
||
|
||
location / {
|
||
try_files $uri $uri/ =404;
|
||
}
|
||
|
||
location ~ \.php$ {
|
||
include fastcgi_params;
|
||
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
|
||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||
}
|
||
|
||
# includes/, data/ a .env jsou mimo document root, takže už jsou
|
||
# skryté; tenhle blok je jen pojistka, kdyby se root někdy spletl
|
||
location ~ /\.(env|git) {
|
||
deny all;
|
||
}
|
||
}
|
||
```
|
||
|
||
4. Uprav práva zápisu na `data/` (potřebuje tam vzniknout `ratelimit.sqlite`) —
|
||
uprav uživatele podle toho, pod kterým webserver skutečně běží (`www-data`
|
||
na Debianu/Ubuntu, `http` na Arch, `nginx` apod.):
|
||
|
||
```bash
|
||
chown -R www-data:www-data data
|
||
chmod 750 data
|
||
```
|
||
|
||
5. Ověř, že GMP na serveru počítá SRP6 verifier správně (porovná se s
|
||
nezávisle spočítanou referenční hodnotou):
|
||
|
||
```bash
|
||
php includes/srp6_selftest.php
|
||
```
|
||
|
||
Očekávaný výstup je `OK - shoduje se s referenční implementací.` Pokud
|
||
vypíše chybu, něco je špatně s PHP/GMP na serveru a registrace by
|
||
vytvářela účty, se kterými se nepůjde přihlásit — než to nespadne,
|
||
dál nepokračuj.
|
||
|
||
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
|
||
cd /cesta/k/wow-registrace
|
||
git pull
|
||
```
|
||
|
||
`.env` a `data/ratelimit.sqlite` nejsou v repozitáři, takže `git pull`
|
||
je nepřepíše.
|
||
|
||
## Poznámky k herním pravidlům
|
||
|
||
- Uživatelské jméno i heslo se před výpočtem SRP6 verifieru převádí na
|
||
velká písmena (`strtoupper`) a jméno se tak i ukládá — přesně jak to dělá
|
||
samotný AzerothCore/klient, aby přihlášení fungovalo case-insensitive.
|
||
- Heslo je omezené na tisknutelná ASCII znaky (`REG_PASSWORD_MIN/MAX` v `.env`,
|
||
výchozí 8–16 znaků) — WoW klient jiné znaky v hesle nepodporuje.
|
||
- `expansion`, `locale` a další sloupce tabulky `account` se nechávají na
|
||
výchozích hodnotách definovaných v DB schématu AzerothCore — uprav
|
||
`public/register.php`, pokud chceš nový účet zařadit jinak (např. jiný expansion level).
|
||
- Pokud web neběží přímo na stejném stroji jako MySQL, zvaž TLS pro DB
|
||
spojení nebo tunelování (SSH tunel / VPN), ať heslo/verifier neputuje po síti čistě.
|
||
|
||
## Struktura projektu
|
||
|
||
```
|
||
includes/ # PHP logika mimo webroot (DB, SRP6, Turnstile, rate limiter)
|
||
public/ # webroot — index.php (formulář), register.php (zpracování)
|
||
data/ # SQLite pro rate limiting (zapisovatelné webserverem)
|
||
.env # tajné údaje, needituj do gitu
|
||
```
|