I am trying to configure re-encryption on a backend, so that traffic between nginx and the upstream app is encrypted separately from traffic between the user and nginx. For the purpose of a test example, I am using this: https://github.com/jlengstorf/tutorial-deploy-nodejs-ssl-digitalocean-app.git. I have read many threads, but I always end up getting Error 502: Bad Gateway. Also, I am not sure how paranoid it is to even bother with this. Everything is on one host, but I will be running several services and my reasoning is that any one of them might have exploits and that risk could be mitigated by each app communicating with nginx under a different certificate. To keep the example simple, I just used one key for Everything. Obviously if I were doing this for real I would make a new certificate for each instance of re-encryption. I'm new to web hosting and thinking about security, so please let me know if I said anything cringy above.


# HTTP — redirect all traffic to HTTPS
server {
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    root /var/www/html;
    index test_index.html;
    return 301 https://$host$request_uri;

# HTTPS — proxy all requests to the Node app
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name mydomain.com;
    root /var/www/html;
    index test_index.html;
    # Use the Let’s Encrypt certificates
    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    # Include the SSL configuration from cipherli.st
    include snippets/ssl-params.conf;
    location /app {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass https://localhost:5000/;
        proxy_ssl_verify on;
        proxy_ssl_trusted_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
        proxy_ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
        proxy_ssl_session_reuse off;
        proxy_set_header Host $http_host;
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;

The corresponding error from /var/nginx/error.log:

2020/10/22 16:17:13 [error] 11311#11311: *1 SSL_do_handshake() failed
(SSL: error:1408F10B:SSL routines:ssl3_get_record:wrong version number
) while SSL handshaking to upstream, client: xx.xxx.xx.xx, server: the
3guys.com, request: "GET /app HTTP/1.1", upstream: "
5000/", host: "mydomain.com"

In ssl-params.conf snippet included in the nginx site conf, I set to use all versions of TLS that I am aware of:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
  • Your backend server uses a ssl/tls version nginx can't handle. Most probably it's too old, the example you are using hasn't been updated since 2016. – Gerald Schneider Oct 22 '20 at 16:36
  • 3
    What's the point of encryption for purely local traffic? Nobody but the kernel sees it anyway. – Michael Hampton Oct 22 '20 at 16:36
  • @MichaelHampton I plan to run multiple services exposed to the web. It was my understanding that if one of them has a vulnerability that gets exploited, the backend ssl will protect data from the other apps. Is that incorrect? – Stonecraft Oct 22 '20 at 16:41
  • @GeraldSchneider but I configured nginx to use older versions in my ssl-params.conf. Shouldn't it be able to handle any older version of ssl/tls? – Stonecraft Oct 22 '20 at 16:44
  • 1
    If you haven't configured permissions correctly, then perhaps. But that has nothing to do with TLS. Such users wouldn't be able to sniff any network connections. – Michael Hampton Oct 22 '20 at 23:54

In general there is absolutely no security benefit to encrypting traffic between services running on the same host.

(Localhost traffic can only be intercepted by an attacker that has full access to the server. When they can do that they can already access all data stored on your server directly (from the file system) and won't need to bother with intercepting traffic.)

Your error messages seems to indicate that you tried converting your existing connection to your app server by switching from

    proxy_pass http://localhost:5000/;


    proxy_pass https://localhost:5000/;

Without actually converting the backend to actually run https.

Generally you also cannot run http and https services concurrently on the same port.

To connect to your Node.js application over https you first need to configure that it actually loads a certificate and starts supporting https.

Then proxy_ssl_verify on is probably not good idea either in combination with proxy_pass https://localhost as you cannot get public TLS certificates for the localhost domain name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.