Certbot - How to create SSL certs and keys for IP:3030? - node.js

I have an ExpressJS app that is running on an IP address only at port 3030.
How can I create the SSL cert and key for this type of address?
I tried with:
$ certbot certonly --standalone --email test1#yahoo.co.uk -d 127.0.1.1:3030
I get this error:
Requested domain 127.0.1.1:3030 is not a FQDN
Any ideas?
This is the package I use - certbot.
This is my www file in my ExpressJS bin directory:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('mongoose-iot:server');
var http = require('http');
// Add HTTPS support.
// https://www.hacksparrow.com/express-js-https.html
// http://stackoverflow.com/questions/11744975/enabling-https-on-express-js
// http://blog.mgechev.com/2014/02/19/create-https-tls-ssl-application-with-express-nodejs/
var https = require('https');
var fs = require('fs');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Get port from environment and store in Express.
*/
var httpsPort = normalizePort(process.env.PORT || '3030');
app.set('port', httpsPort);
/**
* Create HTTPS server.
*/
var options = {
key: fs.readFileSync('ssl/key.pem'),
cert: fs.readFileSync('ssl/cert.pem')
};
var httpsServer = https.createServer(options, app);
/**
* Listen on provided port, on all network interfaces.
*/
httpsServer.listen(httpsPort);
httpsServer.on('error', onError);
httpsServer.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

The problem is that letsencrypt ssl certficates are for domain names, it doesn't have much to do with the IP address or the port. You must have a valid and publicly accessible domain name so that the letsencrypt authority server can verify it.
In this case it is common practice to use http (and not https) in development using a simple check like:
if (process.env.NODE_ENV === "production") {
// httpsServer.listen(httpsPort)
} else {
// ...
}

Related

Port number showing in Nodejs express folder listing

I have a node js express application which is running on port 3000. when i ran it first it worked. Then when i ran it for the second time, it says the "port is already in use". I have checked all the running ports and also searched by specific 3000 port, but still cannot find a process running on 3000 port.
Then i changed the port to 3002 and checked, now the program ran. And when i closed and ran it again, it says "port is already in use".
Same is the case when i tried with port 3003.
i tried the below to check for the running ports
sudo lsof -i -P -n | grep LISTEN
netstat -an | grep 3000
lsof -i:3000
kill <PID>
Afterwards i noticed that when i did a folder listing it showed the folder "3000", "3002", "3003" as folder/file. I don't know what this is.
below is my www file
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('mqtt-node:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3001');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
Could anyone help me with why the ran port numbers are showing in the folder listing and also i cannot find any running node ports, but still says the port is already in use.
I made a change in my env file and the issue is resolved. I had defined the port in my .env as PORT="3000" and i changed to PORT=3000, and it works.
I am not sure why PORT="3000" was working in my PC and not in my server. This is why i was not focusing on this factor.

Cannot Connect to Dockerized Express HTTPS Server

I'm trying to serve my app over HTTPS so that I can use a service worker with my React app.
To do this, I added https.createServer() to my Express startup script
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('robotapp:server');
var http = require('http');
var fs = require('fs');
var https = require('https');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '8000');
app.set('port', port);
console.log('Listening on localhost:', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Add HTTPS server
*/
if (process.env.NODE_ENV === 'prod') {
https
.createServer(
{
key: fs.readFileSync('sslcerts/server.key', 'utf8'),
cert: fs.readFileSync('sslcerts/server.pem', 'utf8')
},
app
)
.listen(443, function() {
console.log('HTTPS listening on PORT 443');
});
}
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
debug('Listening on ' + bind);
}
When I build the Docker container and start the app, both the HTTP and HTTPS server start up (I can see the "Listening on localhost:8000" and "HTTPS listening on PORT 443" messages). I can successfully access the HTTP version of my app on PORT 8000, but when I go to access PORT 443 on my server I get a "This site cannot be reached" error.
At first I thought maybe I mapped my container ports wrong, but I checked and nothing seems out of ordinary
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
16d0013eec8a robotapp:2.1 "npm start" 4 seconds ago Up 3 seconds 0.0.0.0:443->443/tcp, 0.0.0.0:8000->8000/tcp silly_tesla
If anyone has any suggestions as to what I'm doing wrong, please let me know :)

Express app with MSSQL created with CLI not connecting correctly to database

I have a problem with an app I created using the Express CLI. It's important to note that I'm using mssql for my connection to the database.
When I use npm start, the app starts without a problem, but when I run node ./bin/www, the app starts, but it fails to connect to the database. I'm getting the error "Invalid server: undefined".
When I check my package.json file, I have:
"scripts": {
"start": "node ./bin/www",
"debug": "set DEBUG=myapp:* & npm start",
"nodemon": "npx nodemon"
},
As far as I understand, it should be exactly the same to run npm start than node ./bin/www, but for some reason it is not.
As to why this is a problem, I want to leave the app running using pm2, and so, I need to be able to run the app from a file, and not from a command.
This is my www file:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('mtloops-web-api:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort('3543');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
This is my database connection file:
const sql = require('mssql')
// const path = require('path')
require('dotenv').config()
var config = {
user: process.env.DBUSERNAME,
password: process.env.DBPASSWORD,
server: process.env.HOST,
database: process.env.DATABASE,
connectionTimeout: 300000,
requestTimeout: 300000,
pool: {
idleTimeoutMillis: 300000,
max: 100
},
options: {
encrypt: false
}
}
async function sp (procedure, params) {
const toReturn = await new sql.ConnectionPool(config).connect().then(pool => {
const request = pool.request()
Object.keys(params).forEach(key => {
if (isNaN(params[key])) {
request.input(key, sql.VarChar(8), params[key])
} else {
var numeric = parseInt(params[key])
request.input(key, sql.Int, numeric <= 0 ? -1 : numeric)
}
})
return request.execute(procedure)
}).catch(error => {
throw error.message
})
return toReturn
}
module.exports = {
sp
}

how to set local node ports for production?

Trying to bring a local project onto an ubuntu mongodb server.
Currently the project runs on my localhost:8000 when I run npm start on my server and I visit curl http://localhost:8000 i can see the markup of my homepage being outputted. How can i change this to use my domain/server ip in production?
Below is my node file which is run by npm start
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('05-express-first-app:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '8000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
My server ip address is: 165.227.196.209, just not sure where to put it.
Thanks!
You'll have to change the IP on which the Node.js server runs to be whatever the public IP address of your server is. In your case, the public IP is 165.227.196.209
This is assuming your name server is already configured to route the domain (eg: mywebsite.com) to that particular IP address.
Read more about it here - How to assign a domain name to node.js server? (Check the selected answer)
UPDATE:: Opening the URL - http://165.227.196.209/,
I notice that you're using nginx. So you'll have to setup reverse proxying.
I suggest going through the link here - Node.js + Nginx - What now?
You can read about the benefits of putting nginx infornt of Node.js here - Using Node.js only vs. using Node.js with Apache/Nginx
Couple of other problems that I notice here that would be good to fix,
You should be using a process manager to run your application in Production. Something like pm2 is recommended. This way if you application crashes, pm2 will restart it.
You can use pm2 with environment variables as described here to run on a different port on production - http://pm2.keymetrics.io/docs/usage/environment/

NodeJS app not working on Openshift after deployed

I'm having trouble with my nodejs app deployment. I use Express, MySQL and the basic Express structure for my app. When I open the app URL on openshift I get the 503 error message. On the nodejs.log, I can see this:
Warning: connect.session() MemoryStore is not
designed for a production environment, as it will leak
memory, and will not scale past a single process.
Pipe 8080 is already in use
The application is run with ./bin/www. This is the code I have in that file:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('adressbook:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
//var addr = server.address();
var addr = process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1";
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
The error occurred because the OPENSHIFT_NODEJS_PORT variable was not set on your application's server. This cause the application to use the hardcoded port (8080).
To resolve this, you need to set the OPENSHIFT_NODEJS_PORT environment variable on your application's server. This can be done with:
$ rhc env set OPENSHIFT_NODEJS_PORT=<Value> -a App_Name
where <Value> is the port number you wish to use and App_Name is your application's name.
You can read more about handling environment variables on Openshift here

Resources