First version of server config for omny

Apache vhost for omny-test.psi.ch (migration from lighttpd)
This config replaces the lighttpd setup for the OMNY status page. All authentication is done at the PHP level via rewrite rules — there is no mod_auth usage. Requests to the administrators:

Enable mod_rewrite and mod_ssl. Note: the vhost will fail configtest without mod_rewrite — this is intentional (without the rewrite rules, Apache would serve all files with no authentication, so failing loudly is the safe mode).
Certificate: the SSLCertificateFile / SSLCertificateKeyFile paths are placeholders in Let's Encrypt layout — please adjust to the actual certificate location for omny-test.psi.ch, or let us know how TLS is provisioned on this host.
PHP execution must be active for .php files under /var/www/omny (PHP-FPM, CGI/FastCGI, or mod_php — whichever is standard on this host is fine; the code requires PHP ≥ 7.1, no extensions beyond the defaults).
Please confirm whether any reverse proxy / load balancer sits in front of Apache. Several endpoints (upload.php, session_query.php, set_password.php) authorize by client IP (REMOTE_ADDR); if requests arrive via a proxy, we need to know so we can adapt the whitelist logic.
After deployment: apachectl configtest and reload. A quick functional check is opening https://omny-test.psi.ch/login.php — the login form should render (if PHP source code is shown instead, PHP execution is not wired up; please don't leave it in that state, as the source contains a secret).

The optional HSTS header is present but commented out (would additionally require mod_headers)
This commit is contained in:
2026-07-14 14:46:46 +02:00
committed by gitadmin
parent c0fed2147a
commit c2dc78b958
+108 -5
View File
@@ -1,11 +1,114 @@
# ============================================================
# omny-test.psi.ch — HTTPS test instance
#
# Based on the admin-provided vhost skeleton, extended with:
# * HTTPS vhost + HTTP->HTTPS redirect (ACME path excepted)
# * DirectoryIndex, -Indexes
# * deny rules for .htpasswd/.gen/.inc/backup files
# * auth-gate rewrite rules
#
# Requirements (for the administrators):
# * mod_rewrite and mod_ssl enabled. The vhost will
# intentionally FAIL to load without mod_rewrite, rather
# than silently serving everything unauthenticated.
# * PHP execution active for .php files in /var/www/omny.
# * SSLCertificateFile / SSLCertificateKeyFile paths below
# are PLACEHOLDERS (Let's Encrypt layout) — please adjust
# to the actual certificate location for omny-test.psi.ch.
# ============================================================
# ------------------------------------------------------------
# Port 80: redirect everything to HTTPS, except ACME challenges
# (exception only matters if certbot webroot renewal is used;
# harmless otherwise)
# ------------------------------------------------------------
<VirtualHost *:80>
ServerName omny-test.psi.ch
DocumentRoot /var/www/omny
<Directory "/var/www/omny">
Options +ExecCGI
AllowOverride None
Require all granted
</Directory>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
RewriteRule ^ https://omny-test.psi.ch%{REQUEST_URI} [R=301,L]
# Query strings are preserved automatically on [R] redirects.
</VirtualHost>
# ------------------------------------------------------------
# Port 443: the actual site
# ------------------------------------------------------------
<VirtualHost *:443>
ServerName omny-test.psi.ch
DocumentRoot /var/www/omny
SSLEngine on
# PLACEHOLDER paths — adjust to the real certificate:
SSLCertificateFile /etc/letsencrypt/live/omny-test.psi.ch/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/omny-test.psi.ch/privkey.pem
ErrorLog ${APACHE_LOG_DIR}/omny-test_error.log
CustomLog ${APACHE_LOG_DIR}/omny-test_access.log combined
# Optional hardening (requires mod_headers). Deliberately
# disabled on the test instance; enable on production:
# Header always set Strict-Transport-Security "max-age=31536000"
<Directory "/var/www/omny">
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
</Directory>
# --------------------------------------------------------
# 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".)
# --------------------------------------------------------
<FilesMatch "(\.htpasswd|\.gen|\.inc|~)$">
Require all denied
</FilesMatch>
RewriteEngine On
# 0. URL-level deny before any rewriting.
RewriteRule \.(htpasswd|gen)$ - [F,L]
# 1. 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]
# 2. 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]
# 3. Normalize /samples -> /samples/ so it hits the samples
# gate instead of falling through to the main gate.
RewriteRule ^/samples$ /samples/ [R=301,L]
# 4. 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]
# 5. Everything else: main auth gate.
RewriteRule ^/(.*)$ /auth_gate.php?_file=$1 [END,QSA]
</VirtualHost>