====== Repositories ======
==== DotDeb pour PHP7 ====
''DotDeb était utile sous Debian Jessie, pour avoir accès à PHP7. PHP7 étant de base dans les repos de Debian Stretch, plus aucun utilité d'utiliser DotDeb. Pour l'instant, donc je laisse tout de même le paragraphe.''
wget https://www.dotdeb.org/dotdeb.gpg -O- | apt-key add -
nano /etc/apt/sources.list.d/dotdeb.list
Pour la totalité des packages disponibles chez dotdeb :
deb http://packages.dotdeb.org jessie all
deb-src http://packages.dotdeb.org jessie all
==== MariaDB officiel pour version 10.2 ====
Via : [[https://mariadb.com/kb/en/mariadb/installing-mariadb-deb-files/]]\\
''MariaDB 10.1 est intégré aux repos Debian Stretch par défaut, plus besoin de passer par les repos officielles MariaDB. par contre, si l'on souhaite utiliser la version 10.2 en avance, on peut y revenir :''
apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db
nano /etc/apt/sources.list.d/mariabd.list
Avec l'utilisation du miroir CNRS :
deb [arch=i386,amd64] http://ftp.igh.cnrs.fr/pub/mariadb/repo/10.2/debian stretch main
deb-src http://ftp.igh.cnrs.fr/pub/mariadb/repo/10.2/debian stretch main
On met à jour les sources, et on installe :
apt-get update
apt-get install mariadb-server
**mysql_secure_installation** fonctionne aussi avec MariaDB.
====== Installation : Apache ======
apt-get install apache2
====== Installation : MariaDB ======
apt-get install mariadb-client-10.1 mariadb-server-10.1 mariadb-common
Sachant que les aliases suivant marchent encore, mais installent bien ''MariaDB'', pas ''MySQL'' :
apt-get install mysql-server mysql-client
On sécurise la base directement :
mysql_secure_installation
====== Installation : PHP7 ======
Tout plein de packages avec :
apt-get install memcached libapache2-mod-php7.0 php7.0 php7.0-apcu php7.0-bz2 php7.0-cli php7.0-common php7.0-curl php7.0-gd php7.0-geoip php7.0-imagick php7.0-imap php7.0-intl php7.0-json php7.0-mbstring php7.0-mcrypt php7.0-memcached php7.0-mysql php7.0-opcache php7.0-pgsql php7.0-pspell php7.0-readline php7.0-recode php7.0-redis php7.0-snmp php7.0-sqlite3 php7.0-ssh2 php7.0-tidy php7.0-xml php7.0-xmlrpc php7.0-xsl php7.0-zip
===== Tweaks =====
Dans le fichier de configuration ''php.ini'' qui va bien :
* ''expose_php=Off'' pour masquer la version de PHP dans les headers.
===== Installer PHP 7.1 et 7.2 =====
Pour ''Debian Stretch'', on passera par :
* Pour ''PHP 7.1'', https://www.noobunbox.net/serveur/auto-hebergement/installer-php-7-1-sous-debian-et-ubuntu ou https://www.chris-shaw.com/blog/how-to-install-php-7.1-on-debian-8
* Pour ''PHP 7.2'', https://www.chris-shaw.com/blog/installing-php-7.2-on-debian-8-jessie-and-debian-9-stretch
Pour ''Alpine Linux 3.7'' (fourni de base avec ''PHP 7.1'' déjà), l'on a aussi le choix pour passer à ''PHP 7.2'' :
* Passer par les dépôts Edge,
* Utiliser les dépôts proposés ici : https://github.com/codecasts/php-alpine
====== Apache : Customisation======
On ajoute une ligne au fichier de configuration d'Apache :
nano /etc/apache2/apache2.conf
Include custom.conf
On édite ensuite notre fichier de configuration ''custom.conf'' :
nano /etc/apache2/custom.conf
ServerTokens Prod
ServerSignature Off
HostnameLookups Off
TraceEnable Off #Si pas déjà mis en place dans /etc/apache2/conf-enabled/security.conf
====== Apache : Modules ======
Lister les modules actifs :
apachectl -M
Activer un module : ''a2enmod ''\\
Désactiver un module : ''a2dismod ''
a2enmod cache expires headers rewrite setenvif ssl proxy_fcgi
==== mod_limitipconn : limiter les connexions avec ====
On se rend sur [[http://dominia.org/djao/limitipconn2.html]] et on télécharge la dernière version :
wget http://dominia.org/djao/limit/mod_limitipconn-0.24.tar.bz2
On installe les prérequis pour la build :
apt-get install build-essential apache2-dev
On extrait le package téléchargé, on se rend dans le bon dossier :
tar xavf mod_limitipconn-0.24.tar.bz2
cd mod_limitipconn-0.24
On édite le ''Makefile'' pour changer la ligne ''APXS=apxs'' en ''APXS=apxs2'' :
sed -i 's/APXS=apxs/APXS=apxs2/' Makefile
Enfin on compile :
make install
Fichier de chargement du module :
nano /etc/apache2/mods-available/limitipconn.load
On vérifie qu'il contient bien comme première ligne ''ExtendedStatus On'' sinon on l'ajoute :
ExtendedStatus On
LoadModule limitipconn_module /usr/lib/apache2/modules/mod_limitipconn.so
Fichier de configuration du module (Doc du module : [[http://dominia.org/djao/limitipconn2-README]]) :
nano /etc/apache2/mods-available/limitipconn.conf
Exemple :
ExtendedStatus On
MaxConnPerIP 2
NoIPLimit images/*
OnlyIPLimit audio/mpeg video
ErrorDocument 503 "2 files limit, thanks."
et finalement on active le module (dépend du module ''status'', on active aussi donc) :
a2enmod limitipconn status
==== mod_proxy ====
''mod_proxy'' : [[http://httpd.apache.org/docs/trunk/fr/mod/mod_proxy.html|Documentation]]
==== mod_pagespeed ====
''mod_pagespeed'' : [[https://developers.google.com/speed/pagespeed/module/|Documentation]]\\
Installation :
wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_amd64.deb
dpkg -i mod-pagespeed-stable_current_amd64.deb
apt-get -f install
service apache2 restart
==== mod_status ====
''mod_status'', pour suivre la charge et les statistiques d'Apache.\\
Plus d'informations [[http://www.tecmint.com/monitor-apache-web-server-load-and-page-statistics/|ici]] sur l'installation et la documentation.
==== mod_expires ====
nano /etc/apache2/custom.conf
[...]
ExpiresActive On
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 month"
ExpiresDefault "access plus 2 days"
==== mod_headers ====
nano /etc/apache2/custom.conf
[...]
Header always set Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set Referrer-Policy "unsafe-url"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Download-Options noopen;
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Permitted-Cross-Domain-Policies none
Header always set X-Robots-Tag "index,follow,noarchive"
Header always set X-Xss-Protection "1; mode=block"
#Ajout cookies en secure
Header set Set-Cookie HttpOnly;Secure
#Si on veut supprimer la mention à Apache
Header unset X-Powered-By
====== Apache : mod event MPM et PHP-FPM ======
On installe les paquets dont on a besoin :
#apache2-mpm-event plus dispo
apt-get install php7.0-fpm
On nettoie Apache de ses modules inutiles :
a2dismod mpm_prefork php7.0
On désinstalle le module PHP :
apt-get purge libapache2-mod-php7.0
On active le mode ''event'' :
a2enmod mpm_event
Pour que PHP soit pris en compte, le module Apache ''proxy_fcgi'' doit être activé, si pas déjà activé plus haut :
a2enmod proxy_fcgi
On relance Apache :
service apache2 restart
On vérifie que le fichier de configuration PHP-FPM existe bien :
nano /etc/apache2/conf-available/php7.0-fpm.conf
# Redirect to local php-fpm if mod_php is not available
# Enable http authorization headers
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
SetHandler "proxy:unix:/run/php/php7.0-fpm.sock|fcgi://localhost"
# Deny access to raw php sources by default
# To re-enable it's recommended to enable access to the files
# only in specific virtual host or directory
Require all denied
# Deny access to files without filename (e.g. '.php')
Require all denied
Si tout ok, on la valide :
a2enconf php7.0-fpm
On relance Apache (encore) :
service apache2 restart
====== Apache : SSL ======
Voir : [[selfhosted:setup:4-lets-encrypt#apache|Let's Encrypt & Certbot]] pour les configurations des vhosts.\\
Pour la configuration globale, ajouter :
nano /etc/apache2/custom.conf
[...]
# Mozilla : OCSP Stapling, only in httpd 2.3.3 and later
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
''Include ssl.conf'' dans les vhost demandant SSL :
nano /etc/apache2/ssl.conf
# Adaptation de l'ancienne config auto fournie par Let's Encrypt
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLHonorCipherOrder on
SSLCompression off
SSLProxyEngine On
SSLVerifyClient none
SSLOptions +StrictRequire
#Header edit Set-Cookie (?i)^(.*)(;\s*secure)??((\s*;)?(.*)) "$1; Secure$3$4"
#SSLDHParametersFile "/etc/ssl/private/dhparams.pem"
Et la redirection ''http'' vers ''https'' dans les vhosts, ici à l'aide du mod ''rewrite'' :
RewriteEngine on
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,QSA,R=permanent]
Ou bien simplement avec une ''redirection 301'' permanente :
Redirect permanent / https://example.com/
====== Apache : HTTP2 ======
apt-get install openssl libssl-dev
Pour vérifier la disponibilité, la commande ''apachectl -v'' doit renvoyer une version supérieure à ''2.4.17''.\\
\\
On va enfin activer ''http2'' sur nos sites, via les ''VirtualHost'' :
Protocols h2 http/1.1
[...]
On active le mod :
a2enmod http2
Enfin, on relance apache :
service apache2 restart
Et on va tester son site sur [[https://tools.keycdn.com/http2-test]] par exemple.
====== Apache : Custom errors ======
Dans un fichier de vhost, définir l'autorisation au minimum à ''AllowOverride FileInfo'', ou ''AllowOverride All'' pour tout autoriser par les fichiers ''.htaccess''.\\
On édite ensuite le ''.htaccess'' voulu, et on lui ajoute une ligne :
ErrorDocument ErrorCode Action
Par exemple :
ErrorDocument 404 /errors/404.html
====== Apache : Reverse Proxy simple ======
A défaut d'utiliser Apache comme reverse proxy, on peut passer par :
* Nginx,
* [[https://traefik.io|Traefik]],
* [[https://caddyserver.co|Caddy]]
On active le mod, et on redémarra Apache :
a2enmod proxy_http
service apache2 restart
On édite le fichier du vhost qui va avoir le rôle de proxy :
nano /etc/apache2/sites-available/proxy
# Pour relayer du https self-signed
RequestHeader set X-Forwarded-Proto "https" early
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyPreserveHost On
ProxyRequests off
# Exemple pour un serveur Proxmox, sur port 8006
ProxyPass / https://37.65.17.232:8006/ Keepalive=On
ProxyPassReverse / https://37.65.17.232:8006/ Keepalive=On
ServerName my.domain.tld
[...]
Enfin, on active le site et on relance Apache :
a2ensite proxy
service apache2 reload
==== Bonus : petit load-balancing ====
Fichier vhost :
# Serveur 1
BalancerMember http://10.0.1.10:8080/
# Serveur 2
BalancerMember http://10.0.1.11:8080/
# Appel vers le cluster de serveurs créé plus haut
ProxyPass / balancer://mycluster
====== Apache : Custom index avec h5ai ======
Site officiel : [[https://larsjung.de/h5ai/]]\\
On se place dans le dossier racine du vhost voulu :
cd /var/www/my.domain.tld/
On télécharge la dernière version en date :
wget https://release.larsjung.de/h5ai/h5ai-0.29.0.zip
On décompresse le tout :
# installation de zip/unzip au besoin
apt-get install zip unzip
unzip h5ai-0.29.0.zip
# et on supprime l'archive devenue inutile :
rm h5ai-0.29.0.zip
On met en place la possession des fichiers si installé avec un autre utilisateur que celui qui gère Apache :
chown -R www-data:www-data /var/www/my.domain.tld/_h5ai/
On teste dans un navigateur que tout est ok avec l'url ''my.domain.tld/_h5ai/public/index.php'', on change le password par défaut comme indiqué.\\
Pour définir h5ai comme index par défaut, on ajoute la ligne suivante au fichier ''/etc/apache2/custom.conf'' :
DirectoryIndex index.html index.php /_h5ai/public/index.php
Doit écraser l'attribut ''DirectoryIndex'' déjà déclaré, soit dans ''apache2.conf'' ou bien ''/etc/apache2/mods-available/dir.conf''
====== Fichiers de configuration ======
Configuration PHP ''php.ini'' :
nano /etc/php/7.0/fpm/php.ini
[...]
PHP-FPM pool config :
nano /etc/php/7.0/fpm/pool.d/www.conf
[...]
MariaDB :
Voir : [[linux:db:mysql-mariadb#les_options_qui_vont_bien|Les options MySQL/MariaDB]]
nano /etc/mysql/my.cnf
[mysqld]
# Prérequis Nextcloud, si besoin
binlog-format=mixed
[...]
max_allowed_packet = 64M
[...]
table_open_cache = 2000
table_definition_cache = 2000
Fichier ''custom.conf'' final pour Apache :
ServerTokens Prod
ServerSignature Off
HostnameLookups Off
TraceEnable Off
ServerName my.domain.tld
Header always set Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set Referrer-Policy "unsafe-url"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Download-Options noopen;
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Permitted-Cross-Domain-Policies none
Header always set X-Robots-Tag "index,follow,noarchive"
Header always set X-Xss-Protection "1; mode=block"
#Ajout cookies en secure
Header set Set-Cookie HttpOnly;Secure
#Si on veut supprimer la mention à Apache
Header unset X-Powered-By
# Mozilla : OCSP Stapling, only in httpd 2.3.3 and later
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
====== Connaître le fichier de configuration utilisé par PHP ======
Avec PHP :
php -i | grep "Loaded Configuration File"
Avec PHP-FPM(7) :
php-fpm(7) -i | grep "Loaded Configuration File"
====== Documentation supplémentaire ======
* https://www.maketecheasier.com/securing-apache-ubuntu/
* https://github.com/gregrickaby/The-Perfect-Apache-Configuration/blob/master/http.conf
* https://wiki.evolix.org/HowtoPHP
====== Aller plus loin avec Apache et Nginx ======
* Apache : [[system/linux/debian/5.1-apache]]
* Nginx : [[system/linux/debian/5.2-nginx]]