Zmerit i to, jak nas vidi vlastni proxy

Echo sluzba na internetu odpovi verejnou adresu. Jenze volani na vlastni
domenu se otaci zpatky na tentyz stroj a reverse proxy pak vidi neco jineho,
typicky adresu docker bridge. A prave tu porovnava seznam povolenych IP
u sluzeb za toutez proxy, takze verejna adresa muze byt povolena a volani
z containeru presto skonci na 403.

Zmeri se to tak, ze portal zavola svoji vlastni verejnou adresu
(PUBLIC_ORIGIN + ROOT_PATH + /whoami) a precte si, jak k nemu volani doslo.
Kruh sam pres sebe, ale nic jineho tuhle adresu nezjisti: mezi container
a server se tim dostane ta sama proxy, kterou prochazi volani na sousedni
sluzby.

Novy /api/whoami je zamerne bez prihlaseni. Vraci volajicimu jeho vlastni
adresu, tedy nic, co by uz nevedel, stejne jako kterakoliv echo sluzba.

Obe mereni bezi naraz a jsou videt na strance Konektory vedle sebe.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
JiriUhlir
2026-08-25 07:33:46 +02:00
co-authored by Claude Opus 5
parent 4545de8076
commit 6a2e0dc424
7 changed files with 228 additions and 21 deletions
+39 -14
View File
@@ -234,22 +234,47 @@ function EgressNotice({ egress }: { egress: EgressIp }) {
<Globe className="mt-0.5 size-4 shrink-0 text-white/40" />
<div className="min-w-0">
{egress.ip ? (
<>
<p className="text-sm text-white/70">
Volání odcházejí z IP <span className="font-mono text-white">{egress.ip}</span>
</p>
<p className="mt-0.5 text-xs text-white/40">
Tuhle adresu vidí volaná služba, takže právě ona musí být na jejím seznamu
povolených. Zjištěno {formatDateTime(egress.checkedAt)} přes {egress.source}.
</p>
</>
<p className="text-sm text-white/70">
Ven do internetu voláme z IP <span className="font-mono text-white">{egress.ip}</span>
<span className="mt-0.5 block text-xs text-white/40">
Zjištěno {formatDateTime(egress.checkedAt)} přes {egress.source}.
</span>
</p>
) : (
<>
<p className="text-sm text-white/70">Odchozí IP adresu se nepodařilo zjistit.</p>
<p className="mt-0.5 text-xs text-white/40">
<p className="text-sm text-white/70">
Odchozí IP adresu se nepodařilo zjistit.
<span className="mt-0.5 block text-xs text-white/40">
{egress.error ?? 'Bez důvodu.'} Adresu echo služby určuje EGRESS_IP_URL.
</p>
</>
</span>
</p>
)}
{/*
Druhé měření, a to důležitější: volání na vlastní veřejnou doménu se
otočí zpátky na tentýž stroj a proxy pak vidí něco jiného než internet.
Právě tuhle adresu porovnává seznam povolených IP u sousedních služeb.
*/}
{egress.viaProxy && (
<p className="mt-2 border-t border-ink-600/50 pt-2 text-sm text-white/70">
{egress.viaProxy.ip ? (
<>
Přes vlastní proxy nás vidí jako{' '}
<span className="font-mono text-white">{egress.viaProxy.ip}</span>
</>
) : (
'Přes vlastní proxy se změřit nepodařilo.'
)}
<span className="mt-0.5 block text-xs text-white/40">
{egress.viaProxy.error ??
'Tohle je adresa, kterou porovnává seznam povolených IP u služeb za toutéž proxy. Když se liší od té veřejné, volání se točí přes vnitřní síť a na seznamu musí být ona.'}
</span>
{(egress.viaProxy.forwardedFor || egress.viaProxy.remoteAddress) && (
<span className="mt-1 block font-mono text-xs break-all text-white/35">
x-forwarded-for: {egress.viaProxy.forwardedFor ?? '(nic)'} / spojení z:{' '}
{egress.viaProxy.remoteAddress ?? '(nic)'}
</span>
)}
</p>
)}
</div>
</div>
+12
View File
@@ -429,6 +429,18 @@ export interface EgressIp {
source: string;
checkedAt: string;
error?: string;
/**
* Jak nas vidi nase vlastni reverse proxy, kdyz volani vyjde z containeru
* a otoci se pres verejnou domenu zpatky. Prave tuhle adresu porovnava
* seznam povolenych IP u sluzeb za toutez proxy.
*/
viaProxy: {
ip: string | null;
forwardedFor: string | null;
remoteAddress: string | null;
url: string;
error?: string;
} | null;
}
export interface ServiceCatalog {