skip to Main Content

after around 12 hours of continuously trying a lot of things including asking Copilot I finally quit and made up mind to ask this.
I am having problem while running nodejs app.js on my server.

My server config are as follows:

  • Server type: VPS
  • OS: Linux: Ubuntu 24.x
  • WebHost Manager: Webuzo
  • Application handler: Webuzo’s default, (although it has "passenger" too)
  • SSL: present, active, forced for all domains
  • App file: app.js
  • Webserver: OpenLiteSpeed
  • App port (as defined by handler and in code): 30000

Now, if I run nodemon app.jsfrom cli or run the start from app handler in the interface. The application runs fine when the port is set to 30000 with express and no https configured.
Application is visible on:

  1. example.com – LiteSpeed redirects it to https://example.com (I believe that’s reverse proxy working on its own) as the https is forced on all domains. [Note: this is without implementing https.createServer or even importing it in my app.js file]
  2. example.com:30000 – this is accessible on http:// which is what I wanted to be on https:// even if someone wants to access http:// on port 30000.

In the debugging/workaround things which I did to achieve, I added the https.createServer after importing https and defining the cert and key files in options.

Now what happened:

  1. example.com:30000 goes to https://example.com:30000 without hassle. Application is accessible/visible there.
  2. But now my default domain is broken i.e. http://example.com and https://example.com both are inaccessible (keeps on loading). [seems litespeed reverse proxy messed up]

My code:

import https from "https";
import http from "http";
import fs from "fs";
import express from "express";
import path from "path";
import { dirname } from "path";
import url from "url";
import {fileURLToPath} from "url";
import bodyParser from "body-parser";
import morgan from "morgan";
import "dotenv/config";



const app = express();
const httpApp = express();
const __dirname = dirname(fileURLToPath(import.meta.url));


var visitor = 1;
const port = 30000;

app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));


// app.use((req, res, next) => { if (!req.headers.host.startsWith('www.')) { return res.redirect(301, 'https://www.' + req.headers.host + req.url); } next(); }); 


const options = {
    key: fs.readFileSync(path.resolve("example.com.key")),
    cert: fs.readFileSync("example.com.crt"),
    ca: fs.readFileSync(path.resolve("example.com-ca.crt"))
};



const httpsOptions = {
    key: fs.readFileSync("example.com.key"),
    cert: fs.readFileSync("example.com.crt")
};
httpApp.set('port',30001);
httpApp.get("*", function (req, res, next) {
    res.redirect("https://" + req.headers.host + "/" + req.path);
});



function logger(req, res, next){
    console.log("Request method: ", req.method);
    console.log("Request URL:", req.url);
    next();
}


app.use(morgan("tiny"));

//request method
app.use(logger);


app.post("/submit", (req, res) => {
    console.log(req.body);
    console.log(req.body.name);
    var name = req.body.name;
    var email = req.body.email;


    res.send(`<h1>Hey ${name} with email id ${email}, we got your message, unfortunately we are unable to serve at this moment. </h2>`)
});


app.get('/', (req, res) => {
    console.log(visitor);   
    res.sendFile(__dirname + "/public/index.html");
        
    
});





app.get('/test', (meow, bhow) => {
    bhow.send("Testing works on Http2?");
        // bhow.sendStatus(200);

});



app.use((req, res, next) => {


//   res.status(404).render('status');
  res.status(404).send(`<h1><center> The location <a href="https://${req.hostname}${req.originalUrl}">${req.hostname}${req.originalUrl}</a> is not available at this moment. <br><br> That's a 404 Not Found Error</h1></center>
    <center>
    <h2> Let's go back to home @ <a href="https://example.com">${req.hostname}</a></h2></center>`);
});




 




 




const servinginSSL = https.createServer(options, app);

servinginSSL.listen(30000, ()=>{
    console.log("Running at port 30000");
});




// http.createServer((req, res)=>{
//     res.writeHead(301, {"Location": `https://${req.headers.host}${req.url}`});
//     res.end();
// }).listen(30000, () => {
//     console.log("Http server ran and redirecting to HTTPS")
// });




// app.set('port', 30000);
// app.enable('trust proxy');

// http.createServer(httpApp).listen(httpApp.get('port'), function() {
//     console.log('Express HTTP server listening on port ' + httpApp.get('port'));
// });

// https.createServer(httpsOptions, app).listen(30000, function() {
//     console.log('Express HTTPS server listening on port ' + "30000");
// });







// app.listen(port, () => {
//     console.log(`Running at ${port}`);
// });

I’ve tried a couple of solutions with changing proxy, rewrite rules of litespeed but nothing worked.

while not implementing https.createServer and just going with app.listen(30000, ....) seems to work fine when example.com is accessed which automatically goes to https://example.com.
I am just worried that port 30000 is also accessible without http which will make my app directly vulnerable anyway.

The stackoverflow answer which I tried: How can I adjust my NodeJs server code to responf to HTTPS requests?

Please help. I am a

2

Answers


  1. Chosen as BEST ANSWER

    😭 I found a way and it's working as intended. I am still not sure if it's right method (since I am new to vhost customization and all) but here you go:

    I just edited the vhost files for my example.com for port 80 (vhost.conf) in litespeed folder.

    What I changed in the file was a simple line of code:

    extprocessor 30000 {
      type                    proxy
      address                 https://127.0.0.1:30000
      env             NODE_ENV=production
      maxConns                5 
      initTimeout             20
      retryTimeout            20
      respBuffer              0
    }
    

    I just changed the address 127.0.0.1:30000 to address https://127.0.0.1:30000

    Now, example.com is:

    • Firefox - redirects to https://example.com without problems, working.
    • Chrome/Edge/Brave - redirects to https://example.com without problems, working.

    https://example.com is

    1. Firefox - working without problems
    2. Edge/Brave/Chrome - working without problems

    http://example.com:30000 is

    https://example.com:30000 is

    • Working across all browsers.

    this was done with nodejs using:

    https.createServer(options, app).listen(30000, ()=>{
    console.log("Running at port 30000");
    });
    

    and in options:

    const options = {
        key: fs.readFileSync(path.resolve("example.com.key")),
        cert: fs.readFileSync("example.com.crt"),
        ca: fs.readFileSync(path.resolve("example.com-ca.crt"))
    };
    

    ca file(s) might not be available under your control panel's ssl folder. Mine works even when I omit the ca key-value pair.

    P.S. Last night copilot broke my brain after serving me an answer where the code asked http and https to listen to port 30000, and then copilot itself said one port cannot be assigned to two different things. 😭 I quit copilot then and there.


  2. Reverse Proxy Method

    I assume you are using the rewrite method to implement the reverse proxy with that "30000" External Applications.

    RewriteRule ^(.*)$ HTTPS://30000/$1 [P,L,E=PROXY-HOST:EXAMPLE.COM]
    

    If you simply want to force all traffic to HTTPS, then you can use rewrite cond, e.g. RewriteCond %{HTTPS} off to force it.

    If you can make your nodejs app support both HTTP and HTTPS, then you can create additional External Applications for it.

    extprocessor 30001 {
       type                    proxy
       address                 http://127.0.0.1:30001
       env             NODE_ENV=production
       maxConns                5 
       initTimeout             20
       retryTimeout            20
       respBuffer              0
     }
    

    Rewrite Rule example will become like this,

    RewriteCond %{HTTPS} !=on
    REWRITERULE ^(.*)$ HTTP://30001/$1 [P,L,E=PROXY-HOST:EXAMPLE.COM]
    RewriteRule ^(.*)$ HTTPS://30000/$1 [P,L,E=PROXY-HOST:EXAMPLE.COM]
    

    App context method

    Set up an App Server Context by following the OpenLiteSpeed NodeJS Context Guide, and let OLS handle the HTTP and HTTPS for you. In this case, OLS proxy traffic to Node.JS directly, and you don’t need to worry about Rewrite, HTTP, and HTTPS configuration issues.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search