From a8766b0a084afa83d9337884f623458ab7c351da Mon Sep 17 00:00:00 2001 From: Key Networks <34238649+key-networks@users.noreply.github.com> Date: Fri, 29 Dec 2017 15:58:18 +0800 Subject: [PATCH] Listen on localhost for HTTP and all interfaces for HTTPS --- app.js | 3 +- bin/www | 46 +++++++++++------- etc/tls/.gitignore | 2 + package-lock.json | 119 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 5 files changed, 152 insertions(+), 19 deletions(-) create mode 100644 etc/tls/.gitignore diff --git a/app.js b/app.js index 6f8f1e6..4147d79 100644 --- a/app.js +++ b/app.js @@ -14,6 +14,7 @@ const cookieParser = require('cookie-parser'); const bodyParser = require('body-parser'); const expressValidator = require('express-validator'); const session = require('express-session'); +const helmet = require('helmet'); const index = require('./routes/index'); const users = require('./routes/users'); @@ -27,7 +28,7 @@ const session_secret = Math.random().toString(36).substring(2,12); app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'pug'); -// uncomment after placing your favicon in /public +app.use(helmet()); app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(logger('dev')); app.use(bodyParser.json()); diff --git a/bin/www b/bin/www index 53db151..7deb134 100755 --- a/bin/www +++ b/bin/www @@ -4,28 +4,34 @@ * Module dependencies. */ -var app = require('../app'); -var debug = require('debug')('ztncui:server'); -var http = require('http'); +const app = require('../app'); +const debug = require('debug')('ztncui:server'); +const http = require('http'); +const https = require('https'); +const fs = require('fs'); + +const options = { + cert: fs.readFileSync('etc/tls/fullchain.pem'), + key: fs.readFileSync('etc/tls/privkey.pem') +} /** * Get port from environment and store in Express. */ -var port = normalizePort(process.env.PORT || '3000'); +const port = normalizePort(process.env.PORT || '3000'); app.set('port', port); +const sport = normalizePort(process.env.SPORT || '3443'); +app.set('sport', sport); /** - * Create HTTP server. + * Create HTTPS server and listen on localhost only for HTTP and on all network interfaces for HTTPS */ -var server = http.createServer(app); +app.listen(port, 'localhost'); +const server = https.createServer(options, app); -/** - * Listen on provided port, on loopback network interface. - */ - -server.listen(port, 'localhost'); +server.listen(sport); server.on('error', onError); server.on('listening', onListening); @@ -34,7 +40,7 @@ server.on('listening', onListening); */ function normalizePort(val) { - var port = parseInt(val, 10); + let port = parseInt(val, 10); if (isNaN(port)) { // named pipe @@ -58,18 +64,22 @@ function onError(error) { throw error; } - var bind = typeof port === 'string' + let bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; + let sbind = typeof sport === 'string' + ? 'Pipe ' + sport + : 'Port ' + sport; + // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': - console.error(bind + ' requires elevated privileges'); + console.error(bind + ' and ' + sbind + ' require elevated privileges'); process.exit(1); break; case 'EADDRINUSE': - console.error(bind + ' is already in use'); + console.error(bind + ' and/or ' + sbind + ' already in use'); process.exit(1); break; default: @@ -78,12 +88,12 @@ function onError(error) { } /** - * Event listener for HTTP server "listening" event. + * Event listener for HTTPS server "listening" event. */ function onListening() { - var addr = server.address(); - var bind = typeof addr === 'string' + let addr = server.address(); + let bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); diff --git a/etc/tls/.gitignore b/etc/tls/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/etc/tls/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/package-lock.json b/package-lock.json index 576f765..0a9bccf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -294,6 +294,11 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" }, + "camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + }, "capture-stack-trace": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", @@ -427,6 +432,14 @@ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" }, + "content-security-policy-builder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-1.1.0.tgz", + "integrity": "sha1-2R8bB2I2wRmFDH3umSS/VeBXcrM=", + "requires": { + "dashify": "0.2.2" + } + }, "content-type": { "version": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=" @@ -484,6 +497,16 @@ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", "dev": true }, + "dasherize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz", + "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg=" + }, + "dashify": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dashify/-/dashify-0.2.2.tgz", + "integrity": "sha1-agdBWgHJH69KMuONnfunH2HLIP4=" + }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -520,11 +543,21 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "dns-prefetch-control": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz", + "integrity": "sha1-YN20V3dOF48flBXwyrsOhbCzALI=" + }, "doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=" }, + "dont-sniff-mimetype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz", + "integrity": "sha1-WTKJDcn04vGeXrAqIAJuXl78j1g=" + }, "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", @@ -628,6 +661,11 @@ "fill-range": "2.2.3" } }, + "expect-ct": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.1.0.tgz", + "integrity": "sha1-UnNWeN4YUwiQ2Ne5XwrGNkCVgJQ=" + }, "express": { "version": "4.16.2", "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", @@ -803,6 +841,11 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, + "frameguard": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.0.0.tgz", + "integrity": "sha1-e8rUae57lukdEs6zlZx4I1qScuk=" + }, "fresh": { "version": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" @@ -1814,6 +1857,52 @@ "has-symbol-support-x": "1.4.1" } }, + "helmet": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.9.0.tgz", + "integrity": "sha512-czCyS77TyanWlfVSoGlb9GBJV2Q2zJayKxU5uBw0N1TzDTs/qVNh1SL8Q688KU0i0Sb7lQ/oLtnaEqXzl2yWvA==", + "requires": { + "dns-prefetch-control": "0.1.0", + "dont-sniff-mimetype": "1.0.0", + "expect-ct": "0.1.0", + "frameguard": "3.0.0", + "helmet-csp": "2.6.0", + "hide-powered-by": "1.0.0", + "hpkp": "2.0.0", + "hsts": "2.1.0", + "ienoopen": "1.0.0", + "nocache": "2.0.0", + "referrer-policy": "1.1.0", + "x-xss-protection": "1.0.0" + } + }, + "helmet-csp": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.6.0.tgz", + "integrity": "sha512-n/oW9l6RtO4f9YvphsNzdvk1zITrSN7iRT8ojgrJu/N3mVdHl9zE4OjbiHWcR64JK32kbqx90/yshWGXcjUEhw==", + "requires": { + "camelize": "1.0.0", + "content-security-policy-builder": "1.1.0", + "dasherize": "2.0.0", + "lodash.reduce": "4.6.0", + "platform": "1.3.4" + } + }, + "hide-powered-by": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.0.0.tgz", + "integrity": "sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys=" + }, + "hpkp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz", + "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" + }, + "hsts": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.1.0.tgz", + "integrity": "sha512-zXhh/DqgrTXJ7erTN6Fh5k/xjMhDGXCqdYN3wvxUvGUQvnxcFfUd8E+6vLg/nk3ss1TYMb+DhRl25fYABioTvA==" + }, "http-errors": { "version": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", @@ -1828,6 +1917,11 @@ "version": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs=" }, + "ienoopen": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.0.0.tgz", + "integrity": "sha1-NGpCj0dKrI9QzzeE6i0PFvYr2ms=" + }, "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", @@ -2249,6 +2343,11 @@ "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=" }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + }, "lodash.repeat": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/lodash.repeat/-/lodash.repeat-4.1.0.tgz", @@ -2416,6 +2515,11 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, + "nocache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.0.0.tgz", + "integrity": "sha1-ICtIAhoMTL3i34DeFaF0Q8i0OYA=" + }, "node-persist": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-2.1.0.tgz", @@ -2633,6 +2737,11 @@ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, + "platform": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.4.tgz", + "integrity": "sha1-bw+xftqqSPIUQrOpdcBjEw8cPr0=" + }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", @@ -2921,6 +3030,11 @@ "set-immediate-shim": "1.0.1" } }, + "referrer-policy": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.1.0.tgz", + "integrity": "sha1-NXdOtzW/UPtsB46DM0tHI1AgfXk=" + }, "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", @@ -3379,6 +3493,11 @@ "signal-exit": "3.0.2" } }, + "x-xss-protection": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.0.0.tgz", + "integrity": "sha1-iYr7k4abJGYc+cUvnujbjtB2Tdk=" + }, "xdg-basedir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", diff --git a/package.json b/package.json index 5002888..4787e14 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "express-session": "^1.15.6", "express-validator": "^4.3.0", "got": "^7.1.0", + "helmet": "^3.9.0", "ip-address": "^5.8.9", "jquery": "^3.2.1", "morgan": "~1.9.0",