PmaControl logo PmaControl
  • Accueil
  • PmaControl
    • Agents IA 13 agents on-premise
    • Nos offres Community, Cloud, On-Premise, Premium
    • Documentation Guides, API, architecture
    • Clients 28+ entreprises
    • FAQ 25 questions / 7 catégories
    Bases de données
    • MariaDB 30 articles
    • MySQL 10 articles
    • Galera Cluster 6 articles
    • MaxScale 3 articles
    • ProxySQL 2 articles
    • Amazon Aurora MySQL 0 article
    • Azure Database 0 article
    • ClickHouse 0 article
    • GCP CloudSQL 0 article
    • Percona Server 0 article
    • SingleStore 0 article
    • TiDB 0 article
    • Vitess 0 article
    Solutions
    • Support 24×7 Urgences MariaDB & MySQL
    • Observabilité SQL Monitoring, alertes, topologie
    • Haute disponibilité Réplication, failover, Galera
    • Disaster Recovery Backup, restore, RPO/RTO
    • Sécurité & conformité Audit, RGPD, SOC2
    • Migration & upgrade Zero downtime, pt-osc, gh-ost
  • Nos offres
  • Ressources
    • Documentation Guides techniques & API
    • FAQ 25 questions fréquentes
    • Témoignages Retours clients & cas d'usage
    • Blog Articles & insights
    • Roadmap Fonctionnalités à venir
    Domaines d'expertise
    • Observabilité SQL Monitoring, alertes, topologie Dot3
    • Haute disponibilité Réplication, failover, Galera
    • Sécurité & conformité Audit, RGPD, SOC2, ISO 27001
    • Disaster Recovery Backup, restore, RPO/RTO
    • Performance & optimisation Digests, EXPLAIN, tuning
    • Migration & upgrade Zero downtime, pt-osc
    Liens rapides
    • Wiki GitHub 26 pages — install, engine, plugins
    • Code source Repository GitHub officiel
    • Support 24×7 Urgences MariaDB & MySQL
    • Réserver une démo 30 min — architecture réelle
  • Support 24×7
  • Réserver une démo
Réserver une démo
🇫🇷 FR Français 🇬🇧 EN English 🇵🇱 PL Polski 🇷🇺 RU Русский 🇨🇳 ZH 中文
← Retour au blog

Durcir PmaControl en production : guide de sécurité complet

Publié le 13 avril 2026 Par Aurélien LEQUOY
pmacontrol security hardening apache php mariadb
Partager X LinkedIn Facebook Email PDF
Durcir PmaControl en production : guide de sécurité complet

PmaControl a les clés du royaume

PmaControl supervise vos serveurs MariaDB / MySQL de production. Il stocke les credentials de connexion, les clés SSH, les métriques de performance, la structure des bases. Si un attaquant compromet PmaControl, il a potentiellement accès à toute votre infrastructure de bases de données.

Ce guide détaille les mesures de durcissement à appliquer avant de mettre PmaControl en production. Il est issu d'un audit sécurité interne et couvre chaque couche : Apache, PHP, MariaDB, secrets, ACL, CSRF, permissions fichier et monitoring.

Couche 1 : Apache

Désactiver le listing de répertoires

Par défaut, Apache peut afficher le contenu des répertoires sans fichier index. C'est une fuite d'information :

<Directory /srv/www/pmacontrol>
    Options -Indexes
    AllowOverride All
    Require all granted
</Directory>

Le -Indexes est non négociable. Sans lui, un attaquant peut explorer la structure du projet et trouver des fichiers de configuration, des logs, des dumps.

Forcer HTTPS

PmaControl transmet des credentials en clair dans les requêtes HTTP. Sans HTTPS, un attaquant sur le réseau peut les intercepter :

<VirtualHost *:80>
    ServerName pmacontrol.internal.company.com
    Redirect permanent / https://pmacontrol.internal.company.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName pmacontrol.internal.company.com
    SSLEngine On
    SSLCertificateFile /etc/ssl/certs/pmacontrol.pem
    SSLCertificateKeyFile /etc/ssl/private/pmacontrol.key

    # Modern TLS only
    SSLProtocol -all +TLSv1.2 +TLSv1.3
    SSLCipherSuite HIGH:!aNULL:!MD5:!3DES

    DocumentRoot /srv/www/pmacontrol
</VirtualHost>

Restreindre au réseau interne

PmaControl ne doit jamais être exposé sur Internet. Limitez l'accès au réseau interne :

<Location />
    Require ip 10.0.0.0/8
    Require ip 172.16.0.0/12
    Require ip 192.168.0.0/16
</Location>

Ou mieux encore : placez PmaControl derrière un VPN et ne l'exposez pas du tout via Apache public.

Supprimer le vhost par défaut

Le vhost par défaut d'Apache (000-default.conf) répond à toute requête sur l'IP du serveur. Supprimez-le :

a2dissite 000-default.conf
systemctl reload apache2

Headers de sécurité

Ajoutez les headers de sécurité HTTP :

Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"

Couche 2 : PHP

Désactiver les fonctions dangereuses

PmaControl utilise exec() et shell_exec() pour certaines opérations (SSH, collecte). La solution n'est pas de les désactiver globalement, mais d'isoler les workers qui en ont besoin.

Pour le vhost web (l'interface) :

; php.ini ou .user.ini dans le DocumentRoot
disable_functions = exec,shell_exec,system,passthru,popen,proc_open
expose_php = Off

Pour les workers CLI (Aspirateur, Listener) :

; php-cli.ini — ces workers ont besoin de shell_exec
disable_functions =

Cette séparation garantit que l'interface web ne peut pas exécuter de commandes système, même si un attaquant trouve une faille.

Sécuriser les sessions

session.cookie_httponly = 1
session.cookie_secure = 1
session.cookie_samesite = Strict
session.use_strict_mode = 1
session.name = PMACSESSID

cookie_httponly empêche JavaScript d'accéder au cookie de session (protection XSS). cookie_secure force l'envoi uniquement sur HTTPS. cookie_samesite = Strict protège contre le CSRF basic.

Limiter l'upload et l'exécution

upload_max_filesize = 2M
post_max_size = 8M
max_execution_time = 30
max_input_time = 60
memory_limit = 256M

PmaControl n'a pas besoin d'uploads massifs. Limitez pour réduire la surface d'attaque.

Cacher la version PHP

expose_php = Off

Cela supprime l'en-tête X-Powered-By: PHP/8.x des réponses HTTP.

Couche 3 : MariaDB

Restreindre les privilèges de l'utilisateur PmaControl

Après l'installation, l'utilisateur PmaControl a souvent tous les privilèges. Restreignez-le :

-- Révoquer les privilèges excessifs
REVOKE ALL PRIVILEGES ON *.* FROM 'pmacontrol'@'localhost';

-- Accorder uniquement ce qui est nécessaire
GRANT SELECT, INSERT, UPDATE, DELETE ON pmacontrol.* TO 'pmacontrol'@'localhost';
GRANT SELECT ON performance_schema.* TO 'pmacontrol'@'localhost';
GRANT REPLICATION CLIENT ON *.* TO 'pmacontrol'@'localhost';
GRANT PROCESS ON *.* TO 'pmacontrol'@'localhost';

FLUSH PRIVILEGES;

Le principe du moindre privilège : PmaControl n'a besoin que de lire les métriques et d'écrire dans sa propre base.

Lier au localhost

La base de données PmaControl ne doit écouter que sur l'interface locale :

[mysqld]
bind-address = 127.0.0.1

Si PmaControl et sa base sont sur le même serveur (configuration typique), il n'y a aucune raison d'écouter sur le réseau.

Activer le log des requêtes sensibles

[mysqld]
general_log = OFF          # Trop verbeux en production
slow_query_log = ON
long_query_time = 1
log_error = /var/log/mysql/error.log

Le slow query log permet de détecter les requêtes anormales qui pourraient indiquer une injection SQL exploitée.

Couche 4 : Secrets

Chiffrer les credentials

PmaControl stocke les credentials de connexion dans db.config.ini.php. Ce fichier supporte le chiffrement :

; configuration/db.config.ini.php
[default]
driver = mysql
host = 127.0.0.1
port = 3306
login = pmacontrol
password = "ENCRYPTED_VALUE_HERE"
database = pmacontrol
crypted = 1

Le flag crypted=1 indique à PmaControl de déchiffrer le mot de passe au runtime. La clé de chiffrement est séparée du fichier de configuration.

Utiliser un secret store externe

Pour les déploiements en production critique, externalisez les secrets :

  • Vault (HashiCorp) : PmaControl peut lire les secrets via l'API
  • AWS Secrets Manager ou GCP Secret Manager : pour les déploiements cloud
  • Variables d'environnement : le minimum viable, mieux que du texte en clair
# Exemple avec variables d'environnement
export PMAC_DB_PASSWORD="secret_value"
export PMAC_SSH_PASSPHRASE="ssh_secret"

Protéger les fichiers de configuration

# Propriétaire : www-data (l'utilisateur Apache)
chown root:www-data /srv/www/pmacontrol/configuration/*.php

# Permissions : lecture pour le groupe, rien pour les autres
chmod 640 /srv/www/pmacontrol/configuration/*.php

# Le fichier de credentials ne doit être lisible que par www-data
chmod 600 /srv/www/pmacontrol/configuration/db.config.ini.php

Couche 5 : ACL (Access Control Lists)

Réviser acl.config.ini

PmaControl a un système d'ACL basé sur les profils. Le fichier acl.config.ini définit quel profil peut accéder à quel contrôleur.

; configuration/acl.config.ini
[admin]
* = allow

[dba]
Slave = allow
Server = allow
Dashboard = allow
Backup = deny
Config = deny

[readonly]
Slave = allow
Server = allow(show)
Dashboard = allow
* = deny

Règles essentielles :

  • Restreindre les contrôleurs sensibles : Config, Backup, Install, Api ne doivent être accessibles qu'aux admins
  • Créer un profil read-only : pour les développeurs qui ont besoin de consulter sans modifier
  • Auditer régulièrement : vérifier que de nouveaux contrôleurs ajoutés sont couverts par les ACL

Protéger les endpoints critiques

Certains endpoints sont particulièrement sensibles :

[admin]
Install = allow      ; Installation / réinstallation
Config = allow       ; Modification de la configuration
Api = allow          ; API REST complète
Backup = allow       ; Accès aux backups (contient des données)

[dba]
Install = deny       ; JAMAIS accessible aux non-admins
Config = deny
Api = allow(read)    ; Lecture seule via API
Backup = deny

Couche 6 : CSRF (Cross-Site Request Forgery)

Vérifier la présence de tokens

Chaque formulaire PmaControl doit inclure un token CSRF :

<form method="POST" action="/slave/start/42/">
    <input type="hidden" name="csrf_token" value="<?= $csrf_token ?>">
    <button type="submit">Start Slave</button>
</form>

Côté serveur, le contrôleur doit valider le token :

if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    throw new SecurityException('Invalid CSRF token');
}

Actions à protéger en priorité

Les actions qui modifient l'état sont les plus critiques :

  • START/STOP SLAVE
  • SKIP error
  • Ajout/suppression de serveur
  • Modification de configuration
  • Création/suppression d'utilisateur

Sans protection CSRF, un attaquant pourrait forcer un DBA connecté à arrêter la réplication d'un serveur de production en lui envoyant un lien piégé.

Couche 7 : Permissions fichier

Arborescence de permissions

# Répertoire principal : lisible, pas modifiable
chown -R root:www-data /srv/www/pmacontrol/
chmod -R 750 /srv/www/pmacontrol/

# Répertoires d'écriture : www-data propriétaire
chown -R www-data:www-data /srv/www/pmacontrol/tmp/
chown -R www-data:www-data /srv/www/pmacontrol/data/

# Fichiers PHP : lecture seule pour www-data
find /srv/www/pmacontrol/App/ -name "*.php" -exec chmod 640 {} \;

# Configuration : restrictif
chmod 640 /srv/www/pmacontrol/configuration/*.php
chmod 600 /srv/www/pmacontrol/configuration/db.config.ini.php

Le principe : www-data peut lire le code et écrire dans tmp/ et data/. Il ne peut pas modifier le code source ni la configuration.

Couche 8 : Monitoring de la sécurité

Logger les accès API

Chaque appel à l'API REST doit être loggé avec :

  • Timestamp
  • IP source
  • Utilisateur (token)
  • Endpoint appelé
  • Code de réponse
// Dans le middleware API
$log = sprintf(
    "[%s] %s %s %s → %d",
    date('Y-m-d H:i:s'),
    $_SERVER['REMOTE_ADDR'],
    $user->name,
    $_SERVER['REQUEST_URI'],
    http_response_code()
);
file_put_contents('/var/log/pmacontrol/api.log', $log . "\n", FILE_APPEND);

Alertes Telegram sur les échecs d'authentification

Configurez une alerte Telegram pour chaque échec de connexion :

if (!$auth->isValid()) {
    Telegram::send(
        "🔴 Auth failure on PmaControl\n" .
        "IP: " . $_SERVER['REMOTE_ADDR'] . "\n" .
        "User: " . $_POST['login'] . "\n" .
        "Time: " . date('Y-m-d H:i:s')
    );
}

Trois échecs depuis la même IP en 5 minutes devraient déclencher un blocage temporaire.

Surveiller les fichiers de configuration

Utilisez inotifywait ou un outil similaire pour détecter les modifications non autorisées :

inotifywait -m -r /srv/www/pmacontrol/configuration/ -e modify,create,delete |
while read path action file; do
    echo "[$action] $path$file" >> /var/log/pmacontrol/config_changes.log
    # Envoyer alerte Telegram
done

Couche 9 : Réseau

Règles de firewall

# Autoriser HTTP/HTTPS uniquement depuis le réseau interne
iptables -A INPUT -p tcp --dport 80  -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 80  -j DROP
iptables -A INPUT -p tcp --dport 443 -j DROP

# Autoriser MySQL uniquement en localhost
iptables -A INPUT -p tcp --dport 3306 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j DROP

Pas d'exposition publique

PmaControl ne doit jamais être accessible depuis Internet. Même avec authentification, la surface d'attaque est trop grande :

  • Les credentials des serveurs supervisés sont stockés
  • Les clés SSH sont stockées
  • L'interface permet d'exécuter des actions sur des serveurs de production

Si un accès distant est nécessaire, utilisez un VPN (WireGuard, OpenVPN) ou un tunnel SSH.

Couche 10 : Injections SQL — remédiation

Notre audit interne a identifié des risques d'injection SQL dans quatre contrôleurs :

Contrôleur Risque Remédiation
Tag.php Construction dynamique de clause WHERE Requêtes paramétrées
Client.php Concaténation dans les filtres Requêtes paramétrées
Environment.php Interpolation de variable dans ORDER BY Whitelist de colonnes
Backup.php Paramètre non échappé dans LIKE Requêtes paramétrées

Avant (vulnérable) :

// Tag.php — VULNÉRABLE
$sql = "SELECT * FROM tags WHERE name LIKE '%" . $_GET['search'] . "%'";
$results = $db->query($sql);

Après (sécurisé) :

// Tag.php — SÉCURISÉ
$sql = "SELECT * FROM tags WHERE name LIKE ?";
$results = $db->query($sql, ['%' . $_GET['search'] . '%']);

Pour les clauses ORDER BY, la whitelist est la seule solution sûre :

$allowed_columns = ['name', 'created_at', 'id'];
$sort = in_array($_GET['sort'], $allowed_columns) ? $_GET['sort'] : 'name';
$sql = "SELECT * FROM tags ORDER BY " . $sort;

Checklist de durcissement

Avant de passer PmaControl en production, validez chaque point :

  • [ ] Apache : -Indexes activé
  • [ ] Apache : HTTPS forcé
  • [ ] Apache : accès restreint au réseau interne
  • [ ] Apache : vhost par défaut supprimé
  • [ ] PHP : fonctions dangereuses désactivées sur le vhost web
  • [ ] PHP : session.cookie_httponly = 1
  • [ ] PHP : session.cookie_secure = 1
  • [ ] PHP : expose_php = Off
  • [ ] MariaDB : utilisateur avec privilèges minimaux
  • [ ] MariaDB : bind-address = 127.0.0.1
  • [ ] Secrets : credentials chiffrés (crypted=1)
  • [ ] Fichiers de config : permissions 640
  • [ ] ACL : contrôleurs sensibles restreints
  • [ ] CSRF : tokens sur tous les formulaires d'action
  • [ ] Permissions : tmp/ et data/ seuls répertoires inscriptibles
  • [ ] Monitoring : log des accès API
  • [ ] Monitoring : alertes sur échecs d'authentification
  • [ ] Réseau : firewall en place
  • [ ] Réseau : pas d'exposition publique
  • [ ] SQL : requêtes paramétrées dans Tag, Client, Environment, Backup

Conclusion

Sécuriser PmaControl n'est pas un luxe — c'est une obligation. L'outil a accès à vos serveurs MariaDB / MySQL de production, stocke des credentials, et peut exécuter des commandes via SSH.

Le durcissement se fait en couches : chaque couche (Apache, PHP, MariaDB, secrets, ACL, CSRF, permissions, réseau) ajoute une barrière. Si une couche est percée, les autres ralentissent l'attaquant.

La bonne nouvelle : toutes ces mesures sont standards et applicables en une journée de travail. Le coût est négligeable comparé au risque d'une compromission de votre infrastructure de bases de données.

Partager X LinkedIn Facebook Email PDF
← Retour au blog

Commentaires (0)

Aucun commentaire pour le moment.

Laisser un commentaire

PmaControl
+33 6 63 28 27 47 contact@pmacontrol.com
Mentions légales GitHub Contact
N'attendez pas l'incident pour comprendre votre architecture. © 2014-2026 PmaControl — 68Koncept