Sécuriser un site WordPress en DMZ avec Podman rootless et les images officielles

Découvrez comment sécuriser un site WordPress en DMZ grâce à Podman rootless : isolation renforcée, images officielles, déploiement automatisé et bonnes pratiques DevSecOps.


Introduction

De nombreuses organisations hébergent encore leurs sites web dans une DMZ (zone démilitarisée) sur des machines virtuelles classiques.
L’architecture typique repose sur une VM Debian/Ubuntu, avec Apache, PHP et MySQL installés à la main. Cette approche, encore répandue, présente plusieurs limites : mises à jour compliquées, dépendances figées, surfaces d’attaque élevées.

Aujourd’hui, il existe des solutions plus modernes, plus sûres et plus simples à maintenir. Dans cet article, nous allons voir comment moderniser l’hébergement d’un site WordPress en DMZ grâce à Podman rootless et aux images officielles WordPress/MariaDB validées par les éditeurs.


Hébergement legacy en VM : limites et risques

Un hébergement “à l’ancienne” repose généralement sur :

  • VM Debian/Ubuntu en DMZ
  • Apache + PHP + MySQL installés manuellement
  • WordPress téléchargé et mis à jour via son interface

Inconvénients

  • Mises à jour fastidieuses (OS + Apache + PHP + MySQL + WordPress).
  • Risque de retard dans l’application des patchs de sécurité.
  • Surfaces d’attaque multiples (chaque service peut contenir une faille).
  • Peu d’automatisation possible.

En DMZ, où la surface d’attaque doit être minimisée, ces limites deviennent critiques.


Modernisation avec Podman rootless

Pourquoi Podman ?

Podman est un moteur de conteneurs Linux, compatible avec Docker, qui fonctionne sans démon root. En mode rootless, chaque utilisateur gère ses propres conteneurs, dans son namespace, sans privilèges administrateur.

Avantages

  • Isolation renforcée : exécution rootless avec namespaces Linux.
  • Sécurité accrue : pas de démon root exposé.
  • Images officielles et signées : WordPress et MariaDB depuis Docker Hub.
  • Maintenance simplifiée : mises à jour automatiques (podman auto-update).
  • Intégration systemd : gestion des conteneurs comme des services.

Pourquoi pas Kubernetes ?

Kubernetes est très puissant, mais surdimensionné pour un simple WordPress exposé en DMZ.
Podman est un compromis idéal :

  • léger et simple,
  • compatible avec YAML/Kube (via podman generate kube),
  • sans la complexité opérationnelle de Kubernetes.

Choisir l’OS hôte pour Podman en DMZ

L’OS hôte doit être :

  • léger et minimal (réduire la surface d’attaque),
  • maintenu et patché régulièrement,
  • supportant Podman rootless nativement.

Recommandations

  • Fedora Server ou CentOS Stream / RHEL : Podman est intégré et supporté par Red Hat.
  • Debian 12 ou Ubuntu 22.04 LTS : stables, largement utilisés, installation de Podman simple via apt.
  • Rocky Linux / AlmaLinux : alternatives RHEL compatibles.

👉 En DMZ, installez uniquement les paquets nécessaires : un hôte minimal réduit la surface d’attaque.


Installation de Podman

Sur Debian 12 / Ubuntu 22.04 LTS

sudo apt update
sudo apt -y install podman podman-compose

Sur CentOS Stream / Rocky / AlmaLinux

sudo dnf -y install podman podman-compose

Vérification

podman --version
podman info

Activer l’exécution rootless

sudo loginctl enable-linger webuser

Cela permet à systemd --user de gérer les conteneurs, même sans session ouverte.


Tableau comparatif : VM Legacy vs Podman rootless

CritèreLegacy (VM Apache/MySQL)Podman rootless (WordPress officiel)
Surface d’attaqueLarge (OS + Apache + PHP + MySQL)Réduite (containers isolés rootless)
Mises à jourManuelles et fastidieusesAutomatisées via podman auto-update
IsolationProcessus partagés sur la VMNamespaces + cgroups rootless
ComplexitéSimple mais rigideLéger, modulable, plus moderne
Sécurité en DMZRisques élevésCloisonnement + images validées
ÉvolutivitéFaibleÉlevée (pods, compat YAML/Kube)

Déploiement complet WordPress + MariaDB avec Podman rootless

Pré-requis

  • Serveur minimal Debian/Ubuntu en DMZ
  • Utilisateur non-root (ex. webuser)
  • Podman et podman-compose installés

1. Préparer l’environnement

sudo -iu webuser

mkdir -p ~/wordpress-stack/{data/wordpress,data/mariadb,secrets,logs}
podman network create wordpress-net

# Génération des secrets
openssl rand -base64 32 > ~/wordpress-stack/secrets/db_root_password
openssl rand -base64 32 > ~/wordpress-stack/secrets/db_user_password

podman secret create db_root_password ~/wordpress-stack/secrets/db_root_password
podman secret create db_user_password ~/wordpress-stack/secrets/db_user_password

2. Fichier Compose (clé en main)

~/wordpress-stack/docker-compose.yml

version: "3.8"

services:
  mariadb:
    image: docker.io/library/mariadb:11
    restart: always
    networks: [ wordpress-net ]
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD_FILE: /run/secrets/db_user_password
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
    volumes:
      - ./data/mariadb:/var/lib/mysql:Z
    secrets:
      - db_root_password
      - db_user_password
    healthcheck:
      test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot --password=$$(cat /run/secrets/db_root_password) || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 5
    labels:
      io.containers.autoupdate: "registry"
    read_only: true
    tmpfs: ["/tmp","/run"]
    cap_drop: [ "ALL" ]
    security_opt: [ "no-new-privileges:true" ]

  wordpress:
    image: docker.io/library/wordpress:6-apache
    restart: always
    depends_on:
      mariadb:
        condition: service_healthy
    networks: [ wordpress-net ]
    environment:
      WORDPRESS_DB_HOST: mariadb
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_user_password
      WORDPRESS_TABLE_PREFIX: wp_
    volumes:
      - ./data/wordpress:/var/www/html:Z
    secrets:
      - db_user_password
    ports:
      - "8080:80"
    healthcheck:
      test: ["CMD-SHELL", "curl -fsS http://127.0.0.1/wp-login.php >/dev/null || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 5
    labels:
      io.containers.autoupdate: "registry"
    read_only: true
    tmpfs: ["/tmp","/run"]
    cap_drop: [ "ALL" ]
    security_opt: [ "no-new-privileges:true" ]

networks:
  wordpress-net:
    external: true

secrets:
  db_root_password:
    external: true
  db_user_password:
    external: true

3. Démarrage

cd ~/wordpress-stack
podman-compose up -d

WordPress est accessible sur http://<hôte>:8080.
En DMZ, utilisez un reverse proxy (Nginx/HAProxy) en frontal avec SSL offloading.


4. Intégration systemd user

~/.config/systemd/user/wordpress-stack.service

[Unit]
Description=WordPress Stack (Podman rootless)
After=network-online.target

[Service]
Type=oneshot
WorkingDirectory=%h/wordpress-stack
ExecStart=/usr/bin/podman-compose up -d
ExecStop=/usr/bin/podman-compose down
RemainAfterExit=yes

[Install]
WantedBy=default.target

Activation :

systemctl --user daemon-reload
systemctl --user enable --now wordpress-stack.service
loginctl enable-linger $(whoami)

5. Mise à jour automatique

systemctl --user enable --now podman-auto-update.timer

Mise à jour forcée :

podman auto-update

Mises à jour majeures : au-delà de podman auto-update

L’option podman auto-update permet de garder les conteneurs à jour sur leur branche actuelle :

  • Exemple : wordpress:6-apache → reçoit automatiquement les patchs de sécurité et mises à jour mineures publiées par WordPress pour la branche 6.
  • Exemple : mariadb:11 → suit les correctifs publiés par les mainteneurs.

👉 Limite : cette approche ne couvre pas les changements de version majeure (ex. WordPress 6 → 7, MariaDB 11 → 12).

Comment gérer les montées de version

  1. Surveiller les nouvelles releases (notes de version officielles WordPress/MariaDB).
  2. Modifier le tag dans docker-compose.yml :
    - image: docker.io/library/wordpress:6-apache
    + image: docker.io/library/wordpress:7-apache
  3. Redéployer après sauvegarde et tests :
    podman-compose pull
    podman-compose up -d
  4. Rollback facile si besoin (revenir à l’ancien tag).

Bonnes pratiques

  • Utiliser auto-update pour rester à jour dans une branche stable.
  • Planifier des fenêtres de mise à jour contrôlées (ex. trimestrielles) pour les montées de version majeures.
  • Vérifier la compatibilité PHP/MySQL avant un bump WordPress.
  • Automatiser la détection des nouvelles versions avec un outil comme Renovate ou Watchtower, afin d’être notifié lorsqu’un nouveau tag est disponible.

Sécurisation en DMZ

  1. Base non exposée : MariaDB uniquement via wordpress-net.
  2. Reverse proxy : Nginx/HAProxy avec SSL.
  3. Images officielles signées : WordPress/MariaDB Docker Hub.
  4. Isolation : rootless, SELinux, cap_drop=ALL.
  5. Mises à jour automatisées : via Podman auto-update.
  6. Scanning vulnérabilités : trivy image docker.io/library/wordpress:6-apache.
  7. Firewall strict : seuls 80/443 exposés.
  8. Sauvegardes : persistance des volumes ~/wordpress-stack/data/.

Comparatif visuel : avant / après

[Legacy]
Internet ──> [Firewall DMZ] ──> [VM Debian]
                            ├─ Apache + PHP + WordPress
                            └─ MySQL

[Modernisé]
Internet ──> [Firewall DMZ] ──> [Host Debian minimal]
                               ├─ Podman rootless (webuser)
                               │   ├─ WordPress (image officielle)
                               │   └─ MariaDB (isolé)
                               └─ Reverse Proxy (SSL, filtrage)

FAQ (SEO)

Pourquoi utiliser Podman rootless pour WordPress en DMZ ?
Parce qu’il renforce l’isolation (pas de démon root), réduit la surface d’attaque et simplifie les mises à jour.

Quelle différence entre Docker et Podman rootless ?
Docker fonctionne avec un démon root, Podman rootless n’en nécessite pas. Cela réduit l’impact potentiel d’une compromission.

Est-il nécessaire d’avoir Kubernetes ?
Non. Pour un simple WordPress en DMZ, Podman rootless suffit. Kubernetes est adapté à des architectures multi-sites ou multi-services complexes.

Comment mettre à jour WordPress automatiquement ?
Avec podman auto-update et les labels io.containers.autoupdate=registry.


Liens utiles


Conclusion

Migrer un site WordPress legacy hébergé en DMZ vers un déploiement Podman rootless offre :

  • Une sécurité renforcée (isolation utilisateur, images validées, surface d’attaque réduite).
  • Une maintenance simplifiée (mises à jour automatiques, containers jetables).
  • Une architecture moderne et légère, sans la complexité de Kubernetes.

C’est une solution idéale pour sécuriser rapidement un site WordPress exposé en DMZ, tout en préparant une éventuelle évolution vers des environnements plus complexes.


Assistant IA