Search code examples
node.jsamazon-web-servicesexpressnginxssl

Why am I getting a 502 error when I connect to my express server over HTTPs?


The HTTPS connection to my server is not working and I can't figure out why. Every time I navigate to the default route for my server ("/"), I get a "502 Bad Gateway" error.

Here are some details about my setup:

  • I'm hosting an Express server on an Amazon EC2 Ubuntu instance.
  • The security group assigned to this instance accepts http, https, and ssh requests from anywhere.
  • I'm using nginx (v1.18.0) as a reverse proxy.
  • I obtained a SSL certificate from Zerossl.

Express app:

const app = express();

app.use(express.json());

app.use(
  cors({
    origin: ["*"],
    methods: ["GET", "PUT", "POST", "DELETE"],
    allowedHeaders: ["Origin", "Content-Type", "Authorization"],
  })
);

const httpPort = 3001;
const httpsPort = 3002;

// Read the SSL/TLS certificate and private key
const privateKey = fs.readFileSync(path.join(__dirname, process.env.SSL_FOLDER_PATH!, "private.key"), "utf8");
const certificate = fs.readFileSync(path.join(__dirname, process.env.SSL_FOLDER_PATH!, "certificate.crt"), "utf8");
const credentials = { key: privateKey, cert: certificate };

// Create an HTTPS server using the credentials
const httpsServer = https.createServer(credentials, app);

app.listen(httpPort, () => {
  console.log(`HTTP gia-trainer-server listening on port ${httpPort}`);
});

httpsServer.listen(httpsPort, () => {
  console.log(`HTTPS gia-trainer-server listening on port ${httpsPort}`);
});

app.get("/", (req, res) => {
  res.send("Hello World!!");
});

My nginx conf file (located at /etc/nginx/conf.d):

server {
        listen 80;
        server_name 3.145.91.237;

        location / {
                proxy_pass http://localhost:3001;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        #location / {
        #       return 301 https://$host$request_uri;
        #}
}

server {
        listen 443 ssl;
        server_name 3.145.91.237;

        ssl_certificate /home/ubuntu/ssl/gia-trainer/certificate.crt;
        ssl_certificate_key /home/ubuntu/ssl/gia-trainer/private.key;

location / {
                proxy_pass http://localhost:3002;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                # Additional proxy settings if needed
                #proxy_read_timeout 300s;
                #proxy_connect_timeout 75s;
        }
}

I checked the nginx error logs and this is what I get when I make a request:

2023/06/23 20:50:49 [error] 56080#56080: *1 upstream prematurely closed connection while reading response header from upstream, client: 176.27.127.113, server: 3.145.91.237, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:3002/", host: "ec2-3-145-91-237.us-east-2.compute.amazonaws.com"

Any ideas about what might be causing this error? I've spent two whole days trying to sort this issue out, tinkering with the config files endlessly. It was working fine with just plain old HTTP :(

Thanks all


Solution

  • Your Nodejs server is serving data as SSL encryption but your Nginx server is proxy to non SSL server. Change

    proxy_pass http://localhost:3002;
    

    To

    proxy_pass https://localhost:3002;