Files
computer-playbook/roles/web-app-moodle/meta/volumes.yml
kevinveenbirkenbachandClaude Opus 5.5 d89c74feab feat(security): harden PHP services and proxy response headers
Proxy:
- server_tokens off, X-Powered-By stripped from upstream responses,
  HSTS max-age raised to one year.
- No global X-Content-Type-Options: under nosniff, ORB (step 3.4)
  blocks no-cors cross-origin responses typed text/html, e.g. tracking
  beacons answered with an empty 204.

PHP (CVE-2026-109618, CVE-2026-109619):
- New role sys-svc-compose-php installs a shared ini (expose_php Off,
  session.upload_progress.enabled 0, fatal_error_backtraces 0 for
  PHP 8.5, interim memory_limit -1) and a PHP-FPM [www] drop-in
  (pm.max_requests = PHP_FPM_MAX_REQUESTS) once per stack host,
  before 04_files renders any compose file.
- The host file names carry a sha1 prefix of the controller-side
  source, so a content change alters every PHP app's compose.yml and
  recreates it, also on remote deploys where compose_volumes cannot
  read the stack host file and hashes the path instead.
- 20 PHP roles mount the ini as a compose/swarm config into their
  image's scan dir; moodle, nextcloud and shopware also mount the FPM
  drop-in. Magento keeps its own pool: its php-fpm.conf has no
  include= and is rendered without notify.
- Joomla's php-upload.ini now loads as zzz-joomla-uploads.ini so its
  own memory_limit wins: the media API compares Content-Length with
  toBytes(memory_limit) and rejects every upload at -1.

TODOs record the memory_limit revert condition and accepted
trade-offs, Akaunting on PHP 8.1, FusionDirectory on PHP 7.4 and the
public Keycloak admin console.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 21:03:38 +02:00

66 lines
1.7 KiB
YAML

---
data:
type: volume
name: moodle_data
nfs:
uid: "33"
gid: "33"
mode: "0770"
mounts:
- service: moodle
target: &var_www_moodledata_target /var/www/moodledata
- service: cron
target: *var_www_moodledata_target
localcache:
type: volume
name: moodle_localcache
# nocheck: nfs-false-data-loss Reason: Moodle documents localcachedir as node-local and safe to delete, unlike cachedir and tempdir which stay on the shared dataroot
nfs: false
mounts:
- service: moodle
target: &moodle_localcache /var/www/moodlelocalcache
- service: cron
target: *moodle_localcache
code:
type: volume
name: moodle_code
mounts:
- service: moodle
target: &var_www_html_target /var/www/html
- service: nginx
target: *var_www_html_target
read_only: true
- service: cron
target: *var_www_html_target
nginx_conf:
type: config
source: "{{ [lookup('container', 'web-app-moodle', 'directories.instance'), 'nginx.conf'] | path_join }}"
mode: "0444"
mounts:
- service: nginx
target: /etc/nginx/conf.d/default.conf
msmtprc:
type: config
source: "{{ [lookup('container', 'web-app-moodle', 'directories.config'), 'msmtprc.conf'] | path_join }}"
mode: "0444"
mounts:
- service: moodle
target: &etc_msmtprc_target /etc/msmtprc
- service: cron
target: *etc_msmtprc_target
php_hardening:
type: config
source: "{{ FILE_PHP_HARDENING_INI }}"
mode: "0444"
mounts:
- service: moodle
target: /usr/local/etc/php/conf.d/zz-infinito-hardening.ini
php_fpm_hardening:
type: config
source: "{{ FILE_PHP_FPM_HARDENING_CONF }}"
mode: "0444"
mounts:
- service: moodle
target: /usr/local/etc/php-fpm.d/zz-infinito-hardening.conf