0

I have a running Node app that is live and works fine on http and https.

I setup Nginx and it is also running fine, tested with an sshtunnel, and it is getting a correct response from static files (such as MyPath/index.html).

However, I am trying to get Nginx to work as a reverse-proxy for Node. Because I want to make another app on my machine, and Nginx should sort the incoming requests for each app.

But there seems to be an issue with Nginx I cannot figure out. I suspect it is a config problem. When I try to reach my Node app through SSH tunnel on localhost, instead of getting a webpage, I am always getting an error page from my browser, saying:

This site can’t provide a secure connectionlocalhost sent an invalid response. ERR_SSL_PROTOCOL_ERROR.

When I try to reach it from WAN, it just times out.

Nginx config

server {
        listen [::]:4444 default_server;
        server_name localhost mysite.com www.mysite.com;    

        access_log /home/mysite/access-log;    

        location / {
            proxy_pass http://127.0.0.1:5555;
        }
}    

I tried changing http://127.0.0.1:5555 to https://127.0.0.1:6666 but that didn't change anything.

Node app

const port = 5555;
const secureport = 6666;    

...

const privateKey = fs.readFileSync('PATHTOCERT');
const certificate = fs.readFileSync('PATHTOKEY');
const credentials = {key: privateKey, cert: certificate};    

... I use an express app instance here, also configured CSP with helmet. But I don't think that's the problem, because I disabled helmet and that did not solve anything. ...

const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);    

httpServer.listen(port);
httpsServer.listen(secureport);
jlanssie
  • 21
  • 2
  • 7
  • 1
    What is the actual problem you are having? No vague descriptions please; copy and paste exactly. – Michael Hampton Feb 28 '21 at 02:11
  • My problem is that when I visit my Nginx port, I don't get my webpage from Node. On my SSH tunnel, displays an error, that SSL certificates not correct. And from WAN, it just doesn't connect and I get a timeout error. – jlanssie Feb 28 '21 at 19:47
  • You haven't shown any nginx SSL configuration? – Michael Hampton Feb 28 '21 at 19:56
  • The only config I have is the one in the server block.There is an ssl config in Node, though. – jlanssie Feb 28 '21 at 20:09
  • It sounds like you have multiple issues here. The most important one is that you seem to be hosting from home, which we do not recommend or support. – Michael Hampton Feb 28 '21 at 22:56
  • Why would that be an issue? What's the difference for Nginx between hosting from home and hosting from a server park? The OS is Ubuntu Server 20.04, just like some servers in server parks are running. My ISP allows me to configure my home router for my home server, which works perfectly for Node and Apache, so I really don't see the problem with the setup. – jlanssie Mar 01 '21 at 12:19

1 Answers1

0

I figured out my problem. There was an issue that the SSL-certificates were never valid because the domain name "localhost" or the ip-address (MyIP) obviously did no match the certificate records. I had to put it on my "live server" to check if it worked (a small leap of faith). :-)

I now have it working with the following config in Nginx.

/etc/nginx/nginx.conf

#user www-data;
user $nginxuser $nginxusergroup;
worker_processes auto;
#pid run/nginx.pid
include /etc/nginx/modules-enabled/*.conf;

I changed the user for worker processes of Nginx, for improved security. I would have liked to run Nginx entirely with a user without root-privileges, but that threw several errors. Something I will look into later. After changing the user, I also had to comment out the pid-directive, because it posed problems. The rest of the main config file was untouched, except for the logs locations.

for HTTPS:

/etc/nginx/sites-available/mysite-ssl

(with a symbolic link from sites-enabled to this file)

server {
        # Ports
        listen 4444 ssl http2 default_server;
        listen [::]:4444 ssl http2 default_server;    

        # Server name
        server_name localhost example.com www.example.com;    

        # SSL
        ssl_certificate     /mypath/fullchain.pem;
        ssl_certificate_key /mypath/privkey.pem;    

        # Logs
        access_log /mypath/access.log;
        error_log /mypath/ssl-error.log;    

        location / {
                proxy_pass https://127.0.0.1:6666;
                proxy_redirect https://127.0.0.1:6666 https://www.example.com;    

                proxy_set_header Host $host;
                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;
        }
}

for HTTP:

/etc/nginx/sites-available/mysite

(with a symbolic link from sites-enabled to this file)

server {
        # Ports
        listen 3333 default_server;
        listen [::]:3333 default_server;    

        # Server name
        server_name localhost example.com www.example.com;      

        # Logs
        access_log /mypath/access.log;
        error_log /mypath/error.log;    

        location / {
                proxy_pass http://127.0.0.1:5555;
                proxy_redirect http://127.0.0.1:5555 http://www.example.com;    

                proxy_set_header Host $host;
                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;
        }
}

And my node app has the following (unchanged) config:

const port = 5555;
const secureport = 6666;    

...

const privateKey = fs.readFileSync('PATHTOCERT');
const certificate = fs.readFileSync('PATHTOKEY');
const credentials = {key: privateKey, cert: certificate};

...

This part redirects http to https inside Node:

app.use(function (req, res, next) {
  if(!req.secure) {
    return res.redirect(301, ['https://', req.get('Host'), req.url].join(''));
  }
  next();
});

... An express-powered app ...

const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);    

httpServer.listen(port);
httpsServer.listen(secureport);

After restarting the node and nginx services, this setup is working for me on https and http.

jlanssie
  • 21
  • 2
  • 7