diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
 __pycache__
 *.pyc
 *.pyo
+
+# Autogenerated content
+roles/webserver-core/nginx/files/ocsp-ca-certs.pem
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -31,18 +31,24 @@
 #   Build targets - repository
 #   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
-repo: roles/webserver-content/init.sls .git/hooks/pre-commit
+repo: roles/webserver-content/init.sls \
+	roles/webserver-core/nginx/files/ocsp-ca-certs.pem \
+	.git/hooks/pre-commit
 
 roles/webserver-content/init.sls:
 	tmpfile=`mktemp /tmp/make-rOPS-generate-webcontent-index.XXXXXX` ; \
 	utils/generate-webcontent-index.py > "$$tmpfile" ;\
 	${MV} "$$tmpfile" roles/webserver-content/init.sls
 
+roles/webserver-core/nginx/files/ocsp-ca-certs.pem:
+	utils/generate-ocsp-bundle.sh > roles/webserver-core/nginx/files/ocsp-ca-certs.pem
+
 .git/hooks/pre-commit:
 	pre-commit install
 
 clean-repo:
 	${RM} roles/webserver-content/init.sls .git/hooks/pre-commit
+	${RM} roles/webserver-core/nginx/files/ocsp-ca-certs.pem
 
 #   -------------------------------------------------------------
 #   Build targets - API
diff --git a/roles/paas-docker/nginx/config.sls b/roles/paas-docker/nginx/config.sls
--- a/roles/paas-docker/nginx/config.sls
+++ b/roles/paas-docker/nginx/config.sls
@@ -9,34 +9,6 @@
 {% from "map.jinja" import dirs with context %}
 {% set containers = pillar.get('docker_containers', {}) %}
 
-#   -------------------------------------------------------------
-#   Base folder
-#
-#    :: general configuration
-#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-{{ dirs.etc }}/nginx/nginx.conf:
-  file.managed:
-    - source: salt://roles/paas-docker/nginx/files/nginx.conf
-
-nginx_dhparams:
-  cmd.run:
-    - name: openssl dhparam -out {{ dirs.etc }}/nginx/dhparams.pem 2048
-    - creates: {{ dirs.etc }}/nginx/dhparams.pem
-
-#   -------------------------------------------------------------
-#   includes folder
-#
-#    :: general configuration
-#    :: application-specific code
-#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-{{ dirs.etc }}/nginx/includes:
-  file.recurse:
-    - source: salt://roles/paas-docker/nginx/files/includes
-    - dir_mode: 755
-    - file_mode: 644
-
 #   -------------------------------------------------------------
 #   vhosts folder
 #
diff --git a/roles/paas-docker/nginx/files/includes/cors-open b/roles/paas-docker/nginx/files/includes/cors-open
deleted file mode 100644
--- a/roles/paas-docker/nginx/files/includes/cors-open
+++ /dev/null
@@ -1,54 +0,0 @@
-#   -------------------------------------------------------------
-#   Configuration for Nasqueron web sites
-#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#   Project:        Nasqueron
-#   Description:    nginx CORS configuration
-#   Reference:      Michiel Kalkman, "Wide open nginx CORS configuration",
-#                   https://michielkalkman.com/snippets/nginx-cors-open-configuration/
-#   License:        Trivial work, not eligible for copyright.
-#   Source file:    roles/paas-docker/nginx/files/includes/cors-open
-#   -------------------------------------------------------------
-#
-#   <auto-generated>
-#       This file is managed by our rOPS SaltStack repository.
-#
-#       Changes to this file may cause incorrect behavior
-#       and will be lost if the state is redeployed.
-#   </auto-generated>
-
-#   -------------------------------------------------------------
-#   OPTIONS
-#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-if ($request_method = 'OPTIONS') {
-    add_header 'Access-Control-Allow-Origin' '*';
-    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
-    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
-    add_header 'Access-Control-Max-Age' 1728000;
-    add_header 'Content-Type' 'text/plain; charset=utf-8';
-    add_header 'Content-Length' 0;
-
-    return 204;
- }
-
- #   -------------------------------------------------------------
- #   GET
- #   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-if ($request_method = 'GET') {
-    add_header 'Access-Control-Allow-Origin' '*';
-    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
-    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
-    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
-}
-
-#   -------------------------------------------------------------
-#   POST
-#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-if ($request_method = 'POST') {
-    add_header 'Access-Control-Allow-Origin' '*';
-    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
-    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
-    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
-}
diff --git a/roles/paas-docker/nginx/files/includes/geo_nasqueron b/roles/paas-docker/nginx/files/includes/geo_nasqueron
deleted file mode 100644
--- a/roles/paas-docker/nginx/files/includes/geo_nasqueron
+++ /dev/null
@@ -1,24 +0,0 @@
-geo $nasqueron_server {
-    default 0;
-
-    # Dreadnought
-    51.255.124.8/30 1;
-
-    # Ysul
-    163.172.49.16 1;
-    212.83.187.132 1;
-
-    # WindRiver
-    51.159.18.59 1;
-
-    # CloudHugger
-    188.165.200.229 1;
-
-    # Docker containers
-    172.17.0.0/16 1;
-}
-
-map $nasqueron_server $not_a_nasqueron_server {
-    default 0;
-    0 1;
-}
diff --git a/roles/paas-docker/nginx/files/includes/letsencrypt b/roles/paas-docker/nginx/files/includes/letsencrypt
deleted file mode 100644
--- a/roles/paas-docker/nginx/files/includes/letsencrypt
+++ /dev/null
@@ -1,20 +0,0 @@
-#   -------------------------------------------------------------
-#   Configuration for Let's encrypt nginx
-#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#   Author:         Sébastien Santoro aka Dereckson
-#   Created:        2016-01-05
-#   Description:    Get SSL certificates from Let's encrypt
-#   Source file:    roles/paas-docker/nginx/files/includes/letsencrypt
-#   -------------------------------------------------------------
-#
-#   <auto-generated>
-#       This file is managed by our rOPS SaltStack repository.
-#
-#       Changes to this file may cause incorrect behavior
-#       and will be lost if the state is redeployed.
-#   </auto-generated>
-
-        location /.well-known/acme-challenge {
-            default_type text/plain;
-            root /srv/letsencrypt/www;
-        }
diff --git a/roles/paas-docker/nginx/files/includes/tls b/roles/paas-docker/nginx/files/includes/tls
deleted file mode 100644
--- a/roles/paas-docker/nginx/files/includes/tls
+++ /dev/null
@@ -1,28 +0,0 @@
-#   -------------------------------------------------------------
-#   Configuration for Let's encrypt nginx
-#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#   Author:         Sébastien Santoro aka Dereckson
-#   Created:        2017-04-03
-#   Description:    Get SSL certificates from Let's encrypt
-#   Source file:    roles/paas-docker/nginx/files/includes/tls
-#   -------------------------------------------------------------
-#
-#   <auto-generated>
-#       This file is managed by our rOPS SaltStack repository.
-#
-#       Changes to this file may cause incorrect behavior
-#       and will be lost if the state is redeployed.
-#   </auto-generated>
-
-listen              443 ssl http2;
-listen              [::]:443 ssl http2;
-keepalive_timeout   70;
-
-ssl_session_timeout 1d;
-ssl_session_cache shared:SSL:10m;
-ssl_session_tickets off;
-
-ssl_protocols TLSv1.2;
-ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
-ssl_prefer_server_ciphers on;
-ssl_dhparam         /etc/nginx/dhparams.pem;
diff --git a/roles/shellserver/web-hosting/files/eglide/nginx/includes/letsencrypt.conf b/roles/shellserver/web-hosting/files/eglide/nginx/includes/letsencrypt.conf
deleted file mode 100644
--- a/roles/shellserver/web-hosting/files/eglide/nginx/includes/letsencrypt.conf
+++ /dev/null
@@ -1,22 +0,0 @@
-#   -------------------------------------------------------------
-#   Configuration for Let's encrypt nginx
-#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#   Author:         Sébastien Santoro aka Dereckson
-#   Created:        2016-01-05
-#   Description:    Get SSL certificates from Let's encrypt
-#   Source file:    roles/shellserver/web-hosting/files/eglide/nginx/includes/letsencrypt.conf
-#   -------------------------------------------------------------
-#
-#   <auto-generated>
-#       This file is managed by our rOPS SaltStack repository.
-#
-#       Changes to this file may cause incorrect behavior
-#       and will be lost if the state is redeployed.
-#   </auto-generated>
-
-        location /.well-known/acme-challenge {
-            allow all;
-
-            default_type text/plain;
-            root /var/letsencrypt-auto;
-        }
diff --git a/roles/shellserver/web-hosting/files/eglide/nginx/nginx.conf b/roles/shellserver/web-hosting/files/eglide/nginx/nginx.conf
deleted file mode 100644
--- a/roles/shellserver/web-hosting/files/eglide/nginx/nginx.conf
+++ /dev/null
@@ -1,46 +0,0 @@
-#   -------------------------------------------------------------
-#   Eglide — nginx configuration
-#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#   Project:        Eglide
-#   Created:        2016-07-26
-#   License:        Trivial work, not eligible to copyright
-#   Source file:    roles/shellserver/web-hosting/files/eglide/nginx/nginx.conf
-#   -------------------------------------------------------------
-#
-#   <auto-generated>
-#       This file is managed by our rOPS SaltStack repository.
-#
-#       Changes to this file may cause incorrect behavior
-#       and will be lost if the state is redeployed.
-#   </auto-generated>
-
-#   -------------------------------------------------------------
-#   Server configuration
-#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-worker_processes  1;
-
-events {
-    worker_connections  1024;
-}
-
-#   -------------------------------------------------------------
-#   HTTP configuration
-#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-http {
-    include       mime.types;
-    default_type  text/plain;
-
-    server_names_hash_bucket_size  128;
-
-    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;
-    gzip  on;
-
-    include vhosts/*.conf;
-}
diff --git a/roles/shellserver/web-hosting/files/eglide/nginx/ssl_params b/roles/shellserver/web-hosting/files/eglide/nginx/ssl_params
deleted file mode 100644
--- a/roles/shellserver/web-hosting/files/eglide/nginx/ssl_params
+++ /dev/null
@@ -1,15 +0,0 @@
-        #Enable https
-        listen 443 ssl http2;
-        listen [2001:470:1f13:896:0:c0de:15:11fe]:443 ssl http2;
-
-        ssl_session_timeout 1d;
-        ssl_session_cache shared:SSL:50m;
-        ssl_session_tickets off;
-
-        ssl_protocols TLSv1.2;
-        ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
-        ssl_prefer_server_ciphers on;
-
-        add_header Strict-Transport-Security max-age=15768000;
-        ssl_stapling on;
-        ssl_stapling_verify on;
diff --git a/roles/shellserver/web-hosting/files/eglide/nginx/vhosts/000.conf b/roles/shellserver/web-hosting/files/eglide/nginx/vhosts/000-fallback.conf
rename from roles/shellserver/web-hosting/files/eglide/nginx/vhosts/000.conf
rename to roles/shellserver/web-hosting/files/eglide/nginx/vhosts/000-fallback.conf
--- a/roles/shellserver/web-hosting/files/eglide/nginx/vhosts/000.conf
+++ b/roles/shellserver/web-hosting/files/eglide/nginx/vhosts/000-fallback.conf
@@ -4,7 +4,7 @@
 #   Project:        Eglide
 #   Created:        2016-07-26
 #   License:        Trivial work, not eligible to copyright
-#   Source file:    roles/shellserver/web-hosting/files/eglide/nginx/vhosts/000.conf
+#   Source file:    roles/shellserver/web-hosting/files/eglide/nginx/vhosts/000-fallback.conf
 #   -------------------------------------------------------------
 #
 #   <auto-generated>
diff --git a/roles/shellserver/web-hosting/files/eglide/nginx/vhosts/001-eglide.org.conf b/roles/shellserver/web-hosting/files/eglide/nginx/vhosts/001-server.conf
rename from roles/shellserver/web-hosting/files/eglide/nginx/vhosts/001-eglide.org.conf
rename to roles/shellserver/web-hosting/files/eglide/nginx/vhosts/001-server.conf
--- a/roles/shellserver/web-hosting/files/eglide/nginx/vhosts/001-eglide.org.conf
+++ b/roles/shellserver/web-hosting/files/eglide/nginx/vhosts/001-server.conf
@@ -4,7 +4,7 @@
 #   Project:        Eglide
 #   Created:        2016-07-26
 #   License:        Trivial work, not eligible to copyright
-#   Source file:    roles/shellserver/web-hosting/files/eglide/nginx/vhosts/001-eglide.org.conf
+#   Source file:    roles/shellserver/web-hosting/files/eglide/nginx/vhosts/001-server.conf
 #   -------------------------------------------------------------
 #
 #   <auto-generated>
@@ -33,12 +33,11 @@
         ### SSL
         ###
 
-        include includes/letsencrypt.conf;
+        include includes/letsencrypt;
 
-        include ssl_params;
+        include includes/tls;
         ssl_certificate          /etc/letsencrypt/live/www.eglide.org/fullchain.pem;
         ssl_certificate_key      /etc/letsencrypt/live/www.eglide.org/privkey.pem;
-        ssl_trusted_certificate  /etc/letsencrypt/live/www.eglide.org/chain.pem;
 
         ###
         ### Main site
diff --git a/roles/webserver-core/map.jinja b/roles/webserver-core/map.jinja
new file mode 100644
--- /dev/null
+++ b/roles/webserver-core/map.jinja
@@ -0,0 +1,18 @@
+{% set options = salt["grains.filter_by"]({
+    "Debian": {
+        "www_user": "nobody",
+    },
+    "FreeBSD": {
+        "www_user": "www",
+    },
+    "RedHat": {
+        "www_user": "nginx",
+        "pid_path": "/run/nginx.pid",
+    }
+}, default="Debian") %}
+
+{% if salt["node.has_role"]("paas-docker") %}
+{% set certbot_dir = "/srv/letsencrypt/www" %}
+{% else %}
+{% set certbot_dir = "/var/letsencrypt-auto" %}
+{% endif %}
diff --git a/roles/webserver-core/nginx/config.sls b/roles/webserver-core/nginx/config.sls
--- a/roles/webserver-core/nginx/config.sls
+++ b/roles/webserver-core/nginx/config.sls
@@ -6,6 +6,19 @@
 #   -------------------------------------------------------------
 
 {% from "map.jinja" import dirs with context %}
+{% from "roles/webserver-core/map.jinja" import options, certbot_dir with context %}
+
+#   -------------------------------------------------------------
+#   Base configuration
+#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{{ dirs.etc }}/nginx/nginx.conf:
+  file.managed:
+    - source: salt://roles/webserver-core/nginx/files/nginx.conf
+    - template: jinja
+    - context:
+        nginx_dir: {{ dirs.etc }}/nginx
+        nginx_options: {{ options }}
 
 #   -------------------------------------------------------------
 #   includes folder
@@ -20,6 +33,39 @@
     - source: salt://roles/webserver-core/nginx/files/includes
     - dir_mode: 755
     - file_mode: 644
+    - template: jinja
+    - context:
+        nginx_dir: {{ dirs.etc }}/nginx
+        nginx_options: {{ options }}
+        certbot_dir: {{ certbot_dir }}
+
+#   -------------------------------------------------------------
+#   Parameters for Diffie-Hellman
+#
+#   Some ciphers still require DH exchange. They contain "DHE" in
+#   the name, e.g. DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384
+#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+webserver_core_nginx_dh:
+  cmd.run:
+    - name: openssl dhparam -out {{ dirs.etc }}/nginx/dhparams.pem 4096
+    - creates: {{ dirs.etc }}/nginx/dhparams.pem
+
+#   -------------------------------------------------------------
+#   OCSP - Online Certificate Status Protocol
+#
+#   To allow nginx to verify TLS certificate presented by CA
+#   when it makes requests to the CRL, a bundle of CA certificates
+#   should be available.
+#
+#   To generate the bundle file on this repository, use `make`.
+#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+/usr/local/share/certs/ocsp-ca-certs.pem:
+  file.managed:
+    - source: salt://roles/webserver-core/nginx/files/ocsp-ca-certs.pem
+    - makedirs: True
+    - mode: 644
 
 #   -------------------------------------------------------------
 #   vhost folder
diff --git a/roles/webserver-legacy/nginx/files/includes/cors-open b/roles/webserver-core/nginx/files/includes/cors-open
rename from roles/webserver-legacy/nginx/files/includes/cors-open
rename to roles/webserver-core/nginx/files/includes/cors-open
--- a/roles/webserver-legacy/nginx/files/includes/cors-open
+++ b/roles/webserver-core/nginx/files/includes/cors-open
@@ -1,12 +1,12 @@
 #   -------------------------------------------------------------
-#   Configuration for Nasqueron web sites
+#   nginx :: configuration :: CORS :: open policy
 #   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 #   Project:        Nasqueron
 #   Description:    nginx CORS configuration
 #   Reference:      Michiel Kalkman, "Wide open nginx CORS configuration",
 #                   https://michielkalkman.com/snippets/nginx-cors-open-configuration/
 #   License:        Trivial work, not eligible for copyright.
-#   Source file:    roles/webserver-legacy/nginx/files/includes/cors-open
+#   Source file:    roles/webserver-core/nginx/files/includes/cors-open
 #   -------------------------------------------------------------
 #
 #   <auto-generated>
diff --git a/roles/webserver-legacy/nginx/files/includes/cors-open-no-cache b/roles/webserver-core/nginx/files/includes/cors-open-no-cache
rename from roles/webserver-legacy/nginx/files/includes/cors-open-no-cache
rename to roles/webserver-core/nginx/files/includes/cors-open-no-cache
--- a/roles/webserver-legacy/nginx/files/includes/cors-open-no-cache
+++ b/roles/webserver-core/nginx/files/includes/cors-open-no-cache
@@ -1,12 +1,12 @@
 #   -------------------------------------------------------------
-#   Configuration for Nasqueron web sites
+#   nginx :: configuration :: CORS + no cache :: open policy
 #   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 #   Project:        Nasqueron
 #   Description:    nginx CORS configuration
 #   Reference:      Michiel Kalkman, "Wide open nginx CORS configuration",
 #                   https://michielkalkman.com/snippets/nginx-cors-open-configuration/
 #   License:        Trivial work, not eligible for copyright.
-#   Source file:    roles/webserver-legacy/nginx/files/includes/cors-open-no-cache
+#   Source file:    roles/webserver-core/nginx/files/includes/cors-open-no-cache
 #   -------------------------------------------------------------
 #
 #   <auto-generated>
diff --git a/roles/webserver-core/nginx/files/includes/fastcgi_params b/roles/webserver-core/nginx/files/includes/fastcgi_params
--- a/roles/webserver-core/nginx/files/includes/fastcgi_params
+++ b/roles/webserver-core/nginx/files/includes/fastcgi_params
@@ -1,8 +1,6 @@
 #   -------------------------------------------------------------
-#   Configuration for Nasqueron web sites
+#   nginx :: configuration :: FastCGI
 #   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#   Author:         Sébastien Santoro aka Dereckson
-#   Created:        2017-11-19
 #   Project:        Nasqueron
 #   Description:    nginx FastCGI configuration
 #   License:        Trivial work, not eligible for copyright.
diff --git a/roles/webserver-core/nginx/files/includes/geo_nasqueron b/roles/webserver-core/nginx/files/includes/geo_nasqueron
new file mode 100644
--- /dev/null
+++ b/roles/webserver-core/nginx/files/includes/geo_nasqueron
@@ -0,0 +1,43 @@
+#   -------------------------------------------------------------
+#   nginx :: configuration :: geo :: Nasqueron servers
+#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#   Project:        Nasqueron
+#   Source file:    roles/webserver-core/nginx/files/includes/geo_nasqueron
+#   -------------------------------------------------------------
+#
+#   <auto-generated>
+#       This file is managed by our rOPS SaltStack repository.
+#
+#       Changes to this file may cause incorrect behavior
+#       and will be lost if the state is redeployed.
+#   </auto-generated>
+
+geo $nasqueron_server {
+    default 0;
+
+    # Dreadnought
+    51.255.124.8/30 1;
+
+    # Ysul
+    163.172.49.16 1;
+    212.83.187.132 1;
+
+    # WindRiver
+    51.159.18.59 1;
+
+    # CloudHugger
+    188.165.200.229 1;
+
+    # Drake private network
+    172.27.27.0/24 1;
+
+    # Docker containers
+    172.17.0.0/16 1;
+    172.18.0.0/16 1;
+    172.21.0.0/16 1;
+}
+
+map $nasqueron_server $not_a_nasqueron_server {
+    default 0;
+    0 1;
+}
diff --git a/roles/webserver-legacy/nginx/files/includes/letsencrypt b/roles/webserver-core/nginx/files/includes/letsencrypt
rename from roles/webserver-legacy/nginx/files/includes/letsencrypt
rename to roles/webserver-core/nginx/files/includes/letsencrypt
--- a/roles/webserver-legacy/nginx/files/includes/letsencrypt
+++ b/roles/webserver-core/nginx/files/includes/letsencrypt
@@ -1,11 +1,10 @@
 #   -------------------------------------------------------------
-#   Configuration for Let's encrypt nginx
+#   nginx :: configuration :: Let's Encrypt
 #   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#   Author:         Sébastien Santoro aka Dereckson
-#   Created:        2016-01-05
+#   Project:        Nasqueron
 #   Description:    Get SSL certificates from Let's encrypt
 #   License:        Trivial work, not eligible for copyright.
-#   Source file:    roles/webserver-legacy/nginx/files/includes/letsencrypt
+#   Source file:    roles/webserver-core/nginx/files/includes/letsencrypt
 #   -------------------------------------------------------------
 #
 #   <auto-generated>
@@ -16,6 +15,8 @@
 #   </auto-generated>
 
 location /.well-known/acme-challenge {
+    allow all;
+
     default_type text/plain;
-    root /var/letsencrypt-auto;
+    root {{ certbot_dir }};
 }
diff --git a/roles/paas-docker/nginx/files/includes/proxy_params b/roles/webserver-core/nginx/files/includes/proxy_params
rename from roles/paas-docker/nginx/files/includes/proxy_params
rename to roles/webserver-core/nginx/files/includes/proxy_params
--- a/roles/paas-docker/nginx/files/includes/proxy_params
+++ b/roles/webserver-core/nginx/files/includes/proxy_params
@@ -1,12 +1,10 @@
 #   -------------------------------------------------------------
-#   Configuration for Nasqueron web sites
+#   nginx :: configuration :: proxy
 #   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#   Author:         Sébastien Santoro aka Dereckson
-#   Created:        2018-03-16
 #   Project:        Nasqueron
 #   Description:    nginx proxy configuration
 #   License:        Trivial work, not eligible for copyright.
-#   Source file:    roles/paas-docker/nginx/files/includes/proxy_params
+#   Source file:    roles/webserver-core/nginx/files/includes/proxy_params
 #   -------------------------------------------------------------
 #
 #   <auto-generated>
diff --git a/roles/webserver-core/nginx/files/includes/tls b/roles/webserver-core/nginx/files/includes/tls
--- a/roles/webserver-core/nginx/files/includes/tls
+++ b/roles/webserver-core/nginx/files/includes/tls
@@ -1,11 +1,20 @@
 #   -------------------------------------------------------------
-#   Configuration for nginx TLS
+#   nginx :: configuration :: TLS
 #   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#   Author:         Sébastien Santoro aka Dereckson
-#   Created:        2016-01-05
+#   Project:        Nasqueron
+#   Description:    Compatible TLS configuration for most clients
+#   Strategy:       nginx 1.22.1, intermediate config, OpenSSL 1.1.1o
+#   See also:       https://ssl-config.mozilla.org/
 #   License:        Trivial work, not eligible for copyright.
 #   Source file:    roles/webserver-core/nginx/files/includes/tls
 #   -------------------------------------------------------------
+#
+#   <auto-generated>
+#       This file is managed by our rOPS SaltStack repository.
+#
+#       Changes to this file may cause incorrect behavior
+#       and will be lost if the state is redeployed.
+#   </auto-generated>
 
 listen 443 ssl http2;
 listen [::]:443 ssl http2;
@@ -13,9 +22,45 @@
 keepalive_timeout   70;
 
 ssl_session_timeout 1d;
-ssl_session_cache shared:SSL:50m;
+ssl_session_cache shared:SSL:10m;
 ssl_session_tickets off;
 
-ssl_protocols TLSv1.2;
-ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
-ssl_prefer_server_ciphers on;
+ssl_dhparam {{ nginx_dir }}/dhparams.pem;
+
+ssl_protocols TLSv1.2 TLSv1.3;
+ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+ssl_prefer_server_ciphers off;
+
+#   -------------------------------------------------------------
+#   HSTS - HTTP Strict Transport Security
+#
+#   As we provide a Let's Encrypt certificate for all our services,
+#   browser should be instructed to connect directly to HTTPS.
+#
+#   This is low risk, as the browser only honour this request
+#   as soon as it successfully connected to HTTPS without any
+#   certificate issue.
+#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+add_header Strict-Transport-Security "max-age=63072000" always;
+
+#   -------------------------------------------------------------
+#   OCSP - Online Certificate Status Protocol
+#
+#   To improve TLS handshake speed, and to help protecting the
+#   privacy of the users connecting here, as there isn't any need
+#   for them to connect to the CRL anymore, OSCP is enabled.
+#
+#   The parameter `ssl_trusted_certificate` points to a bundle
+#   of CA certificates, currently containing Let's Encrypt
+#   intermediate and root certificates. If *any* certificate
+#   is issued by another CA, their certificates must be added
+#   to the bundle too.
+#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+ssl_stapling on;
+ssl_stapling_verify on;
+
+ssl_trusted_certificate /usr/local/share/certs/ocsp-ca-certs.pem
+
+resolver 127.0.0.1;
diff --git a/roles/paas-docker/nginx/files/nginx.conf b/roles/webserver-core/nginx/files/nginx.conf
rename from roles/paas-docker/nginx/files/nginx.conf
rename to roles/webserver-core/nginx/files/nginx.conf
--- a/roles/paas-docker/nginx/files/nginx.conf
+++ b/roles/webserver-core/nginx/files/nginx.conf
@@ -1,9 +1,8 @@
 #   -------------------------------------------------------------
-#   Configuration for Docker PaaS front-end nginx
+#   nginx :: configuration
 #   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-#   Author:         Sébastien Santoro aka Dereckson
-#   Created:        2020-02-18
-#   Source file:    roles/paas-docker/nginx/files/nginx.conf
+#   Project:        Nasqueron
+#   Source file:    roles/webserver-core/nginx/files/nginx.conf
 #   -------------------------------------------------------------
 #
 #   <auto-generated>
@@ -13,12 +12,13 @@
 #       and will be lost if the state is redeployed.
 #   </auto-generated>
 
-user nginx;
+user {{ nginx_options["www_user"] }};
 worker_processes auto;
 error_log /var/log/nginx/error.log;
-pid /run/nginx.pid;
 
-include /usr/share/nginx/modules/*.conf;
+{% if "pid_path" in nginx_options -%}
+pid {{ nginx_options["pid_path"] }};
+{%- endif %}
 
 events {
     worker_connections  1024;
@@ -42,7 +42,7 @@
     server_names_hash_bucket_size 128;
 
     include       mime.types;
-    default_type  application/octet-stream;
+    default_type  text/plain;
 
     map $http_upgrade $connection_upgrade {
         default upgrade;
@@ -50,9 +50,9 @@
     }
 
     # Base
-    include /etc/nginx/vhosts/000-fallback.conf;
-    include /etc/nginx/vhosts/001-server.conf;
+    include vhosts/000-fallback.conf;
+    include vhosts/001-server.conf;
 
-    # Services hosted in containers
-    include /etc/nginx/vhosts/*/*.conf;
+    # Services hosted
+    include vhosts/*/*.conf;
 }
diff --git a/roles/webserver-core/nginx/init.sls b/roles/webserver-core/nginx/init.sls
--- a/roles/webserver-core/nginx/init.sls
+++ b/roles/webserver-core/nginx/init.sls
@@ -7,3 +7,4 @@
 
 include:
   - .software
+  - .config
diff --git a/utils/generate-ocsp-bundle.sh b/utils/generate-ocsp-bundle.sh
new file mode 100755
--- /dev/null
+++ b/utils/generate-ocsp-bundle.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+#   -------------------------------------------------------------
+#   rOPS — generate OCSP bundle with CA certificates
+#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#   Project:        Nasqueron
+#   License:        Trivial work, not eligible to copyright
+#   -------------------------------------------------------------
+
+#   -------------------------------------------------------------
+#   Let's encrypt
+#
+#   Active certificates:
+#     - Let’s Encrypt R3 - signed by ISRG Root X1
+#     - Let’s Encrypt E1 - signed by ISRG Root X2
+#
+#   Disaster recovery certificates:
+#     - Let’s Encrypt R4 - signed by ISRG Root X1
+#     - Let’s Encrypt E2 - signed by ISRG Root X2
+#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+curl -sS https://letsencrypt.org/certs/lets-encrypt-r3.pem
+curl -sS https://letsencrypt.org/certs/lets-encrypt-e1.pem
+
+curl -sS https://letsencrypt.org/certs/lets-encrypt-r4.pem
+curl -sS https://letsencrypt.org/certs/lets-encrypt-e2.pem
+
+curl -sS https://letsencrypt.org/certs/isrg-root-x1-cross-signed.pem
+curl -sS https://letsencrypt.org/certs/isrg-root-x2-cross-signed.pem