nextJS / NodeJS keeps triggering ip_ban - node.js

So not sure why, but my nodeJS / NextJS app keeps triggering plesks ip_ban. I recoded our site and moved it away from ReactJS to NextJS. But seems by doing so their must be a command that is making it look like an IP address is trying to connect to many times which makes the plesk server add the IP to a ban list (the rule that keeps getting triggered is - recidive).
I am wondering what is the correct way to solve this issue. Disabling ip_ban is a temp solution but not the ideal solution.
my server.js script is very clear and has no issues (once ip_ban is disabled).
const { createServer } = require("http");
const { parse } = require("url");
const next = require("next");
const dev = process.env.NODE_ENV !== "production";
const port = !dev ? process.env.PORT : 3000;
// Create the Express-Next App
const app = next({ dev });
const handle = app.getRequestHandler();
app
.prepare()
.then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
handle(req, res, parsedUrl);
console.log("pathname", pathname);
}).listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://example.com:${port}`);
});
})
.catch((ex) => {
console.error(ex.stack);
process.exit(1);
});
The rule that keeps getting triggered:
[recidive]
enabled = true
filter = recidive
action = iptables-allports[name=recidive]
logpath = /var/log/fail2ban.log
maxretry = 3

Related

Express app failing to connect without errors

I have been trying to connect my express app, but for some reason it is just not connecting.
I am going to "IP:PORT" on chrome and I get a typical "Refused to connect" error.
I am using node.js, and the latest version of express.
"Received" does not print to the console, however it logs "App listening on port 8088"
I have tried a lot of things, hosting on digital ocean, no connection. I am currently trying it in VSC (Ip address is my ipv4 address)
When trying using HTTP, I get a connect fail error.
My code:
const express = require('express');
const app = express()
app.use(express.json())
const fs = require('fs');
require('dotenv').config()
const serverKey = process.env.SERVER_KEY
const port = process.env.PORT
function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
}
module.exports = {
async execute(client) {
console.log('Test')
app.post("/getVerificationCode", function (req, res, next) {
console.log("Recieved")
if (req.body.serverKey !== serverKey) {
console.log("Invalid serverKey supplied.")
return res.status(403).json({
error: "You do not have permission to use this."
})
}
let verificationCode = randomString(4, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ').toUpperCase()
const userID = parseInt(req.body.userid)
console.log(verificationCode)
client.verificationCodes[userID] = {
code: verificationCode
}
fs.writeFile("./codes.json", JSON.stringify(client.verificationCodes, null, 4), err => {
if (err) throw err
})
return res.status(200).json({
VerificationCode: verificationCode
})
})
app.get("/*", function (req, res, next) {
return res.status(200).json({})
})
app.listen(port)
console.log(`App listening on port ${port}`)
}
}
"Test" does log, so the module IS being required. Before, I was trying it in my server.js, but that did not work and the code was messy, so I moved it into a folder.
I would really appreciate some help, thank you!

Problem with publication Next js project on Digital Ocean droplet

I'm trying to run Next js application on my Digital Ocean Droplet (with OpenLiteSpeed).
I have start.js file with the following content:
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
handle(req, res, parsedUrl)
}).listen(80, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:80')
})
})
When I calling this file from console: node start.js, my site successfully running on port 80.
But when I'm trying to add this file as a start up file in App Server Context Definition, site is not running, and my website just cannot be reached.
But when I'm changing the file to default one (app.js):
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World! From OpenLiteSpeed NodeJS\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://:/`);
});
The website is successfully opening with Hello World.
Listener is successfully setup to port 80:
Grace restart is done. changing ports to 3000 (for example) not helping much: I got same behavior.
What I am doing wrong?
UPDATE:
I found temporary solution:
node start.js & disown
and then close the Terminal.
Please anyone give me drawbacks of this method.

Automatic exit - NodeJS https webserver

To elaborate on the question in the title,
I have made a simple app with js that runs on a node server. I have a thumbdrive that contains a folder and a start.bat file. Start.bat, as the name implies, switches the directory to my server folder and starts the server. Start.bat also starts another process that opens the edge browser to localhost in kiosk mode. When a user starts start.bat, the app will appear on the screen with the server running in the background. When the user exits the edge browser, they are then required to CTRL + C out of the server cmd prompt to properly shut down the server.
I need a system which effectively automatically shuts down the server after the Edge browser has been closed. I am not sure if it is possible to tie together the closing of the browser and the node server and am yet to find a solution online. If anyone has any ideas regarding possible fixes to my problem I would love to hear it!
https-server.js
const https = require("https");
const path = require("path");
const fs = require("fs");
const ip = require("ip");
const process = require("process");
const app = express();
const port = 443;
process.chdir("..");
console.log("Current working dir: " + process.cwd());
var rootDir = process.cwd();
//determines what folder houses js, css, html, etc files
app.use(express.static(rootDir + "/public/"), function (req, res, next) {
const ip = req.ip;
console.log("Now serving ip:", "\x1b[33m", ip, "\x1b[37m");
next();
});
//determines which file is the index
app.get("/", function (req, res) {
res.sendFile(path.join(rootDir + "/public/index.html"));
});
var sslServer = https.createServer(
{
key: fs.readFileSync(path.join(rootDir, "certificate", "key.pem")),
cert: fs.readFileSync(path.join(rootDir, "certificate", "certificate.pem")),
},
app
);
//determines which port app (http server) should listen on
sslServer.listen(port, function () {
console.log(
"Server has successfully started, available on:",
"\x1b[33m",
ip.address(),
"\x1b[37m",
"listening on port:",
"\x1b[33m",
+port,
"\x1b[37m"
);
console.log("CTRL + C to exit server");
sslServer.close();
});
Will provide any needed information.
Have an endpoint registered to exit the process
app.get('/shutdown', (req, res, next) => {
res.json({"message": "Received"});
next();
}, () => {
process.exit();
});
Then register a listener for onbeforeunload to do a request to this endpoint.
let terminateCmdReceived = false;
async function shutdown(e) {
let response;
if (!terminateCmdReceived) {
e.preventDefault();
try {
response = await fetch('http://localhost:3000/shutdown');
const json = await response.json();
if(json.message === "Received") {
terminateCmdReceived = true;
window.close();
}
} catch (e) {
console.error("Terminate Command was not received");
}
}
}
window.onbeforeunload = shutdown

How to remove x-powered-by header in nextjs custom server

I'm using Next to create a web app, and I want to remove x-powered-by from response header, I tried to create custom server and use expressjs .disable('x-powered-by') but it didn't work.
here is what I've done:
const express = require('express')
const next = require('next')
const port = parseInt(process.env.PORT, 10) || 3001
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare()
.then(() => {
const server = express()
.use(handle)
server.disable('x-powered-by'); // ???
server.listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
For me when I use server.disable('x-powered-by');, was ended up with Next.js 7.0.2 as x-powered-by value.
adding below line in next.config.js should work
module.exports = {
poweredByHeader: false,
...
}
or
const app = next({ dev, xPoweredBy: false })
The following code works. What you are doing here is correct to remove X-Powered-By header from Express. Because you are using Next you need to disable both Next and Express X-Powered-By header.
I did not find api from Next to disable. But you can directly change the object app.config.poweredByHeader = false
const express = require('express')
const next = require('next')
const port = parseInt(process.env.PORT, 10) || 3001
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.config.poweredByHeader = false
app.prepare()
.then(() => {
const server = express().use(handle)
server.disable('x-powered-by'); // This disables Express Header
server.listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
Well, if you dont want to return this header you have to simply write
res.removeHeader('header-name'); //any header that you want to remove
So you need to write
res.removeHeader('X-Powered-By');
in the End Point
It's very simple now.
By default Next.js will add the x-powered-by header. To opt-out of it, open next.config.js and disable the poweredByHeader config:
module.exports = {
poweredByHeader: false,
}
See - https://nextjs.org/docs/api-reference/next.config.js/disabling-x-powered-by

Why does my Node application keep sending data after every refresh?

I am using node.js and express.js to build a very simple application. I want to read the content of a directory and when I browse to localhost:3000/names, the application will print an array of the content to the web page except for the content that I choose not to. Here is my code:
const express = require('express');
const fs = require('fs');
const app = express();
const port = 3000;
let result = [];
app.get('/names', (req, res) => {
const printNames = (err, file) => {
file.forEach(e => {
if (e !== 'john') {
result.push(e);
}
});
res.send(result);
};
fs.readdir('./home', printNames);
});
app.listen(port, () => {
console.log('Listening on port 3000');
});
The application works the way that I wanted to, but there is a small bug. Every time I refresh the page, the application will add on the same content of the array to the existing array. My array keeps getting bigger with every refresh. I want the application to send the array to the page and will stay the same when I refresh. I do not have the slightest idea why my application is behaving this way. Can someone explain to me why it is behaving like this and what would be the right steps to fix this?
It is because you've declared your result array in the global scope.
Your result array is getting bigger and bigger every time.
Simply move the declaration to your route and you should be fine.
This should work fine:
const express = require('express');
const fs = require('fs');
const app = express();
const port = 3000;
// let result = []; Remove this line
app.get('/names', (req, res) => {
let result = []; // And add it here
const printNames = (err, file) => {
file.forEach(e => {
if (e !== 'john') {
result.push(e);
}
});
res.send(result);
};
fs.readdir('./home', printNames);
});
app.listen(port, () => {
console.log('Listening on port 3000');
});
Read more about scopes in JavaScript here:
https://www.w3schools.com/js/js_scope.asp
Every time you request to load the page /names, it is re-running the code in that handler. If you only want to run that script once, then move it outside of the handler, and only send the result.
let result = [];
const printNames = (err, file) => {
file.forEach(e => {
if (e !== 'john') {
result.push(e);
}
});
};
fs.readdir('./home', printNames);
app.get('/names', (req, res) => {
res.send(result)
});

Resources