0

I've got a node.js project running locally with http2 and https. Everything is running great, I generated a self signed cert and running the app serves everything up correctly. So now i'm trying to move it to my server, which is centos running nginx, and uses proxypass to map http://myserverip:port to http://example.com. HTTP works fine and is currently running, but in my attempts to convert over to https, I haven't been able to get the site to display. Note that going to https://myserverip:port works and serves everything up, so I believe this is isolated to my nginx config.

Here is my nginx conf for this site:

server
{
  listen 80;
  listen [::]:80;
  server_name example.com www.example.com;

  location /
  {
    proxy_pass http://127.0.0.1:3103;
    include /etc/nginx/proxy_params;
  }
}

server {
  listen 443 ssl http2;
  listen [::]:443;
  server_name example.com www.example.com;

  ssl_certificate      /var/www/example.com/app/certs/example.crt;
  ssl_certificate_key  /var/www/example.com/app/certs/example.key;

  location / {
    proxy_pass https://127.0.0.1:3103;
  }
}

In my nginx log i get the following error: no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking. Seems wierd since i have the ssl_certificate & ssl_certificate_key set. One thing that does confuse me a bit is that my node server requires me to load a cert in the code, so it seems wierd to have to load the same cert twice? Here is the relevant code from my server so you can see what that is doing.

const spdyOptions = {
  key: fs.readFileSync( path.resolve(__dirname, `../certs/${certName}.key`) ),
  cert: fs.readFileSync( path.resolve(__dirname, `../certs/${certName}.crt`) )
}
// Export
module.exports = handle => {
  const server = express()

  server

    // Frontend
    .get('*', (req, res) => handle(req, res))

  spdy
    .createServer(spdyOptions, server)
    .listen(cf.port, listen)

}

Hopefully something jumps out at you that i'm doing wrong... i'm fairly new to nginx so i could just be misunderstanding something easy. If you need any more info just ask! Thanks!

  • Why are you trying to have your node app listen on https? – Michael Hampton Sep 25 '18 at 23:24
  • the spdy package (https://www.npmjs.com/package/spdy) defaults to using https. – Shan Robertson Sep 25 '18 at 23:48
  • That doesn't explain why you used it in the first place? – Michael Hampton Sep 26 '18 at 00:06
  • well, this is server fault, talking about my code is more for S/O... but `spdy` creates an http2 server that plays nice with `express` and provides fallbacks for browsers that don't support http2. – Shan Robertson Sep 26 '18 at 00:08
  • I know what it does. I don't know why you decided to add it, if you are going to be using nginx to serve TLS. You were not using it before you decided to add https and you still don't need it now. So, again, why did you add it? – Michael Hampton Sep 26 '18 at 00:41
  • again, wanted to serve over http2, and spdy plays nice with express, which is what my app is based on. as stated in my last comment. Are you going somewhere with this? If i've completely mis understood how to get my site setup with https... then are you able to help steer me on the right path? – Shan Robertson Sep 26 '18 at 04:15
  • Then why are you using nginx to terminate TLS? Or installing nginx at all? – Michael Hampton Sep 26 '18 at 16:16

1 Answers1

1

In your current configuration, you are trying to have double TLS connection: from client to nginx and from nginx to Node server.

There is no point in having two TLS connections here.

In general there are two options here:

  1. Implement the connection from nginx to Node server via normal http protocol.
  2. Use the nginx stream TCP proxy feature to proxy TLS packets as is to Node server, which then terminates the TLS connection.

I don't know how if this Node.js module does provide some extra optimisation with HTTP/2. If it does, that optimisation does not happen if you use option 1.

Option 2 has the drawback that you cannot get the client IP address on the Node application.

Tero Kilkanen
  • 36,796
  • 3
  • 41
  • 63
  • Thank you for this explanation. So do people normally have their backend serving on regular http and then use nginx solely for the https config? The app it's self doesn't have to be serving https? – Shan Robertson Sep 26 '18 at 15:24
  • Yes, the standard configuration is to have http from nginx to backend web server. – Tero Kilkanen Sep 26 '18 at 18:40