1

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);
}
Run
  • 54,938
  • 169
  • 450
  • 748

1 Answers1

1

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 {
   // ...
}
Philippe
  • 1,169
  • 12
  • 14
  • 1
    According to https://stackoverflow.com/questions/2043617/is-it-possible-to-have-ssl-certificate-for-ip-address-not-domain-name and https://stackoverflow.com/questions/1095780/are-ssl-certificates-bound-to-the-servers-ip-address answers it is possible on public facing ip-addresses, but not in reserved ip-ranges such as 127.0.0.0/24 – taur Oct 20 '17 at 13:48