# apt install apache2-mpm-itk \
libapache2-mod-evasive apachetop libwww-perl
# apachectl configtest
/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
# a2enmod rewrite expires headers rewrite cgi
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>
# grep umask /etc/apache2/envvars
umask 007
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
DocumentRoot /home/example/www/
<Directory /home/example/www/>
Options SymLinksIfOwnerMatch
AllowOverride AuthConfig Limit FileInfo Indexes
</Directory>
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]
</VirtualHost>
# adduser example
# adduser --ingroup example www-example
# mkdir /home/example/{www,log,awstats}
# chown example: /home/example/{www,log,awstats}
# a2ensite example
# chmod 750 /home/example
# 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 {} \;
Ne jamais forcer les droits récursivement
sur toute l’arborescence. #NEVER777
Si la restriction en écriture pour Apache est impossible :
# a2enmod ssl
# 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
<VirtualHost *:80 *:443>
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]
</VirtualHost>
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
AuthType Basic
AuthName "Restricted"
AuthUserFile /foo/.htpasswd
AuthGroupFile /dev/null
require valid-user
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]
Limite les accès, notamment les dénis de service
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 5
DOSSiteCount 30
DOSPageInterval 3
DOSSiteInterval 1
DOSBlockingPeriod 60
DOSEmailNotify security@example.com
</IfModule>
$ apachetop -f access.log -T 3600 -q
<IfModule mod_status.c>
ExtendedStatus On
<Location /server-status-XXXX>
SetHandler server-status
Deny from all
Include ipaddr_whitelist.conf
Allow from 192.0.2.43
Allow from 127.0.0.1
</Location>
</IfModule>
Serveur web, alternative à Apache
# apt install nginx
# nginx -t -c /etc/nginx/nginx.conf
/etc/nginx/ ├── conf.d ├── fastcgi.conf ├── fastcgi_params ├── koi-utf ├── koi-win ├── mime.types ├── nginx.conf ├── proxy_params ├── scgi_params ├── sites-available │ └── default ├── sites-enabled │ └── default -> /etc/nginx/sites-available/default ├── snippets │ ├── fastcgi-php.conf │ └── snakeoil.conf ├── uwsgi_params └── win-utf
user www-data;
worker_processes 8;
pid /var/run/nginx.pid;
events {
use epoll;
worker_connections 10240;
}
http {
keepalive_timeout 15;
[…]
# disable Nginx version
server_tokens off;
server {
listen 80;
server_name static.example.com assets.example.com;
access_log /var/log/nginx/access.log;
root /home/static/www;
location /crossdomain.xml {
alias /home/static/www/crossdomain.xml;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/nginx-default;
}
location ~\.(jpeg|jpg|gif|png)$ {
add_header Cache-Control "public";
expires 2w;
}
location ~\.(js|pdf|css|swf)$ {
add_header Cache-Control "public";
expires 3w;
}
}
server {
listen 443;
server_name static.example.com assets.example.com;
ssl on;
ssl_certificate /etc/ssl/certs/static.example.com.crt;
ssl_certificate_key /etc/ssl/private/static.example.com.key;
# add_header Strict-Transport-Security "max-age=31536000;";
}
Proxy et load-balancer TCP/HTTP/HTTPS
# apt install haproxy
# haproxy -c -f /etc/haproxy/haproxy.cfg
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
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
listen mysql 127.0.0.1:3306
mode tcp
option mysql-check user haproxy_check
server sql00 192.0.2.1:3306 check
Accélérateur web : cache et reverse-proxy
# apt install varnish
Varnish relaie les requêtes vers le port 8080 local.
backend default {
.host = "127.0.0.1";
.port = "8080";
}
# varnishstat
# varnishtop -i ReqURL
# varnishlog
# varnishnsca
Filtres possibles
# varnishlog -q 'TxHeader eq MISS' -q "ReqHeader \
~ '^Host: example\.com$'" | grep RxURL
# varnishncsa -q "ReqHeader eq 'X-Cache: MISS'"
sub vcl_recv {
if (req.http.host == "boutique.example.com") {
if (req.url ~ "^/" || req.url ~ "/newsletter" ) {
unset req.http.cookie;
}
}
}
sub vcl_backend_response {
if (bereq.http.host == "boutique.example.com") {
if (bereq.url ~ "^/" || bereq.url ~ "/newsletter" ) {
unset beresp.http.Set-Cookie;
set beresp.ttl = 1h;
return (deliver);
}
}
}
Langage de programmation très adapté au web.
# apt install php5 libapache2-mod-php5 php5-gd php5-imap php5-ldap \
php5-mcrypt php5-mhash php5-mysql php5-pgsql \
php-gettext librsvg2-bin
$ php -v
PHP 5.6.30-0+deb8u1 (cli) (built: Feb 8 2017 08:50:21)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
# apt install php5-fpm
short_open_tags = Off
disable_functions = exec, shell-exec, system, passthru, putenv, popen
expose_php = Off
display_errors = Off
log_errors = On
allow_url_fopen = Off
memory_limit = 128M
max_execution_time = 10
open_basedir = /home
#php_admin_flag engine off
#AddType text/html .html
#php_admin_flag safe_mode off
#php_admin_value safe_mode_exec_dir /usr/bin
#php_admin_flag display_errors on
#php_flag short_open_tag on
#php_flag register_globals on
#php_admin_value upload_tmp_dir "/home/bloginfo/tmp/
php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f www-bloginfo"
php_admin_value error_log "/home/bloginfo/log/php.log"
php_admin_value memory_limit "64M"
[global]
pid = /run/php5-fpm.pid
error_log = /var/log/php5-fpm.log
[www]
listen = /var/run/php5-fpm.sock
;listen = 127.0.0.1:9000
user = www-data
group = www-data
pm = dynamic
php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f return-path@example.com
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/fpm-php.www.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 32M
pm = dynamic
pm.max_children = 100
pm.start_servers = 50
pm.min_spare_servers = 20
pm.max_spare_servers = 30
pm.max_requests = 100
OU
pm = ondemand
pm.max_children = 100
pm.process_idle_timeout = 10s
slowlog = log/$pool.log.slow
request_slowlog_timeout = 5s
pm.status_path = /fpm-status
request_terminate_timeout = 60s
chroot = /home/foo
access.log = log/$pool.access.log
# a2enmod proxy_fcgi
DocumentRoot /home/foo/www/
# ProxyPassMatch "^/(.*\.php(/.*)?)$" "fcgi://127.0.0.1:9000//home/foo/www/$1"
ProxyPassMatch "^/(.*\.php(/.*)?)$" "unix:/var/run/php5-fpm.sock|fcgi://localhost/home/foo/www/"
server {
listen 80;
server_name www.example.com example.com;
root /home/foo/www;
index index.php;
location ~ \.php$ {
try_files $uri =404;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME /home/foo/www$fastcgi_script_name;
include fastcgi_params;
}
}
$ echo "" > /var/www/info.php
# apt install certbot