evoformations/reveal/httpd.html

629 lines
17 KiB
HTML
Raw Normal View History

2017-06-19 11:03:13 +02:00
<!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">
2017-06-19 21:42:02 +02:00
<link rel="stylesheet" href="reveal.js/css/reveal.css">
<link rel="stylesheet" href="reveal.js/css/theme/beige.css" id="theme">
2017-06-19 11:03:13 +02:00
<!-- Theme used for syntax highlighting of code -->
2017-06-19 21:42:02 +02:00
<link rel="stylesheet" href="reveal.js/lib/css/zenburn.css">
2017-06-19 11:03:13 +02:00
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
2017-06-19 21:42:02 +02:00
link.href = window.location.search.match( /print-pdf/gi ) ? 'reveal.js/css/print/pdf.css' : 'reveal.js/css/print/paper.css';
2017-06-19 11:03:13 +02:00
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<!--[if lt IE 9]>
2017-06-19 21:42:02 +02:00
<script src="reveal.js/lib/js/html5shiv.js"></script>
2017-06-19 11:03:13 +02:00
<![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>
2017-06-20 12:04:51 +02:00
<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>
2017-06-20 03:26:41 +02:00
/etc/apache2/
2017-06-20 12:04:51 +02:00
├── 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>
2017-06-20 03:26:41 +02:00
umask 007
2017-06-20 12:04:51 +02:00
</pre>
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<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>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<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;
2017-06-20 03:26:41 +02:00
ServerName www.example.com
ServerAlias example.com
DocumentRoot /home/example/www/
2017-06-20 12:04:51 +02:00
&lt;Directory /home/example/www/&gt;
2017-06-20 03:26:41 +02:00
Options SymLinksIfOwnerMatch
AllowOverride AuthConfig Limit FileInfo Indexes
2017-06-20 12:04:51 +02:00
&lt;/Directory&gt;
2017-06-20 03:26:41 +02:00
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]
2017-06-20 12:04:51 +02:00
&lt;/VirtualHost&gt;
</code></pre>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<section>
<h4>Activation du site</h4>
<pre><code data-trim class="hljs nohighlight">
2017-06-20 03:26:41 +02:00
# adduser example
# adduser --ingroup example www-example
2017-06-20 12:04:51 +02:00
# mkdir /home/example/{www,log,awstats}
# chown example: /home/example/{www,log,awstats}
2017-06-20 03:26:41 +02:00
# a2ensite example
2017-06-20 12:04:51 +02:00
</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">
2017-06-20 03:26:41 +02:00
# chmod 750 /home/example
2017-06-20 12:04:51 +02:00
</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">
2017-06-20 03:26:41 +02:00
# 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 {} \;
2017-06-20 12:04:51 +02:00
</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">
2017-06-20 03:26:41 +02:00
# a2enmod ssl
2017-06-20 12:04:51 +02:00
</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>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<section>
<h3>Modification du VirtualHost</h3>
<pre><code data-trim class="apache">
&lt;VirtualHost *:80 *:443&gt;
2017-06-20 03:26:41 +02:00
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
2017-06-20 12:04:51 +02:00
# SSLCertificateChainFile /etc/ssl/certs/certificates_chain.pem
2017-06-20 03:26:41 +02:00
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [L,R=permanent]
2017-06-20 12:04:51 +02:00
&lt;/VirtualHost&gt;
</code></pre>
</section>
<section>
<h3>logs</h3>
Apache propose plusieurs formats de logs
<pre><code data-trim class="hljs nohighlight">
2017-06-20 03:26:41 +02:00
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
2017-06-20 12:04:51 +02:00
</code></pre>
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<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>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<section>
<h3>Règles de ré-écriture</h3>
<pre><code data-trim class="apache" style="max-height: 500px">
2017-06-20 03:26:41 +02:00
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]
2017-06-20 12:04:51 +02:00
</code></pre>
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<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>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<section>
<h3>Fail2ban</h3>
<ul>
<li>recherche de comportements anormaux dans les logs</li>
<li>blocage temporaire ou permanent, via firewall</li>
</ul>
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<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>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<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;
2017-06-20 03:26:41 +02:00
SetHandler server-status
Deny from all
Include ipaddr_whitelist.conf
Allow from 192.0.2.43
Allow from 127.0.0.1
2017-06-20 12:04:51 +02:00
&lt;/Location&gt;
&lt;/IfModule&gt;
</code></pre>
</section>
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<section>
2017-06-20 18:33:17 +02:00
<section>
<h2>Nginx</h2>
<p>Serveur web, alternative à Apache</p>
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 18:33:17 +02:00
<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>
2017-06-20 03:26:41 +02:00
2017-06-20 18:33:17 +02:00
<section>
2017-06-20 03:26:41 +02:00
https://wiki.evolix.org/HowtoNginx
2017-06-20 18:33:17 +02:00
</section>
2017-06-20 12:04:51 +02:00
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<section>
2017-06-20 18:33:17 +02:00
<section>
<h2>HAProxy</h2>
<p>Proxy et load-balancer TCP/HTTP/HTTPS</p>
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 18:33:17 +02:00
<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>
2017-06-20 12:04:51 +02:00
</section>
2017-06-20 18:33:17 +02:00
<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>
2017-06-20 12:04:51 +02:00
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<section>
2017-06-20 18:33:17 +02:00
<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>
2017-06-20 12:04:51 +02:00
<section>
2017-06-20 18:33:17 +02:00
<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>
2017-06-20 03:26:41 +02:00
2017-06-20 18:33:17 +02:00
<section>
<section>
<h2>Varnish</h2>
<p>Accélérateur web : cache et reverse-proxy</p>
2017-06-20 12:04:51 +02:00
</section>
2017-06-20 18:33:17 +02:00
<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>
2017-06-20 12:04:51 +02:00
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<section>
2017-06-20 18:33:17 +02:00
<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>
2017-06-20 12:04:51 +02:00
<section>
2017-06-20 18:33:17 +02:00
<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>
2017-06-20 03:26:41 +02:00
2017-06-20 18:33:17 +02:00
<section>
<h3>Syntaxe VCL</h3>
</section>
</section>
<section>
<section>
<h2>PHP</h2>
<p>Langage de programmation très adapté au web.</p>
2017-06-20 12:04:51 +02:00
</section>
2017-06-20 18:33:17 +02:00
https://wiki.evolix.org/HowtoLAMP/PHP
2017-06-20 12:04:51 +02:00
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 12:04:51 +02:00
<section>
2017-06-20 12:43:15 +02:00
<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>
2017-06-20 03:26:41 +02:00
2017-06-20 12:43:15 +02:00
<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>
2017-06-20 12:04:51 +02:00
</section>
2017-06-20 03:26:41 +02:00
2017-06-20 12:43:15 +02:00
<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>
2017-06-19 11:03:13 +02:00
2017-06-20 12:43:15 +02:00
<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>
2017-06-19 11:03:13 +02:00
2017-06-20 12:43:15 +02:00
<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>
2017-06-19 11:03:13 +02:00
2017-06-20 12:43:15 +02:00
<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>
2017-06-19 11:03:13 +02:00
</div>
</div>
2017-06-19 21:42:02 +02:00
<script src="reveal.js/lib/js/head.min.js"></script>
<script src="reveal.js/js/reveal.js"></script>
2017-06-19 11:03:13 +02:00
<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: [
2017-06-19 21:42:02 +02:00
{ 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 }
2017-06-19 11:03:13 +02:00
]
});
</script>
</body>
</html>