Restrict guide gateway DNS to the console VLAN
Add an ALLOWED_CLIENTS source-address filter to the DNS service so it only answers queries from the authorized PS5 VLAN (192.168.40.0/28 by default). Queries from any other source address are dropped and logged as "denied" on both UDP and TCP. The value accepts a comma-separated mix of individual addresses and CIDR ranges, and an empty value disables the filter. Record the two authorized consoles (PS5PRO 192.168.40.14, PS5FAT 192.168.40.13) and the stale 192.168.10.x workstation address in the docs. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
@@ -22,6 +22,7 @@ services:
|
|||||||
REDIRECT_URL: "${GUIDE_REDIRECT_URL:-http://192.168.20.30:8000/}"
|
REDIRECT_URL: "${GUIDE_REDIRECT_URL:-http://192.168.20.30:8000/}"
|
||||||
FORWARDED_DOMAINS: "${FORWARDED_DOMAINS:-homebrew.page,itsplk.github.io,store.spectrumlibrary.online,api.github.com,github.com,raw.githubusercontent.com,release-assets.githubusercontent.com,prosperopatches.com,cdn.prosperopatches.com,image.api.playstation.com,gmedia.playstation.com}"
|
FORWARDED_DOMAINS: "${FORWARDED_DOMAINS:-homebrew.page,itsplk.github.io,store.spectrumlibrary.online,api.github.com,github.com,raw.githubusercontent.com,release-assets.githubusercontent.com,prosperopatches.com,cdn.prosperopatches.com,image.api.playstation.com,gmedia.playstation.com}"
|
||||||
UPSTREAM_DNS: "${UPSTREAM_DNS:-1.1.1.1}"
|
UPSTREAM_DNS: "${UPSTREAM_DNS:-1.1.1.1}"
|
||||||
|
ALLOWED_CLIENTS: "${ALLOWED_CLIENTS:-192.168.40.0/28}"
|
||||||
ports:
|
ports:
|
||||||
- "${GATEWAY_BIND_IP:-192.168.20.30}:53:8053/udp"
|
- "${GATEWAY_BIND_IP:-192.168.20.30}:53:8053/udp"
|
||||||
- "${GATEWAY_BIND_IP:-192.168.20.30}:53:8053/tcp"
|
- "${GATEWAY_BIND_IP:-192.168.20.30}:53:8053/tcp"
|
||||||
|
|||||||
+26
-1
@@ -26,10 +26,28 @@ FORWARDED_DOMAINS = frozenset(
|
|||||||
)
|
)
|
||||||
UPSTREAM_DNS = str(ipaddress.ip_address(os.environ.get("UPSTREAM_DNS", "1.1.1.1")))
|
UPSTREAM_DNS = str(ipaddress.ip_address(os.environ.get("UPSTREAM_DNS", "1.1.1.1")))
|
||||||
UPSTREAM_TIMEOUT = 3.0
|
UPSTREAM_TIMEOUT = 3.0
|
||||||
|
# Source networks allowed to query the DNS service (PS5 VLAN by default).
|
||||||
|
# Accepts comma-separated individual addresses and CIDR ranges; empty disables
|
||||||
|
# the filter and serves every client.
|
||||||
|
ALLOWED_CLIENTS = tuple(
|
||||||
|
ipaddress.ip_network(entry.strip(), strict=False)
|
||||||
|
for entry in os.environ.get("ALLOWED_CLIENTS", "192.168.40.0/28").split(",")
|
||||||
|
if entry.strip()
|
||||||
|
)
|
||||||
CERTIFICATE = "/srv/certificates/manuals.crt"
|
CERTIFICATE = "/srv/certificates/manuals.crt"
|
||||||
PRIVATE_KEY = "/srv/certificates/manuals.key"
|
PRIVATE_KEY = "/srv/certificates/manuals.key"
|
||||||
|
|
||||||
|
|
||||||
|
def client_allowed(address):
|
||||||
|
if not ALLOWED_CLIENTS:
|
||||||
|
return True
|
||||||
|
try:
|
||||||
|
client = ipaddress.ip_address(address)
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
return any(client in network for network in ALLOWED_CLIENTS)
|
||||||
|
|
||||||
|
|
||||||
def parse_question(packet):
|
def parse_question(packet):
|
||||||
if len(packet) < 17:
|
if len(packet) < 17:
|
||||||
raise ValueError("short DNS query")
|
raise ValueError("short DNS query")
|
||||||
@@ -150,6 +168,9 @@ class ThreadingTCPServer(socketserver.ThreadingTCPServer):
|
|||||||
class UDPDNSHandler(socketserver.BaseRequestHandler):
|
class UDPDNSHandler(socketserver.BaseRequestHandler):
|
||||||
def handle(self):
|
def handle(self):
|
||||||
packet, connection = self.request
|
packet, connection = self.request
|
||||||
|
if not client_allowed(self.client_address[0]):
|
||||||
|
print(f"DNS UDP {self.client_address[0]} denied", flush=True)
|
||||||
|
return
|
||||||
try:
|
try:
|
||||||
name, qtype, _, _ = parse_question(packet)
|
name, qtype, _, _ = parse_question(packet)
|
||||||
print(f"DNS UDP {self.client_address[0]} {name} type={qtype}", flush=True)
|
print(f"DNS UDP {self.client_address[0]} {name} type={qtype}", flush=True)
|
||||||
@@ -162,6 +183,9 @@ class UDPDNSHandler(socketserver.BaseRequestHandler):
|
|||||||
|
|
||||||
class TCPDNSHandler(socketserver.BaseRequestHandler):
|
class TCPDNSHandler(socketserver.BaseRequestHandler):
|
||||||
def handle(self):
|
def handle(self):
|
||||||
|
if not client_allowed(self.client_address[0]):
|
||||||
|
print(f"DNS TCP {self.client_address[0]} denied", flush=True)
|
||||||
|
return
|
||||||
length_bytes = self._receive_exactly(2)
|
length_bytes = self._receive_exactly(2)
|
||||||
if length_bytes is None:
|
if length_bytes is None:
|
||||||
return
|
return
|
||||||
@@ -248,7 +272,8 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
print(
|
print(
|
||||||
f"PS5 guide gateway: {TARGET_DOMAIN} -> {GATEWAY_IP}; redirect -> {REDIRECT_URL}; "
|
f"PS5 guide gateway: {TARGET_DOMAIN} -> {GATEWAY_IP}; redirect -> {REDIRECT_URL}; "
|
||||||
f"forward {','.join(sorted(FORWARDED_DOMAINS))} -> {UPSTREAM_DNS}",
|
f"forward {','.join(sorted(FORWARDED_DOMAINS))} -> {UPSTREAM_DNS}; "
|
||||||
|
f"clients {','.join(str(network) for network in ALLOWED_CLIENTS) or 'any'}",
|
||||||
flush=True,
|
flush=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+16
-4
@@ -163,10 +163,12 @@ successful smoke test; user selection is separate from evidence.
|
|||||||
|
|
||||||
## PS5 and DNS state
|
## PS5 and DNS state
|
||||||
|
|
||||||
The PS5 now uses the static address:
|
Two authorized consoles now use static addresses on the console VLAN
|
||||||
|
`192.168.40.0/28`:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
192.168.40.14
|
PS5PRO 192.168.40.14
|
||||||
|
PS5FAT 192.168.40.13
|
||||||
```
|
```
|
||||||
|
|
||||||
The local HTTP endpoint is available and verified at:
|
The local HTTP endpoint is available and verified at:
|
||||||
@@ -191,6 +193,14 @@ Library and BlackBox while continuing to block PSN and update resolution. The PS
|
|||||||
sends DNS only to `net-utils01`; that host must be allowed to reach the configured
|
sends DNS only to `net-utils01`; that host must be allowed to reach the configured
|
||||||
upstream resolver on UDP/TCP 53.
|
upstream resolver on UDP/TCP 53.
|
||||||
|
|
||||||
|
The gateway additionally restricts which source clients it answers. `ALLOWED_CLIENTS`
|
||||||
|
defaults to the console VLAN `192.168.40.0/28`; queries from any other source address
|
||||||
|
are dropped and logged as `denied`, on both UDP and TCP. The value accepts a
|
||||||
|
comma-separated mix of individual addresses and CIDR ranges, and an empty value
|
||||||
|
disables the filter. This keeps the service dedicated to the two authorized consoles
|
||||||
|
and prevents other LAN hosts from using it as an open resolver for the allowlisted
|
||||||
|
names.
|
||||||
|
|
||||||
The Payload Manager review used upstream commit
|
The Payload Manager review used upstream commit
|
||||||
`e4e72dc9d831dd09ee8fabc222ad1e7f5139050e` and the official catalog current on
|
`e4e72dc9d831dd09ee8fabc222ad1e7f5139050e` and the official catalog current on
|
||||||
2026-10-07. Its fixed catalog URL uses `itsplk.github.io`; all 25 catalog download
|
2026-10-07. Its fixed catalog URL uses `itsplk.github.io`; all 25 catalog download
|
||||||
@@ -218,8 +228,10 @@ Vikingfile and their download infrastructure are intentionally excluded: they se
|
|||||||
third-party game files, many catalog entries have no SHA-256, and those hosts are
|
third-party game files, many catalog entries have no SHA-256, and those hosts are
|
||||||
not required for catalog browsing or BlackBox updates.
|
not required for catalog browsing or BlackBox updates.
|
||||||
The PS5 was previously identified as `192.168.10.26`; requests from
|
The PS5 was previously identified as `192.168.10.26`; requests from
|
||||||
`192.168.10.6` seen at that time were from a different client. Those addresses
|
`192.168.10.6` seen at that time were from the operator's own workstation, not a
|
||||||
are historical and must not be used as the current payload destination.
|
console, before the consoles were moved onto VLAN 40. All `192.168.10.0/24`
|
||||||
|
addresses are historical and must not be used as the current payload destination;
|
||||||
|
with `ALLOWED_CLIENTS` set to `192.168.40.0/28` they can no longer query the gateway.
|
||||||
|
|
||||||
The PS5 ELF loader listens on TCP port `9021` after a successful exploit run. On
|
The PS5 ELF loader listens on TCP port `9021` after a successful exploit run. On
|
||||||
2026-10-01, a connection-only probe from `net-utils01` to
|
2026-10-01, a connection-only probe from `net-utils01` to
|
||||||
|
|||||||
+12
-1
@@ -20,7 +20,8 @@ Na rede onde este projeto foi inicialmente instalado:
|
|||||||
- porta publicada: `8000`.
|
- porta publicada: `8000`.
|
||||||
- DNS local: `192.168.20.30:53` (UDP e TCP);
|
- DNS local: `192.168.20.30:53` (UDP e TCP);
|
||||||
- gateway do Guia: `192.168.20.30:80` e `192.168.20.30:443`.
|
- gateway do Guia: `192.168.20.30:80` e `192.168.20.30:443`.
|
||||||
- IP estático atual da PS5: `192.168.40.14`.
|
- consolas autorizadas (VLAN `192.168.40.0/28`): PS5PRO `192.168.40.14`,
|
||||||
|
PS5FAT `192.168.40.13`.
|
||||||
|
|
||||||
A porta 8080 do host já pertence ao UniFi e não deve ser reutilizada.
|
A porta 8080 do host já pertence ao UniFi e não deve ser reutilizada.
|
||||||
|
|
||||||
@@ -146,6 +147,9 @@ O Compose inclui um DNS controlado no `net-utils01` que:
|
|||||||
Manager, Spectrum Library e BlackBox;
|
Manager, Spectrum Library e BlackBox;
|
||||||
- devolva `NXDOMAIN` para todos os restantes nomes, mantendo PSN, updates e
|
- devolva `NXDOMAIN` para todos os restantes nomes, mantendo PSN, updates e
|
||||||
telemetria bloqueados por DNS;
|
telemetria bloqueados por DNS;
|
||||||
|
- responda apenas a clientes na VLAN das consolas (`192.168.40.0/28` por
|
||||||
|
defeito, via `ALLOWED_CLIENTS`), descartando consultas de qualquer outra
|
||||||
|
origem;
|
||||||
- registe as consultas nos logs do container;
|
- registe as consultas nos logs do container;
|
||||||
- apresente um gateway HTTPS local e redirecione o browser para o exploit em
|
- apresente um gateway HTTPS local e redirecione o browser para o exploit em
|
||||||
`http://192.168.20.30:8000/`.
|
`http://192.168.20.30:8000/`.
|
||||||
@@ -173,6 +177,13 @@ não um hostname. A firewall deve permitir UDP e TCP `53` de `net-utils01` para
|
|||||||
resolvedor. A consola continua a precisar apenas de UDP/TCP `53` para
|
resolvedor. A consola continua a precisar apenas de UDP/TCP `53` para
|
||||||
`192.168.20.30`; não deve consultar diretamente um DNS público.
|
`192.168.20.30`; não deve consultar diretamente um DNS público.
|
||||||
|
|
||||||
|
O gateway só responde a consultas DNS vindas das redes listadas em `ALLOWED_CLIENTS`
|
||||||
|
(por defeito `192.168.40.0/28`, a VLAN das consolas). O valor aceita uma lista
|
||||||
|
separada por vírgulas de endereços individuais e/ou intervalos CIDR — por exemplo,
|
||||||
|
`192.168.40.13,192.168.40.14` para trancar apenas às duas PS5 autorizadas (PS5FAT e
|
||||||
|
PS5PRO). Um valor vazio desativa o filtro e serve todos os clientes. Consultas de
|
||||||
|
origens não permitidas são descartadas e registadas como `denied`.
|
||||||
|
|
||||||
O acesso WAN da consola pode ficar limitado a TCP `443` para os domínios
|
O acesso WAN da consola pode ficar limitado a TCP `443` para os domínios
|
||||||
permitidos. Não são necessárias regras WAN de entrada. Se faltarem ícones, consultar
|
permitidos. Não são necessárias regras WAN de entrada. Se faltarem ícones, consultar
|
||||||
os logs da firewall: um URL de ícone apontado pelo catálogo para outro domínio será
|
os logs da firewall: um URL de ícone apontado pelo catálogo para outro domínio será
|
||||||
|
|||||||
Reference in New Issue
Block a user