====== 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]]