Ubuntu 22.04 - Installation de Piwigo avec Nginx, MariaDB et SSL/TLS

Article écrit par • créé le • mis à jour le 8 mai 2022 à 23h42
🔙 Partie 1
Installation de Piwigo et Nginx

7 - Création de la base de données piwigo sous MariaDB

7.1 - Installation de MariaDB

Installez les paquets suivants :

sudo apt-get install -y mariadb-server mariadb-client

7.2 - Configuration de MariaDB

Lancez le script de configuration (recommandé) avec la commande sudo mysql_secure_installation :

sudo mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): [Touche Entrée]
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

You already have your root account protected, so you can safely answer 'n'.

Switch to unix_socket authentication [Y/n] n
... skipping.

You already have your root account protected, so you can safely answer 'n'.

Change the root password? [Y/n] Y
New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

7.3 - Création de la base de données piwigo

  • Tout d'abord, connectez-vous sur l'interface MySQL avec l'utilisateur root et grâce au mot de passe saisi lors de la configuration de MariaDB :
    sudo mysql -u root -p
    Enter password: 
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MariaDB connection id is 42
    Server version: 10.6.7-MariaDB-2ubuntu1 Ubuntu 22.04
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
  • Créez la base de données piwigo :
    CREATE DATABASE piwigo;
    Query OK, 1 row affected (0.001 sec)

    Tout comme pour la gestion du répertoire piwigo et pour plus de sécurité, vous allez tout d'abord créer un utilisateur MySQL piwigo dédié à la base de données piwigo, renseigner un mot de passe et ensuite lui donner les droits sur cette base de données. Exécutez les commandes suivantes en remplaçant mon_mot_de_passe par le vôtre (attention deux commandes sont à modifier) :

    CREATE USER "piwigo"@"localhost";
    Query OK, 0 rows affected (0.002 sec)
    
    SET password FOR "piwigo"@"localhost" = password('mon_mot_de_passe');
    Query OK, 0 rows affected (0.001 sec)
    
    GRANT ALL PRIVILEGES ON piwigo.* TO "piwigo"@"localhost" IDENTIFIED BY "mon_mot_de_passe";
    Query OK, 0 rows affected (0.010 sec)
    
    FLUSH PRIVILEGES;
    Query OK, 0 rows affected (0.001 sec)
    
    EXIT;
    Bye

8 - Nom de domaine & virtual host

ⓘ Si vous souhaitez accéder à votre Piwigo de l'extérieur (et non seulement via localhost), il est nécessaire de faire pointer votre domaine ou sous-domaine vers l'IP de votre serveur. Pour cela, commencez par modifier les règles DNS dans l'interface administrateur du fournisseur de votre nom de domaine. Les règles à ajouter sont de type « A ».

Si votre serveur est hébergé chez vous, il sera aussi nécessaire de créer une redirection du port 80 et 443 vers votre serveur dans l'interface de configuration de votre box internet (ou routeur).

  • Créez le fichier suivant /etc/nginx/sites-available/piwigo et modifiez les lignes en surbrillance en fonction de votre configuration :
    upstream php-piwigo {
        server                        unix:/var/run/piwigo.sock;
    }
    
    server {
        listen                        80;
        listen                        [::]:80;
        server_name                   piwigo.mondomaine.com;
    
        # Path to the root of your installation
        root                          /var/www/piwigo/;
    
        # Add headers to serve security related headers
        add_header                    X-Frame-Options "SAMEORIGIN";
        add_header                    X-Content-Type-Options nosniff;
        add_header                    X-XSS-Protection "1; mode=block";
        add_header                    X-Robots-Tag none;
        add_header                    X-Download-Options noopen;
        add_header                    X-Permitted-Cross-Domain-Policies none;
        add_header                    Strict-Transport-Security 'max-age=31536000; includeSubDomains;';
        add_header                    Referrer-Policy no-referrer always;
    
        # set max upload size
        client_max_body_size          512M;
        fastcgi_buffers               64 4K;
    
        # Enable gzip but do not remove ETag headers
        gzip                          on;
        gzip_vary                     on;
        gzip_comp_level               4;
        gzip_min_length               256;
        gzip_proxied                  expired no-cache no-store private no_last_modified no_etag auth;
        gzip_types                    application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
    
        location / {
            index                     index.php;
            try_files                 $uri $uri/ @rewrite;
        }
    
        location @rewrite {
            rewrite                   ^/picture((/|$).*)$ /picture.php$1 last;
            rewrite                   ^/index((/|$).*)$ /index.php$1 last;
            rewrite                   ^/i((/|$).*)$ /i.php$1 last;
        }
    
        location ~ ^(?<script_name>.+?\.php)(?<path_info>/.*)?$ {
            try_files                 $script_name = 404;
            include                   /etc/nginx/fastcgi_params;
            fastcgi_pass              php-piwigo;
            fastcgi_param             PATH_INFO $path_info;
            fastcgi_param             SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    
        location ~ ^/.well-known/acme-challenge/* {
            allow                     all;
        }
    
        location ~ ^/favicon.ico$ {
            log_not_found             off;
            access_log                off;
            expires                   max;
        }
    
        location = /robots.txt {
            allow                     all;
            log_not_found             off;
            access_log                off;
        }
    
        # piwigo distribution files 
        location ~ ^/(README|doc)$ {
            deny                      all;
        }
    
        # prevent direct acces to uploaded images, derivates and logs
        location ~ ^/(_data/(i|logs)|upload)/ {
            deny                      all;
        }
    
        # prevent any hotlinks and direct access to alias URIs (/i/upload/...)
        # which are not from Piwigo itself (happens when exporting from lightroom via ws.php)
    
        set                           $check_referal "";
    
        # very restrictive
        valid_referers                *.domain.tld;
        # if you want google etc to be able to show your images:
        #valid_referers ~google\.com ~bing\.com *.domain.tld
    
        if ($invalid_referer) {
            set                       $check_referal "invalid";
        }
        if ($http_user_agent !~ "Piwigo") {
            set                       $check_referal "${check_referal}+not_piwigo";
        }
    }
  • Activez le virtual host :
    sudo ln -s /etc/nginx/sites-available/piwigo /etc/nginx/sites-enabled/piwigo
  • La nouvelle configuration sera prise en compte après redémarrage des services Nginx et PHP-FPM :
    sudo systemctl restart nginx.service
    sudo systemctl restart php8.1-fpm.service

9 - SSL/TLS avec Let's Encrypt

Let's Encrypt est une autorité de certification libre, automatisée et ouverte. Cette autorité fournit des certificats gratuits X.509 pour le protocole cryptographique SSL/TLS au moyen d'un processus automatisé destiné à se passer du processus complexe actuel impliquant la création manuelle, la validation, la signature, l'installation et le renouvellement des certificats pour la sécurisation des sites internet. Depuis sa création, Let's Encrypt a livré plus de 100 millions de certificats.

9.1 - Installation

Installez les paquets software-properties-common et certbot :

sudo apt-get install -y software-properties-common
sudo apt-get install -y certbot

9.2 - Génération des certificats

Let's Encrypt permet de générer de différentes façons plus ou moins automatisées un certificat. La méthode standalone permet de générer simplement un certificat. En revanche, celle-ci demande d'arrêter le serveur Nginx et ceci est valable à chaque renouvellement dudit certificat. Il existe aussi des plugins Apache et Nginx entièrement automatisés. Ces plugins mettent à jour automatiquement la configuration des virtual hosts mais le plugin Nginx est encore expérimental. Dans cet article, nous recommandons d'utiliser le plugin webroot pour Nginx qui permet de générer et renouveler son certificat sans interrompre le serveur Nginx.

Le plugin webroot crée un fichier temporaire /var/www/piwigo/.well-known/acme-challenge dans le dossier racine de votre Piwigo, celui-ci permettra aux serveurs de Let's Encrypt de valider votre certificat en appelant ce fichier temporaire.

  • Générez votre certificat en remplaçant [email protected] et piwigo.mondomaine.com par vos informations personnelles :
    sudo certbot certonly --webroot -w /var/www/piwigo --agree-tos --no-eff-email --email [email protected] -d piwigo.mondomaine.com --rsa-key-size 4096
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Requesting a certificate for piwigo.mondomaine.com
    
    Successfully received certificate.
    Certificate is saved at: /etc/letsencrypt/live/piwigo.mondomaine.com/fullchain.pem
    Key is saved at:         /etc/letsencrypt/live/piwigo.mondomaine.com/privkey.pem
    This certificate expires on 20XX-XX-XX.
    These files will be updated when the certificate renews.
    Certbot has set up a scheduled task to automatically renew this certificate in the background.
    
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    If you like Certbot, please consider supporting our work by:
     * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
     * Donating to EFF:                    https://eff.org/donate-le
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Vous obtiendrez 4 fichiers dans le répertoire /etc/letsencrypt/live/piwigo.mondomaine.com :

    • cert.pem : le certificat de votre domaine piwigo.mondomaine.com
    • chain.pem : le certificat Let's Encrypt
    • fullchain.pem : les certificats cert.pem et chain.pem combinés
    • privkey.pem : la clé privée du certificat.
  • SSL/TLS utilise un système de chiffrement asymétrique (comme RSA ou Diffie-Hellman) afin de sécuriser les échanges de vos flux. Par défaut, Nginx utilise une clé de 1048 bits. En augmentant la longueur de la clé à 4096 bits, vous augmenterez ainsi la sécurité de votre protocole SSL/TLS. Générez une nouvelle clé Diffie-Hellman (DH) de 4096 bits et attribuez-lui un minimum de permissions. La première commande peut prendre plusieurs heures :
    sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
    sudo chmod 600 /etc/ssl/certs/dhparam.pem
  • Ajoutez ou modifiez les lignes en surbrillance dans votre virtual host (/etc/nginx/sites-available/piwigo) en remplaçant les chemins des directives ssl_certificate, ssl_certificate_key, ssl_trusted_certificate et ssl_dhparam par l'emplacement de vos certificats et de la clé DH précédemment générés :
    upstream php-piwigo {
        server                        unix:/var/run/piwigo.sock;
    }
    
    server {
        listen                        80;
        listen                        [::]:80;
        server_name                   piwigo.mondomaine.com;
        return                        301 https://$server_name$request_uri;
    }
    
    server {
        listen                        443 ssl http2;
        listen                        [::]:443 ssl http2;
        server_name                   piwigo.mondomaine.com;
    
        # Path to the root of your installation
        root                          /var/www/piwigo/;
    
        ssl                           on;
        ssl_certificate               /etc/letsencrypt/live/piwigo.mondomaine.com/fullchain.pem;
        ssl_certificate_key           /etc/letsencrypt/live/piwigo.mondomaine.com/privkey.pem;
        ssl_trusted_certificate       /etc/letsencrypt/live/piwigo.mondomaine.com/chain.pem;
        ssl_dhparam                   /etc/ssl/certs/dhparam.pem;
    
        ssl_session_cache             shared:SSL:1m;
        ssl_session_timeout           1440m;
        ssl_buffer_size               8k;
        ssl_protocols                 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers                   TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
        ssl_prefer_server_ciphers     on;
        ssl_stapling                  on;
        ssl_stapling_verify           on;
    
        # Add headers to serve security related headers
        add_header                    X-Frame-Options "SAMEORIGIN";
        add_header                    X-Content-Type-Options nosniff;
        add_header                    X-XSS-Protection "1; mode=block";
        add_header                    X-Robots-Tag none;
        add_header                    X-Download-Options noopen;
        add_header                    X-Permitted-Cross-Domain-Policies none;
        add_header                    Strict-Transport-Security 'max-age=31536000; includeSubDomains;';
        add_header                    Referrer-Policy no-referrer always;
    
            # set max upload size
        client_max_body_size          512M;
        fastcgi_buffers               64 4K;
    
        # Enable gzip but do not remove ETag headers
        gzip                          on;
        gzip_vary                     on;
        gzip_comp_level               4;
        gzip_min_length               256;
        gzip_proxied                  expired no-cache no-store private no_last_modified no_etag auth;
        gzip_types                    application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
    
        location / {
            index                     index.php;
            try_files                 $uri $uri/ @rewrite;
        }
    
        location @rewrite {
            rewrite                   ^/picture((/|$).*)$ /picture.php$1 last;
            rewrite                   ^/index((/|$).*)$ /index.php$1 last;
            rewrite                   ^/i((/|$).*)$ /i.php$1 last;
        }
    
        location ~ ^(?<script_name>.+?\.php)(?<path_info>/.*)?$ {
            try_files                 $script_name = 404;
            include                   /etc/nginx/fastcgi_params;
            fastcgi_pass              php-piwigo;
            fastcgi_param             PATH_INFO $path_info;
            fastcgi_param             SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param             HTTPS on;
        }
    
        location ~ ^/.well-known/acme-challenge/* {
            allow                     all;
        }
    
        location ~ ^/favicon.ico$ {
            log_not_found             off;
            access_log                off;
            expires                   max;
        }
    
        location = /robots.txt {
            allow                     all;
            log_not_found             off;
            access_log                off;
        }
    
        # piwigo distribution files 
        location ~ ^/(README|doc)$ {
            deny                      all;
        }
    
        # prevent direct acces to uploaded images, derivates and logs
        location ~ ^/(_data/(i|logs)|upload)/ {
            deny                      all;
        }
    
        # prevent any hotlinks  and direct access to alias URIs (/i/upload/...)
        # which are not from Piwigo itself (happens when exporting from lightroom via ws.php)
    
        set                           $check_referal "";
    
        # very restrictive
        valid_referers                *.domain.tld;
        # if you want google etc to be able to show your images:
        #valid_referers ~google\.com ~bing\.com *.domain.tld
    
        if ($invalid_referer) {
            set                       $check_referal "invalid";
        }
        if ($http_user_agent !~ "Piwigo") {
            set                       $check_referal "${check_referal}+not_piwigo";
        }
    }
  • Rechargez votre configuration Nginx :
    sudo systemctl reload nginx.service

9.3 - Renouvellement automatique du certificat

Les certificats délivrés par Let's Encrypt sont valides 90 jours. Une tâche planifiée permettant de renouveler l'ensemble des certificats présents sur votre serveur est fournie avec le paquet certbot. Celle-ci est exécutée deux fois par jour et les renouvelle si et seulement si vos certificats expirent dans un délai inférieur à 30 jours.

  • Testez si le renouvellement automatique est fonctionnel avec la commande suivante :
    sudo certbot renew --dry-run

10 - Piwigo

Lancez votre navigateur et rendez-vous à l'adresse suivante : https://piwigo.mondomaine.com/.

Configurez votre compte administrateur et les informations de votre base de données nécessaires à Piwigo :

Piwigo configuration

Vérifiez la force de votre protocole SSL/TLS en vérifiant votre Piwigo sur SSL Labs. Avec une telle configuration, vous devriez obtenir un A+.

11 - Améliorer les performances de votre Piwigo avec OPcache

OPcache (qui signifie Optimizer Plus Cache) est introduit depuis la version 5.5.0 de PHP. Il sert à cacher l'opcode de PHP, c’est-à-dire les instructions de bas niveau générées par la machine virtuelle PHP lors de l’exécution d’un script. Autrement dit, le code pré-compilé est stocké en mémoire.

 

La suite est réservée aux membres. Déjà membre ? Se connecter

12 - Améliorer la sécurité de votre Piwigo


Développé en langage Python, Fail2Ban est un outil permettant d'analyser des fichiers de logs et de déclencher des actions si certaines choses suspectes sont détectées. Fail2ban est capable de détecter des connexions non autorisées et de bannir (via iptables) l'adresse IP de l'attaquant

 

La suite est réservée aux membres. Déjà membre ? Se connecter


13 - Piwigo sur Android...

Disponible sur Google Play
Découvrez l'excellente application officielle Piwigo sur Android qui vous permettra de synchroniser et de partager vos fichiers sur votre mobile.

Testé sur
Ubuntu Server 22.04 LTS
Auteur
Edouard WATTECAMPS

7 réflexions au sujet de “Ubuntu 22.04 - Installation de Piwigo avec Nginx, MariaDB et SSL/TLS”

  1. Bonjour,
    Merci pour cette documentation. Je l’ai testée et elle fonctionne parfaitement. J’ai une question à vous poser.
    Je souhaite installer Piwigo et Nextcloud sur le même serveur. J’ai donc installé Piwigo en suivant votre doc, qui fonctionne bien, puis Nextcloud. Et je bute sur la partie « Nom de domaine & virtual host » au moment de redémarrer le service Nginx, j’ai un message d’erreur:
    nginx: [emerg] duplicate upstream « php-handler » in /etc/nginx/sites-enabled/piwigo:1
    nginx: configuration file /etc/nginx/nginx.conf test failed
    De plus Piwigo ne fonctionne plus
    Merci d’avance si vous avez une idée.
    Laurent

    Répondre
  2. Bonsoir,
    Encore un tuto excellent, clair et détaillé. Toutefois, alors que je n’ai paas eu de problème avec l’installation de Nextcloud, j’en ai un avec piwigo. Alors que l’installation s’est bien déroulée, lorsque je lance piwigo dans Firefox, j’obtiens le message 502 Bad gateway. Après quelques recherches, je me suis rendu compte que lefichier piwigo.sock dans /var/run est absent, alors qu’il est bien présent pour nextcloud.
    Une idée pour résoudre le problème?
    Merci par avance
    Jean Claude

    Répondre
  3. Bonjour,
    Problème résolu. Cela provenait du fichier /etc/php/8.0/pool.d/piwigo.conf. Ne trouvant pas l’erreur, ayant fait un copier coller depuis le site, je l’ai supprimé et recréé par copie du nextcloud.conf qui fonctionnait. Après le remplacement de nextcloud par piwigo dans le fichier, le bad gateway a disparu. Par contre en arrivant sur le site, j’avais une page blanche. Après plusieurs heures de recherche et analyse des logs, le problème provenait du fait que j’utilise php8.0 et que la fonction PHP get_magic_quotes_gpc n’existe plus. J’ai donc modifier le fichier /var/www/piwigo/include/common.inc.php pour commenter la ligne 20 if ([email protected]_magic_quotes_gpc() ) (en mettant un // en début de ligne. Mais il m’a fallu effectuer la même modif dans le fichier /var/www/piwigo/install.php à la ligne 17. J’ai eu ensuite accès à la page de configuration de piwigo.
    J’espère que ces informations rendront service à d’autres.
    Cordialement
    Jean Claude

    Répondre
  4. Bonsoir,
    En fait j’ai fait tellement de manips que je ne savais plus où j’en étais. J’ai donc refait une installation propre de la debian 10 sur mon serveur. J’ai ensuite suivi à la lettre le tuto sur nextcloud. Nickel, je me suis connecté sans problème. J’ai fait de même avec le tuto sur Piwigo. L’installation s’est bien passée, mais au lancement de Piwigo, j’ai le message d’erreur 502 Bad gateway. Je suis allé voir dans /var/run et je n’ai pas piwigo.sock alors que j’ai bien nextcloud.sock. C’est comme si les 2 étaient incompatibles. J’ai php7.3-fpm pour les 2 sites et nginx 1.14.
    Merci par avance pour le coup de main
    Jean Claude

    Répondre

Laisser un commentaire