Reverzní proxy a Nette router

- Rndoom04
- Člen | 78
Ahoj,
dokázal by mi někdo poradit? Zatím je to 1:0 pro mou neznalost a nevím kde
už dělám chybu.
- Hlavní doména domainA.tld má modul /w. Takže kdybych načetl domainA.tld/w/identifikator, tak to funguje dobře.
- K tomu se generuje identifikator.domainA.tld, který se podívá do routy a upřednostní tento zápis.
- K dispozici ale může být i zcela jiná doména – domainB.tld, která má jediný cíl a to načíst modul W.
Nastavil jsem proxy takto:
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN Off
SSLProxyCheckPeerName Off
ProxyPreserveHost Off
ProxyPass / https://www.domainA.cz/
ProxyPassReverse / https://www.domainA.cz/
RequestHeader set X-Forwarded-Host "www.domainB.cz"
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
RequestHeader set Host "www.domainA.cz"
To funguje relativně dobře, ale problém je, že se mi to redirectne na zápis se subdoménou: identifikator.domainA.tld. V případě, že filterOut upravím, tak dochází k nekonečné smyčce přesměrování. Takže to false v té podmínce je teď pro to, aby to fungovalo nějak, ale určitě to není cílem. Cílem je, že www.domainB.tld načte modul /w/identifikator. Propojené to mám databází.
<?php
declare(strict_types=1);
namespace App\Core;
use Nette\Application\Routers\RouteList;
use Nette\Database\Explorer;
final class RouterFactory {
public function __construct(private Explorer $db,) { ; }
public function createRouter(): RouteList {
$router = new RouteList;
/* ===== 1. Dynamické domény a subdomény pro W ===== */
$router[] = $w = new RouteList('W');
$w->addRoute('//<host>/[<presenter>][/<action>]', [
'presenter' => 'Home',
'action' => 'default',
'' => [
'filterOut' => function (array $params) {
if (!isset($params['url'])) {
return null;
}
$url = $params['url'];
$row = $this->db->fetch('SELECT vlastni_domena FROM websites WHERE url = ?', $url);
if (false && $row && $row->vlastni_domena) {
// Úmyslně false, aby to zatím nějak fungovalo, ale jinak tady je způsoben ten nekonečný redirect
$params['host'] = $row->vlastni_domena;
} else {
$currentHost = $_SERVER['HTTP_X_FORWARDED_HOST']
?? $_SERVER['HTTP_HOST']
?? 'domainA.local';
$currentHost = trim(explode(',', $currentHost)[0]);
$currentHost = explode(':', $currentHost)[0];
$baseDomain = str_ends_with($currentHost, '.cz') ? 'domainA.cz' : 'domainA.local';
$params['host'] = $url . '.' . $baseDomain;
}
unset($params['url']);
return $params;
},
'filterIn' => function (array $params) {
$forwardedHost = isset($_SERVER['HTTP_X_FORWARDED_HOST'])
? trim(explode(',', $_SERVER['HTTP_X_FORWARDED_HOST'])[0])
: null;
// Pokud X-Forwarded-Host je hlavní doména, tato routa se netýká
$mainDomains = [
'domainA.local',
'domainA.cz',
'www.domainA.cz',
'192.168.100.204',
];
if ($forwardedHost && in_array($forwardedHost, $mainDomains, true)) {
return null;
}
// Přepíšeme host skutečnou doménou klienta
if ($forwardedHost) {
$params['host'] = $forwardedHost;
}
$hostWithPort = $params['host'] ?? '';
if ($hostWithPort === '')
return null;
$host = explode(':', $hostWithPort)[0];
if (in_array($host, $mainDomains, true)) {
return null;
}
// A) Kontrola vlastní domény
$row = $this->db->fetch(
'SELECT url FROM websites WHERE vlastni_domena = ? AND zverejneno = 1 AND platne_do > NOW()',
$host,
);
if ($row) {
$params['url'] = $row->url;
return $params;
}
// B) Kontrola subdomény
foreach (['domainA.local', 'domainA.cz'] as $main) {
if (str_ends_with($host, '.' . $main)) {
$slug = substr($host, 0, -strlen('.' . $main));
$row = $this->db->fetch(
'SELECT url FROM websites WHERE url = ? AND platne_do > NOW()',
$slug,
);
if ($row) {
$params['url'] = $row->url;
return $params;
}
}
}
// C) Neznámá doména – redirect na hlavní web
$currentHost = $forwardedHost ?? ($_SERVER['HTTP_HOST'] ?? '');
$isLocal = str_contains($currentHost, '.local') || str_contains($currentHost, '192.168.');
$targetMain = $isLocal ? $currentHost : 'domainA.cz';
if ($host === '192.168.100.204' || $host === $targetMain || $host === "www.$targetMain") {
return null;
}
header("Location: https://$targetMain/domena-nenapojena", true, 302);
exit;
},
],
]);
/* ===== 2. Výchozí doména (Administrace, Cron, atd.) ===== */
$router[] = $admin = new RouteList('Admin');
$admin->addRoute('admin/<presenter>/<action>[/<id>]', 'Home:default');
$router[] = $cron = new RouteList('Cron');
$cron->addRoute('cron/<presenter>/<action>', 'Home:default');
$router[] = $app = new RouteList('App');
$app->addRoute('app/plan/dekujeme/<orderVS>', 'Plan:dekujeme');
$app->addRoute('app/<presenter>[/<action>][/<id>]', 'Home:default');
$router[] = $webhook = new RouteList('Webhook');
$webhook->addRoute('webhook/<presenter>/<action>[/<id>]', 'Home:default');
$router[] = $error = new RouteList('Error');
$error->addRoute('error/<presenter>/<action>', 'Error4xx:default');
$router[] = $front = new RouteList('Front');
$front->addRoute('sitemap.xml', 'Sitemap:default');
$front->addRoute('stahnout[/<cloudJob>]', 'Stahnout:default');
$front->addRoute('<presenter>/<action>[/<id>]', 'Home:default');
return $router;
}
}
Budu moc rád za popostrčení, AI neporadilo – kromě přepsání práv k souborům na serveru nebo nějakých dalších nesmyslů. Ale nemyslím si, že bych chtěl nějak moc. :) Předem děkuji. :)
Editoval Rndoom04 (Dnes 5:03)