evoformations/reveal/httpd.html

629 lines
17 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Formation Evolix : Services HTTP</title>
<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
<meta name="author" content="Hakim El Hattab">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="reveal.js/css/reveal.css">
<link rel="stylesheet" href="reveal.js/css/theme/beige.css" id="theme">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="reveal.js/lib/css/zenburn.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'reveal.js/css/print/pdf.css' : 'reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<!--[if lt IE 9]>
<script src="reveal.js/lib/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<section>
<h1>Formation Evolix</h1>
<h3>Services HTTP</h3>
</section>
<section>
<section>
<h2>Apache</h2>
Serveur HTTP le plus utilisé, depuis 1996
</section>
<section>
<h3>Installation</h3>
<pre><code data-trim class="hljs nohighlight">
# apt install apache2-mpm-itk \
libapache2-mod-evasive apachetop libwww-perl
</code></pre>
</section>
<section>
<h3>Fichiers de configuration</h3>
<pre>
/etc/apache2/
├── apache2.conf
├── conf-available
│ └── *.conf
├── conf-enabled
│ └── *.conf -> ../conf-available/*.conf
├── envvars
├── magic
├── mods-available
│ ├── *.conf
│ └── *.load
├── mods-enabled
│ ├── *.conf -> ../mods-available/*.conf
│ └── *.load -> ../mods-available/*.load
├── ports.conf
├── sites-available
│ └── *.conf
└── sites-enabled
└── *.conf -> ../sites-available/*.conf
</pre>
</section>
<section>
<h3>Des modules à la carte</h3>
<pre><code data-trim class="hljs nohighlight">
# a2enmod rewrite expires headers rewrite cgi
</code></pre>
</section>
<section>
<h3>Optimisations "Evolix"</h3>
<pre><code data-trim class="apache" style="max-height: 500px">
ServerTokens Prod
Timeout 10
KeepAliveTimeout 2
MaxKeepAliveRequests 10
ServerLimit 250
#MaxClients 250
MaxRequestWorkers 250
StartServers 50
MinSpareServers 20
MaxSpareServers 30
MaxRequestsPerChild 100
<Directory /home/>
AllowOverride None
Require all granted
</Directory>
<IfModule mod_ssl.c>
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4
</IfModule>
</code></pre>
</section>
<section>
<h4>Forcer le umask</h4>
<pre><code data-trim class="hljs nohighlight"># grep umask /etc/apache2/envvars</code>
umask 007
</pre>
</section>
<section>
<h3>VirtualHost</h3>
<ul>
<li>Permet de séparer de plusieurs sites sur un même serveur HTTP</li>
<li>Séparation par nom de domaine ou par adresses IP</li>
</ul>
</section>
<section>
<h4>VirtualHost basé sur un nom de domaine</h4>
<!-- Je n'ai pas trouvé le moyen d'avoir du code à balise qui soit proprement affiché tout en conservant le texte brut intacte. -->
<pre><code data-trim class="hljs nohighlight" style="max-height: 600px">
&lt;VirtualHost *:80&gt;
ServerName www.example.com
ServerAlias example.com
DocumentRoot /home/example/www/
&lt;Directory /home/example/www/&gt;
Options SymLinksIfOwnerMatch
AllowOverride AuthConfig Limit FileInfo Indexes
&lt;/Directory&gt;
AssignUserID www-example example
MaxClientsVHost 150
CustomLog /var/log/apache2/access.log vhost_combined
CustomLog /home/example/log/access.log combined
ErrorLog /home/example/log/error.log
RewriteEngine On
UseCanonicalName On
RewriteCond %{HTTP_HOST} !^www.example.com$
RewriteRule ^/(.*) http://%{SERVER_NAME}/$1 [L,R]
&lt;/VirtualHost&gt;
</code></pre>
</section>
<section>
<h4>Activation du site</h4>
<pre><code data-trim class="hljs nohighlight">
# adduser example
# adduser --ingroup example www-example
# mkdir /home/example/{www,log,awstats}
# chown example: /home/example/{www,log,awstats}
# a2ensite example
</code></pre>
</section>
<section>
<h3>Gestion des droits avec Apache-ITK</h3>
<ul>
<li>user/group distincts pour chaque VirtualHost</li>
<li>séparation stricte des droits</li>
<li>… y compris la lecture</li>
<li>… y compris avec PHP</li>
</ul>
<pre><code data-trim class="hljs nohighlight">
# chmod 750 /home/example
</code></pre>
</section>
<section>
<h3>Restriction en écriture pour Apache</h3>
<ul>
<li>Lecture seule pour Apache, sauf certains répertoires (uploads/, cache/)</li>
<li>utilisateur dédié pour l'écriture par Apache : www-example</li>
<li>… et pour FTP/SSH/SFTP/SCP/RSYNC : example</li>
<li>groupe commun pour tous et droits accordés au groupe</li>
<li>pas besoin de chmod, Apache a son umask à 007</li>
</ul>
<pre><code data-trim class="hljs nohighlight">
# echo "umask 027" >> /etc/profile
# find /home/example -type f -user www-example -exec chmod 660 {} \;
# find /home/example -type d -user www-example -exec chmod 770 {} \;
</code></pre>
</section>
<section>
<h4>Attention !</h4>
<p><strong>Ne jamais forcer les droits<br>récursivement sur toute larborescence.</strong></p>
<p>Si la restriction en écriture pour Apache est impossible :</p>
<ul>
<li>plus dutilisateur distinct</li>
<li>"AssignUserID example example" élimine 100% des soucis de droits</li>
<li>… mais réduction de la sécurité</li>
</ul>
</section>
<section>
<h2>HTTPS TLS/SSL</h2>
</section>
<section>
<h3>Activation du module SSL pour Apache</h3>
<pre><code data-trim class="hljs nohighlight">
# a2enmod ssl
</code></pre>
</section>
<section>
<h3>Création d'un certificat</h3>
<pre><code data-trim class="hljs nohighlight">
# openssl req -newkey rsa:2048 -sha256 -nodes \
-keyout private.key -out demande.csr
# openssl x509 -req -days 3650 -sha256 -in demande.csr \
-signkey private.key -out certificate.crt
# mv private.key /etc/ssl/private/
# chown root:ssl-cert /etc/ssl/private/private.key
# chmod 640 /etc/ssl/private/private.key
# mv certificate.crt /etc/ssl/certs
# chown root:root /etc/ssl/certs/certificate.crt
# chmod 644 /etc/ssl/certs/certificate.crt
</code></pre>
</section>
<section>
<h3>Modification du VirtualHost</h3>
<pre><code data-trim class="apache">
&lt;VirtualHost *:80 *:443&gt;
ServerName secure.example.com
ServerAlias www.example.com example.com
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCertificateKeyFile /etc/ssl/private/private.key
SSLCertificateFile /etc/ssl/certs/certificate.crt
# SSLCertificateChainFile /etc/ssl/certs/certificates_chain.pem
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [L,R=permanent]
&lt;/VirtualHost&gt;
</code></pre>
</section>
<section>
<h3>logs</h3>
Apache propose plusieurs formats de logs
<pre><code data-trim class="hljs nohighlight">
CustomLog log/global_access.log vhost_combined
CustomLog log/access.log combined
SetEnvIf User-Agent "Foo" dontlog
CustomLog log/access.log combined env=!dontlog
ErrorLog log/error.log
</code></pre>
</section>
<section>
<h3>Authentification "HTTP Basic"</h3>
Le module mod_auth_basic est disponible par défaut.
<pre><code data-trim class="apache">
AuthType Basic
AuthName "Restricted"
AuthUserFile /foo/.htpasswd
AuthGroupFile /dev/null
require valid-user
</code></pre>
</section>
<section>
<h3>Règles de ré-écriture</h3>
<pre><code data-trim class="apache" style="max-height: 500px">
RedirectPermanent / http://new.example.com
RedirectMatch ^/(.*)$ http://new.example.com/$1
# GET / --> /sub/
RedirectMatch ^/$ /sub/
RewriteRule ^/(.*) http://new.example.com/$1 [L,R=permanent]
RewriteCond %{REQUEST_URI} !^/foo.txt
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [L,R]
# le drapeau NC pour ne pas tenir compte de la casse
RewriteRule ^/FoO.tXt /sub/ [L,R,NC]
# empêcher des requêtes POST sur une URL particulière
RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^/foo.txt [L,F]
</code></pre>
</section>
<section>
<h3>mod_evasive</h3>
<p>Limite les accès, notamment les dénis de service </p>
<pre><code data-trim class="apache">
&lt;IfModule mod_evasive20.c&gt;
DOSHashTableSize 3097
DOSPageCount 5
DOSSiteCount 30
DOSPageInterval 3
DOSSiteInterval 1
DOSBlockingPeriod 60
DOSEmailNotify security@example.com
&lt;/IfModule&gt;
</code></pre>
</section>
<section>
<h3>Fail2ban</h3>
<ul>
<li>recherche de comportements anormaux dans les logs</li>
<li>blocage temporaire ou permanent, via firewall</li>
</ul>
</section>
<section>
<h3>Apachetop</h3>
Affiche en direct des stats sur le traffic, d'après les logs.
<pre><code data-trim class="hljs nohighlight">
$ apachetop -f access.log -T 3600 -q
</code></pre>
</section>
<section>
<h3>mod_status</h3>
Génère une page web résumant l'état d'Apache.
<pre><code data-trim class="apache">
&lt;IfModule mod_status.c&gt;
ExtendedStatus On
&lt;Location /server-status-XXXX&gt;
SetHandler server-status
Deny from all
Include ipaddr_whitelist.conf
Allow from 192.0.2.43
Allow from 127.0.0.1
&lt;/Location&gt;
&lt;/IfModule&gt;
</code></pre>
</section>
</section>
<section>
<section>
<h2>Nginx</h2>
<p>Serveur web, alternative à Apache</p>
</section>
<section>
<h3>Installation</h3>
<pre><code data-trim class="hljs nohighlight">
# aptitude install nginx
# nginx -v
</code>
nginx version: nginx/1.10.3
</pre>
</section>
<section>
https://wiki.evolix.org/HowtoNginx
</section>
</section>
<section>
<section>
<h2>HAProxy</h2>
<p>Proxy et load-balancer TCP/HTTP/HTTPS</p>
</section>
<section>
<h3>Installation</h3>
<pre><code data-trim class="hljs nohighlight">
# apt install haproxy
# varnishd -v
</code>
HA-Proxy version 1.7.5-2 2017/05/17
Copyright 2000-2017 Willy Tarreau &lt;willy@haproxy.org&gt;
</pre>
</section>
<section>
<h3>Configuration minimale</h3>
<pre><code data-trim class="hljs haproxy">
global
log 127.0.0.1 local5 debug
defaults
mode http
listen www
bind *:80
balance roundrobin
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www.example.com
stats uri /haproxy-stats
stats auth foo:bar
server www00 192.0.2.1:80 maxconn 50 check inter 10s
server www01 192.0.2.2:80 maxconn 50 check inter 10s
</code></pre>
</section>
<section>
<h3>Configuration avancée</h3>
<ul>
<li>gestion fine des performances</li>
<li>multiples IP/domaines écoutés</li>
<li>différents algorithmes de load-balancing</li>
</ul>
</section>
<section>
<h4>TLS/SSL</h4>
<ul>
<li>terminaison SSL ou transmission transparente</li>
<li>multi certificats et SNI</li>
<li>agrafage OCSP facilitée</li>
</ul>
</section>
<section>
<h4>mode TCP</h4>
<pre><code data-trim class="hljs haproxy">
listen memcached 127.0.0.1:11211
option tcp-check
server nosql00 192.0.2.3:11211 check
server nosql01 192.0.2.4:11211 check backup
</code></pre>
</section>
<section>
<h4>mode MySQL (simple)</h4>
<pre><code data-trim class="hljs haproxy">
listen mysql 127.0.0.1:3306
mode tcp
option mysql-check user haproxy_check
server sql00 192.0.2.1:3306 check
</code></pre>
</section>
<section>
<h4>mode MySQL (avancé)</h4>
Si le test de connexion à MySQL ne suffit pas,<br>on indique un programme pour un test personnalisé<br>qui indiquera à HAProxy si le backend va bien.
</section>
<section>
<h4>Dashboard</h4>
Une interface web permet de suivre l'état du proxy.
</section>
</section>
<section>
<section>
<h2>Varnish</h2>
<p>Accélérateur web : cache et reverse-proxy</p>
</section>
<section>
<h3>Installation</h3>
<pre><code data-trim class="hljs nohighlight">
# apt install varnish
# varnishd -V
</code>
varnishd (varnish-4.0.2 revision bfe7cd1)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2014 Varnish Software AS
</pre>
</section>
<section>
<h3>Configuration minimale</h3>
<p>Varnish relaie les requêtes vers le port 8080 local.</p>
<pre><code data-trim class="hljs varnish">
backend default {
.host = "127.0.0.1";
.port = "8080";
}
</code></pre>
</section>
<section>
<h3>Logs</h3>
Par défaut les logs sont gardés en mémoire (taille fixe) pour les performances.
<pre><code data-trim class="hljs nohighlight">
# varnishstat
# varnishtop -i ReqURL
# varnishlog
# varnishnsca
</code></pre>
Filtres possibles
<pre><code data-trim class="hljs nohighlight">
# varnishlog -q 'TxHeader eq MISS' -q "ReqHeader \
~ '^Host: example\.com$'" | grep RxURL
# varnishncsa -q "ReqHeader eq 'X-Cache: MISS'"
</code></pre>
</section>
<section>
<h3>Syntaxe VCL</h3>
</section>
</section>
<section>
<section>
<h2>PHP</h2>
<p>Langage de programmation très adapté au web.</p>
</section>
https://wiki.evolix.org/HowtoLAMP/PHP
</section>
<section>
<section>
<h2>Let's Encrypt</h2>
<ul>
<li>Autorité de certification</li>
<li>propose des certificats X-509</li>
<li>DV Domain Validation</li>
</ul>
</section>
<section>
<h3>Principes de base</h3>
<ul>
<li>gratuit</li>
<li>automatique</li>
<li>sécurisé</li>
<li>transparent</li>
<li>ouvert</li>
<li>cooperatif</li>
</ul>
</section>
<section>
<h3>Composants</h3>
<ul>
<li>Protocole ACME (standard IETF en janvier 2018)</li>
<li>Boulder : serveur ACME</li>
<li>Certbot : client ACME pour gérer des certificats</li>
<li>des dizaines d'autres clients tiers</li>
</ul>
</section>
<section>
<h3>Installation de certbot</h3>
<pre><code data-trim class="hljs nohighlight">
# apt install certbot
</code></pre>
<ul>
<li>création du compte Let's Encrypt</li>
<li>création de certificats</li>
<li>auto-configuration du serveur web</li>
<li>renouvellement/révocation de certificats</li>
</ul>
</section>
<section>
<h3>3 Challenges pour la validation</h3>
<ul>
<li>HTTP ressource signée</li>
<li>DNS enregistrement DNS signé</li>
<li>TLS-SNI certificat TLS contenant une signature</li>
</ul>
</section>
<section>
<h3>Particularités</h3>
<ul>
<li>Durée de vie de 90 jours</li>
<li>Entièrement automatisé</li>
<li>… donc seulement DV et pas OV ou EV</li>
</ul>
</section>
</section>
</div>
</div>
<script src="reveal.js/lib/js/head.min.js"></script>
<script src="reveal.js/js/reveal.js"></script>
<script>
// More info https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: true,
transition: 'slide', // none/fade/slide/convex/concave/zoom
// More info https://github.com/hakimel/reveal.js#dependencies
dependencies: [
{ src: 'reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'reveal.js/plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'reveal.js/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'reveal.js/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: 'reveal.js/plugin/zoom-js/zoom.js', async: true },
{ src: 'reveal.js/plugin/notes/notes.js', async: true }
]
});
</script>
</body>
</html>