• Please be aware: Kaspersky Anti-Virus has been deprecated
    With the upgrade to Plesk Obsidian 18.0.64, "Kaspersky Anti-Virus for Servers" will be automatically removed from the servers it is installed on. We recommend that you migrate to Sophos Anti-Virus for Servers.
  • The Horde webmail has been deprecated. Its complete removal is scheduled for April 2025. For details and recommended actions, see the Feature and Deprecation Plan.
  • We’re working on enhancing the Monitoring feature in Plesk, and we could really use your expertise! If you’re open to sharing your experiences with server and website monitoring or providing feedback, we’d love to have a one-hour online meeting with you.

Input PLESK reaches the stars with only Nginx + HSTS (390%)

Dukemaster

Regular Pleskian
ONLY NGINX on PLESK without Apache (reverse proxy)

A+ Grade HSTS 390% .jpg A+ HSTS Preload List Chrome + Mozilla + Edge+IE11 + Safari + Opera .jpg


Ladies & Gentlemen,
Here is the conclusion of the work of all developers, supporters, members:
Yes, it's possible, only the ciphers make the difference in the result (%). But in this case more percent means also less compatibility and access with older browsers, devices and OS's, which means to left hungry visitors outside.
Hereby I will be show what amazing is possible. The last 10% would be also no problem, BUT this will be a kind of desaster for performance (site loading speed), accessibility like mentioned before, and other problems according to cross-dependecies.
Thanks PLESK and all of You for making this interesting puzzle. All of my 8 sites with the following configuration are accepted as pending for the chrome preload list.

  • Update OpenSSL to the most common version, provided by operation system vendor

  • Change "Apache and Nginx" settings to Nginx only, static files served by Nginx, FPM PHP 7.1.8 will be automatically set to served by Nginx

  • Do not select www. in hosting settings (top), also not in PLESK server settings. Set it to "nothing" as third option. Redirection to subdomain www. will be realized only in additional nginx settings. In order to have the redirection to SSL with HSTS header first, and then redirecting both together to the subdomain. This is important for the chrom preload list check, otherwise you get an error similar to "HSTS is also set unnecessarily for http".

  • Plesk panel.ini certificate setting rsa-key-size 4096 is one of the important changes.
    Code:
    [ext-letsencrypt]
    renew-before-expiration = 45
    rsa-key-size = 4096

  • Additional Nginx settings (Domain - Apache and Nginx) Thanks to @UFHH01 and @Lloyd_mcse :
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /usr/local/psa/var/modules/letsencrypt/etc/live/example.com/fullchain.pem;
    resolver 8.8.4.4 8.8.8.8 valid=300s;
    resolver_timeout 10s;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options nosniff;
    if ($scheme !~* ^https ){
    rewrite ^ https://www.example.com$request_uri? permanent;
    }
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
    if (!-e $request_filename)
    ...with a little more included which is not related to ratings (like redirect and things I would better not recommend)

  • own_additional_ssl_hsts_.conf (/etc/nginx/conf.d/), provided by @mr-wolf, @UFHH01 and me (only 6th and 8th column)
    Code:
    map $scheme $hsts_header {
        https 'max-age=15768000; preload';
    }
    ssl_session_timeout 10m;
    ssl_session_cache shared:SSL:50m;
    ssl_session_cache shared:ssl_session_cache:10m;
    ssl_dhparam /etc/dhparam/dhparam4096.pem;
    ssl_ecdh_curve secp521r1:secp384r1:prime256v1;


  • gzip.conf: (/etc/nginx/conf.d/) greatly provided and recommended by @UFHH01 (for great performance but not necessary for this kind of rating)
    Code:
    gzip on;
    gzip_disable "MSIE [1-6]\\.(?!.*SV1)";
    gzip_proxied any;
    gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon image/bmp image/svg+xml image/gif image/jpeg application/atom+xml application/javascript image/png image/tiff image/x-ms-bmp application/font-woff application/json application/msword application/pdf application/postscript application/rtf application/vnd.apple.mpegurl application/vnd.ms-excel application/vnd.ms-fontobject application/vnd.ms-powerpoint application/vnd.wap.wmlc application/vnd.google-earth.kml+xml application/vnd.google-earth.kmz application/x-7z-compressed application/x-cocoa application/x-java-archive-diff application/x-perl application/x-rar-compressed application/x-shockwave-flash application/x-tcl application/x-x509-ca-cert application/xhtml+xml application/xspf+xml application/zip application/octet-stream audio/midi audio/mpeg audio/ogg audio/x-m4a audio/x-realaudio video/3gpp video/mp2t video/mp4 video/mpeg video/quicktime video/webm video/x-flv video/x-m4v video/x-mng video/x-ms-asf video/x-ms-wmv video/x-msvideo;
    gzip_vary on;
    gzip_comp_level 9;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 1000;


  • ssl.conf (/etc/nginx/conf.d/) already posted by @UFHH01 and/or @IgorG especially with the included ciphers, for only 485% but better compatibility with TLS 1.2, TLS 1.1 and TLS 1.0 (another long, long list I found somewhere else)
    With the following cipherlist you get 390%
    Code:
    EECDH+AESGCM+AES128:EECDH+AESGCM+AES256:EECDH+CHACHA20:EDH+AESGCM+AES128:EDH+AESGCM+AES256:EDH+CHACHA20;


Here is a CIPHER LIST for more compatibility according to protocol support [TLS 1.2, TLS 1.1, TLS 1.0] for more access for visitors with older browsers and devices ---> You will catch 385%

A+ Grade HSTS 385% .jpg

Code:
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
_______________________________________________________

Never forget to test nginx by
Code:
nginx -t
and restart or reload nginx afterwards
Code:
service nginx restart
(or reload)
________________________________________________________

What I did to be sure: Restarting the whole server by Shell in the end, minimum restart Nginx and Apache.
Before starting it's a good idea to check PLESK Database for all certificates if everything is correct and no "NULL"-entries or double certificates by
Code:
plesk db "select c.id, c.name, r.rep_id, d.name from certificates c left join Repository r on (c.id = r.component_id) left join domains d on (r.rep_id = d.cert_rep_id) where r.rep_id not in (select val from misc where param = 'cert_rep_id') or r.rep_id is null"
Before doing are short
Code:
# updatedb
In the very end I Renewed ALL CERTIFICATES
1. Certificates for "Nginx only" domains and subdomains, and also
2. "Let's encrypt certificate for PLESK" the main and one and only certificate for Hostname+IP+PLESK+Email certificate.
That's really not necessary but I'm a kind of control and security freak. :)

PLESK is amazing and also this community ! ! !
 
Last edited:
The map command is not doing anything in the way you implemented it.
It just creates a variable now, which should later be used, but you're not doing that..

You should not use
Code:
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;

You should use

Code:
add_header Strict-Transport-Security $hsts_header always;

I would create 2 variables. 1 with the IncludeSubDomains and another one without.

Having these 2 variables defined you can use them later on for each site different.
Some domains want to use it for the subdomains and some not.

For preloading the "IncludeSubDomains" is imperative, so you could leave that part out of the header when doing it only on the domain itself.

By using the variable instead of the literal text you prevent the header to be sent with the plain connection. Doing so would, according to the RFC, be incorrect behavior.
That's the trick with using "map"


Code:
map $scheme $hsts_header {
    https   'max-age=15768000';
}
map $scheme $hsts_is_header {
    https   'max-age=15768000; includeSubDomains; preload';
}
 
Last edited:
Back
Top