🛠 Outils IT
🛠 78 outils 📚 32 docs
🤖 Assistant

Apache / Nginx

1. Installation Apache

1.1 Debian / Ubuntu

# Mise a jour des depots
sudo apt update

# Installation du paquet Apache2
sudo apt install apache2 -y

# Verifier que le service est actif
sudo systemctl status apache2

# Activer le demarrage automatique
sudo systemctl enable apache2

1.2 CentOS / RHEL / AlmaLinux

# Installation du paquet httpd
sudo dnf install httpd -y

# Demarrer le service
sudo systemctl start httpd

# Activer le demarrage automatique
sudo systemctl enable httpd

# Ouvrir les ports dans le firewall
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

1.3 Verification de l'installation

# Verifier la version installee
apache2 -v          # Debian/Ubuntu
httpd -v            # CentOS/RHEL

# Tester dans le navigateur
curl http://localhost
Astuce : Sur Debian/Ubuntu, le service s'appelle apache2. Sur CentOS/RHEL, il s'appelle httpd. Les commandes, fichiers de configuration et chemins different entre les deux familles.
Attention : Apres l'installation, Apache ecoute sur le port 80. Si un autre service (comme Nginx) occupe deja ce port, Apache ne demarrera pas. Verifiez avec ss -tlnp | grep :80.

2. Structure des fichiers de configuration

2.1 Arborescence Debian / Ubuntu

/etc/apache2/
├── apache2.conf            # Configuration principale
├── ports.conf              # Ports d'ecoute (Listen 80, Listen 443)
├── envvars                 # Variables d'environnement (APACHE_RUN_USER, etc.)
├── conf-available/         # Configurations supplementaires disponibles
├── conf-enabled/           # Configurations actives (liens symboliques)
├── mods-available/         # Modules disponibles (.load + .conf)
├── mods-enabled/           # Modules actifs (liens symboliques)
├── sites-available/        # VirtualHosts disponibles
│   ├── 000-default.conf    # VirtualHost par defaut (port 80)
│   └── default-ssl.conf    # VirtualHost SSL par defaut (port 443)
└── sites-enabled/          # VirtualHosts actifs (liens symboliques)
    └── 000-default.conf

2.2 Arborescence CentOS / RHEL

/etc/httpd/
├── conf/
│   └── httpd.conf          # Configuration principale (tout-en-un)
├── conf.d/                 # Configurations supplementaires (*.conf)
│   ├── ssl.conf            # Configuration SSL globale
│   └── welcome.conf        # Page d'accueil par defaut
├── conf.modules.d/         # Chargement des modules (*.conf)
│   ├── 00-base.conf
│   ├── 00-ssl.conf
│   └── ...
└── modules/                # Lien vers /usr/lib64/httpd/modules/

2.3 Fichier apache2.conf - Directives importantes

# Timeout global (en secondes)
Timeout 300

# Connexions persistantes (Keep-Alive)
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

# Configuration du MPM (Multi-Processing Module)
# Fichier : /etc/apache2/mods-available/mpm_prefork.conf
<IfModule mpm_prefork_module>
    StartServers             5
    MinSpareServers          5
    MaxSpareServers         10
    MaxRequestWorkers      150
    MaxConnectionsPerChild   0
</IfModule>

# Interdire l'acces par defaut
<Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all denied
</Directory>

# Autoriser le DocumentRoot
<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

2.4 Fichier ports.conf

# Port HTTP standard
Listen 80

# Port HTTPS (uniquement si mod_ssl est charge)
<IfModule ssl_module>
    Listen 443
</IfModule>

# Ajouter un port personnalise
Listen 8080
Astuce : Sur Debian/Ubuntu, la logique *-available / *-enabled avec des liens symboliques permet d'activer ou desactiver rapidement des sites, modules et configurations sans supprimer de fichiers. Utilisez les commandes a2ensite, a2dissite, a2enmod, a2dismod, a2enconf, a2disconf.

3. VirtualHosts (HTTP et HTTPS)

3.1 Concept

Un VirtualHost permet a Apache d'heberger plusieurs sites web sur un meme serveur. Chaque VirtualHost est associe a un nom de domaine (ou une IP) et definit sa propre configuration (DocumentRoot, logs, options, etc.).

3.2 VirtualHost HTTP simple (port 80)

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    ServerAdmin webmaster@example.com

    DocumentRoot /var/www/example.com/public

    <Directory /var/www/example.com/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>

3.3 VirtualHost HTTPS (port 443)

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com/public

    <Directory /var/www/example.com/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    # Configuration SSL
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf

    # En-tetes de securite
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"

    ErrorLog ${APACHE_LOG_DIR}/example.com-ssl-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-ssl-access.log combined
</VirtualHost>
</IfModule>

3.4 Redirection HTTP vers HTTPS

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com

    # Methode 1 : Redirect permanent
    Redirect permanent / https://example.com/

    # Methode 2 : RewriteRule (necessite mod_rewrite)
    # RewriteEngine On
    # RewriteCond %{HTTPS} off
    # RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>

3.5 Activer / desactiver un VirtualHost

# Creer le fichier dans sites-available
sudo nano /etc/apache2/sites-available/example.com.conf

# Activer le site
sudo a2ensite example.com.conf

# Desactiver le site
sudo a2dissite example.com.conf

# Desactiver le site par defaut
sudo a2dissite 000-default.conf

# Toujours recharger apres modification
sudo systemctl reload apache2

3.6 Preparer le DocumentRoot

# Creer le repertoire du site
sudo mkdir -p /var/www/example.com/public

# Attribuer les droits
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com

# Creer une page de test
echo "<h1>example.com fonctionne</h1>" | sudo tee /var/www/example.com/public/index.html
Attention : N'utilisez jamais Options +Indexes en production. Cette directive permet le listage du contenu des repertoires et peut exposer des fichiers sensibles. Utilisez toujours Options -Indexes.

4. Modules (a2enmod, a2dismod, mod_rewrite, mod_ssl, mod_proxy)

4.1 Gestion des modules (Debian/Ubuntu)

# Lister les modules disponibles
ls /etc/apache2/mods-available/

# Lister les modules actifs
ls /etc/apache2/mods-enabled/
# ou
apache2ctl -M

# Activer un module
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2enmod headers
sudo a2enmod proxy proxy_http

# Desactiver un module
sudo a2dismod autoindex

# Toujours redemarrer apres activation/desactivation de module
sudo systemctl restart apache2

4.2 Gestion des modules (CentOS/RHEL)

# Les modules sont charges dans /etc/httpd/conf.modules.d/
# Pour desactiver un module, commentez la ligne LoadModule

# Lister les modules charges
httpd -M

# Exemple : desactiver un module
sudo sed -i 's/^LoadModule autoindex_module/#LoadModule autoindex_module/' \
    /etc/httpd/conf.modules.d/00-base.conf

sudo systemctl restart httpd

4.3 mod_rewrite - Reecriture d'URL

# Activer le module
sudo a2enmod rewrite

# Exemple dans un VirtualHost ou .htaccess
RewriteEngine On

# Redirection www vers non-www
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]

# URL propres (front controller pattern - ex: Laravel, Symfony)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?url=$1 [QSA,L]

4.4 mod_ssl - Chiffrement HTTPS

# Activer le module
sudo a2enmod ssl

# Verifier que le port 443 est bien configure dans ports.conf
# Listen 443

# Configuration SSL recommandee (dans le VirtualHost)
SSLEngine on
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES
SSLHonorCipherOrder on

# Activer HSTS
Header always set Strict-Transport-Security "max-age=63072000"

4.5 mod_proxy - Proxy et Reverse Proxy

# Activer les modules necessaires
sudo a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests

# Configuration basique dans un VirtualHost
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/

4.6 Autres modules utiles

# mod_headers : manipulation des en-tetes HTTP
sudo a2enmod headers

# mod_expires : controle du cache navigateur
sudo a2enmod expires

# mod_deflate : compression gzip des reponses
sudo a2enmod deflate

# mod_security2 : pare-feu applicatif (WAF)
sudo apt install libapache2-mod-security2
sudo a2enmod security2

# mod_evasive : protection contre les attaques DDoS
sudo apt install libapache2-mod-evasive
sudo a2enmod evasive
Astuce : Pour lister rapidement tous les modules charges avec leur statut (static ou shared), utilisez apache2ctl -M 2>/dev/null | sort. Les modules "static" sont compiles dans Apache, les "shared" sont charges dynamiquement.

5. .htaccess (rewrite, redirections, protection)

5.1 Prerequis

Pour que les fichiers .htaccess soient pris en compte, la directive AllowOverride doit etre configuree dans le VirtualHost :

<Directory /var/www/example.com/public>
    # AllowOverride None   = .htaccess ignore (meilleure performance)
    # AllowOverride All    = .htaccess pris en compte entierement
    AllowOverride All
    Require all granted
</Directory>
Attention : AllowOverride All a un impact sur les performances car Apache doit lire le fichier .htaccess a chaque requete dans chaque repertoire. En production, il est preferable de placer les regles directement dans le VirtualHost et d'utiliser AllowOverride None.

5.2 Reecriture d'URL

RewriteEngine On

# Forcer HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Forcer www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [L,R=301]

# URLs propres (front controller)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

# Supprimer l'extension .php de l'URL
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

5.3 Redirections

# Redirection 301 (permanente)
Redirect 301 /ancienne-page.html https://example.com/nouvelle-page.html

# Redirection 302 (temporaire)
Redirect 302 /promo https://example.com/soldes

# Redirection avec expression reguliere
RedirectMatch 301 ^/blog/([0-9]+)/(.*)$ https://example.com/articles/$1/$2

# Redirection de tout un repertoire
RedirectMatch 301 ^/ancien-repertoire/(.*)$ https://example.com/nouveau-repertoire/$1

5.4 Protection par mot de passe

# Dans le .htaccess
AuthType Basic
AuthName "Zone protegee"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user

# Creer le fichier de mots de passe
sudo htpasswd -c /etc/apache2/.htpasswd utilisateur1

# Ajouter un utilisateur supplementaire (sans -c)
sudo htpasswd /etc/apache2/.htpasswd utilisateur2

5.5 Restriction d'acces par IP

# Autoriser uniquement certaines IP (Apache 2.4+)
<RequireAny>
    Require ip 192.168.1.0/24
    Require ip 10.0.0.50
</RequireAny>

# Bloquer une IP specifique
<RequireAll>
    Require all granted
    Require not ip 203.0.113.50
</RequireAll>

5.6 Protection de fichiers et repertoires

# Interdire l'acces aux fichiers .env, .git, etc.
<FilesMatch "^\.(?!well-known)">
    Require all denied
</FilesMatch>

# Proteger un fichier specifique
<Files "config.php">
    Require all denied
</Files>

# Interdire le listage des repertoires
Options -Indexes

# Interdire l'acces a certaines extensions
<FilesMatch "\.(sql|log|bak|old|env)$">
    Require all denied
</FilesMatch>

5.7 Cache et compression

# Activer la compression gzip
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/css
    AddOutputFilterByType DEFLATE application/javascript application/json
    AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>

# Configuration du cache navigateur
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
    ExpiresByType text/html "access plus 0 seconds"
</IfModule>
Astuce : Pour tester vos regles .htaccess sans impacter la production, utilisez le flag [R=302] (redirection temporaire) au lieu de [R=301] (permanente). Les navigateurs mettent en cache les 301, ce qui rend le debogage difficile.

6. Reverse Proxy avec Apache

6.1 Concept

Un reverse proxy est un serveur intermediaire qui recoit les requetes des clients et les transmet a un ou plusieurs serveurs backend. Le client ne communique jamais directement avec le backend. Cas d'usage typiques : application Node.js, API, Tomcat, serveur interne, etc.

6.2 Activer les modules necessaires

sudo a2enmod proxy proxy_http proxy_wstunnel proxy_balancer lbmethod_byrequests headers
sudo systemctl restart apache2

6.3 Reverse proxy simple

<VirtualHost *:80>
    ServerName app.example.com

    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/

    # Transmettre les en-tetes du client au backend
    RequestHeader set X-Forwarded-Proto "http"
    RequestHeader set X-Real-IP "%{REMOTE_ADDR}s"

    ErrorLog ${APACHE_LOG_DIR}/app-proxy-error.log
    CustomLog ${APACHE_LOG_DIR}/app-proxy-access.log combined
</VirtualHost>

6.4 Reverse proxy avec HTTPS en facade

<VirtualHost *:443>
    ServerName app.example.com

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/app.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/app.example.com/privkey.pem

    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/

    RequestHeader set X-Forwarded-Proto "https"
    RequestHeader set X-Forwarded-Port "443"

    ErrorLog ${APACHE_LOG_DIR}/app-ssl-proxy-error.log
    CustomLog ${APACHE_LOG_DIR}/app-ssl-proxy-access.log combined
</VirtualHost>

6.5 Proxy vers un sous-chemin specifique

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example.com/public

    # Le site principal est servi normalement
    # /api est proxy vers le backend Node.js
    ProxyPass /api http://127.0.0.1:4000/api
    ProxyPassReverse /api http://127.0.0.1:4000/api

    # /admin est proxy vers un autre backend
    ProxyPass /admin http://127.0.0.1:8080/admin
    ProxyPassReverse /admin http://127.0.0.1:8080/admin
</VirtualHost>

6.6 Support WebSocket

<VirtualHost *:80>
    ServerName ws.example.com

    ProxyPreserveHost On

    # Proxy WebSocket
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule ^/?(.*) ws://127.0.0.1:3000/$1 [P,L]

    # Proxy HTTP classique
    ProxyPass / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/
</VirtualHost>

6.7 Load Balancing

<Proxy "balancer://moncluster">
    BalancerMember http://127.0.0.1:3001
    BalancerMember http://127.0.0.1:3002
    BalancerMember http://127.0.0.1:3003
    ProxySet lbmethod=byrequests
</Proxy>

<VirtualHost *:80>
    ServerName app.example.com

    ProxyPreserveHost On
    ProxyPass / balancer://moncluster/
    ProxyPassReverse / balancer://moncluster/
</VirtualHost>
Attention : Ne jamais activer ProxyRequests On sauf besoin explicite de forward proxy. Un forward proxy ouvert permet a n'importe qui d'utiliser votre serveur comme relais, ce qui constitue une faille de securite majeure.

7. SSL/TLS avec Let's Encrypt (Apache)

7.1 Installation de Certbot

# Methode recommandee : via snap
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# Installer le plugin Apache
sudo apt install python3-certbot-apache     # Debian/Ubuntu
sudo dnf install python3-certbot-apache     # CentOS/RHEL

7.2 Obtenir un certificat

# Certificat automatique (modifie le VirtualHost)
sudo certbot --apache -d example.com -d www.example.com

# Obtenir le certificat sans modifier Apache
sudo certbot certonly --apache -d example.com -d www.example.com

# Mode non-interactif (scripts / automatisation)
sudo certbot --apache --non-interactive --agree-tos \
    --email admin@example.com -d example.com -d www.example.com

7.3 Renouvellement automatique

# Tester le renouvellement
sudo certbot renew --dry-run

# Le renouvellement est gere automatiquement par un timer systemd ou un cron
# Verifier le timer
sudo systemctl list-timers | grep certbot

# Ou ajouter un cron manuellement
# 0 3 * * * certbot renew --quiet --post-hook "systemctl reload apache2"

7.4 Configuration SSL renforcee

# Dans le VirtualHost SSL ou dans un fichier inclus
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off

# En-tetes de securite
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "DENY"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Astuce : Apres avoir configure SSL, testez la qualite de votre configuration sur SSL Labs. Visez un score A ou A+.

8. Installation Nginx

8.1 Debian / Ubuntu

# Installation depuis les depots officiels
sudo apt update
sudo apt install nginx -y

# Verifier le service
sudo systemctl status nginx

# Activer le demarrage automatique
sudo systemctl enable nginx

8.2 Depot officiel Nginx (version plus recente)

# Ajouter la cle GPG et le depot officiel Nginx
sudo apt install curl gnupg2 ca-certificates lsb-release
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor \
    -o /usr/share/keyrings/nginx-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
    http://nginx.org/packages/debian $(lsb_release -cs) nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list

sudo apt update
sudo apt install nginx -y

8.3 CentOS / RHEL / AlmaLinux

# Installation depuis EPEL
sudo dnf install epel-release
sudo dnf install nginx -y

# Demarrer et activer
sudo systemctl start nginx
sudo systemctl enable nginx

# Ouvrir les ports du firewall
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

8.4 Structure des fichiers Nginx

/etc/nginx/
├── nginx.conf              # Configuration principale
├── mime.types              # Types MIME
├── conf.d/                 # Configurations supplementaires (*.conf)
│   └── default.conf        # Server block par defaut
├── sites-available/        # Server blocks disponibles (Debian/Ubuntu)
├── sites-enabled/          # Server blocks actifs (liens symboliques)
├── snippets/               # Fragments de configuration reutilisables
│   ├── fastcgi-php.conf
│   └── snakeoil.conf
├── modules-available/      # Modules disponibles
└── modules-enabled/        # Modules actifs

8.5 Verification de l'installation

# Version installee
nginx -v

# Modules compiles
nginx -V

# Tester la configuration
sudo nginx -t

# Tester dans le navigateur
curl http://localhost
Astuce : Sur Debian/Ubuntu, le paquet Nginx des depots officiels utilise la structure sites-available / sites-enabled similaire a Apache. Le paquet du depot nginx.org utilise uniquement conf.d/. Adaptez votre workflow en consequence.

9. Configuration server blocks

9.1 Concept

Les server blocks de Nginx sont l'equivalent des VirtualHosts d'Apache. Chaque server block definit la configuration pour un domaine specifique.

9.2 Server block HTTP simple

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/example.com/public;
    index index.html index.htm index.php;

    # Logs
    access_log /var/log/nginx/example.com-access.log;
    error_log /var/log/nginx/example.com-error.log;

    # Gestion des fichiers statiques
    location / {
        try_files $uri $uri/ =404;
    }

    # Bloquer l'acces aux fichiers caches
    location ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }
}

9.3 Server block avec PHP (PHP-FPM)

server {
    listen 80;
    server_name example.com;

    root /var/www/example.com/public;
    index index.php index.html;

    # Traitement des requetes PHP via PHP-FPM
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Front controller (Laravel, Symfony, etc.)
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # Fichiers statiques : cache long
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}

9.4 Activer / desactiver un server block

# Creer la configuration dans sites-available
sudo nano /etc/nginx/sites-available/example.com

# Activer (creer le lien symbolique)
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

# Desactiver (supprimer le lien symbolique)
sudo rm /etc/nginx/sites-enabled/example.com

# Desactiver le site par defaut
sudo rm /etc/nginx/sites-enabled/default

# Tester la configuration AVANT de recharger
sudo nginx -t

# Recharger la configuration
sudo systemctl reload nginx

9.5 Directives de securite et optimisation

# Dans nginx.conf (bloc http)
http {
    # Cacher la version de Nginx dans les en-tetes
    server_tokens off;

    # Taille maximale d'upload
    client_max_body_size 50M;

    # Compression gzip
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript
               text/xml application/xml image/svg+xml;

    # Timeouts
    client_body_timeout 12;
    client_header_timeout 12;
    keepalive_timeout 15;
    send_timeout 10;

    # Buffers
    client_body_buffer_size 10K;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;
}
Attention : Testez toujours la configuration avec nginx -t avant de recharger. Contrairement a Apache, Nginx ne demarrera pas du tout si la configuration contient une erreur de syntaxe.

10. Reverse Proxy avec Nginx

10.1 Reverse proxy simple

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

10.2 Reverse proxy vers un sous-chemin

server {
    listen 80;
    server_name example.com;

    root /var/www/example.com/public;

    # Site principal
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # API vers un backend Node.js
    location /api/ {
        proxy_pass http://127.0.0.1:4000/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

10.3 Support WebSocket

server {
    listen 80;
    server_name ws.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;

        # En-tetes necessaires pour WebSocket
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # Timeout pour les connexions longue duree
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
    }
}

10.4 Load Balancing

# Definir le groupe de serveurs backend
upstream backend_cluster {
    # Methodes de repartition :
    # (defaut)          round-robin
    # least_conn;       moins de connexions actives
    # ip_hash;          affinite par IP client
    # hash $request_uri consistent;  affinite par URI

    least_conn;

    server 127.0.0.1:3001 weight=3;    # recoit 3x plus de trafic
    server 127.0.0.1:3002;
    server 127.0.0.1:3003;
    server 127.0.0.1:3004 backup;      # utilise uniquement si les autres sont down
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://backend_cluster;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

10.5 Proxy avec cache

# Dans nginx.conf (bloc http) : definir la zone de cache
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mon_cache:10m
                 max_size=1g inactive=60m use_temp_path=off;

# Dans le server block
server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_cache mon_cache;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503;

        # En-tete pour debugger le cache (HIT/MISS/BYPASS)
        add_header X-Cache-Status $upstream_cache_status;
    }

    # Ne pas cacher les requetes API
    location /api/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_cache off;
    }
}
Astuce : Attention au trailing slash dans proxy_pass. proxy_pass http://backend/ (avec slash) remplace le chemin du location. proxy_pass http://backend (sans slash) conserve le chemin complet. Ce detail peut causer des problemes de routage subtils.

11. SSL/TLS avec Nginx

11.1 Obtenir un certificat avec Certbot

# Installer le plugin Nginx
sudo apt install python3-certbot-nginx     # Debian/Ubuntu
sudo dnf install python3-certbot-nginx     # CentOS/RHEL

# Obtenir et configurer automatiquement
sudo certbot --nginx -d example.com -d www.example.com

# Obtenir sans modifier la configuration Nginx
sudo certbot certonly --nginx -d example.com

11.2 Server block HTTPS complet

# Redirection HTTP vers HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

# Server block HTTPS
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    root /var/www/example.com/public;
    index index.html index.php;

    # Certificats SSL
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # Parametres SSL recommandes
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # Cache de session SSL
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # En-tetes de securite
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "DENY" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
}

11.3 Reverse Proxy HTTPS

server {
    listen 443 ssl http2;
    server_name app.example.com;

    ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}

11.4 Generer des parametres Diffie-Hellman

# Generer un fichier dhparam (peut prendre plusieurs minutes)
sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048

# Ajouter dans le server block SSL
ssl_dhparam /etc/nginx/dhparam.pem;
Astuce : Creez un fichier /etc/nginx/snippets/ssl-params.conf avec vos parametres SSL et incluez-le dans chaque server block avec include snippets/ssl-params.conf;. Cela evite la duplication et facilite la maintenance.

12. Comparaison Apache vs Nginx

12.1 Architecture

Critere Apache Nginx
Modele Processus/threads (MPM prefork, worker, event) Evenementiel asynchrone (event-driven)
Connexions simultanees 1 thread/processus par connexion (MPM prefork) Des milliers de connexions par worker
Memoire Consommation plus elevee sous forte charge Empreinte memoire faible et stable
Fichiers statiques Bonnes performances Excellentes performances
Contenu dynamique mod_php integre (simple) Necessite un backend externe (PHP-FPM)

12.2 Configuration et fonctionnalites

Critere Apache Nginx
.htaccess Supporte (configuration par repertoire) Non supporte
Modules Chargeables dynamiquement (a2enmod) Compiles a la construction (sauf modules dynamiques recents)
Configuration XML-like, flexible, distribue (.htaccess) Blocs C-like, centralise, pas de .htaccess
Reverse Proxy Bon (mod_proxy) Excellent (natif, principal cas d'usage)
Load Balancing Basique (mod_proxy_balancer) Avance (upstream, health checks, etc.)
Documentation Tres riche, communaute historique Bonne, en croissance

12.3 Quand utiliser lequel ?

  • Apache : hebergement mutualise, besoin de .htaccess, applications PHP classiques (WordPress, etc.), compatibilite avec des configurations existantes, modules specifiques (mod_security, mod_pagespeed)
  • Nginx : reverse proxy, load balancing, fort trafic sur fichiers statiques, architecture microservices, API gateway, sites a forte audience
  • Combinaison Nginx + Apache : Nginx en facade (reverse proxy, fichiers statiques, SSL termination) et Apache en backend (contenu dynamique PHP avec mod_php). Cette architecture combine les forces des deux serveurs.
Astuce : En cas de doute, Nginx est generalement le meilleur choix pour les nouveaux deployements. Sa consommation memoire reduite et ses performances en reverse proxy en font un choix polyvalent. Apache reste pertinent pour les hebergements mutualises et les applications qui dependent de .htaccess.

13. Commandes de maintenance

13.1 Apache - Commandes essentielles

# --- Gestion du service ---
sudo systemctl start apache2        # Demarrer
sudo systemctl stop apache2         # Arreter
sudo systemctl restart apache2      # Redemarrer (coupe les connexions en cours)
sudo systemctl reload apache2       # Recharger la config (sans couper les connexions)
sudo systemctl status apache2       # Verifier le statut

# --- Test de configuration ---
sudo apache2ctl configtest          # Debian/Ubuntu
sudo httpd -t                       # CentOS/RHEL
sudo apache2ctl -S                  # Afficher les VirtualHosts configures

# --- Gestion des sites ---
sudo a2ensite monsite.conf          # Activer un site
sudo a2dissite monsite.conf         # Desactiver un site

# --- Gestion des modules ---
sudo a2enmod rewrite                # Activer un module
sudo a2dismod autoindex             # Desactiver un module
apache2ctl -M                       # Lister les modules actifs

# --- Gestion des configurations ---
sudo a2enconf security              # Activer une configuration
sudo a2disconf serve-cgi-bin        # Desactiver une configuration

# --- Informations ---
apache2 -v                          # Version d'Apache
apache2 -V                          # Version + options de compilation

13.2 Nginx - Commandes essentielles

# --- Gestion du service ---
sudo systemctl start nginx          # Demarrer
sudo systemctl stop nginx           # Arreter
sudo systemctl restart nginx        # Redemarrer
sudo systemctl reload nginx         # Recharger la config (graceful)
sudo systemctl status nginx         # Verifier le statut

# --- Test de configuration ---
sudo nginx -t                       # Tester la syntaxe de la configuration
sudo nginx -T                       # Tester et afficher toute la configuration

# --- Signaux Nginx ---
sudo nginx -s reload                # Recharger (equivalent a systemctl reload)
sudo nginx -s stop                  # Arret immediat
sudo nginx -s quit                  # Arret graceful (attend la fin des requetes)
sudo nginx -s reopen                # Reouverture des fichiers de log

# --- Gestion des sites (Debian/Ubuntu) ---
sudo ln -s /etc/nginx/sites-available/monsite /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/monsite

# --- Informations ---
nginx -v                            # Version de Nginx
nginx -V                            # Version + options de compilation

13.3 Gestion des logs

# --- Rotation des logs (logrotate) ---
# Apache : /etc/logrotate.d/apache2
# Nginx  : /etc/logrotate.d/nginx

# Exemple de configuration logrotate personnalisee
# /etc/logrotate.d/monsite
/var/log/nginx/monsite-*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
    endscript
}

# Forcer la rotation manuellement
sudo logrotate -f /etc/logrotate.d/nginx

13.4 Mise a jour

# Apache (Debian/Ubuntu)
sudo apt update && sudo apt upgrade apache2

# Nginx (Debian/Ubuntu)
sudo apt update && sudo apt upgrade nginx

# Apres mise a jour, toujours verifier
sudo apache2ctl configtest && sudo systemctl restart apache2
sudo nginx -t && sudo systemctl restart nginx
Attention : Privilegiez toujours reload plutot que restart en production. Le reload recharge la configuration sans interrompre les connexions actives. Le restart coupe toutes les connexions en cours, ce qui peut impacter les utilisateurs.

14. Depannage (logs, configtest)

14.1 Verification de la configuration

# Apache - Tester la syntaxe
sudo apache2ctl configtest
# Resultat attendu : "Syntax OK"

# Apache - Afficher tous les VirtualHosts et leur priorite
sudo apache2ctl -S

# Nginx - Tester la syntaxe
sudo nginx -t
# Resultat attendu : "test is successful"

# Nginx - Afficher la configuration complete resolue
sudo nginx -T

14.2 Emplacements des logs

# === APACHE ===
# Logs par defaut
/var/log/apache2/access.log         # Debian/Ubuntu
/var/log/apache2/error.log          # Debian/Ubuntu
/var/log/httpd/access_log           # CentOS/RHEL
/var/log/httpd/error_log            # CentOS/RHEL

# Logs specifiques au VirtualHost
/var/log/apache2/example.com-access.log
/var/log/apache2/example.com-error.log

# === NGINX ===
# Logs par defaut
/var/log/nginx/access.log
/var/log/nginx/error.log

# Logs specifiques au server block
/var/log/nginx/example.com-access.log
/var/log/nginx/example.com-error.log

14.3 Lecture des logs en temps reel

# Suivre les logs d'erreur en temps reel
sudo tail -f /var/log/apache2/error.log
sudo tail -f /var/log/nginx/error.log

# Filtrer les erreurs recentes
sudo tail -100 /var/log/apache2/error.log | grep "error"
sudo tail -100 /var/log/nginx/error.log | grep "error"

# Utiliser journalctl pour les logs systemd
sudo journalctl -u apache2 -f --no-pager
sudo journalctl -u nginx -f --no-pager

# Voir les logs depuis le dernier demarrage
sudo journalctl -u apache2 -b
sudo journalctl -u nginx -b

14.4 Problemes courants et solutions

Port deja utilise

# Identifier le processus qui occupe le port 80 ou 443
sudo ss -tlnp | grep ':80'
sudo ss -tlnp | grep ':443'

# Ou avec lsof
sudo lsof -i :80
sudo lsof -i :443

# Solution : arreter le service concurrent ou changer le port d'ecoute

Permission refusee (403 Forbidden)

# Verifier les permissions du DocumentRoot
ls -la /var/www/example.com/
ls -la /var/www/example.com/public/

# Corriger les permissions
sudo chown -R www-data:www-data /var/www/example.com/    # Apache/Nginx Debian
sudo chown -R nginx:nginx /var/www/example.com/          # Nginx CentOS
sudo find /var/www/example.com/ -type d -exec chmod 755 {} \;
sudo find /var/www/example.com/ -type f -exec chmod 644 {} \;

# Verifier SELinux (CentOS/RHEL)
ls -Z /var/www/example.com/
sudo setsebool -P httpd_can_network_connect 1
sudo chcon -R -t httpd_sys_content_t /var/www/example.com/

502 Bad Gateway (Nginx reverse proxy)

# Verifier que le backend est en cours d'execution
sudo ss -tlnp | grep ':3000'
curl http://127.0.0.1:3000

# Verifier les logs Nginx pour plus de details
sudo tail -20 /var/log/nginx/error.log

# Causes frequentes :
# - Le backend n'est pas demarre
# - Le backend ecoute sur une adresse/port different
# - Timeout du backend (augmenter proxy_read_timeout)
# - PHP-FPM ne tourne pas (pour les sites PHP)

504 Gateway Timeout

# Augmenter les timeouts dans Nginx
location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_connect_timeout 300;
    proxy_send_timeout 300;
    proxy_read_timeout 300;
    send_timeout 300;
}

# Augmenter les timeouts dans Apache
ProxyTimeout 300
Timeout 300

Certificat SSL expire ou invalide

# Verifier les dates du certificat
sudo openssl x509 -noout -dates -in /etc/letsencrypt/live/example.com/fullchain.pem

# Verifier le certificat en ligne
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
    | openssl x509 -noout -dates

# Forcer le renouvellement
sudo certbot renew --force-renewal

# Verifier que le certificat configure correspond au domaine
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
    | openssl x509 -noout -subject -issuer

14.5 Outils de diagnostic

# Tester la connectivite HTTP
curl -I http://example.com                # En-tetes HTTP uniquement
curl -Lv https://example.com 2>&1         # Verbeux avec suivi des redirections
curl -k https://example.com               # Ignorer les erreurs SSL (debug)

# Tester les en-tetes de reponse
curl -sI https://example.com | grep -i "server\|x-\|strict\|content-type"

# Tester un VirtualHost specifique avec un en-tete Host
curl -H "Host: example.com" http://192.168.1.10

# Benchmark basique avec Apache Bench
ab -n 1000 -c 50 https://example.com/

# Verifier les processus Apache/Nginx
ps aux | grep apache2
ps aux | grep nginx

# Verifier la consommation memoire
systemctl status apache2 | grep Memory
systemctl status nginx | grep Memory

14.6 Debug des regles de reecriture

# Apache : activer le log de reecriture
# Dans le VirtualHost (pas dans .htaccess)
LogLevel alert rewrite:trace3

# Nginx : activer le mode debug pour le log d'erreur
# Dans le server block
error_log /var/log/nginx/example.com-error.log debug;

# Attention : le mode debug genere ENORMEMENT de logs
# Desactivez-le immediatement apres le diagnostic
Attention : N'activez jamais les logs de debug en production de maniere prolongee. Le volume de donnees generees peut saturer le disque en quelques heures et degrader fortement les performances du serveur.
Astuce : Reflexe de depannage systematique : 1) configtest / nginx -t pour valider la syntaxe, 2) consulter les logs d'erreur, 3) verifier les permissions et SELinux, 4) verifier les ports avec ss -tlnp, 5) tester avec curl en local. Cette methode resout 90% des problemes courants.