Ke zmerene adrese i rozsah, ktery ji pokryje cely
Povolit jednu adresu nema smysl: docker prideluje z bloku a pri prekresleni site nebo redeployi se cisla meni, takze povoleni vydrzi do prvniho restartu. Portal proto k namerene adrese dopocita CIDR rozsah - 127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 169.254.0.0/16, ::1/128, fc00::/7, fe80::/10. U 172.16-31 schvalne /12 a ne /16 toho konkretniho bridge: docker si smi vzit kterykoliv podblok a nikdo nezaruci, ze zustane u toho dnesniho. Verejna adresa zadny rozsah nedostane, tam nabizet blok nema smysl. Taky opravena popiska u remoteAddress. Je to sama proxy, ne volajici - k nam uz to jde od ni. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6a2e0dc424
commit
b25a149574
+54
-3
@@ -35,17 +35,64 @@ export interface EgressIp {
|
||||
}
|
||||
|
||||
export interface ProxyView {
|
||||
/** Adresa po `trust proxy`, tedy z X-Forwarded-For. */
|
||||
/**
|
||||
* **Tohle je to cislo.** Adresa po `trust proxy`, tedy z X-Forwarded-For -
|
||||
* proxy tam zapsala, s jakou adresou k ni nase volani doslo.
|
||||
*/
|
||||
ip: string | null;
|
||||
/** Surova hlavicka, at je videt i to, co proxy nepripsala. */
|
||||
forwardedFor: string | null;
|
||||
/** Adresa druheho konce spojeni, jak ji vidi nas server. */
|
||||
/**
|
||||
* Adresa druheho konce spojeni. Pozor, to je **sama proxy**, ne volajici -
|
||||
* k nam uz to jde od ni. Je to tu na to, aby bylo poznat, ze se volani
|
||||
* opravdu tocilo pres ni a ne primo.
|
||||
*/
|
||||
remoteAddress: string | null;
|
||||
/**
|
||||
* Rozsah, ktery tuhle adresu pokryje cely. Docker prideluje z bloku,
|
||||
* takze povolit jednu adresu vydrzi do prvniho prekresleni site - patri
|
||||
* tam cely rozsah. null = adresa je verejna, zadny blok se nenabizi.
|
||||
*/
|
||||
suggestedRange: string | null;
|
||||
/** Kam se volalo. Pro uzivatele, at vi, co se vlastne merilo. */
|
||||
url: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rozsah, ktery danou adresu pokryje cely.
|
||||
*
|
||||
* U dockeru nema smysl povolovat jednu adresu: bridge se pri prekresleni site
|
||||
* nebo pri redeployi muze precislovat a povoleni vydrzi do prvniho restartu.
|
||||
* Proto cely blok, ze ktereho adresa pochazi.
|
||||
*
|
||||
* U 172.16-31 se schvalne vraci `/12`, ne `/16` toho konkretniho bridge.
|
||||
* Docker si smi vzit kterykoliv podblok a nikdo nezaruci, ze zustane u toho
|
||||
* dnesniho.
|
||||
*/
|
||||
export function suggestRange(raw: string | null): string | null {
|
||||
if (raw === null) return null;
|
||||
// Node casto vraci IPv4 zabalenou do IPv6 jako `::ffff:172.17.0.1`.
|
||||
const ip = raw.trim().replace(/^::ffff:/i, '').toLowerCase();
|
||||
if (ip === '') return null;
|
||||
|
||||
if (ip === '::1') return '::1/128';
|
||||
if (/^f[cd]/.test(ip) && ip.includes(':')) return 'fc00::/7';
|
||||
if (/^fe80:/.test(ip)) return 'fe80::/10';
|
||||
|
||||
const parts = ip.split('.');
|
||||
if (parts.length !== 4) return null;
|
||||
const [first, second] = parts.map((part) => Number(part));
|
||||
if (!Number.isInteger(first) || !Number.isInteger(second)) return null;
|
||||
|
||||
if (first === 127) return '127.0.0.0/8';
|
||||
if (first === 10) return '10.0.0.0/8';
|
||||
if (first === 192 && second === 168) return '192.168.0.0/16';
|
||||
if (first === 172 && second >= 16 && second <= 31) return '172.16.0.0/12';
|
||||
if (first === 169 && second === 254) return '169.254.0.0/16';
|
||||
return null;
|
||||
}
|
||||
|
||||
let cached: EgressIp | null = null;
|
||||
let cachedAt = 0;
|
||||
/** Rozdelane volani. Deset soubeznych dotazu nema delat deset volani ven. */
|
||||
@@ -98,16 +145,19 @@ async function askProxy(): Promise<ProxyView | null> {
|
||||
ip: null,
|
||||
forwardedFor: null,
|
||||
remoteAddress: null,
|
||||
suggestedRange: null,
|
||||
url,
|
||||
error: `Vlastní adresa vrátila HTTP ${response.status}.`,
|
||||
};
|
||||
}
|
||||
|
||||
const body = (await response.json()) as Partial<ProxyView>;
|
||||
const ip = typeof body.ip === 'string' ? body.ip : null;
|
||||
return {
|
||||
ip: typeof body.ip === 'string' ? body.ip : null,
|
||||
ip,
|
||||
forwardedFor: typeof body.forwardedFor === 'string' ? body.forwardedFor : null,
|
||||
remoteAddress: typeof body.remoteAddress === 'string' ? body.remoteAddress : null,
|
||||
suggestedRange: suggestRange(ip),
|
||||
url,
|
||||
};
|
||||
} catch (err) {
|
||||
@@ -116,6 +166,7 @@ async function askProxy(): Promise<ProxyView | null> {
|
||||
ip: null,
|
||||
forwardedFor: null,
|
||||
remoteAddress: null,
|
||||
suggestedRange: null,
|
||||
url,
|
||||
error: `Vlastní adresu se nepodařilo zavolat: ${message}`,
|
||||
};
|
||||
|
||||
+16
-1
@@ -1718,7 +1718,22 @@ export function buildOpenApiDocument() {
|
||||
properties: {
|
||||
ip: { type: 'string', nullable: true },
|
||||
forwardedFor: { type: 'string', nullable: true },
|
||||
remoteAddress: { type: 'string', nullable: true },
|
||||
remoteAddress: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
description:
|
||||
'Sama proxy, ne volajici - k nam uz to jde od ni. Je to tu na to, ' +
|
||||
'aby bylo poznat, ze se volani opravdu tocilo pres ni.',
|
||||
},
|
||||
suggestedRange: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
description:
|
||||
'CIDR rozsah, ktery tu adresu pokryje cely (napr. 172.16.0.0/12 ' +
|
||||
'nebo 127.0.0.0/8). Do seznamu povolenych patri on, ne jedna ' +
|
||||
'adresa: docker prideluje z bloku a pri prekresleni site se cisla ' +
|
||||
'meni. null = adresa je verejna, zadny blok se nenabizi.',
|
||||
},
|
||||
url: { type: 'string' },
|
||||
error: { type: 'string' },
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user