111 lines
4.5 KiB
Plaintext
111 lines
4.5 KiB
Plaintext
# Hostnames that are reachable from the public internet. The operator console
|
|
# (/admin) must NEVER be served on these — only the marketing site and the
|
|
# customer portal are public; Proxmox hosts and /admin stay on the private
|
|
# network / VPN.
|
|
#
|
|
# Deliberately a denylist, not an allowlist: a typo in an allowlist would lock
|
|
# the operators out of their own console. The app-level allowlist (ADMIN_HOSTS,
|
|
# see config/admin_access.php) is the strict layer — this one guarantees that a
|
|
# request arriving on a known-public hostname never even reaches PHP.
|
|
map $host $admin_host_is_public {
|
|
default 0;
|
|
www.dev.clupilot.com 1;
|
|
app.dev.clupilot.com 1;
|
|
api.dev.clupilot.com 1;
|
|
ws.dev.clupilot.com 1;
|
|
www.clupilot.com 1;
|
|
app.clupilot.com 1;
|
|
api.clupilot.com 1;
|
|
ws.clupilot.com 1;
|
|
}
|
|
|
|
server {
|
|
listen 80 default_server;
|
|
server_name _;
|
|
root /var/www/html/public;
|
|
index index.php;
|
|
|
|
charset utf-8;
|
|
client_max_body_size 64M;
|
|
|
|
# ^~ beats the regex locations, so this decides before PHP is reached. The
|
|
# try_files rewrite to /index.php re-runs location matching, so the console
|
|
# still executes normally on a permitted host.
|
|
#
|
|
# This only covers direct hits: Livewire posts component actions to
|
|
# /livewire/update, which nginx cannot attribute to /admin. That case is
|
|
# handled in the app (RestrictAdminHost is registered as Livewire-persistent
|
|
# middleware) — do not treat this block as the only control.
|
|
location ^~ /admin {
|
|
if ($admin_host_is_public) {
|
|
return 404;
|
|
}
|
|
try_files $uri $uri/ /index.php?$query_string;
|
|
}
|
|
|
|
# Der einzige Pfad zur Terminal-Bruecke. Bewusst eng: kein Praefix-Match
|
|
# auf /terminal, sondern genau dieser eine Ort.
|
|
#
|
|
# AN DER WURZEL, nicht unter AdminArea::prefix(): nginx kann die Konfiguration
|
|
# der Anwendung nicht lesen, dieser Ort muss also ein fester Text sein — und
|
|
# er ist ohnehin keine Konsolenseite, sondern eine Steckdose, die PHP nie
|
|
# sieht. resources/js/terminal.js verbindet aus demselben Grund fest hierher.
|
|
#
|
|
# ACHTUNG: dieser Pfad laeuft NICHT durch PHP, also greift
|
|
# RestrictConsoleNetwork hier nicht. Der Riegel ist allein das Ticket —
|
|
# einmalig, dreissig Sekunden, an einen Host und einen Betreiber gebunden.
|
|
# So steht es auch in der Spec. Das Ticket steht deshalb NICHT in der
|
|
# Adresszeile, sondern in `Sec-WebSocket-Protocol`: die Adresse eines
|
|
# Upgrade-Antrags landet im Zugriffsprotokoll, der Kopf nicht.
|
|
#
|
|
# `terminal` ist ein Netz-Alias von queue-provisioning (siehe
|
|
# docker-compose.yml): die Bruecke steht im Tunnel und teilt sich dessen
|
|
# Netz-Namensraum.
|
|
location = /terminal/ws {
|
|
# Dieselbe Regel wie bei /admin darueber: die Bruecke ist Werkzeug der
|
|
# Konsole und hat auf einem oeffentlichen Namen nichts zu suchen.
|
|
if ($admin_host_is_public) {
|
|
return 404;
|
|
}
|
|
|
|
# Aufgeloest zur Laufzeit, nicht beim Start. nginx loest einen festen
|
|
# Namen in `proxy_pass` beim Laden der Konfiguration auf und WEIGERT
|
|
# SICH ZU STARTEN, wenn er ihn nicht findet ("host not found in
|
|
# upstream"). Damit haengte die ganze Konsole daran, dass die
|
|
# Terminal-Bruecke schon laeuft — wegen eines Fensters, das gerade
|
|
# niemand offen hat. Ueber eine Variable mit `resolver` (Dockers
|
|
# eingebauter DNS) wird daraus ein 502 an genau dieser Stelle, waehrend
|
|
# alles andere weiterlaeuft.
|
|
resolver 127.0.0.11 valid=10s ipv6=off;
|
|
set $terminal_upstream terminal:8082;
|
|
|
|
proxy_pass http://$terminal_upstream;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_read_timeout 900s;
|
|
proxy_send_timeout 900s;
|
|
}
|
|
|
|
location / {
|
|
try_files $uri $uri/ /index.php?$query_string;
|
|
}
|
|
|
|
location = /favicon.ico { access_log off; log_not_found off; }
|
|
# robots.txt is generated by the app (it changes with the site's visibility),
|
|
# so it must NOT be short-circuited to a file on disk.
|
|
|
|
location ~ \.php$ {
|
|
fastcgi_pass 127.0.0.1:9000;
|
|
fastcgi_index index.php;
|
|
include fastcgi_params;
|
|
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
|
fastcgi_param DOCUMENT_ROOT $realpath_root;
|
|
}
|
|
|
|
location ~ /\.(?!well-known).* {
|
|
deny all;
|
|
}
|
|
}
|