diff --git a/apache/conf/omny.conf b/apache/conf/omny.conf index e2af834..21632dc 100644 --- a/apache/conf/omny.conf +++ b/apache/conf/omny.conf @@ -1,11 +1,100 @@ +# ============================================================ +# omny-test.psi.ch — behind an SSL-terminating reverse proxy +# +# The proxy terminates HTTPS and forwards requests to this +# Apache as plain HTTP on port 80. Therefore: +# * everything (auth-gate rewrites, deny rules) lives in the +# *:80 vhost — there is no *:443 vhost on this host +# * the HTTP->HTTPS redirect fires ONLY when the proxy +# explicitly reports "X-Forwarded-Proto: http". If the +# header is absent, no redirect happens (loop-proof). +# +# Requirements (for the administrators): +# * mod_rewrite enabled. The vhost will intentionally FAIL +# to load without it, rather than silently serving +# everything unauthenticated. +# * PHP execution active for .php files in /var/www/omny. +# * IMPORTANT: mod_remoteip configured with the proxy's IP +# (RemoteIPHeader X-Forwarded-For + +# RemoteIPInternalProxy ), so REMOTE_ADDR shows +# the real client. Several endpoints authorize by client +# IP; without mod_remoteip they see only the proxy address. +# ============================================================ + - ServerName omny.web.psi.ch + ServerName omny.psi.ch DocumentRoot /var/www/omny + ErrorLog ${APACHE_LOG_DIR}/omny_error.log + CustomLog ${APACHE_LOG_DIR}/omny_access.log combined + - Options +ExecCGI + Options +ExecCGI -Indexes AllowOverride None Require all granted + # Bare "/" is normally caught by the catch-all rewrite + # below; DirectoryIndex kept as fallback. + DirectoryIndex login.php index.html index.php - + # -------------------------------------------------------- + # Block direct filesystem access to sensitive / junk files. + # (Apache's default "^\.ht" rule does NOT cover + # users.htpasswd / session.htpasswd — they don't start + # with ".ht".) + # -------------------------------------------------------- + + Require all denied + + + RewriteEngine On + + # -------------------------------------------------------- + # 0. HTTPS enforcement, loop-proof behind the proxy: + # redirect ONLY if the proxy explicitly reports that the + # original request was plain HTTP. If the proxy does not + # send X-Forwarded-Proto, this never matches -> no loop. + # -------------------------------------------------------- + RewriteCond %{HTTP:X-Forwarded-Proto} =http + RewriteRule ^ https://omny-test.psi.ch%{REQUEST_URI} [R=301,L] + + # 1. URL-level deny before any rewriting. + RewriteRule \.(htpasswd|gen)$ - [F,L] + + # 2. Guard: forbid direct client requests that pass the + # internal _file parameter to the gate scripts (would + # otherwise let a logged-in user stream PHP source incl. + # TOKEN_SECRET). Internal rewrites are unaffected: the + # gate rewrites below use [END], which skips rule + # re-processing. + RewriteCond %{QUERY_STRING} (^|&)_file= + RewriteRule ^/(samples/)?auth_gate\.php$ - [F,L] + + # 3. Pass-throughs (no cookie check) — first match wins. + RewriteRule ^/login\.php$ - [L] + RewriteRule ^/upload\.php$ - [L] + RewriteRule ^/session_query\.php$ - [L] + RewriteRule ^/set_password\.php$ - [L] + RewriteRule ^/info\.php$ - [L] + RewriteRule ^/auth_gate\.php$ - [L] + RewriteRule ^/samples/auth_gate\.php$ - [L] + RewriteRule ^/\.well-known/acme-challenge/ - [L] + RewriteRule ^/samples/upload\.php$ - [L] + RewriteRule ^/samples/newmeasurement\.php$ - [L] + + # 4. Normalize /samples -> /samples/ so it hits the samples + # gate instead of falling through to the main gate. + RewriteRule ^/samples$ /samples/ [R=301,L] + + # 5. Samples area: fixed users only. + # [END] (not [L]) is essential: Apache re-runs the rule + # set after internal redirects; without END this rule + # would match its own output and loop. + # [QSA] appends the original query string, e.g. + # /samples/x.json?t=1 -> _file=x.json&t=1 + # (auth_gate.php handles this form via strtok). + RewriteRule ^/samples/(.*)$ /samples/auth_gate.php?_file=$1 [END,QSA] + + # 6. Everything else: main auth gate. + RewriteRule ^/(.*)$ /auth_gate.php?_file=$1 [END,QSA] + diff --git a/conf.d/omny.conf b/conf.d/omny.conf index eaed463..e743d45 100644 --- a/conf.d/omny.conf +++ b/conf.d/omny.conf @@ -2,13 +2,13 @@ server { listen 80; - server_name omny.web.psi.ch; + server_name omny.psi.ch; return 301 https://$host$request_uri; } server { listen 443 ssl; - server_name omny.web.psi.ch; + server_name omny.psi.ch; ssl_certificate /etc/nginx/certs/lx-docker-dmz-01.psi.ch.crt; ssl_certificate_key /etc/nginx/private/lx-docker-dmz-01.psi.ch.key; diff --git a/docker-compose.yaml b/docker-compose.yaml index 56765bb..8a0d58a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -30,11 +30,11 @@ services: volumes: - /opt/webcontent/DMZ/rfmwtools:/var/www/rfmwtools:ro - /opt/webcontent/DMZ/fluid-eos:/var/www/fluid-eos:rw - - /opt/webcontent/DMZ/omny:/var/www/omny:rw - /opt/webcontent/DMZ/cas-status:/var/www/cas_status:rw - /mount/srem/webhosting:/var/www/srem:rw - /mount/webhosting_dmz_write/tcpwiki:/var/www/tcpwiki:rw - /mount/webhosting_dmz_write/dokuwiki-core:/var/www/dokuwiki-core:r + - /mount/webhosting_dmz_write/omny:/var/www/omny:rw - ./apache/conf:/etc/apache2/sites-enabled:ro networks: - backend @@ -44,7 +44,7 @@ services: image: gitea.psi.ch/images/mcda-calculator:1.0.3 container_name: mcda-calculator restart: always - networks: + networks: - backend # MCDA DSS Huang He @@ -117,7 +117,7 @@ services: image: gitea.psi.ch/images/up-mavt-suite-frontend:0.9.8 container_name: up-mavt-suite-frontend environment: - VITE_DEBUG_CONSOLE: true + VITE_DEBUG_CONSOLE: true depends_on: - up-mavt-suite-backend networks: @@ -144,7 +144,6 @@ services: networks: - backend - # Lange Clemens # summer-project-selection.psi.ch summer-project-selection: @@ -204,7 +203,7 @@ services: volumes: - /mount/rocrate_qa:/rocrate:rw -# LEAPS ultrafast frithjof.nolting@psi.ch + # LEAPS ultrafast frithjof.nolting@psi.ch felira-web: image: gitea.psi.ch/leaps/leaps-felira:3.0.3 container_name: felira-web