Archives de catégorie : WEB

Check DDOS Apache

#!/bin/bash

export LANG="POSIX"

# Get parameters
warning=${1:-"50"}
critical=${2:-"100"}
log_file=${3:-"*access_log"}
pattern=$4

# Get current hour
hour=$(date +%d/%b/%Y:%H -d '1 hours ago')

grep "$hour" /var/log/httpd/${log_file} | awk -v WARNING="${warning}" -v CRITICAL="${critical}" -v pattern="${pattern}" '

$0 ~ pattern {
  counter[$1]++
}

END {
  for (ip in counter) {
    if (counter[ip] > CRITICAL) {
	print "2";
	exit;
    } else if (counter[ip] > WARNING) {
	print "1";
	exit;
    }
  }
  print "0"
}

'

Varnish

On ira voir l'excellent site : https://sysadmin.infragate.fr qui possède un article très complet sur le sujet. :

https://sysadmin.infragate.fr/varnish/

Commandes Varnish

VarnishTop

statistiques façon top Linux, qui présentent les événements de trace les plus récurrents par ordre d’importance.

VarnishStat

ensemble de compteurs comme le nombre de requêtes, le nombre de requêtes envoyées depuis le cache, le nombre de requêtes envoyées au backend, etc.

VarnishLog

l’accès au log détaillé de Varnish se trouve être une file mémoire qui se purge au fur et à mesure qu’elle se remplit. Il est possible de la diriger vers un fichier et de filtrer son contenu.

VarnishHist

histogramme permettant de suivre en secondes le temps mis par Varnish pour desservir le contenu, qu’il provienne du cache ou non.

config test varnish :

varnishd -C -f /etc/varnish/default.vcl

S’il le retour de la commande ne crash pas d’erreur, on peut reload le service varnish. N.B : la configuration sera dégueulée dans shell si tout est OK.

Définition du backend

Dans le fichier de configuration /etc/varnish/default.vcl

En mode LoadBalancing : https://www.varnish-cache.org/trac/wiki/LoadBalancing

backend server1 {
  .host = "x.x.x.x";
  .port = "80";
  .probe = {
     .url = "/";
     .interval = 5s;
     .timeout = 1 s;
     .window = 5;
     .threshold = 3;
  }
}
backend server2 {
  .host = "y.y.y.y";
  .port = "80";
  .probe = {
     .url = "/";
     .interval = 5s;
     .timeout = 1 s;
     .window = 5;
     .threshold = 3;
  }
}

director server_group round-robin {
        {
                .backend = server1;
        }
        {
                .backend = server2;
        }
}

Purge cash

le restart du service varnish vide le cache. Il est possible de purge le cache avec une URL, il faut vérifier les acl au niveau de la configuration de varnish

Redirect

Dans le fichier de configuration /etc/varnish/default/vcl

if (req.http.Host ~ "^(www\.)?consosmart-novalgicfort\.com$") {
     error 801 "Moved Permanently";
     }

if (obj.status == 801) {
    set obj.http.Location = "https://www.consosmart.com/odr/214/novalgic";
    set obj.status = 301;
    return (deliver);
    }

ACL sur un vhost

Dans le fichier de configuration /etc/varnish/default/vcl

acl ip_name {
	"x.x.x.x/26"
	"y.y.y.y/25"
}

if (server.ip == "z.z.z.z" && req.http.host == "www.yourdomain.fr" && client.ip !~ ip_name ) {
        error 401 "Unauthorized.";
      }

ACL sur un User Agent

Dans le fichier de configuration /etc/varnish/default/vcl

 if (req.http.User-Agent ~ "(YaBrowser|YandexBot)") {
        error 401 "Unauthorized.";
      }
 

/

WordPress

Augmentation du upload_max_filesize

Ne fonctionne uniquement pour Apache dans le .htaccess

php_value post_max_size 24M
php_value upload_max_filesize 15M

Pour Nginx on placera dans le vhost dans la directive server{}

client_max_body_size 512M;

pour php-fpm 7.0 : /etc/php/7.0/fpm/php.ini pour php-fpm 5.0 : /etc/php5/fpm/php.ini

post_max_size = 0  # nolimlit 
upload_max_filesize = 1000M  # 1G

On vérifiera via l’upload dans media

Problème mode maintenance

Il se peut que le mode maintenance ne s’enlève pas de lui même lors d’une montée de version il faut alors supprimer le fichier nommé .maintenance à la racine du site.

Proxyfication de WP SSL proxy

Example de proxy avec cache à l’aide de NginX

location / {
      proxy_pass http://1.2.3.4;
      proxy_cache wp_cache;
      proxy_cache_valid      200  1d;
      proxy_cache_use_stale  error timeout invalid_header updating http_500 http_502 http_503 http_504;
      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $remote_addr;
      proxy_set_header        X-Forwarded-Proto $scheme;
      proxy_set_header       X-Forwarded-Host $host;
    

wp-config.php

define('WP_HOME','https://www.site.com');
define('WP_SITEURL','https://www.site.com');

if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
    $_SERVER['HTTPS']='on';

if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}

Changement du nom de la base

sed -i 's/wordpress_old_name/wp_new_name/' wordpress_old_name_2017-08-11_10-56-02.sql


Problème de mise à jour bloquée

wp-admin/includes/class-core-upgrader.php

//return new WP_Error( ‘locked’, $this->strings[‘locked’] );

ligne 121 wordpress 5.4.1

Php-fpm

useradd site -s /bin/false -d /var/www/site
[site.fr]
user = site
group = www-data
listen = /run/php/php-fpm-site.sock
listen.owner = site
listen.group = www-data
pm = ondemand
pm.max_children = 5
pm.start_servers = 3
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Taille maximale upload fichier

/etc/php5/fpm/php.ini

php_value upload_max_filesize 20M
php_value post_max_size 20M

Dans le vhost

client_max_body_size 20M;
client_body_buffer_size 128k;

optimisation multivhosting

L’idée est de rendre disponible la ram qui est saturée très rapidement par les processus php-fpm. En effet, les processus php ne rendent pas la mémoire qui s’allouent au fur et à mesure.

les paramètres suivant contrôle la relance des processus de leur échec après la réception de 3 Segmentation, page fault ou access violation (SIGSEGV ou SIGBUS) et il attendra 1 minute pour faire un graceful restart .

cette valeur peut être tunnée si la consommation processeur devient trop importante pendant les périodes de charges.

process_control_timeout est le de seconde qu’attends un processus fils pour les signaux venant du master.

dans /etc/php5/fpm/php-fpm.conf

emergency_restart_threshold = 3
emergency_restart_interval = 1m ( 5m )  //ceci est un workaround pour les problème de plugins ( wp better security ) qui font nimp avec le cache et tole les process php.
process_control_timeout = 5s

dans /etc/php5/pfm/pool.d/ passage a ondemand au lieu de dynamic

sed -i -e s/dynamic/ondemand/ig *

relance de la couche php

/etc.init.d/php-fpm restart

Ainsi une coket php5-fpm ne sera ouverte que si le site est utilisé. Economisant ainsi drastiquement la RAM.

Sécurisation

Dans le fichier /etc/php5/fpm/php.ini :

  expose_php = Off
  date.timezone = Europe/Paris

Affiche la configuration php

php -c /etc/php5/apache2/php.ini -i |grep -i opcache

Il faut l’adapter au niveau du grep -i suivant la configuration recherchée

Tracing de processus

Afin de connaitre l’état des sous processus php-fpm on peut strace comme suit

strace -p 30772
Process 30772 attached - interrupt to quit
futex(0x7f562602ae40, FUTEX_WAIT_PRIVATE, 2, NULL

Le futex wait indique un état bloqué , généralement en attente d’un accès fichier. on peut kill le processus et réattaché directement le strace dessus pour voir le déroulement ou la boucle afin d’indentifier le fichier qui pose problème. parmis les problème fréquent : fichier de cache wp qui n’existe plus et qui essaie d’être lsstat par php ou boucle infinie sur un fichier php upload avec un méta caratère.

Fonctions dangereuses

Fonction php potentiellement dangereuses

grep -RPn "(passthru|shell_exec|system|base64_decode|fopen|fclose|eval)" /var/www/

Connaitre l’empreinte mémoire u’un process php-fpm

service php7.0-fpm start && ps --no-headers -o "rss,cmd" -C php-fpm7.0 | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'

Changement de version

update-alternatives –set php /usr/bin/php7.3

Mod Security

Mod_security disponible pour Apache et Nginx, c’est un Web application Firewall. ( WAF )

https://www.modsecurity.org/download.html

Excellent pour se prémunir du cross-scripting / sql injection etc

il analyse finement le trafic http et aussi https.

A la manière de snort il fonctionne avec un système de rules ( payante pour les plus mieux ) et un jeu de base sympa en GPL.

Pour apache voir le site plus haut, pour nginx il faut recompiler le web serveur et les sources de mod_security

sinon voir https://github.com/nbs-system/naxsi

la recompilation est aussi nécessaire, il protège Charli hebdo après l’intrusion et au vu du nombre de attaks/day le test In Real situation est plus que correct. nbs-system est composé par certains membres des gcu-squad http://www.gcu-squad.org/ des intégristes de la GPL plutôt velu

http://blog-fr.bluevision.be/la-securite-autour-du-site-charlie-hebdo/

Installation Debian

apt-get install libapache-mod-security
cd /etc/modsecurity
mv modsecurity.conf-recommended modsecurity.conf

Pour information, dans /etc/apache2/mod-enabled se trouvent les fichiers suivants :

lrwxrwxrwx 1 root root   35 févr. 26 15:24 mod-security.conf -> ../mods-available/mod-security.conf
lrwxrwxrwx 1 root root   35 févr. 26 15:24 mod-security.load -> ../mods-available/mod-security.load

mod-security.conf des modules apache2 on trouve :

<IfModule security2_module>
        # Default Debian dir for modsecurity's persistent data
        SecDataDir /var/cache/modsecurity
        # Include all the *.conf files in /etc/modsecurity.
        # Keeping your local configuration in that directory
        # will allow for an easy upgrade of THIS file and
        # make your life easier
       Include "/etc/modsecurity/*.conf"
</IfModule>
vim /etc/modsecurity/modsecurity.conf
  1. –SecRuleEngine DetectionOnly mode de journalisation uniquement

+++SecRuleEngine On mode de blocage

Règles

ls -al /usr/share/modsecurity-crs/ total 48

drwxr-xr-x 2 root root 4096 févr. 26 15:24 activated_rules drwxr-xr-x 2 root root 4096 févr. 26 15:24 base_rules drwxr-xr-x 2 root root 4096 févr. 26 15:24 experimental_rules drwxr-xr-x 2 root root 4096 févr. 26 15:24 lua -rw-r–r– 1 root root 13544 juil. 2 2012 modsecurity_crs_10_setup.conf drwxr-xr-x 2 root root 4096 févr. 26 15:24 optional_rules drwxr-xr-x 3 root root 4096 févr. 26 15:24 util

mkdir /etc/modsecurity/activated_rules
ln -s /usr/share/modsecurity-crs/base_rules/* /etc/modsecurity/activated_rules
cp /usr/share/modsecurity-crs/modsecurity_crs_10_setup.conf /etc/modsecurity

vim /etc/apache2/mods-enabled/mod-security.conf

+++Include "/etc/modsecurity/activated_rules/*.conf"
service apache2 reload

fichier de log

/var/log/apache2/modsec_audit.log

Nginx WordPress Vhost

upstream php-wp-infra {
server unix:/var/run/infragate.fr.sock;server {
listen 80;
listen [::]:80;
server_name infragate.fr www.infragate.fr;
return 301 https://infragate.fr$request_uri;
}

server

    listen 443 ssl default_server;
    listen [::]:443 ssl http2 default_server;
    server_name infragate.fr;

    #SSL

    ssl on;
    ssl_certificate        /etc/letsencrypt/live/infragate.fr/fullchain.pem;
    ssl_certificate_key    /etc/letsencrypt/live/infragate.fr/privkey.pem;
    ssl_trusted_certificate   /etc/letsencrypt/live/infragate.fr/chain.pem;
    ssl_session_cache shared:le_nginx_SSL:1m;
    ssl_session_timeout 1440m;
    ssl_ciphers               'kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECDH+AES256 kEDH+AES128 kEDH+AES256 oDES-CBC3-SHA +SHA !aNULL !eNULL !LOW !kECDH !DSS !MD5 !EXP !PSK !SRP !CAMELLIA !SEED';
    ssl_ecdh_curve            secp384r1;
    ssl_dhparam               /etc/ssl/certs/dhparam.pem;

    add_header                Strict-Transport-Security max-age=31536000;
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Referrer-Policy "same-origin";

    #OCSP
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 9.9.9.9 8.8.8.8 valid=300s;
    resolver_timeout 3s;


    root /var/www/infragate.fr;
    index index.php ;

    access_log /var/log/nginx/infragate.fr_access.log;
    error_log /var/log/nginx/infragate.fr_error.log;

    rewrite ^/wp/([_0-9a-zA-Z-]+)/(xmlrpc\.php|wp-[0-9a-z-]+\.php) /wp/$2;
    rewrite ^/wp/([_0-9a-zA-Z-]+)/(wp-(admin|content|includes).*) /wp/$2;
    rewrite /wp-admin$ $scheme://$host$uri/ permanent;


    location / {
            try_files $uri $uri/ /index.php?$args;
    }


    location ~* /(?:uploads|files)/.*\.php$ {
       deny all;
    }

    location ~ \.php$ {
            try_files $uri =404;
            include fastcgi.conf;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass php-wp-infra;
            fastcgi_index index.php;

    }

    location ~* ^.+.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
    access_log                      off;
    log_not_found                   off;
    expires                         max;
    }

    location ~ /\. {
    access_log                      off;
    log_not_found                   off;
    deny                            all;
    }

    location = /favicon.ico {
            log_not_found off;
            access_log    off;
    }

    location = /robots.txt {
            allow                    all;
            log_not_found off;
            access_log    off;
    }

    #let'sencrypt
    location ^~ /.well-known {
        alias /var/www/infragate.fr/.well-known;
        default_type "text/plain";
        allow all;
    }

    location = /.well-known/acme-challenge/ {
         return 404;
    }

}

Nginx Configuration Vhosts

Exemple de configuration Seafile

https://www.seafile.com seafile.conf

 server {
        listen 80;
        server_name frontal.no-ip.org;
        rewrite ^ https://$http_host$request_uri? permanent;
 }
 
 
 server {
         listen 443;
 
         server_name frontal.no-ip.org;
 
         ssl on;
         ssl_certificate         /etc/nginx/ssl.crt/frontal.no-ip.org.crt;
         ssl_certificate_key    /etc/nginx/ssl.priv/frontal.no-ip.org.key;
 
        proxy_set_header X-Forwarded-For $remote_addr;
 
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
 
            access_log      /var/log/nginx/frontal.no-ip.org.access.log;
            error_log       /var/log/nginx/frontal.no-ip.org.error.log;
 
 
        location / {
            fastcgi_pass    127.0.0.1:8000;
            fastcgi_param   SCRIPT_FILENAME     $document_root$fastcgi_script_name;
            fastcgi_param   PATH_INFO           $fastcgi_script_name;
 
            fastcgi_param   SERVER_PROTOCOL     $server_protocol;
            fastcgi_param   QUERY_STRING        $query_string;
            fastcgi_param   REQUEST_METHOD      $request_method;
            fastcgi_param   CONTENT_TYPE        $content_type;
            fastcgi_param   CONTENT_LENGTH      $content_length;
            fastcgi_param   SERVER_ADDR         $server_addr;
            fastcgi_param   SERVER_PORT         $server_port;
            fastcgi_param   SERVER_NAME         $server_name;
            fastcgi_param   HTTPS               on;
            fastcgi_param   HTTP_SCHEME         https;
 
            access_log      /var/log/nginx/frontal.no-ip.org.access.log;
            error_log       /var/log/nginx/frontal.no-ip.org.error.log;
        }
 
        location /seafhttp {
            rewrite ^/seafhttp(.*)$ $1 break;
            proxy_pass http://127.0.0.1:8082;
            client_max_body_size 0;
            proxy_connect_timeout  36000s;
            proxy_read_timeout  36000s;
            proxy_send_timeout  36000s;
 #           proxy_request_buffering off;      #nginx =>1.8.2 file transfert > 4Go
        }
        location /media {
            root /srv/sea_cloud/seafile-server-latest/seahub;
        }
 
 }

Exemple de configuration dokuwiki

https://www.dokuwiki.org/dokuwiki# sample.conf

upstream php-fpm-site {
    server unix:/var/run/php/php-fpm-site.sock;
}
 
 
server {
     listen               80 default_server;
     listen               [::]:80;
     server_name          site.fr;
     rewrite ^ https://$server_name$request_uri? permanent;
}
 
server {
 
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name site.fr;
 
    ssl on;
    ssl_certificate        /etc/letsencrypt/live/site.fr/fullchain.pem;
    ssl_certificate_key    /etc/letsencrypt/live/site.fr/privkey.pem;
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
 
    access_log /var/log/nginx/site.access.log;
    error_log /var/log/nginx/site.error.log;
 
    # Maximum file upload size is 20MB modif php_value upload_max_filesize & post_max_size
    client_max_body_size 20M;
    client_body_buffer_size 128k;
 
    root /var/www/site;
    index index.php;
 
    location ~ /(data|conf|bin|inc)/ {
        deny all;
    }
 
    location /data/ {
        internal;
    }
 
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires 31536000s;
        add_header Pragma "public";
        add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
        log_not_found off;
    }
 
    location ^~ /.well-known {
            alias /var/www/site/.well-known;
            default_type "text/plain";
            allow all;
    }
 
    location = /.well-known/acme-challenge/ {
             return 404;
    }
 
    location ~ /\.ht {
             deny all;
    }
 
    location = /robots.txt  { access_log off; log_not_found off; }
    location = /favicon.ico { access_log off; log_not_found off; }
    location ~ /\.          { access_log off; log_not_found off; deny all; }
    location ~ ~$           { access_log off; log_not_found off; deny all; }
 
    location / { try_files $uri $uri/ @dokuwiki; }
 
    location @dokuwiki {
        rewrite ^/_media/(.*) /lib/exe/fetch.php?media=$1 last;
        rewrite ^/_detail/(.*) /lib/exe/detail.php?media=$1 last;
        rewrite ^/_export/([^/]+)/(.*) /doku.php?do=export_$1&id=$2 last;
        rewrite ^/(.*) /doku.php?id=$1&$args last;
    }
 
    location ~ \.php$ {
        try_files $uri $uri/ /doku.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param REDIRECT_STATUS 200;
        fastcgi_pass php-fpm-site;
    }
 
}

Exemple de configuration Owncloud

owncloud.conf

upstream php-handler-tata{
    #server 127.0.0.1:9000;
    server unix:/var/run/php5-fpm-tata.sock;
}
 
server {
    listen 80;
    server_name tata.fr;
 
    access_log /var/log/nginx/tata.fr_access.log;
    error_log  /var/log/nginx/tata.fr_error.log;
 
si proxy SSL devant
 
     set_real_ip_from 1.2.3.4;
         real_ip_header X-Real-IP;
         real_ip_recursive on;
 
 
    # Add headers to serve security related headers
    # Before enabling Strict-Transport-Security headers please read into this topic first.
    #add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
 
    # Path to the root of your installation
    root /srv/data/tata.fr;
 
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
 
    # The following 2 rules are only needed for the user_webfinger app.
    # Uncomment it if you're planning to use this app.
    #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
    #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
 
    location = /.well-known/carddav {
        return 301 $scheme://$host/remote.php/dav;
    }
    location = /.well-known/caldav {
        return 301 $scheme://$host/remote.php/dav;
    }
 
    location /.well-known/acme-challenge { }
 
    # set max upload size
    client_max_body_size 512M;
    fastcgi_buffers 64 4K;
 
    # Disable gzip to avoid the removal of the ETag header
    gzip off;
 
    # Uncomment if your server is build with the ngx_pagespeed module
    # This module is currently not supported.
    #pagespeed off;
 
    error_page 403 /core/templates/403.php;
    error_page 404 /core/templates/404.php;
 
    location / {
        rewrite ^ /index.php$uri;
    }
 
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
        return 404;
    }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
        return 404;
    }
 
    location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS on;
        fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
        fastcgi_param front_controller_active true;
        fastcgi_pass php-handler-tata;
        fastcgi_intercept_errors on;
#        fastcgi_request_buffering off; #Available since nginx 1.7.11
    }
 
    location ~ ^/(?:updater|ocs-provider)(?:$|/) {
        try_files $uri $uri/ =404;
        index index.php;
    }
 
    # Adding the cache control header for js and css files
    # Make sure it is BELOW the PHP block
    location ~* \.(?:css|js)$ {
        try_files $uri /index.php$uri$is_args$args;
        add_header Cache-Control "public, max-age=7200";
        # Optional: Don't log access to assets
        access_log off;
    }
 
    location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
        try_files $uri /index.php$uri$is_args$args;
        # Optional: Don't log access to other assets
        access_log off;
    }
}

Example de configuration Nextcloud

nextcloud.conf

upstream php-fpm-files {
    server unix:/var/run/php/php-fpm-files.sock;
}
 
server {
     listen               80;
     listen               [::]:80;
     server_name          xxxx.xxxx.fr;
     return 301 https://$server_name$request_uri;
}
 
server {
 
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name xxxx.xxxx.fr;
 
    ssl on;
    ssl_certificate        /etc/letsencrypt/live/xxxx.xxxx.fr/fullchain.pem;
    ssl_certificate_key    /etc/letsencrypt/live/xxxx.xxxx.fr/privkey.pem;
 
    #OCSP
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 9.9.9.9 8.8.8.8 valid=300s;
    resolver_timeout 3s;
 
    access_log /var/log/nginx/files_access.log;
    error_log  /var/log/nginx/files_error.log;
 
    root /var/www/nextcloud;
 
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
 
    # The following 2 rules are only needed for the user_webfinger app.
    # Uncomment it if you're planning to use this app.
    #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
    #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
 
    location = /.well-known/carddav {
        return 301 $scheme://$host/remote.php/dav;
    }
    location = /.well-known/caldav {
        return 301 $scheme://$host/remote.php/dav;
    }
 
    location ^~ /.well-known {
            alias /var/www/nextcloud/.well-known;
            default_type "text/plain";
            allow all;
    }
 
    location = /.well-known/acme-challenge/ {
             return 404;
    }
 
    # set max upload size
    client_max_body_size 512M;
    fastcgi_buffers 64 4K;
 
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
 
 
    # Uncomment if your server is build with the ngx_pagespeed module
    # This module is currently not supported.
    #pagespeed off;
 
    error_page 403 /core/templates/403.php;
    error_page 404 /core/templates/404.php;
 
    location / {
        rewrite ^ /index.php$uri;
    }
 
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
        deny all;
    }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
        deny all;
    }
 
 location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) {
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS on;
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;
        fastcgi_pass php-fpm-files;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
    }
 
    location ~ ^/(?:updater|ocs-provider)(?:$|/) {
        try_files $uri/ =404;
        index index.php;
    }
 
    # Adding the cache control header for js and css files
    # Make sure it is BELOW the PHP block
 
    location ~ \.(?:css|js|woff|svg|gif)$ {
        try_files $uri /index.php$uri$is_args$args;
        add_header Cache-Control "public, max-age=15778463";
        access_log off;
    }
 
    location ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ {
        try_files $uri /index.php$uri$is_args$args;
        # Optional: Don't log access to other assets
        access_log off;
    }
}

Nginx Https

Redirection https

Dans le fichier du vhost :

server {
  listen 80 default_server;
  listen [::]:80;
  server_name xxxx.xxxx.fr;
  rewrite ^ https://$server_name$request_uri? permanent;
} 
ou return 301 https://$server_name$request_uri;

et le bloc ssl correspondant:

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name xxxx.xxxx.fr;
  

[ssl on;]

ssl_certificate /etc/letsencrypt/live/xxxx.xxxx.fr;/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/xxxx.xxxx.fr;/privkey.pem; }

Let’sencrypt

 location ^~ /.well-known {
            alias /var/www/site/.well-known;
            default_type "text/plain";
            allow all;
    }

    location = /.well-known/acme-challenge/ {
             return 404;
    }
certbot certonly --webroot -w /var/www/www.site.fr -d www.site.fr

Renouvellement automatique

crontab -e
47 4,16   * * *   root   certbot renew --quiet --renew-hook "service nginx reload"

SSL avec OCSP

  server {
    listen 443 default;
    server_name xxxxx.xxx.fr;
    
    access_log /var/log/nginx/xxxx.xxxx.fr_access.log;
    error_log  /var/log/nginx/xxxx.xxxx.fr_error.log;
    
    ssl on;
    ssl_certificate     /etc/ssl/certs/xxxxx.xxxx.fr.crt;
    ssl_certificate_key /etc/ssl/private/xxxx.xxxx.fr.key;
    
    #OCSP 
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 9.9.9.9 8.8.8.8 valid=300s;
    resolver_timeout 3s;
  }

test

openssl s_client -connect site.fr:443 -tls1 -tlsextdebug -status

NGinx configuration générale

Options Nginx.conf

dans /etc/nginx/nginx.conf

server_tokens off;
multi_accept on;

# Atention au preload faire des test avant
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;

ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_dhparam /etc/ssl/certs/dhparam.pem;

Pour la génération du diffie hellman parameter en 4096 bit

cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096

Relance du serveur web

service nginx configtest
service ngionx reload

Activation compression

/etc/nginx/nginx.conf

gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;     
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

Nginx Vrac

Optimisation

Apprendre à optimiser les performances de Nginx Par Quentin Busuttil

Date de publication : 24 juillet 2016

Dernière mise à jour : 3 décembre 2017

optimiser-nginx.pdf

Authentification PAM

Dans la configuration du vhost :

auth_pam	"Authentification";
auth_pam_service_name "nginx";

Dans /etc/pam.d/nginx :

auth    required     /lib/x86_64-linux-gnu/security/pam_ldap.so
account required     /lib/x86_64-linux-gnu/security/pam_ldap.so

Filtrage IP

Dans la configuration du vhost :

  location ~ /\.ht {
             allow 11.22.33.44;
             deny all;
             allow all;
    }

Configuration reverse proxy

Dans la configuration du vhost :

location /exemple {
proxy_pass http://URL.du.service.com:8080/chemin/;
  proxy_set_header        X-Real-IP $remote_addr;
  proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header        Host $http_host;
} 

Configuration d’une redirection permanente

Dans la configuration du vhost :

rewrite ^/$ https://$server_name/chemin/ permanent;

Administration

service nginx configcheck
service nginx reload

Activation compression

/etc/nginx/nginx.conf

       gzip on;
       gzip_disable "msie6";
       gzip_vary on;
       gzip_proxied any;
       gzip_comp_level 6;
       gzip_buffers 16 8k;
       gzip_http_version 1.1;
       gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;