FUNIX

Mettez un manchot dans votre PC


Encourager FUNIX

La consultation du site est totalement libre et gratuite, sans publicités. Les dons sont néanmoins appréciés pour payer l'hébergement et encourager son auteur


Apache + PHP + MySQL
[Présentation | Installation  de MariaDB ( Installation par compilation configurationinitialisation des bases de données , lancement automatique par systemd , en cas de mise à jour  ,  installation d'une connexion chiffrée avec MariaDB , perte du mot de passe administrateur ) |   Installation d'Apache ( Compilation d'Apache , présentation de l'arborescence d'Apache  , Le fichier de configuration d'Apache  ,  lancement automatique d'Apache avec systemd  ) |  Installation de PHP ( Compilationconfiguration ) | Configuration avancée d'Apache ( Les pages web utilisateurs , les aliasprotection d'une page , hôtes virtuels , connexion https sécurisée avec SSL , scripts CGI  , PHP et LDAP ) |  Gestion de bases de données avec MariaDB ( Tests de fonctionnement avec MariaDB , administrer ses bases avec phpMyAdmin , connexion sécurisée entre MariaDB et phpMyAdmin )]

Dernière modification 8 août 2024

Apache 2.4.62 + PHP 8.3.10 + MariaDB 11.4.2

(Ce guide peut être téléchargé dans la section téléchargement)

Configuration LAMP


Présentation

Cette page présente l'installation et la configuration d'un serveur Apache avec PHP et MariaDB (communément appelé LAMP pour Linux, Apache, MySQL et PHP), elle est basée sur la compilation complète de ces applications et devrait convenir à toutes les distributions de Linux. Dans le cas présent je me suis servi d'une Mageia 9.
Vous pouvez bien entendu choisir d'installer les packages fournis par votre distribution préférée, mais vous trouverez dans cette page des astuces de configuration qui pourront aussi vous être utiles.

Pour MySQL on choisira maintenant d'installer le fork de MySQL, MariaDB qui reste compatible avec les bases de données MySQL si vous comptez faire une migration. En synthèse MySQL a une approche beaucoup plus commercial alors que MariaDB reste totalement sous licence libre. Dans le détail vous pouvez vous référer à cette page qui présente les différences entre les deux. Par la suite on pourra mentionner indifféremment MySQL ou MariaDB.

Vous devez récupérer préalablement les sources d' Apache à l'URL httpd.apache.org on récupère ensuite PHP à l'URL www.php.net  et enfin MariaDB à l'URL https://mariadb.org/

Pour l'analyser des logs d'Apache, reportez vous à la page "Analyser les logs d'Apache avec Webalizer et Awstats".

Pour mettre en place un moteur de recherche, reportez vous à la page " Hl://Dig"

Pour mettre en place un serveur web sécurisé  dans un environnement "chrooté" consulter cette page (non maintenue).

Pour installer un webmail basé sur Roundcube mail avec une configuration LAMP on ira voir cette page.

Installation de MariaDB

Compilation de MariaDB

Pour éviter tout conflit avec les packages installés par défaut de la Mageia, j'ai supprimé le package mariadb-client et tous les packages associés qui me servent à rien. Dans le répertoire de travail, on décompresse l'archive:

tar xvfz mariadb-11.4.2.tar.gz

Cela crée le répertoire mariadb-11.4.2, sur ma Mageia j'ai dû installer les packages lib64lz4-devel, lib64gnutls-devel, lib64curl-devel et lib64ncurses-devel. Dans le répertoire de MariaDB, on tape alors:

mkdir build
cd build
cmake ..

voilà le résultat

The following features have been enabled:

 * WSREP, Server plugin STATIC
 * SYSTEMD, Systemd scripts and notification support
 * ARCHIVE, Storage Engine MODULE
 * BLACKHOLE, Storage Engine MODULE
 * CONNECT_VCT, Support for VCT in the CONNECT storage engine
 * CONNECT_LIBXML2, Support for LIBXML2 in the CONNECT storage engine
 * CONNECT_ZIP, Support for ZIP in the CONNECT storage engine
 * CONNECT_REST, Support for REST API in the CONNECT storage engine
 * CONNECT_XMAP, Support for index file mapping in the CONNECT storage engine
 * CONNECT, Storage Engine MODULE
 * CSV, Storage Engine STATIC
 * EXAMPLE, Storage Engine MODULE
 * FEDERATED, Storage Engine MODULE
 * FEDERATEDX, Storage Engine MODULE
 * HEAP, Storage Engine STATIC
 * INNODB_AHI, InnoDB Adaptive Hash Index
 * INNODB_ROOT_GUESS, Cache index root block descriptors in InnoDB
 * INNOBASE, Storage Engine STATIC
 * MARIABACKUP, MariaDB Backup Utility
 * ARIA, Storage Engine STATIC
 * S3, Storage Engine MODULE
 * MROONGA, Storage Engine MODULE
 * MYISAM, Storage Engine STATIC
 * MYISAMMRG, Storage Engine STATIC
 * PERFSCHEMA, Storage Engine STATIC
 * ROCKSDB, Storage Engine MODULE
 * ROCKSDB_LZ4, LZ4 Compression in the RocksDB storage engine
 * ROCKSDB_BZip2, BZip2 Compression in the RocksDB storage engine
 * ROCKSDB_Snappy, Snappy Compression in the RocksDB storage engine
 * ROCKSDB_ZSTD, ZSTD Compression in the RocksDB storage engine
 * ROCKSDB_ZLIB, zlib Compression in the RocksDB storage engine
 * SEQUENCE, Storage Engine STATIC
 * SPHINX, Storage Engine MODULE
 * SPIDER, Storage Engine MODULE
 * TEST_SQL_DISCOVERY, Storage Engine MODULE
 * AUDIT_NULL, Server plugin MODULE
 * AUTH_ED25519, Server plugin MODULE
 * DIALOG_EXAMPLES, Server plugin MODULE
 * AUTH_TEST_PLUGIN, Server plugin MODULE
 * QA_AUTH_INTERFACE, Server plugin MODULE
 * QA_AUTH_SERVER, Server plugin MODULE
 * QA_AUTH_CLIENT, Server plugin MODULE
 * AUTH_0X0100, Server plugin MODULE
 * AUTH_GSSAPI, Server plugin MODULE
 * AUTH_PAM_V1, Server plugin MODULE
 * AUTH_PAM, Server plugin MODULE
 * AUTH_SOCKET, Server plugin STATIC
 * DAEMON_EXAMPLE, Server plugin MODULE
 * DEBUG_KEY_MANAGEMENT, Server plugin MODULE
 * DISKS, Server plugin MODULE
 * EXAMPLE_KEY_MANAGEMENT, Server plugin MODULE
 * FEEDBACK, Server plugin STATIC
 * FILE_KEY_MANAGEMENT, Server plugin MODULE
 * FTEXAMPLE, Server plugin MODULE
 * FUNC_TEST, Server plugin MODULE
 * HANDLERSOCKET, Server plugin MODULE
 * HASHICORP_KEY_MANAGEMENT, Hashicorp Key Management Plugin
 * LOCALES, Server plugin MODULE
 * METADATA_LOCK_INFO, Server plugin MODULE
 * PASSWORD_REUSE_CHECK, Server plugin MODULE
 * PROVIDER_BZIP2, Server plugin MODULE
 * PROVIDER_LZ4, Server plugin MODULE
 * PROVIDER_LZMA, Server plugin MODULE
 * QUERY_CACHE_INFO, Server plugin MODULE
 * QUERY_RESPONSE_TIME, Server plugin MODULE
 * SERVER_AUDIT, Server plugin MODULE
 * SIMPLE_PASSWORD_CHECK, Server plugin MODULE
 * SQL_ERRLOG, Server plugin MODULE
 * TEST_SQL_SERVICE, Server plugin MODULE
 * TYPE_GEOM, Server plugin STATIC
 * TYPE_INET, Server plugin STATIC
 * TYPE_MYSQL_JSON, Server plugin MODULE
 * TYPE_MYSQL_TIMESTAMP, Server plugin MODULE
 * TYPE_TEST, Server plugin MODULE
 * TYPE_UUID, Server plugin STATIC
 * USER_VARIABLES, Server plugin STATIC
 * USERSTAT, Server plugin STATIC
 * TEST_VERSIONING, Server plugin MODULE
 * WSREP_INFO, Server plugin MODULE
 * WSREP_PROVIDER, Server plugin STATIC
 * THREAD_POOL_INFO, Server plugin STATIC
 * PARTITION, Storage Engine STATIC
 * SQL_SEQUENCE, Storage Engine STATIC
 * ONLINE_ALTER_LOG, Storage Engine STATIC

-- The following OPTIONAL packages have been found:

 * Git
 * ZLIB
 * LibXml2
 * GSSAPI
 * BZip2
 * LZ4 (required version >= 1.6)
 * LibLZMA
 * BISON (required version >= 2.4)

-- The following RECOMMENDED packages have been found:

 * OpenSSL

-- The following REQUIRED packages have been found:

 * Curses
 * Threads
 * CURL

-- The following features have been disabled:

 * LIBWRAP, Support for tcp wrappers
 * CONNECT_ODBC, Support for ODBC in the CONNECT storage engine
 * CONNECT_JDBC, Support for JDBC in the CONNECT storage engine
 * CONNECT_MONGODB, Support for MongoDB in the CONNECT storage engine
 * NUMA, NUMA memory allocation policy
 * INNODB_EXTRA_DEBUG, Extra InnoDB debug checks
 * AWS_KEY_MANAGEMENT, AWS Encryption Key Management Plugin
 * EMBEDDED_SERVER, Embedded MariaDB Server Library

-- The following OPTIONAL packages have not been found:

 * Java (required version >= 1.6)
   Required for the CONNECT_JDBC feature
 * JNI
   Required for the CONNECT_JDBC feature
 * Boost (required version >= 1.40.0)
   Required for the OQGraph storage engine
 * LZO
 * Snappy

-- Configuring done (89.4s)
-- Generating done (1.0s)
-- Build files have been written to: /home/olivier/compilation/mariadb-11.4.2/build

on tape ensuite

make

et en tant que root make install

On rajoutera la ligne /usr/local/lib/mariadb dans le fichier /etc/ld.so.conf et on tapera ldconfig.

Les exécutables sont installés par défaut sous /usr/local/mysql/bin, les bibliothèques vont se trouver sous /usr/local/mysql/lib, maintenant pour que les headers de mariadb soient accessibles pour d'autres softs qui en auraient l'usage, il faudra créer le lien suivant

ln -s /usr/local/mysql/include/mysql /usr/include

vous mettrez bien sûr votre chemin absolu de mysql. Si vous upgradez MySQL  vous pouvez passer à l'étape suivante. Sinon vous devez taper les commandes suivantes :

groupadd mysql

Puis l'utilisateur mysql du groupe mysql

useradd mysql -c "MySQL Server" -d /dev/null -g mysql -s /sbin/nologin

On va créer préalablement le répertoire /var/log/mysqld, et mysql doit en être propriétaire

mkdir /var/log/mysqld
chown mysql:mysql /var/log/mysqld


Configuration

On installera maintenant le fichier de configuration /etc/my.cnf, voilà à quoi il va ressembler

[client]

#emplacement de la socket
socket = /var/run/mysqld/mysqld.sock

[mysqld]

# chemin par défaut d'installation de mariaDB
basedir = /usr/local/mysql

# chemin de la base de donnée
datadir = /usr/local/mysql/data/

# emplacement de la socket
socket = /var/run/mysqld/mysqld.sock

#répertoire temporaire
tmpdir = /tmp

# configuration diverse
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

on donne les droits qui vont bien

chown root:sys /etc/my.cnf
chmod 644 /etc/my.cnf

Initialisation des bases de donnée

On va d'abord initialiser les bases de données avec le script mysql_install_db.sh qui se trouve dans le répertoire mariadb-11.4.2/scripts, il faudra le modifier pour éviter les erreurs comme cela

FATAL ERROR: Could not find mariadbd

The following directories were searched:

    @mysqld_locations@

ou bien encore

./mysql_install_db.sh: ligne 444: @HOSTNAME@ : commande introuvable

on l'édite et on modifie ainsi les lignes suivantes

resolveip=`find_in_dirs resolveip $bindir`

au lieu de resolveip=`find_in_dirs resolveip @resolveip_locations@` et

mysqld=`find_in_dirs mariadbd $bindir`

langdir="/usr/local/mysql/share/french"

srcpkgdatadir="/usr/local/mysql/share"

ainsi qu'on remplace hostname=`@HOSTNAME@` par hostname=`hostname`

Une fois corrigé, on le lance

bash ./mysql_install_db.sh --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data --builddir=/chemin/mariadb-11.4.2/

et voilà le résultat

Installing MariaDB/MySQL system tables in '/usr/local/mysql/data' ...
OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system


Two all-privilege accounts were created.
One is root@localhost, it has no password, but you need to
be system 'root' user to connect. Use, for example, sudo mysql
The second is mysql@localhost, it has no password either, but
you need to be the system 'mysql' user to connect.
After connecting you can set the password, if you would need to be
able to connect as any of these users with a password and without sudo

See the MariaDB Knowledgebase at https://mariadb.com/kb

You can start the MariaDB daemon with:
cd '/usr/local/mysql/' ; /usr/local/mysql//bin/mysqld_safe --datadir='/usr/local/mysql/data'

You can test the MariaDB daemon with mysql-test-run.pl
cd '/usr/local/mysql//mysql-test' ; perl mysql-test-run.pl

Please report any problems at https://mariadb.org/jira

The latest information about MariaDB is available at https://mariadb.org/.

Consider joining MariaDB's strong and vibrant community:
https://mariadb.org/get-involved/

Dans la configuration présentée dans cette page les bases de données se trouvent sous /usr/local/mysql/data, mysql doit en être propriétaire

chown -R mysql:mysql /usr/local/mysql/data

on va également mettre les droits à 755 sinon seul root aura accès à la base mysql

chmod 755 /usr/local/mysql/data

On lance maintenant le serveur en tapant

/usr/local/mysql/bin/mysqld_safe --datadir='/usr/local/mysql/data'

voilà le résultat

220730 17:28:58 mysqld_safe Logging to '/usr/local/mysql/data/ultra.kervao.fr.err'.
220730 17:28:58 mysqld_safe Starting mariadbd daemon with databases from /usr/local/mysql/data

On sécurise maintenant  l'accès à la base de données en tapant mysql_secure_installation en tant que root, voilà le résultat

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
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password or using the unix_socket 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] y
Enabled successfully!
Reloading privilege tables..
 ... Success!


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

Change the root password? [Y/n] n
 ... skipping.

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]
 - 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]
 ... 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!

maintenant on peut se connecter à la base en tapant

mariadb -u root -p

Enter password:  on rentre le mot de passe défini plus haut, et voilà le résultat

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 246
Server version: 11.4.2-MariaDB Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

A présent reportez vous à la page MariaDB à partir de la  création des autres utilisateurs  qui accèderont à vos base pour éviter de travailler sous root.



[retour haut de la page]

Lancement automatique par systemd

Avec systemd créer le fichier /usr/lib/systemd/system/mariadb.service qui contient

[Unit]
Description=MariaDB Server
After=syslog.target
After=network.target

[Service]
Type=simple
PermissionsStartOnly=true
ExecStartPre=/bin/mkdir -p /var/run/mysqld
ExecStartPre=/bin/chown mysql:mysql -R /var/run/mysqld
ExecStart=/usr/local/mysql/bin/mariadbd --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --log-error=/var/log/mysqld/error.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock
TimeoutSec=300
PrivateTmp=true
User=mysql
Group=mysql
WorkingDirectory=/usr/local

[Install]
WantedBy=multi-user.target


on lance maintenant le service MariaDB en tapant

systemctl start mariadb.service

voilà le statut du daemon une fois lancé

systemctl status mariadb.service

voilà le résultat

● mariadb.service - MariaDB Server
     Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; preset: disabled)
     Active: active (running) since Fri 2024-08-09 14:11:28 CEST; 8s ago
    Process: 2564262 ExecStartPre=/bin/mkdir -p /var/mysql/run (code=exited, status=0/SUCCESS)
    Process: 2564263 ExecStartPre=/bin/chown mysql:mysql -R /var/mysql/run (code=exited, status=0/SUCCESS)
   Main PID: 2564264 (mariadbd)
      Tasks: 16 (limit: 9265)
     Memory: 111.2M
        CPU: 296ms
     CGroup: /system.slice/mariadb.service
             └─2564264 /usr/local/mysql/bin/mariadbd --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --log-error=/var/log/mysqld/error.log --pid-file=/var/mysql/run/mysqld.pid --socket=/var/mysql/run/mysqld.sock

août 09 14:11:28 ultra.kervao.fr systemd[1]: Starting mariadb.service...
août 09 14:11:28 ultra.kervao.fr systemd[1]: Started mariadb.service.

Maintenant pour que le service soit lancé à chaque démarrage on tapera

systemctl enable mariadb.service


[retour haut de la page]

En cas de mise à jour

Juste après avoir installé la nouvelle version de MariaDB la première chose à faire est de relancer le daemon

systemctl restart mariadb

il faudra faire ensuite un upgrade de la base de données en tapant

mariadb-upgrade -u root -p

cela va donner

Major version upgrade detected from 11.1.2-MariaDB to 11.4.2-MariaDB. Check required!
Phase 1/8: Checking and upgrading mysql database
Processing databases
mysql
mysql.column_stats                                 OK
mysql.columns_priv                                 OK
mysql.db                                           OK
mysql.event                                        OK
mysql.func                                         OK
mysql.global_priv                                  OK
mysql.gtid_slave_pos                               OK
mysql.help_category                                OK
mysql.help_keyword                                 OK
mysql.help_relation                                OK
mysql.help_topic                                   OK
mysql.index_stats                                  OK
mysql.innodb_index_stats                           OK
mysql.innodb_table_stats                           OK
mysql.plugin                                       OK
mysql.proc                                         OK
mysql.procs_priv                                   OK
mysql.proxies_priv                                 OK
mysql.roles_mapping                                OK
mysql.servers                                      OK
mysql.table_stats                                  OK
mysql.tables_priv                                  OK
mysql.time_zone                                    OK
mysql.time_zone_leap_second                        OK
mysql.time_zone_name                               OK
mysql.time_zone_transition                         OK
mysql.time_zone_transition_type                    OK
mysql.transaction_registry                         OK
Phase 2/8: Installing used storage engines... Skipped
Phase 3/8: Running 'mysql_fix_privilege_tables'

(...)

roundcubemail.session                              OK
roundcubemail.system                               OK
roundcubemail.users                                OK
spamassassin
spamassassin.userpref                              OK
syncstorage_rs
syncstorage_rs.__diesel_schema_migrations          OK
syncstorage_rs.batch_upload_items                  OK
syncstorage_rs.batch_uploads                       OK
syncstorage_rs.bso                                 OK
syncstorage_rs.collections                         OK
syncstorage_rs.user_collections                    OK
sys
sys.sys_config                                     OK
tokenserver_rs
tokenserver_rs.__diesel_schema_migrations          OK
tokenserver_rs.nodes                               OK
tokenserver_rs.services                            OK
tokenserver_rs.users                               OK
Phase 7/8: uninstalling plugins
Phase 8/8: Running 'FLUSH PRIVILEGES'
OK

La mise à jour de la base est terminée, en revanche si vous avez l'erreur suivante

Error    : Cannot load from mysql.proc. The table is probably corrupted
error    : Corrupt
sys.io_by_thread_by_latency
Error    : Cannot load from mysql.proc. The table is probably corrupted
error    : Corrupt
sys.io_global_by_file_by_bytes
Error    : Cannot load from mysql.proc. The table is probably corrupted
error    : Corrupt
sys.io_global_by_file_by_latency
Error    : Cannot load from mysql.proc. The table is probably corrupted
error    : Corrupt
sys.io_global_by_wait_by_bytes
Error    : Cannot load from mysql.proc. The table is probably corrupted
error    : Corrupt

il faudra retaper la commande en rajoutant

mariadb-upgrade -u root -p --force

Il faudra ensuite relancer le serveur

systemctl restart mariadb

[retour haut de la page]

Mettre en place une connexion chiffrée avec MariaDB

Maintenant pour créer une connexion sécurisée on va créer le répertoire /etc/mysql et /etc/mysql/ssl. On va sous /etc/mysql/ssl et on génère une clé RSA privée pour l'autorité de certification maison (CA pour Certificate Autority). Il est bien évident que les certificats et clé de votre CA ne seront valables que sur votre seul réseau interne, à moins que vous soyiez une CA reconnue et enregistrée sur internet ! Si votre site est accessible par internet je vous conseille de créer un certificat qui sera valable sur internet avec let's encrypt.

openssl genrsa 2048 > ca-key.pem

voilà le résultat

Generating RSA private key, 2048 bit long modulus
............................................................................+++++
.............+++++
e is 65537 (0x010001)

on crée maintenant le certificat du CA basé sur la clé précédemment créée en tapant

openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem

voilà le résultat

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:FR
State or Province Name (full name) [Default Province]:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []: ca-mariadb
Email Address []:olivier.hoarau@funix.org


je me retrouve avec les fichiers ca-cert.pem (certificat) et ca-key.pem (la clé associée au certificat). Maintenant je crée un certificat pour le serveur en tapant

openssl req -newkey rsa:2048 -days 365000 -nodes -keyout server-key.pem -out server-req.pem

voilà le résultat

Generating a RSA private key
......................................................+++++
...............+++++
writing new private key to 'server-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:FR
State or Province Name (full name) [Default Province]:None
Locality Name (eg, city) [Default City]: None
Organization Name (eg, company) [Default Company Ltd]: None
Organizational Unit Name (eg, section) []: None
Common Name (e.g. server FQDN or YOUR name) []: serveur-mariadb
Email Address []:olivier.hoarau@funix.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Attention pour le nom du serveur il faut mettre le nom de notre serveur tel qu'on le retrouve dans le fichier /etc/hosts. Maintenant on crée la clé RSA du serveur

openssl rsa -in server-key.pem -out server-key.pem

et voilà le résultat

writing RSA key

on signe le certificat du serveur

openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem

voilà le résultat

Signature ok
subject=C = FR, ST = None, L = None, O = None, OU = None, CN = serveur-mariadb, emailAddress = olivier.hoarau@funix.org
Getting CA Private Key

je me retrouve avec les fichiers supplémentaires suivants server-cert.pem, server-key.pem et server-req.pem. On crée maintenant le certificat du client

openssl req -newkey rsa:2048 -days 365000 -nodes -keyout client-key.pem -out client-req.pem

voilà le résultat

Generating a RSA private key
.......+++++
................+++++
writing new private key to 'client-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:FR
State or Province Name (full name) [Default Province]:None
Locality Name (eg, city) [Default City]:None
Organization Name (eg, company) [Default Company Ltd]:None
Organizational Unit Name (eg, section) []:None
Common Name (e.g. server FQDN or YOUR name) []:client-mariadb
Email Address []:olivier.hoarau@funix.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:None

on crée la clé RSA du client

openssl rsa -in client-key.pem -out client-key.pem

voilà le résultat

writing RSA key

et on signe le certificat du client

openssl x509 -req -in client-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem

voilà le résultat

Signature ok
subject=C = FR, ST = None, L = None, O = None, OU = None, CN = client-mariadb, emailAddress = olivier.hoarau@funix.org
Getting CA Private Key

on vérifie que tout est OK en tapant

openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem

voilà le résultat

server-cert.pem: OK
client-cert.pem: OK

si vous avez comme erreur

error 18 at 0 depth lookup: self signed certificate
error client-cert.pem: verification failed

Ca vient d'un problème sur la ligne Common Name (e.g. server FQDN or YOUR name) [] vous devez avoir un champ différent pour le CA, le serveur et le client, vous pouvez très bien utiliser des alias différents en les définissant dans /etc/hosts. Maintenant on va rendre mysql propriétaire du répertoire ssl pour qu'il puisse lire les fichiers.

chown -R mysql:mysql /etc/mysql/ssl/

on va éditer le fichier /etc/my.cnf et rajouter les lignes suivantes au niveau du serveur et du client

[client]

ssl-ca=/etc/mysql/ssl/ca-cert.pem
ssl-cert=/etc/mysql/ssl/client-cert.pem
ssl-key=/etc/mysql/ssl/client-key.pem

[mysqld]
ssl-ca=/etc/mysql/ssl/ca-cert.pem
ssl-cert=/etc/mysql/ssl/server-cert.pem
ssl-key=/etc/mysql/ssl/server-key.pem

On relance le serveur

systemctl restart mariadb

et on tape

mariadb -u root -p

Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 11.4.2-MariaDB Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> status
--------------
mariadb from 11.4.2-MariaDB, client 15.2 for Linux (x86_64) using readline 5.1

Connection id:          9
Current database:
Current user:           olivier@ultra.kervao.fr
SSL:                    Cipher in use is TLS_AES_256_GCM_SHA384, cert is OK
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server:                 MariaDB
Server version:         11.4.2-MariaDB Source distribution
Protocol version:       10
Connection:             mariadb-serveur via TCP/IP
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    utf8mb3
Conn.  characterset:    utf8mb3
TCP port:               3306
Uptime:                 1 min 27 sec

Threads: 2  Questions: 63  Slow queries: 0  Opens: 39  Open tables: 32  Queries per second avg: 0.724
--------------

et

+---------------------+--------------------------------+
| Variable_name       | Value                          |
+---------------------+--------------------------------+
| have_openssl        | YES                            |
| have_ssl            | YES                            |
| ssl_ca              | /etc/mysql/ssl/ca-cert.pem     |
| ssl_capath          |                                |
| ssl_cert            | /etc/mysql/ssl/server-cert.pem |
| ssl_cipher          |                                |
| ssl_crl             |                                |
| ssl_crlpath         |                                |
| ssl_key             | /etc/mysql/ssl/server-key.pem  |
| version_ssl_library | OpenSSL 3.0.14 4 Jun 2024      |
+---------------------+--------------------------------+
10 rows in set (0,002 sec)

C'est bon vous êtes en connexion sécurisée. Pour aller plus loin vous pouvez consulter cette page qui va vous indiquer (par exemple) comment forcer les connexions chiffrées par utilisateur, machine, ou autre.

Attention, attention, si maintenant vous vous connectez en tapant simplement

mysql -u root -p

vous avez toutes les chances d'avoir l'erreur suivante

ERROR 2026 (HY000): TLS/SSL error: Validation of SSL server certificate failed

il faudra préciser le nom du serveur qui a été utilisé pour créer le certificat, la commande

mysql -u root -p -h mariadb-serveur -e status

donnera ainsi

--------------
mysql from 11.4.2-MariaDB, client 15.2 for Linux (x86_64) using readline 5.1

Connection id:          23
Current database:
Current user:           olivier@ultra.kervao.fr
SSL:                    Cipher in use is TLS_AES_256_GCM_SHA384, cert is OK
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server:                 MariaDB
Server version:         11.4.2-MariaDB Source distribution
Protocol version:       10
Connection:             mariadb-serveur via TCP/IP
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    utf8mb3
Conn.  characterset:    utf8mb3
TCP port:               3306
Uptime:                 12 min 2 sec

Threads: 1  Questions: 169  Slow queries: 0  Opens: 24  Open tables: 17  Queries per second avg: 0.234
--------------


Perte du mot de passe d'administrateur

Si vous avez perdu le mot de passe root pour le réinitialiser il faut stopper le serveur

systemctl stop mariadb

On redémarre le daemon en désactivant l'identification et l'écoute du réseau (afin d'éviter d'être piraté à ce moment où MariaDB est vulnérable) :

 /usr/local/mysql/bin/mariadbd --user=mysql --skip-grant-tables --skip-networking &

Maintenant on modifie le mot de passe en se connectant à la base mysql 

/usr/local/mysql/bin/mariadb  mysql -u root

Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 25
Server version: 11.4.2-MariaDB Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

MariaDB [(mysql)]>UPDATE user SET password=PASSWORD('nouveau-mot-de-passe') WHERE user="root";

Query OK, 4 rows affected (0,06 sec)
Rows matched: 4  Changed: 4  Warnings: 0

On prend en compte les changements en tapant la commande suivante :

MariaDB [(mysql)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0,04 sec)

on relance ensuite le daemon mariadb

systemctl restart mariadb


[retour haut de la page

Installation d'Apache

Compilation d'Apache

Pour Apache, on installera d'abord le package lib64expat-devel, on désarchive en tapant:

tar xvfz httpd-2.4.62.tar.gz

Cela va créer le répertoire httpd-2.4.62.

Il faudra préalablement installer les outils apr et apr-util qu'on téléchargera sur le site apr.apache.org. On décompresse la première archive en tapant

tar xvfz apr-1.7.4.tar.gz

cela donne le répertoire apr-1.7.4 dans lequel on tape successivement

./configure
make

puis en tant que root

make install

on édite maintenant le fichier /etc/ld.so.conf et on rajoute la ligne suivante

/usr/local/apr/lib

on décompresse la deuxième archive en tapant

tar xvfz apr-util-1.6.3.tar.gz

cela donne le répertoire apr-util-1.6.3 on y tape successivement

./configure --with-apr=/chemin-absolu/apr-1.7.4 --with-crypto --with-openssl=/usr/local/ssl/lib

make

puis en tant que root

make install
ldconfig

Dans le répertoire d'Apache httpd-2.4.62, on tape alors:

./configure --prefix=/usr/local/apache2 --enable-modules=most

Par prefix on indique que les répertoires d'Apache contenant entre autre le fichier de conf se trouveront sous /usr/local/apache2 c'est utile dans le cas où vous voulez faire coexister deux versions d'Apache sur votre système. On tape maintenant:

make

Et enfin en tant que root:

make install

Rajoutez la ligne /usr/local/apache2/lib dans le fichier /etc/ld.so.conf puis tapez

ldconfig

Pour lancer maintenant Apache, il faut taper:

/usr/local/apache2/bin/apachectl start

Maintenant votre navigateur préféré dans le champ URL taper http://localhost ou http://nomdelamachine et là la page d'accueil d'Apache apparaît (ou du moins un It Works !!), pour info celle-ci se trouve sous /usr/local/apache2/htdocs.

NOTE Si vous upgradez d'une ancienne version, vos fichiers de conf ne seront pas écrasés.

[retour haut de la page]

Présentation de l'arborescence d'Apache

L'installation va créer un répertoire /usr/local/apache2  contenant:

- répertoire auth qui contient les mots de passe chiffrée pour les pages web avec accès par mot de passe
- répertoire bin contient les exécutables d'Apache
- répertoire cgi-bin contient les scripts CGI
- répertoire error contient les messages d'erreur dans de multiples langues, la langue est choisie en fonction de la configuration du navigateur. Les messages sont entièrement configurables.
- répertoire lib contient des bibliothèques
- répertoire build contient des paramètres divers de configuration de compilation
- répertoire conf contient les fichiers de configuration d'Apache
- répertoire htdocs contient la page d'accueil d'Apache
- répertoire icons contient des icônes qui servent notamment pour identifier les types de fichier.
- répertoire include contient les includes d'Apache
- répertoire modules contient les modules d'Apache
- répertoire logs contient les fichiers de log d'Apache
- répertoire man contient les manuels d'Apache

Le répertoire de log contient essentiellement deux fichiers:
- access_log listant les accès au serveur
- error_log listant les erreurs en tout genre

Le répertoire de modules modules contient  les modules utilisables par Apache, pour info un module est une extension logicielle à Apache, lui permettant par exemple d'interpréter le PHP (module libphp.so). Ce ne sont que les modules chargés dynamiquement qui sont dans ce répertoire.

Le répertoire /usr/local/apache2/conf contient:
- le fichier de configuration d'Apache http.conf
- mime.types fixe le type de fichier suivant l'extension du dit fichier (.doc=msword, .ps=postscript, ...), ça permet au client qui se connecte sur le serveur, de savoir comment interpréter le fichier suivant son extension.
- magic sert pour le module mod_mime_magic

Vous trouverez également un tas d'autres fichiers de config fournis comme exemple dans les répertoire extra et original.

Le fichier de configuration d'Apache

Le fichier de conf d'Apache se trouve sous /usr/local/apache2 et se nomme httpd.conf, voici les points que je juge important dans le fichier:

(...)

# Répertoire racine d'Apache
ServerRoot "/usr/local/apache"

(...)

# définition de l'adresse IP du port du serveur
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, in addition to the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
#
#Listen 12.34.56.78:80
# avec un deuxième serveur apache, vous pouvez indiquer un port 8080
# dans l'url du navigateur il faudra mettre http://url:8080

Listen 80

(...)

# chargement des modules complémentaires

LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule filter_module modules/mod_filter.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule cgid_module modules/mod_cgid.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule wsgi_module modules/mod_wsgi.so
LoadModule php7_module        modules/libphp7.so

# On lance initialement httpd en tant que root, puis immédiatement
# c'est l'utilisateur nobody (groupe nobody) qui en devient le proprio
# ainsi s'il y a une faille dans Apache, le hacker au lieu de devenir root
# devient daemon avec les droits qui vont avec
# pour vérifier que daemon est bien le proprio
# ps aux | grep httpd

User daemon
Group dameon

# ServerAdmin: Your address, where problems with the server should be
# e-mailed.  This address appears on some server-generated pages, such
# as error documents.
# En cas de problème un email sera envoyé au webmaster, mettez donc
# ici l'adresse email du webmaster
ServerAdmin olivier@asterix.kervao.fr

(...)

# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
# C'est dans ce répertoire qu'on va trouver la page d'accueil d'Apache
DocumentRoot "/usr/local/apache/htdocs"

(...)

# Définition des fichiers d'entrée
DirectoryIndex index.html index.html.var index.htm index.php index.php index.php7

(...)

# nom du fichier d'erreur
ErrorLog logs/error_log

# niveau de log
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
LogLevel warn

(...)

# ordre de préférence des langues
# LanguagePriority allows you to give precedence to some languages
# in case of a tie during content negotiation.
#
# Just list the languages in decreasing order of preference. We have
# more or less alphabetized them here. You probably want to change this.
#
LanguagePriority fr en da nl et de el it ja kr no pl pt pt-br ltz ca es sv tw


En l'état s'est largement suffisant comme configuration pour faire tourner un serveur Apache, on verra plus loin comment le personnaliser et aller plus loin.

Lancement automatique de l'application avec systemd

Pour un lancement automatique il faudra créer préalablement le fichier /usr/lib/systemd/system/httpd.service

[Unit]
Description=Apache Web Server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
ExecStart=/usr/local/apache2/bin/apachectl start
ExecStop=/usr/local/apache2/bin/apachectl graceful-stop
ExecReload=/usr/local/apache2/bin/apachectl graceful
PrivateTmp=true
LimitNOFILE=infinity

[Install]
WantedBy=multi-user.target

attention le répertoire /var/run/httpd doit être créé au préalable, on lance apache en tapant systemctl start httpd

voilà le résultat en tapant systemctl status httpd

● httpd.service - Apache Web Server
     Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; preset: disabled)
     Active: active (running) since Thu 2024-08-08 15:54:29 CEST; 18s ago
    Process: 2073587 ExecStart=/usr/local/apache2/bin/apachectl start (code=exited, status=0/SUCCESS)
   Main PID: 2073590 (httpd)
      Tasks: 83 (limit: 9265)
     Memory: 17.2M
        CPU: 189ms
     CGroup: /system.slice/httpd.service
             ├─2073590 /usr/local/apache2/bin/httpd -k start
             ├─2073591 /usr/local/apache2/bin/httpd -k start
             ├─2073592 /usr/local/apache2/bin/httpd -k start
             ├─2073593 /usr/local/apache2/bin/httpd -k start
             └─2073594 /usr/local/apache2/bin/httpd -k start

août 08 15:54:28 ultra.kervao.fr systemd[1]: Starting httpd.service...

pour qu'apache soit lancé automatique à chaque démarrage on tapera systemctl enable httpd.service 


[retour haut de la page]


Installation de PHP

Compilation de PHP

Pour php, on aura besoin préalablement de d'oniguruma qu'on récupérera ici  https://github.com/kkos/oniguruma/releases on décompresse l'archive en tapant :

tar xvfz onig-6.9.9.tar.gz

cela donne le répertoire onig-6.9.9 dans lequel on tape

./autogen.sh

./configure
make

puis en tant que root

make install

on installera également les packages argon2, argon2-devel, lib64gd-devel, lib64zip-devel et lib64sqlite3-devel on renvient à php qu'on décompresse en tapant 

tar xvfj php-8.3.10.tar.bz2

Cela va créer un répertoire php-8.3.10. A présent dans le répertoire de php, vous taperez

./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-config-file-path=/usr/local/apache2/conf  --enable-bcmath=yes --enable-debug=no  --with-zlib  --with-kerberos  --enable-mbstring  --enable-ftp --with-mysqli --with-openssl   --with-curl --enable-intl --with-ldap --enable-gd --with-zip --with-pdo-mysql --with-password-argon2 --with-freetype --with-external-gd --with-pear

Tapez maintenant

make

Puis en tant que root

make install

Cette dernière commande va installer le module PHP sous /usr/local/apache2/modules et modifier le fichier httpd.conf en rajoutant

LoadModule php_module        modules/libphp.so


[retour haut de la page]

Configuration

On modifiera maintenant manuellement le fichier httpd.conf pour qu'Apache prenne en compte PHP, à la suite des lignes

AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz

On rajoute

AddType application/x-httpd-php .php .phtml
AddType application/x-httpd-php-source .phps

Par ailleurs à la ligne

DirectoryIndex index.html

On rajoutera

DirectoryIndex index.html index.htm index.php

A présent on va copier le fichier php.ini-production se trouvant dans le répertoire de PHP pour le mettre sous /usr/local/apache2/conf et en le renommant php.ini

cp php.ini-production /usr/local/apache2/conf/php.ini

Dans le cas d'une ancienne installation de php, vous avez tout intérêt à repartir du nouveau fichier php-dist.ini fourni et de le remodifier.
Dans le répertoire /usr/local/apache/htdocs on trouve les fichiers qui seront accessibles à partir de la page d'accueil de votre serveur Apache

On relance Apache

systemctl restart httpd

Créer maintenant le fichier infophp.php contenant

<?php
phpinfo();
?>

Que vous placerez sous /usr/local/apache2/htdocs, dans l'URL de votre navigateur préféré, taper http://localhost/infophp.php ou http://nommachine/infophp.php et là magique devrait s'afficher des info sur la configuration de PHP sur votre système.

ATTENTION pour un fonctionnement optimal de mysql avec php, il faudra rajouter préciser la position du fichier socket de mysql dans le fichier php.ini

pdo_mysql.default_socket=/var/run/mysqld/mysqld.sock

sinon avec phpMyAdmin vous pourriez avoir une erreur du style

#2002 - Le serveur ne répond pas. (ou l'interface de connexion ("socket") vers le serveur MySQL local n'est pas correctement configurée)

Configuration avancée d'Apache

Les pages webs utilisateurs

Dans le fichier httpd.conf on doit rajouter

UserDir public_html

<Directory "/home/*/public_html">
   Options Indexes FollowSymLinks Includes ExecCGI
   AllowOverride All
   Require all granted
</Directory>

et relancez httpd, les utilisateurs qui veulent avoir une homepage perso devront placer leurs fichiers dans un répertoire public_html placé dans leur homedirectory. Les pages seront accessibles à partir de l'URL http://serveur-apache/~utilisateur

Le problème  avec le répertoire public_html des utilisateurs et qu'il faut mettre 755 au niveau de la home directory, ce qui est particulièrement génant au niveau sécurité. Vous pouvez spécifier que chaque utilisateur doit créer ses pages sous /home/http/login-utilisateur en écrivant pour la variable UserDir

UserDir /home/httpd

Ainsi pour l'utilisateur toto quand vous taperez comme URL http://serveur-apache/~toto, apache ira chercher le fichier index.htm sous /home/httpd/toto. On peut aller plus loin en spécifiant un répertoire particulier, /home/httpd/toto/html par exemple, en écrivant:

UserDir /home/httpd/*/html


 

Les alias

Si vous ne voulez pas mettre en place un serveur DNS, vous avez un moyen plus simple, les alias. Concrètement, votre serveur s'appelle obelix , vous voulez rendre accessible les fichiers html se trouvant sous /usr/doc/html , les utilisateurs devront taper dans leur navigateur préféré: http://obelix/doc. Pour cela dans votre fichier /etc/httpd/conf/httpd.conf, vous allez rajouter:

 Alias /icons/ "/usr/local/apache/icons/"
 Alias /doc "/usr/doc/html/"

on rajoute ensuite pour chacun des répertoires

<Directory "/usr/doc/html">
   Options Indexes FollowSymLinks Includes ExecCGI
   AllowOverride All
   Require all granted
</Directory>

NOTE Si vous mettre /doc/ à la place de /doc dans l'URL il faudra taper http://obelix/doc/, si vous omettez le dernier /, vous aurez une erreur.

Protection d'une page

La protection d'une page pour l'utilisateur olivier se fait de manière très simple, tout d'abord dans le fichier de configuration d'apache on doit avoir la ligne

# définition des fichiers de protection des pages
AccessFileName .htaccess

il faut bien évidemment relancer apache.

Tous les fichiers à accès limité doivent être concentrés dans un même répertoire /home/olivier/public_html/reserve par exemple, il suffit de créer dans celui-ci un fichier qu'on devra nommer .htaccess contenant:

AuthUserFile auth/olivier.users
AuthGroupFile auth/olivier.group
AuthName "Acces Restreint"
AuthType Basic
require group autorise

Le fichier olivier.users va contenir une liste d'utilisateurs, il va se trouver sous le répertoire /usr/local/apache2/auth (éventuellement à créer), pour info vous pouvez changer le chemin /usr/local/apache2 en modifiant la valeur de la variable ServerRoot qu'on trouve dans le fichier httpd.conf. Le fichier olivier.group correspond à une liste des groupes de personnes, ces mêmes personnes ayant été défini dans le fichier olivier.users. Le principe consiste à créer un groupe de personnes autorisées et à leur attribuer un mot de passe à chacune, seul ce groupe pourra accéder à la section réservée.
Pour créer ces fichiers il suffit, en tant que root, d'une part de créer le répertoire /usr/local/apache2/auth, puis de taper:

htpasswd -c /usr/local/apache2/auth/olivier.users olivier

Pour info cet exécutable se trouve dans le répertoire d'installation d'apache précisement sous httpd-2.4.54/support. L'option -c correspond à la création du fichier olivier.users. On va alors avoir à rentrer un mot de passe pour l'utilisateur olivier.

New password:

On confirme

Re-type new password:
Adding password for user olivier

Pour créer un autre utilisateur veronique vous taperez la même commande sans l'option de création :

htpasswd  /etc/httpd/auth/olivier.users veronique

Toujours en tant que root, créer le fichier /usr/local/apache2/auth/olivier.group qui contiendra la liste des personnes autorisées à accéder aux pages réservées :

autorise: olivier veronique

Maintenant quand à partir de votre navigateur préféré quand vous allez rentrer comme URL http://obelix/~olivier/reserve, vous aurez une fenêtre popup qui va s'ouvrir vous demandant de rentrer votre nom d'utilisateur et le mot de passe préalablement rentré.

Notez que pour que quelqu'un ne puisse jeter un coup d'oeil dans les fichiers .htaccess de vos utilisateurs, le fichier httpd.conf doit contenir la directive suivante:

<Files ~ "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
</Files>

Les hôtes virtuels

On peut mettre en place des hôtes virtuels, en d'autres termes un utilisateur pour un même serveur Apache croira en voir plusieurs. Exemple, soit votre serveur Apache obelix (adresse IP 192.168.13.11), votre domaine breizland.bz, on va créer les hôtes virtuels www.asterix.breizland.bz et www.idefix.breizland.bz qui vont pointer chacun vers un endroit différent du disque (respectivement /usr/local/asterix et /usr/local/idefix chacun contenant des pages html).

On va rajouter tout à la fin du fichier:

<VirtualHost 192.168.13.11>
ServerName obelix.breizland.bz
DocumentRoot /usr/local/apache2/htdocs
ErrorLog logs/obelix-error_log
TransferLog logs/obelix-access_log
</VirtualHost>

<VirtualHost 192.168.13.11>
ServerName www.asterix.breizland.bz
DocumentRoot /usr/local/asterix
ErrorLog logs/asterix-error_log
TransferLog logs/asterix-access_log
</VirtualHost>

<VirtualHost 192.168.13.11>
ServerName www.idefix.breizland.bz
DocumentRoot /usr/local/idefix
ErrorLog logs/idefix-error_log
TransferLog logs/idefix-access_log
</VirtualHost>

pour chacun des répertoires je dois créer ensuite les instructions suivantes

<Directory "/usr/local/asterix">
   Options Indexes FollowSymLinks Includes ExecCGI
   AllowOverride All
   Require all granted
</Directory>

Relancez Apache en tapant:

systemctl restart httpd

Maintenant nous allons créer nos hôtes asterix et idefix, pour cela vous avez deux méthodes:
- rajouter www.asterix.breizland.bz et www.idefix.breizland.bz dans /etc/hosts sur la même ligne que votre serveur Apache (obelix dans notre exemple).

192.168.13.11 obelix obelix.breizland.bz  www.asterix.breizland.bz  www.idefix.breizland.bz

Normalement si vous faites un ping sur www.idefix.breizland.bz ça devrait marcher, pour les postes clients il faudra rajouter la même ligne dans le fichier hosts (non nécessaire).

- si vous disposez d'un serveur DNS sur votre machine, au niveau de votre config DNS dans votre fichier breizland.bz  qui se trouve sous /var/named vous devez rajouter tout à la fin:

www.asterix    A    192.168.13.11
www.idefix    A    192.168.13.11

Relancez le DNS en tapant:

systemctl restart dns

Pour tester tapez dans un shell:

ping www.asterix.breizland.bz

Maintenant dans le champ URL de votre navigateur préféré:

http://www.asterix.breizland.bz

Et là, normalement vous devriez voir s'afficher la page que vous avez placé sous /usr/local/asterix

Dans l'hypothèse où vous utilisez deux serveurs Apache (versions 1.3 et 2 par exemple), vous pouvez spécifier le port 80 pour Apache 1.3 et le port 8080 pour Apache 2 en fixant dans le fichier de configuration Listen à 8080. Au niveau de la déclaration des hôtes virtuels il faudra mettre quelque chose comme ça

<VirtualHost 192.168.13.11:8080>
ServerName tosh.kervao.fr
DocumentRoot /usr/local/apache2/htdocs
ErrorLog logs/tosh-error_log
TransferLog logs/tosh-access_log
</VirtualHost>

[retour haut de la page]


Chiffrer les connexions avec SSL

Si votre site est accessible par internet je vous conseille de créer un certificat qui sera valable sur internet avec let's encrypt. Dans le cas présent on va créer un certificat perso auto signé qui ne marchera que pour mon réseau privé comme j'ai pu le faire pour sendmail et dovecot. On veillera à ce que les répertoires /etc/ssl/apache et /etc/ssl/public soient préalablement créés.

openssl req -new -x509 -nodes -out /etc/ssl/public/apache.crt -keyout /etc/ssl/apache/apache.key

voilà le résultat

Generating a 2048 bit RSA private key
...+++
...................+++
writing new private key to '/etc/ssl/apache/apache.key'
-----
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:Bretagne
Locality Name (eg, city) []:Brest
Organization Name (eg, company) [Internet Widgits Pty Ltd]:None
Organizational Unit Name (eg, section) []:None
Common Name (e.g. server FQDN or YOUR name) []:www.asterix.breizland.bz

Email Address []:olivier.hoarau@funix.org

On va modifier maintenant le fichier de configuration d'apache /usr/local/apache2/conf/httpd.conf en activant les modules suivants

LoadModule ssl_modulemodules/mod_ssl.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so

j'ai décommenté également l'inclusion

# Secure (SSL/TLS) connections
Include conf/extra/httpd-ssl.conf
#
# Note: The following must must be present to support
# starting without SSL on platforms with no /dev/random equivalent
# but a statically compiled-in mod_ssl.
#
SSLRandomSeed startup builtin SSLRandomSeed connect builtin

plus loin dans le fichier au niveau de la déclaration d'un hôte virtuel on écrira

<VirtualHost 192.168.0.13:443>
ServerName funix.kervao.fr
DocumentRoot /data/homepage/www.funix.org
ErrorLog logs/funix-error_log
TransferLog logs/funix-access_log

SSLEngine on
# on pointe vers le certificat et la clé privée
SSLCertificateFile /etc/ssl/public/apache.crt
SSLCertificateKeyFile /etc/ssl/apache/apache.key
</VirtualHost>

si vous voulez rediriger l'ensemble du flux 80 vers le port 443 de votre hôte, il faudra rajouter la directive suivante

<VirtualHost 192.168.0.13:80>
ServerName funix.kervao.fr
# on redirige les connexions sur le port classique 80 vers le port 443 utilisé par SSL
Redirect / https://funix.kervao.fr/
</VirtualHost>

tout en pensant à ce que la redirection vers le port 443 soit bien en place

<VirtualHost 192.168.0.13:443>
ServerName funix.kervao.fr
DocumentRoot /data/homepage/www.funix.org
ErrorLog logs/funix-error_log
TransferLog logs/funix-access_log

SSLEngine on
# on pointe vers le certificat et la clé privée
SSLCertificateFile /etc/ssl/public/apache.crt
SSLCertificateKeyFile /etc/ssl/apache/apache.key
</VirtualHost>

Dans le fichier /usr/local/apache2/conf/extra/httpd-ssl.conf on y trouve

#
# When we also provide SSL we have to listen to the
# standard HTTP port (see above) and to the HTTPS port
Listen 443

# SSL Cipher Suite:
# List the ciphers that the client is permitted to negotiate,
# and that httpd will negotiate as the client of a proxied server.
# See the OpenSSL documentation for a complete list of ciphers, and
# ensure these follow appropriate best practices for this deployment.
# httpd 2.2.30, 2.4.13 and later force-disable aNULL, eNULL and EXP ciphers,
# while OpenSSL disabled these by default in 0.9.8zf/1.0.0r/1.0.1m/1.0.2a.
SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4

# User agents such as web browsers are not configured for the user's
# own preference of either security or performance, therefore this
# must be the prerogative of the web server administrator who manages
# cpu load versus confidentiality, so enforce the server's cipher order.
 SSLHonorCipherOrder on

# SSL Protocol support:
# List the protocol versions which clients are allowed to connect with.
# Disable SSLv3 by default (cf. RFC 7525 3.1.1). TLSv1 (1.0) should be
# disabled as quickly as practical. By the end of 2016, only the TLSv1.2
# protocol or later should remain in use.
SSLProtocol all -SSLv3
SSLProxyProtocol all -SSLv3

# Pass Phrase Dialog:
# Configure the pass phrase gathering process.
# The filtering dialog program (`builtin' is an internal
# terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog builtin

# Inter-Process Session Cache:
# Configure the SSL Session Cache: First the mechanism
# to use and second the expiring timeout (in seconds).
#SSLSessionCache "dbm:/usr/local/apache2/logs/ssl_scache"
SSLSessionCache "shmcb:/usr/local/apache2/logs/ssl_scache(512000)"
SSLSessionCacheTimeout 300

tout le reste est en commentaire, on relance apache
 
systemctl stop httpd.service
systemctl start httpd.service

on pense à ouvrir le port 443 sur le firewall et on se connecte normalement sur le site. La première fois avec un certificat perso auto signé non reconnu par une autorité de certification il faudra accepter l'exception de sécurité, en cliquant sur Accepter le risque et poursuivre


On surfe maintenant de manière sécurisée sur le site.

Pour aller plus loin sur le sujet, voir la doc très complète d'Apache à ce sujet.

Scripts CGI

Les scripts CGI ne sont généralement pas activés par défaut, dans le fichier httpd.conf il faudra sans doute décommenter les lignes

LoadModule cgid_module modules/mod_cgid.so

AddHandler cgi-script .cgi .pl


j'ai rajouté l'extension .pl pour les scripts écrits en perl.

on y trouve notamment la ligne qui indique où trouver les scripts:

ScriptAlias /cgi-bin/    /usr/local/apache2/cgi-bin/

Pour que les scripts CGI soient exécutés dans les répertoires accessibles via HTTP, il faudra rajouter l'option ExecCGI comme ceci

<Directory "/monrepertoire">
   Options Indexes FollowSymLinks Includes ExecCGI
   AllowOverride All
   Require all granted
</Directory>

on relance bien sûr apache en cas de modification du fichier httpd.conf

Le but de l'exercice est de créer un script perl CGI qui va traiter un formulaire quelconque d'une page HTML. Vous allez créer votre script perl sous /usr/local/apache2/cgi-bin, et le nommer form.pl, voici son contenu:

#!/usr/bin/perl
use CGI;
$html=new CGI;
print $html->header;

print "<HTML>\n";
print "<HEAD>\n";
print "<TITLE>Premier script CGI perl</TITLE>\n";
print "</HEAD>\n";
print "<BODY>\n";
print "<H1>Traitement du formulaire</H1>\n";

print "Nom :";
print $html->param('nom');
print "<p>\n";
print "Email :";
print $html->param('email');
print "<p>\n";
print "Commentaire:";
print $html->param('comment');

print "</BODY>\n";
print "</HTML>\n";

Donner les droits qui vont bien avec ce fichier:

chmod 755 form.pl

En tant qu'utilisateur standard (olivier  dans notre exemple), créer maintenant le fichier HTML suivant que vous appellerez formulaire.htm

<html>
<body>
<h2>Formulaire</h2>
<form action="http://obelix/cgi-bin/form.pl" METHOD=GET>
Nom: <input type="text" name=nom size=20><br>
Email: <input type="text" name=email size=30><br>
Commentaire: <input type="text" name=comment size=100><br>
<input type=submit value="Envoyer"> <input type=reset value="remettre à zéro">
</form>
</body>
</html>

Voilà maintenant quand vous allez accéder à http://obelix/~olivier/formulaire.htm , vous allez avoir une page du style:

Nom: 
Email: 
Commentaire: 

En appuyant sur Envoyer ça va déclencher l'exécution du script CGI perl, qui va provoquer l'affichage des valeurs précédemment saisies.

PHP  et LDAP

On peut compiler PHP pour pouvoir utiliser des commandes gérant une base LDAP, pour cela à la compil de PHP on rajoutera aux options de configure l'option :

--with-ldap=/var/lib/ldap

/var/lib/ldap devant être remplacé par le chemin où se trouve votre base LDAP. Recompilez puis réinstallez le module qui va bien :

make

Et en tant que root

make install

Relancez Apache

systemctl restart httpd

Voilà un petit programme qui va nous permettre de rajouter une entrée dans la base, libre à vous maintenant de créer des formulaires de saisie, de destruction, et de recherche:

Appelez ce fichier ldap.php, vous pouvez le tester et vérifier que l'entrée a bien été saisie dans la base.


[retour haut de la page]

Gestion de bases de données avec MariaDB

Tests de fonctionnement avec MariaDB

On suppose que vous avez installé, configuré MariaDB et créé les deux exemples de la page MariaDB. On suppose aussi que le serveur s'appelle obelix et l'utilisateur olivier. Voici une page écrite en PHP qui va accéder à la base de donnée essai et à sa table coord.

<?php
$serveur="localhost";
$login="olivier";
$pass="mot-de-passe";
$base="essai";
$table="coord";

$id=MYSQL_CONNECT($serveur,$login,$pass);
mysql_select_db($base);
$nom="hoarau";
$prenom="olivier";
$email="olivier.hoarau@fnac.net";
$query="INSERT INTO $table VALUES('$nom','$prenom','$email')";
$result=mysql_query($query,$id);
echo "Saisie terminée";
?>

Placer ce script dans ~/public_html et appeler le bd1.php

Dans votre navigateur préféré, dans le champ URL saisissez :

http://obelix/~olivier/bd1.php

A priori y a pas grand chose qui s'est passé, maintenant connecter vous à votre base essai dans un shell

mariadb -u olivier -p essai
Enter password:

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 91
Server version: 11.4.2-MariaDB Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.


Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(essai)]> SELECT * FROM coord;
+-----+-------+--------------------+
| nom     | prenom  | email                              |
+-----+-------+--------------------+
| hoarau | olivier    | olivier.hoarau@fnac.net |
+-----+-------+--------------------+
1 row in set (0.00 sec)

C'est bon ça fonctionne. Passons à un exemple plus pointu, on va entrer les informations concernant vos visiteurs dans une base MySQL , créer la table telle que décrite dans l'exemple 2 de la page MariaDB, créer maintenant le script PHP.

<?php

$page=getenv("HTTP_REFERER");
$ip=getenv( "REMOTE_ADDR");
$host=gethostbyaddr($ip);
$d = date("d/m/Y H:i:s");
$expl=getenv("HTTP_USER_AGENT");

$serveur="localhost";
$login="olivier";
$pass="mot-de-passe";
$base="essai";
$table="ref";

$id=MYSQL_CONNECT($serveur,$login,$pass);
mysql_select_db($base);

$query="INSERT INTO $table VALUES('$d','$host','$ip','$expl','$page')";
$result=mysql_query($query,$id);

echo "$d $host($ip) $expl $page";

?>

Nommez ce script bd2.php et placez le dans ~/public_html . Dans votre navigateur préféré tapez dans le champ URL

http://obelix/~olivier/bd2.php

Vous devriez voir la date, le nom de votre machine avec son adresse IP et des infos sur votre OS et votre navigateur. A présent connectons nous à la base:

mariadb -u olivier -p essai
Enter password:

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 91
Server version: 11.4.2-MariaDB Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(essai)]> SELECT * FROM ref;
+---------------+---------------+----------+-----------------+-----+
| date                         | host                       | ip                  | os                              | page   |
+---------------+---------------+----------+-----------------+-----+
| 24/04/2000 08:34:05 | asterix.armoric.bz | 192.168.13.11 | Mozilla/4.61 [en] (X  |            |
+---------------+---------------+----------+-----------------+-----+
1 row in set (0.00 sec)

C'est bon le visiteur a bien été pris en compte.

Maintenant que vous savez comment Apache fonctionne avec MariaDB et PHP, laissez libre cours à votre imagination.

Administration des bases MySQL avec phpMyAdmin

phpMyAdmin est un ensemble de scripts PHP qui permet d'administrer des bases MySQL à partir d'un navigateur. Vous pouvez le récupérer à l'URL  www.phpmyadmin.net. En détail phpMyAdmin permet de:
- créer et supprimer des bases de données,
- éditer, ajouter ou supprimer des champs,
- taper des commandes SQL,
- gérer les clés de champs,
- ...

L'archive se présente sous la forme d'un zip  qu'on décompresse en tapant :

unzip phpMyAdmin-5.2.1-all-languages.zip

Cela va créer dans le répertoire de travail un répertoire phpMyAdmin-5.2.1-all-languages. Dans ce répertoire vous avez un fichier config.inc.sample.php, il faut le copier en config.inc.php,  dans ce fichier il faut modifier les champs suivants :

Pour cette variable on peut mettre un peu n'importe quoi pourvu que ça fasse 32 octets !  En mettant une ligne de 32 caractères ça semble passer, ça sert ensuite pour chiffrer de manière aléatoire.

$cfg['blowfish_secret'] = 'je suis toto et il faut que la phrase soit suffisamment longue'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */

j'ai défini également cette variable

$cfg['DefaultLang'] = 'fr';

pour le reste j'ai laissé les valeurs par défaut à savoir

Maintenant on doit rendre accessible le répertoire phpMyAdmin d'une page web, pour cela deux solutions:
- (solution simple) placer phpMyAdmin dans /usr/local/apache/htdocs et au niveau de la page d'accueil d'apache faire un lien vers /usr/local/apache/htdocs/phpMyAdmin-5.2-all-languages/index.php
- (solution préconisée), créer un hôte virtuel pointant vers ./phpMyAdmin-5.2.1-all-languages qu'on appelera www.sql.breizland.bz .

Si vous avez l'erreur

mysqli_real_connect(): (HY000/2002): No such file or directory

dans le fichier de configuration il faudra remplacer localhost par 127.0.01 comme ceci

$cfg['Servers'][$i]['host'] = '127.0.0.1';

si vous avez maintenant l'erreur

$cfg['TempDir'] (./tmp/) n'est pas accessible. phpMyAdmin est incapable de mettre en cache les modèles et de ce fait sera lent.

dans le fichier config.inc.php il faudra définir la variable

$cfg['TempDir'] = '/tmp';

Pour cette erreur

Créer une base de données nommée « phpmyadmin » et la configuration du stockage de phpMyAdmin dans cette base.

dans le fichier de configuration config.inc.php on décommentera les lignes suivantes

/* Storage database and tables */
$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
$cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark';
$cfg['Servers'][$i]['relation'] = 'pma__relation';
$cfg['Servers'][$i]['table_info'] = 'pma__table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma__table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma__column_info';
$cfg['Servers'][$i]['history'] = 'pma__history';
$cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs';
$cfg['Servers'][$i]['tracking'] = 'pma__tracking';
$cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
$cfg['Servers'][$i]['recent'] = 'pma__recent';
$cfg['Servers'][$i]['favorite'] = 'pma__favorite';
$cfg['Servers'][$i]['users'] = 'pma__users';
$cfg['Servers'][$i]['usergroups'] = 'pma__usergroups';
$cfg['Servers'][$i]['navigationhiding'] = 'pma__navigationhiding';
$cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
$cfg['Servers'][$i]['central_columns'] = 'pma__central_columns';
$cfg['Servers'][$i]['designer_settings'] = 'pma__designer_settings';
$cfg['Servers'][$i]['export_templates'] = 'pma__export_templates';

Dans la console SQL en bas de l'écran on créera la base phpmyadmin

CREATE DATABASE IF NOT EXISTS `phpmyadmin`
  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;
USE phpmyadmin;

CTRL+enter pour exécuter

On sélectionne la base phpmyadmin à gauche et toujours dans la console on créera les tables en important le fichier phpMyAdmin-5.2.1-all-languages/sql/create_tables.sql

NOTE Si ça vous gène que n'importe qui d'un navigateur puisse aller dans le répertoire phpMyAdmin, mettez y des restrictions d'accès avec un fichier .htaccess.

Avec la solution hôte virtuel, à partir d'un navigateur quand on sélectionne  www.sql.breizland.bz on tombe d'abord sur une bannière de login, ensuite sur une fenêtre avec frame avec à gauche la liste des bases de données disponibles et à droite, le menu suivant:


Pour travailler sur une base de données particulières il suffit de la sélectionner dans le choix déroulant à gauche, on retrouve d'ailleurs notre base essai, pour en créer une autre il suffit de choisir Bases de données puis Créer une base de données.

Si on sélectionne essai par exemple on obtient


Vous pouvez donc créer des nouvelles tables, faire des requêtes SQL, etc.

A noter que si vous avez une erreur de chargement de phpMyAdmin du style

Error during session start; please check your PHP and/or webserver log file and configure your PHP installation properly. Also ensure that cookies are enabled in your browser.

session_start(): open(SESSION_FILE, O_RDWR) failed: No such file or directory (2)

session_start(): Failed to read session data: files (path: )

il faudra éditer le fichier /usr/local/apache2/conf/php.ini et modifier la ligne suivante

session.save_path = "/tmp"

vous mettez le répertoire temporaire que vous voulez.

[retour haut de la page]

Connexion sécurisée entre le serveur MariaDB et phpMyAdmin

Maintenant pour une connexion sécurisée on rajoutera dans le fichier config.inc.php

$cfg['Servers'][$i]['ssl'] = true;
$cfg['Servers'][$i]['ssl_key'] ='/etc/mysql/ssl/client-key.pem';
$cfg['Servers'][$i]['ssl_cert'] = '/etc/mysql/ssl/client-cert.pem';
$cfg['Servers'][$i]['ssl_ca'] = '/etc/mysql/ssl/ca-cert.pem';
$cfg['Servers'][$i]['ssl_ca_path'] = '/etc/mysql/ssl/';
$cfg['Servers'][$i]['ssl_verify'] = 'true';
$cfg['Servers'][$i]['ssl_ciphers'] = 'ECDHE-RSA-AES256-GCM-SHA384';

il faudra sans doute rajouter également le nom du serveur tel que défini plus haut

$cfg['Servers'][$i]['host'] = '127.0.0.1';

$cfg['Servers'][$i]['host'] = 'mariadb-serveur';

ça évitera ce genre d'erreur

mysqli::real_connect(): Peer certificate CN=`mariadb-serveur' did not match expected CN=`127.0.0.1'

et voilà quand on va se connecter, voilà ce que ça va donner dans les propriétés de MariaDB

Il faudra éviter également un autre piège avec les connexions sécurisées si votre utilisateur est déclaré comme étant user@localhost dans la base mysql, vous n'arriverez pas à vous connecter avec user@mariadb-serveur, il faudra créer un nouvel utilisateur user@mariadb-serveur.

 
[Retour page d'accueil FUNIX] [retour haut de la page ]