From 046cb0b76ee8a2e125b52c6ca2320d488e72b19e Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Mon, 12 Nov 2018 21:45:23 +1000 Subject: [PATCH] Added HTTP/2 Support for SSL enabled hosts --- README.md | 2 +- TODO.md | 17 ------- doc/DOCKERHUB.md | 2 +- package.json | 2 +- .../20181113041458_http2_support.js | 51 +++++++++++++++++++ src/backend/schema/definitions.json | 5 ++ src/backend/schema/endpoints/dead-hosts.json | 12 +++++ src/backend/schema/endpoints/proxy-hosts.json | 12 +++++ .../schema/endpoints/redirection-hosts.json | 12 +++++ src/backend/templates/_listen.conf | 4 +- src/frontend/js/app/nginx/dead/form.ejs | 11 +++- src/frontend/js/app/nginx/dead/form.js | 11 +++- src/frontend/js/app/nginx/proxy/form.ejs | 11 +++- src/frontend/js/app/nginx/proxy/form.js | 12 ++++- .../js/app/nginx/redirection/form.ejs | 11 +++- src/frontend/js/app/nginx/redirection/form.js | 11 +++- src/frontend/js/i18n/messages.json | 1 + 17 files changed, 159 insertions(+), 28 deletions(-) delete mode 100644 TODO.md create mode 100644 src/backend/migrations/20181113041458_http2_support.js diff --git a/README.md b/README.md index d42df13b..46bb8cd9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Nginx Proxy Manager -![Version](https://img.shields.io/badge/version-2.0.5-green.svg?style=for-the-badge) +![Version](https://img.shields.io/badge/version-2.0.6-green.svg?style=for-the-badge) ![Stars](https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge) ![Pulls](https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge) diff --git a/TODO.md b/TODO.md deleted file mode 100644 index aa3cc31b..00000000 --- a/TODO.md +++ /dev/null @@ -1,17 +0,0 @@ -# TODO - -- Dashboard stats are caching instead of querying - -Next version: - -- UI Log tail -- Enable/Disable a config - -Testing: - -- Access Levels - - Adding a proxy host without access to read certs or access lists -- Visibility -- Forwarding -- Cert renewals -- Custom certs diff --git a/doc/DOCKERHUB.md b/doc/DOCKERHUB.md index ce28df60..a5bd8230 100644 --- a/doc/DOCKERHUB.md +++ b/doc/DOCKERHUB.md @@ -2,7 +2,7 @@ # Nginx Proxy Manager -![Version](https://img.shields.io/badge/version-2.0.5-green.svg?style=for-the-badge) +![Version](https://img.shields.io/badge/version-2.0.6-green.svg?style=for-the-badge) ![Stars](https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge) ![Pulls](https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge) diff --git a/package.json b/package.json index a0a335f0..e2dd3dcf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nginx-proxy-manager", - "version": "2.0.5", + "version": "2.0.6", "description": "A beautiful interface for creating Nginx endpoints", "main": "src/backend/index.js", "devDependencies": { diff --git a/src/backend/migrations/20181113041458_http2_support.js b/src/backend/migrations/20181113041458_http2_support.js new file mode 100644 index 00000000..f416e0a8 --- /dev/null +++ b/src/backend/migrations/20181113041458_http2_support.js @@ -0,0 +1,51 @@ +'use strict'; + +const migrate_name = 'http2_support'; +const logger = require('../logger').migrate; + +/** + * Migrate + * + * @see http://knexjs.org/#Schema + * + * @param {Object} knex + * @param {Promise} Promise + * @returns {Promise} + */ +exports.up = function (knex/*, Promise*/) { + logger.info('[' + migrate_name + '] Migrating Up...'); + + return knex.schema.table('proxy_host', function (proxy_host) { + proxy_host.integer('http2_support').notNull().unsigned().defaultTo(0); + }) + .then(() => { + logger.info('[' + migrate_name + '] proxy_host Table altered'); + + return knex.schema.table('redirection_host', function (redirection_host) { + redirection_host.integer('http2_support').notNull().unsigned().defaultTo(0); + }); + }) + .then(() => { + logger.info('[' + migrate_name + '] redirection_host Table altered'); + + return knex.schema.table('dead_host', function (dead_host) { + dead_host.integer('http2_support').notNull().unsigned().defaultTo(0); + }); + }) + .then(() => { + logger.info('[' + migrate_name + '] dead_host Table altered'); + }); +}; + +/** + * Undo Migrate + * + * @param {Object} knex + * @param {Promise} Promise + * @returns {Promise} + */ +exports.down = function (knex, Promise) { + logger.warn('[' + migrate_name + '] You can\'t migrate down this one.'); + return Promise.resolve(true); +}; + diff --git a/src/backend/schema/definitions.json b/src/backend/schema/definitions.json index 272b4c43..8320b3d2 100644 --- a/src/backend/schema/definitions.json +++ b/src/backend/schema/definitions.json @@ -186,6 +186,11 @@ "type": "string", "pattern": "^(letsencrypt|other)$" }, + "http2_support": { + "description": "HTTP2 Protocol Support", + "example": false, + "type": "boolean" + }, "block_exploits": { "description": "Should we block common exploits", "example": true, diff --git a/src/backend/schema/endpoints/dead-hosts.json b/src/backend/schema/endpoints/dead-hosts.json index 34d38e7d..641c0063 100644 --- a/src/backend/schema/endpoints/dead-hosts.json +++ b/src/backend/schema/endpoints/dead-hosts.json @@ -24,6 +24,9 @@ "ssl_forced": { "$ref": "../definitions.json#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "../definitions.json#/definitions/http2_support" + }, "advanced_config": { "type": "string" }, @@ -50,6 +53,9 @@ "ssl_forced": { "$ref": "#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "#/definitions/http2_support" + }, "advanced_config": { "$ref": "#/definitions/advanced_config" }, @@ -101,6 +107,9 @@ "ssl_forced": { "$ref": "#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "#/definitions/http2_support" + }, "advanced_config": { "$ref": "#/definitions/advanced_config" }, @@ -138,6 +147,9 @@ "ssl_forced": { "$ref": "#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "#/definitions/http2_support" + }, "advanced_config": { "$ref": "#/definitions/advanced_config" }, diff --git a/src/backend/schema/endpoints/proxy-hosts.json b/src/backend/schema/endpoints/proxy-hosts.json index a7e3e30e..4cfb596f 100644 --- a/src/backend/schema/endpoints/proxy-hosts.json +++ b/src/backend/schema/endpoints/proxy-hosts.json @@ -34,6 +34,9 @@ "ssl_forced": { "$ref": "../definitions.json#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "../definitions.json#/definitions/http2_support" + }, "block_exploits": { "$ref": "../definitions.json#/definitions/block_exploits" }, @@ -80,6 +83,9 @@ "ssl_forced": { "$ref": "#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "#/definitions/http2_support" + }, "block_exploits": { "$ref": "#/definitions/block_exploits" }, @@ -151,6 +157,9 @@ "ssl_forced": { "$ref": "#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "#/definitions/http2_support" + }, "block_exploits": { "$ref": "#/definitions/block_exploits" }, @@ -206,6 +215,9 @@ "ssl_forced": { "$ref": "#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "#/definitions/http2_support" + }, "block_exploits": { "$ref": "#/definitions/block_exploits" }, diff --git a/src/backend/schema/endpoints/redirection-hosts.json b/src/backend/schema/endpoints/redirection-hosts.json index e843e609..54bd377e 100644 --- a/src/backend/schema/endpoints/redirection-hosts.json +++ b/src/backend/schema/endpoints/redirection-hosts.json @@ -32,6 +32,9 @@ "ssl_forced": { "$ref": "../definitions.json#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "../definitions.json#/definitions/http2_support" + }, "block_exploits": { "$ref": "../definitions.json#/definitions/block_exploits" }, @@ -67,6 +70,9 @@ "ssl_forced": { "$ref": "#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "#/definitions/http2_spport" + }, "block_exploits": { "$ref": "#/definitions/block_exploits" }, @@ -128,6 +134,9 @@ "ssl_forced": { "$ref": "#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "#/definitions/http2_support" + }, "block_exploits": { "$ref": "#/definitions/block_exploits" }, @@ -174,6 +183,9 @@ "ssl_forced": { "$ref": "#/definitions/ssl_forced" }, + "http2_support": { + "$ref": "#/definitions/http2_support" + }, "block_exploits": { "$ref": "#/definitions/block_exploits" }, diff --git a/src/backend/templates/_listen.conf b/src/backend/templates/_listen.conf index 067b2dd4..b3f21cfe 100644 --- a/src/backend/templates/_listen.conf +++ b/src/backend/templates/_listen.conf @@ -1,5 +1,5 @@ listen 80; {% if certificate -%} - listen 443 ssl; + listen 443 ssl{% if http2 %} http2{% endif %}; {% endif %} - server_name {{ domain_names | join: " " }}; \ No newline at end of file + server_name {{ domain_names | join: " " }}; diff --git a/src/frontend/js/app/nginx/dead/form.ejs b/src/frontend/js/app/nginx/dead/form.ejs index e014ec9b..4d2c4b5c 100644 --- a/src/frontend/js/app/nginx/dead/form.ejs +++ b/src/frontend/js/app/nginx/dead/form.ejs @@ -36,7 +36,7 @@ -
+
+
+
+ +
+
diff --git a/src/frontend/js/app/nginx/dead/form.js b/src/frontend/js/app/nginx/dead/form.js index 821fd691..24d783c7 100644 --- a/src/frontend/js/app/nginx/dead/form.js +++ b/src/frontend/js/app/nginx/dead/form.js @@ -22,6 +22,7 @@ module.exports = Mn.View.extend({ save: 'button.save', certificate_select: 'select[name="certificate_id"]', ssl_forced: 'input[name="ssl_forced"]', + http2_support: 'input[name="http2_support"]', letsencrypt: '.letsencrypt' }, @@ -35,7 +36,11 @@ module.exports = Mn.View.extend({ } let enabled = id === 'new' || parseInt(id, 10) > 0; - this.ui.ssl_forced.prop('disabled', !enabled).parents('.form-group').css('opacity', enabled ? 1 : 0.5); + this.ui.ssl_forced + .prop('disabled', !enabled) + .parents('.form-group') + .css('opacity', enabled ? 1 : 0.5); + this.ui.http2_support.prop('disabled', !enabled); }, 'click @ui.save': function (e) { @@ -54,6 +59,10 @@ module.exports = Mn.View.extend({ data.ssl_forced = true; } + if (typeof data.http2_support !== 'undefined' && data.http2_support === '1') { + data.http2_support = true; + } + if (typeof data.domain_names === 'string' && data.domain_names) { data.domain_names = data.domain_names.split(','); } diff --git a/src/frontend/js/app/nginx/proxy/form.ejs b/src/frontend/js/app/nginx/proxy/form.ejs index 31828846..eca0ca6d 100644 --- a/src/frontend/js/app/nginx/proxy/form.ejs +++ b/src/frontend/js/app/nginx/proxy/form.ejs @@ -82,7 +82,7 @@
-
+
+
+
+ +
+
diff --git a/src/frontend/js/app/nginx/proxy/form.js b/src/frontend/js/app/nginx/proxy/form.js index f9f8b4f2..15bc63ba 100644 --- a/src/frontend/js/app/nginx/proxy/form.js +++ b/src/frontend/js/app/nginx/proxy/form.js @@ -25,6 +25,7 @@ module.exports = Mn.View.extend({ certificate_select: 'select[name="certificate_id"]', access_list_select: 'select[name="access_list_id"]', ssl_forced: 'input[name="ssl_forced"]', + http2_support: 'input[name="http2_support"]', letsencrypt: '.letsencrypt' }, @@ -38,7 +39,12 @@ module.exports = Mn.View.extend({ } let enabled = id === 'new' || parseInt(id, 10) > 0; - this.ui.ssl_forced.prop('disabled', !enabled).parents('.form-group').css('opacity', enabled ? 1 : 0.5); + this.ui.ssl_forced + .prop('disabled', !enabled) + .parents('.form-group') + .css('opacity', enabled ? 1 : 0.5); + + this.ui.http2_support.prop('disabled', !enabled) }, 'click @ui.save': function (e) { @@ -62,6 +68,10 @@ module.exports = Mn.View.extend({ data.ssl_forced = true; } + if (typeof data.http2_support !== 'undefined' && data.http2_support === '1') { + data.http2_support = true; + } + if (typeof data.domain_names === 'string' && data.domain_names) { data.domain_names = data.domain_names.split(','); } diff --git a/src/frontend/js/app/nginx/redirection/form.ejs b/src/frontend/js/app/nginx/redirection/form.ejs index 1dceb53b..d3f8da80 100644 --- a/src/frontend/js/app/nginx/redirection/form.ejs +++ b/src/frontend/js/app/nginx/redirection/form.ejs @@ -60,7 +60,7 @@
-
+
+
+
+ +
+
diff --git a/src/frontend/js/app/nginx/redirection/form.js b/src/frontend/js/app/nginx/redirection/form.js index 9c1ec314..3cad2bd1 100644 --- a/src/frontend/js/app/nginx/redirection/form.js +++ b/src/frontend/js/app/nginx/redirection/form.js @@ -22,6 +22,7 @@ module.exports = Mn.View.extend({ save: 'button.save', certificate_select: 'select[name="certificate_id"]', ssl_forced: 'input[name="ssl_forced"]', + http2_support: 'input[name="http2_support"]', letsencrypt: '.letsencrypt' }, @@ -35,7 +36,11 @@ module.exports = Mn.View.extend({ } let enabled = id === 'new' || parseInt(id, 10) > 0; - this.ui.ssl_forced.prop('disabled', !enabled).parents('.form-group').css('opacity', enabled ? 1 : 0.5); + this.ui.ssl_forced + .prop('disabled', !enabled) + .parents('.form-group') + .css('opacity', enabled ? 1 : 0.5); + this.ui.http2_support.prop('disabled', !enabled); }, 'click @ui.save': function (e) { @@ -57,6 +62,10 @@ module.exports = Mn.View.extend({ data.ssl_forced = true; } + if (typeof data.http2_support !== 'undefined' && data.http2_support === '1') { + data.http2_support = true; + } + if (typeof data.domain_names === 'string' && data.domain_names) { data.domain_names = data.domain_names.split(','); } diff --git a/src/frontend/js/i18n/messages.json b/src/frontend/js/i18n/messages.json index e849c580..f96c300a 100644 --- a/src/frontend/js/i18n/messages.json +++ b/src/frontend/js/i18n/messages.json @@ -65,6 +65,7 @@ "details": "Details", "enable-ssl": "Enable SSL", "force-ssl": "Force SSL", + "http2-support": "HTTP/2 Support", "domain-names": "Domain Names", "cert-provider": "Certificate Provider", "block-exploits": "Block Common Exploits",