Outils pour utilisateurs

Outils du site


pub:nginx

Nginx, FreeBSD way

Installation

Il suffit d'installer le paquet éponyme ou de compiler le port si besoin.

> dakota ~ % sudo pkg install nginx
ou
> dakota /usr/ports/www/nginx % sudo make install clean
puis
> dakota ~ % sudo sysrc nginx_enable=YES

WEB

Configuration

Le répertoire où sont stockés les fichiers de configuration, dont le principal qui est nginx.conf, est /usr/local/etc/nginx
Reprenant une "bonne pratique" héritée d'Apache24, j'aime bien séparer la configuration de base du service de celles spécifiques des vhosts.

nginx.conf
user  www www;
worker_processes  4;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    #include       /usr/local/etc/nginx/naxsi_core.rules;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    sendfile        on;
    keepalive_timeout  65;

    open_file_cache max=1000;

    ssl_session_timeout 5m;
    ssl_session_cache shared:NginxCacheSSL:50m;
    ssl_dhparam /usr/local/etc/ssl/dhparam.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    #ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_ciphers ALL:!aNULL:!eNULL:!LOW:!EXP:!RC4:!3DES:+HIGH:+MEDIUM;

    gzip  on;
    gzip_comp_level 5;
    gzip_types *;
    gzip_vary on;

    server {
      listen 80 default_server;
      server_name _; # invalid value which will never trigger on a real hostname.
      access_log /var/log/nginx/default.log main;
      server_name_in_redirect off;
      return 444; 
    }

    include  /usr/local/etc/nginx/vhost-enabled/*;

}

user www www;
On défini sur quel UID/GID va se binder nginx après que root l'ai démarré

worker_processes 4;
Cela correspond au nombre de CPU de la machine hôte. C'est une variable d'ajustement des performances.

events { worker_connections 1024; }
Cela défini le nombre maximal de worker_connections c'est une variable d'ajustement des performances. Le nombre de clients max = worker_processes * worker_connections.

open_file_cache max=1000;
Défini la taille maximale du cache coté serveur, ici 1000 entrées.

ssl_session_timeout 5m;
ssl_session_cache shared:NginxCacheSSL:50m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
paramètres régissant les connections HTTPS.
* http://wiki.nginx.org/HttpSslModule
* http://nginx.org/en/docs/http/ngx_http_ssl_module.htm

gzip on;
gzip_comp_level 5;
gzip_types *;
gzip_vary on;
gzip permet de compresser les fichers envoyés depuis le serveur à destination du navigateur.
* http://wiki.nginx.org/HttpGzipModule
on défini un taux de compression entre 1 & 9, du plus faible/rapide au plus fort/lent.
on peut restreindre la compression a certains type de fichiers, ici je choisis de l'appliquer à tous les types (*).

server {
listen 80 default_server;
server_name _;
return 444;
access_log /var/log/nginx/localhost.log main;
}
c'est le serveur /vhost par défaut.
il retourne une erreur 444 car je n'ai aucun contenu a servir “par défaut”.
* https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error

include /usr/local/etc/nginx/vhost-enabled/*;
tous les vhosts servis par ce serveur devront avoir leur fichier de configuration dans le répertoire indiqué.

Il reste à créer manuellement les dossiers vhost-enabled et vhost-available; puis à linker le vhosts actifs du second répertoire vers le premier.

Paramètre additionnel de sécurité SSL/Nginx

root@dakota:~ # cd /usr/local/etc/ssl
root@dakota:/usr/local/etc/ssl # openssl dhparam -out dhparam.pem 4096

PHP

Si des pages PHP doivent être servies depuis Nginx, ce le sera via PHP-FPM !

> dakota ~ % sudo pkg install php56 php56-extensions
L'installation par les ports reste à la charge des plus motivés...

> dakota ~ % sudo sysrc php_fpm_enable=YES

Il faut ensuite “installer” le php.ini

> dakota /usr/local/etc % sudo cp php.ini-production php.ini
une modification de /usr/local/etc/php-fpm.d/www.conf s'impose pour avoir php-fpm qui écoute sur un socket plutôt que sur l'adresse de loopback:
listen = 127.0.0.1:9000
listen = /var/run/php-fpm.sock

OpenSSL

Servir du contenu PHP protégé par OpenSSL

> dakota ~ % sudo pkg install php56-openssl

Ne pas oublier de relancer le daemon php-fpm !

Let's Encrypt

https://medium.com/chris-opperwall/using-acme-client-for-letsencrypt-on-freebsd-db0ee643ef1f

> sd-83258 ~ % sudo pkg install acme-client
...
WARNING: The default configuration paths have changed, rename :
/usr/local/www/letsencrypt to /usr/local/www/acme
/usr/local/etc/letsencrypt to /usr/local/etc/acme
/usr/local/etc/ssl/letsencrypt to /usr/local/etc/ssl/acme
and verify paths in your scripts
...
There are example scripts in : /usr/local/etc/acme
that you can use for renewing and deploying multiple certificates
...
In order to run the script regularly to update the certificates add this line to /etc/periodic.conf
weekly_acme_client_enable="YES"
...
Additionally the following parameters can be added to /etc/periodic.conf (showing default values):
To specify the domain name(s) to include in the certificate
	weekly_acme_client_domains="$(hostname -f)"
To specify the .well-known/acme-challenge directory (full path)
	weekly_acme_client_challengedir="/usr/local/www/acme"
To set additional acme-client arguments (see acme-client(1))
	weekly_acme_client_args="-b"
To run a specific script for the renewal (ignore previously set variables) allows generating/renewing multiple keys/certificates
	weekly_acme_client_renewscript=""/usr/local/etc/acme/acme-client.sh"
To run a script after the renewal to deploy changed certs
	weekly_acme_client_deployscript="/usr/local/etc/acme/deploy.sh

Certifier le vhost git.wezee.eu ?

> sd-83258 /usr/local/etc/ssl % sudo acme-client -v -e -m -b -n -N git.wezee.eu
Mot de passe : 
acme-client: /usr/local/etc/ssl/acme/git.wezee.eu: creating directory
acme-client: /usr/local/etc/ssl/acme/private/git.wezee.eu: creating directory
acme-client: /usr/local/etc/acme/git.wezee.eu: creating directory
acme-client: acme-client: /usr/local/etc/acme/git.wezee.eu/privkey.pem: generating RSA account key/usr/local/etc/ssl/acme/private/git.wezee.eu/privkey.pem: generating RSA domain key
acme-client: https://acme-v01.api.letsencrypt.org/directory: directories
acme-client: acme-v01.api.letsencrypt.org: DNS: 2.18.117.197
acme-client: acme-v01.api.letsencrypt.org: DNS: 2a02:26f0:2d:180::3d5
acme-client: acme-v01.api.letsencrypt.org: DNS: 2a02:26f0:2d:19b::3d5
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-reg: new-reg
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-authz: req-auth: git.wezee.eu
acme-client: /usr/local/www/acme/Lj0ML5yBVHwP3j0XJU9r6QRBwuM8jxnpcXHl6cfHkiA: created
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/V0hy_ZRUh8kDhitU55BgXWQ4QwoakR2oeLBeATR2W5I/1285691726: challenge
acme-client: https://acme-v01.api.letsencrypt.org/acme/challenge/V0hy_ZRUh8kDhitU55BgXWQ4QwoakR2oeLBeATR2W5I/1285691726: status
acme-client: https://acme-v01.api.letsencrypt.org/acme/new-cert: certificate
acme-client: http://cert.int-x3.letsencrypt.org/: full chain
acme-client: cert.int-x3.letsencrypt.org: DNS: 95.101.72.210
acme-client: cert.int-x3.letsencrypt.org: DNS: 95.101.72.218
acme-client: cert.int-x3.letsencrypt.org: DNS: 2a02:26f0:2d::216:30a2
acme-client: cert.int-x3.letsencrypt.org: DNS: 2a02:26f0:2d::216:30a8
acme-client: /usr/local/etc/ssl/acme/git.wezee.eu/cert.pem: linked to cert-1496692785.pem
acme-client: /usr/local/etc/ssl/acme/git.wezee.eu/chain.pem: linked to chain-1496692785.pem
acme-client: /usr/local/etc/ssl/acme/git.wezee.eu/fullchain.pem: linked to fullchain-1496692785.pem
acme-client: /usr/local/etc/ssl/acme/git.wezee.eu/chain.pem: created
acme-client: /usr/local/etc/ssl/acme/git.wezee.eu/cert.pem: created
acme-client: /usr/local/etc/ssl/acme/git.wezee.eu/fullchain.pem: created

MySQL

Servir du contenu PHP lié à une base de donnée MySQL

> dakota ~ % sudo pkg install php56-mysql

Ne pas oublier de relancer le daemon php-fpm !

A ce jour (octobre 2017 - FreeBSD 11.1) je suis passé sous PHP 7.1 avec l'ensemble de ces paquets d'installés :
php71-7.1.10
php71-bz2-7.1.10
php71-ctype-7.1.10
php71-curl-7.1.10
php71-dom-7.1.10
php71-exif-7.1.10
php71-extensions-1.0
php71-fileinfo-7.1.10
php71-filter-7.1.10
php71-ftp-7.1.10
php71-gd-7.1.10
php71-gmp-7.1.10
php71-hash-7.1.10
php71-iconv-7.1.10
php71-imap-7.1.10
php71-intl-7.1.10
php71-json-7.1.10
php71-ldap-7.1.10
php71-mbstring-7.1.10
php71-mcrypt-7.1.10
php71-mysqli-7.1.10
php71-opcache-7.1.10
php71-openssl-7.1.10
php71-pcntl-7.1.10
php71-pdo-7.1.10
php71-pdo_mysql-7.1.10
php71-pdo_sqlite-7.1.10
php71-phar-7.1.10
php71-posix-7.1.10
php71-session-7.1.10
php71-simplexml-7.1.10
php71-sqlite3-7.1.10
php71-tokenizer-7.1.10
php71-wddx-7.1.10
php71-xml-7.1.10
php71-xmlreader-7.1.10
php71-xmlwriter-7.1.10
php71-xsl-7.1.10
php71-zip-7.1.10_1
php71-zlib-7.1.10

Ils me sont nécessaires pour dokuwiki, kanboard, nextcloud & wordpress

VHosts

dokuwiki

server {
  listen  80;
  listen  [::]:80;
  server_name wiki.wezee.eu;

  # SSL renewal
  location ^~ /.well-known/acme-challenge {
   alias /usr/local/www/acme;
      try_files $uri =404;
  }
  
  # force https
  location / {
  return  301 https://$server_name$request_uri;
  }
}
 
server {
  listen 443 ssl;
  listen [::]:443 ssl;
  ssl on;
 
  # SSL cert
  ssl_certificate      /usr/local/etc/ssl/acme/wiki.wezee.eu/cert.pem;
  ssl_certificate_key  /usr/local/etc/ssl/acme/private/wiki.wezee.eu/privkey.pem;

  # VHost stuff
  server_name wiki.wezee.eu;
  index doku.php;
  root /usr/local/www/wezee/dokuwiki;
  access_log  /var/log/nginx/wiki.wezee.eu.log  main;

  # Maximum file upload size is 4MB - change accordingly if needed
  client_max_body_size 4M;
  client_body_buffer_size 128k;
 
  location ~ /(data/|conf/|bin/|inc/|install.php) { 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/;
  include fastcgi_params;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_param REDIRECT_STATUS 200;
  #fastcgi_pass 127.0.0.1:9000;
  fastcgi_pass unix:/var/run/php-fpm.sock;
  }
}

reverse-proxy

server {
  listen  80;
  server_name  transmission.localnet;

  access_log  /var/log/nginx/transmission.access.log main;

  location / {
    proxy_pass    http://127.0.0.1:9091;
  }

}

redirection de traffic

server {
  listen  80;
  server_name foo.bar.com;
  rewrite ^ https://loran42o.wezee.eu$request_uri? permanent;
}

validation certificats Let's encrypt

server {
  listen  80;
  server_name blah.wezee.eu;
  index index.html;
  root /usr/local/www/wezee/blah;
  access_log  /var/log/nginx/blah.wezee.eu.log  main;
  location ^~ /.well-known/acme-challenge {
   alias /usr/local/www/acme;
      try_files $uri =404;
  }
}

Packet Filter

Les règles PF concernant le traffic HTTP/HTTPS

#------------------------------------------------------------
# Pass IN to WEB
#------------------------------------------------------------

pass in log quick on $wan_if inet proto tcp to port {http,https} \
        keep state (max-src-conn 50, max-src-conn-rate 15/5, \
        overload <badguys> flush global)

pass in log quick on $wan_if inet6 proto tcp to port {http,https} \
        keep state (max-src-conn 50, max-src-conn-rate 15/5, \
        overload <badguys> flush global)

MAIL

FIXME reverse-proxy smtp/imap/pop3

pub/nginx.txt · Dernière modification: 2018/09/02 12:36 par loran42o