Чтобы создать безопасный сервер со связкой NGINX+NodeJS, а также, чтобы была возможность использовать http2 протокол передачи данных, необходимо выполнить следующее:

Внимание! Доменное имя должно быть делегировано, активно и подключено к Вашему серверу!
Файлы сертификатов для NodeJS и NGINX должны быть идентичны и могут находится в одной и той же папке.
PATH далее - это полный путь от корня к папке, где лежат файлы необходимого сайта, к примеру /var/www/example.com/

Как получить сертификат смотрите в этой статье.

1. Создайте TLS сертификат.

На сайте https://www.sslforfree.com необходимо создать соответствующие сертификаты по инструкции, которая там указана, либо получить сертификат как-то иначе.

Далее Вам необходимо из файла ca_bundle.crt скопировать его содержимое в файл certificate.crt, чтобы получилось так:

2. Создайте dhparam.pem

При этом файлы certificate.crt и private.key должны находиться в той же директории (например: /etc/nodejs/ctr/), куда Вы указываете создание dhparam.pem (взять эти файлы нужно в скачанном архиве с сайта sslforfree.com).

openssl dhparam -out /PATH/dhparam.pem 4096

После длительного ожидания, выполните следующие пункты...

3. Запустите nodejs скрипт (сохраните файл в директории 'example.com' > [с именем, к примеру] = server.js)

const https = require('https')
const fs = require('fs')
const hostname = 'example.com'

const options = {
key: fs.readFileSync('/PATH/private.key'),
cert: fs.readFileSync('/PATH/certificate.crt'),
dhparam: fs.readFileSync("/PATH/dhparam.pem"),
hostname
}

https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(5000)

Команда для запуска nodejs скрипта:

node /PATH/server.js

4. Создайте NGINX конфигурацию:

server {
server_name example.com;
rewrite ^(.*) https://example.com$1 permanent;
}

server {
listen 80;
# redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}

server{
if ($http_host != "example.com") {
rewrite ^ https://example.com$request_uri permanent;
}

server_name_in_redirect off;
expires $expires;

if ($request_method !~ ^(GET|HEAD|POST)$ ){return 444;}
server_tokens off;
listen 443 ssl http2;

ssl_certificate /PATH/certificate.crt;
ssl_certificate_key /PATH/private.key;
ssl_dhparam /PATH/dhparam.pem;

server_name example.com;

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
http2_push_preload on;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK;
#add_header Strict-Transport-Security max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;

root /PATH/example.com;
charset utf8;

location ~ \.(eot|ttf|otf|woff|woff2)$ {
add_header Access-Control-Allow-Origin *;
access_log off;
expires 365d;
}

location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|pdf|ppt|txt|docx|doc|rtf|js|ttf|otf|woff2|eot|svg|woff)$ {
access_log off;
expires 365d;
}

location ~* ^.+\.(jpg|txt|docx|doc|js)$ {
valid_referers none blocked
example.com www.example.com;

if ($invalid_referer) {
rewrite ^/ https://example.com/errorvps?rq=$request&rf=$http_referer&st=$status;
}
}

location ~ \.mp4${
valid_referers none blocked
example.com www.example.com;

if ($invalid_referer) {
rewrite ^/ https://example.com/sys/errorvps?rq=$request&rf=$http_referer&st=$status;
}
mp4;
if ($request_filename ~* ^.*?/([^/]*?)$){
set $filename $1;
add_header Content-Disposition "attachment; filename=$filename";
}
}

location ~ \.flv${
valid_referers none blocked
example.com www.example.com;

if ($invalid_referer) {
rewrite ^/ https://example.com/sys/errorvps?rq=$request&rf=$http_referer&st=$status;
}
flv;
}

location / {

proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass https://example.com:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;

}

location @missing {
rewrite ^ $scheme://$host/ permanent;
}

error_page 404 /?rq=$request&rf=$http_referer&st=$status;
error_page 403 /?rq=$request&rf=$http_referer&st=$status;
error_page 405 /?rq=$request&rf=$http_referer&st=$status;
error_page 415 /?rq=$request&rf=$http_referer&st=$status;
error_page 401 /?rq=$request&rf=$http_referer&st=$status;
error_page 402 /?rq=$request&rf=$http_referer&st=$status;
error_page 500 /?rq=$request&rf=$http_referer&st=$status;

}
##SERVER

5. Перезапустите nginx:

sudo service nginx reload

6. Попробуйте открыть example.com в своем браузере.

https://example.com

проверка работоспособности https http2 nodejs+nginx

Проверка http2

echo | openssl s_client -alpn h2 -connect example.com:443 | grep ALPN

Ответ

depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = example.com
verify return:1
DONE
ALPN protocol: h2

Проверить http2 онлайн: https://tools.keycdn.com/http2-test

Посмотреть, что поддерживает Ваш сервер по TLS: https://www.ssllabs.com/ssltest/index.html