From e6ec74c2f77fba5ce1b253f3d811696749c2b49b Mon Sep 17 00:00:00 2001 From: milad nazari Date: Mon, 9 Dec 2024 11:27:52 +0330 Subject: [PATCH] feat: add support for selecting SSL key type (ECDSA/RSA) Added the ability to specify the SSL key type (ECDSA or RSA) for each site in the Nginx Proxy Manager. This enhancement is particularly useful for environments with IoT devices that have limitations with specific key types, such as RSA-only support. The implementation includes: - Backend support for storing and validating the `ssl_key_type` field. - Swagger schema updated to validate the new input. - Frontend update to allow users to select the SSL key type via a dropdown menu. This feature ensures greater flexibility and compatibility in managing SSL certificates for diverse setups. --- backend/internal/certificate.js | 5 +++ .../migrations/20241209062244_ssl_key_type.js | 39 +++++++++++++++++++ .../schema/components/proxy-host-object.json | 6 +++ .../paths/nginx/proxy-hosts/hostID/put.json | 3 ++ .../schema/paths/nginx/proxy-hosts/post.json | 3 ++ docker/dev/letsencrypt.ini | 1 - docker/rootfs/etc/letsencrypt.ini | 1 - frontend/js/app/nginx/proxy/form.ejs | 9 +++++ frontend/js/i18n/messages.json | 1 + frontend/js/models/dead-host.js | 1 + frontend/js/models/proxy-host.js | 1 + frontend/js/models/redirection-host.js | 1 + 12 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 backend/migrations/20241209062244_ssl_key_type.js diff --git a/backend/internal/certificate.js b/backend/internal/certificate.js index 34b8fdf5..c4bf379a 100644 --- a/backend/internal/certificate.js +++ b/backend/internal/certificate.js @@ -832,6 +832,7 @@ const internalCertificate = { const cmd = `${certbotCommand} certonly ` + `--config '${letsencryptConfig}' ` + + `--key-type '${certificate.ssl_key_type}' ` + '--work-dir "/tmp/letsencrypt-lib" ' + '--logs-dir "/tmp/letsencrypt-log" ' + `--cert-name "npm-${certificate.id}" ` + @@ -873,6 +874,7 @@ const internalCertificate = { let mainCmd = certbotCommand + ' certonly ' + `--config '${letsencryptConfig}' ` + + `--key-type '${certificate.ssl_key_type}' ` + '--work-dir "/tmp/letsencrypt-lib" ' + '--logs-dir "/tmp/letsencrypt-log" ' + `--cert-name 'npm-${certificate.id}' ` + @@ -969,6 +971,7 @@ const internalCertificate = { const cmd = certbotCommand + ' renew --force-renewal ' + `--config '${letsencryptConfig}' ` + + `--key-type '${certificate.ssl_key_type}' ` + '--work-dir "/tmp/letsencrypt-lib" ' + '--logs-dir "/tmp/letsencrypt-log" ' + `--cert-name 'npm-${certificate.id}' ` + @@ -1002,6 +1005,7 @@ const internalCertificate = { let mainCmd = certbotCommand + ' renew --force-renewal ' + `--config "${letsencryptConfig}" ` + + `--key-type '${certificate.ssl_key_type}' ` + '--work-dir "/tmp/letsencrypt-lib" ' + '--logs-dir "/tmp/letsencrypt-log" ' + `--cert-name 'npm-${certificate.id}' ` + @@ -1035,6 +1039,7 @@ const internalCertificate = { const mainCmd = certbotCommand + ' revoke ' + `--config '${letsencryptConfig}' ` + + `--key-type '${certificate.ssl_key_type}' ` + '--work-dir "/tmp/letsencrypt-lib" ' + '--logs-dir "/tmp/letsencrypt-log" ' + `--cert-path '/etc/letsencrypt/live/npm-${certificate.id}/fullchain.pem' ` + diff --git a/backend/migrations/20241209062244_ssl_key_type.js b/backend/migrations/20241209062244_ssl_key_type.js new file mode 100644 index 00000000..7fcd107d --- /dev/null +++ b/backend/migrations/20241209062244_ssl_key_type.js @@ -0,0 +1,39 @@ +const migrate_name = 'identifier_for_migrate'; +const logger = require('../logger').migrate; + +/** + * Migrate + * + * @see http://knexjs.org/#Schema + * + * @param {Object} knex + * @param {Promise} Promise + * @returns {Promise} + */ +exports.up = function (knex) { + + logger.info(`[${migrate_name}] Migrating Up...`); + + return knex.schema.alterTable('proxy_host', (table) => { + table.enum('ssl_key_type', ['ecdsa', 'rsa']).defaultTo('ecdsa').notNullable(); + }).then(() => { + logger.info(`[${migrate_name}] Column 'ssl_key_type' added to table 'proxy_host'`); + }); +}; + +/** + * Undo Migrate + * + * @param {Object} knex + * @param {Promise} Promise + * @returns {Promise} + */ +exports.down = function (knex) { + logger.info(`[${migrate_name}] Migrating Down...`); + + return knex.schema.alterTable('proxy_host', (table) => { + table.dropColumn('ssl_key_type'); + }).then(() => { + logger.info(`[${migrate_name}] Column 'ssl_key_type' removed from table 'proxy_host'`); + }); +}; diff --git a/backend/schema/components/proxy-host-object.json b/backend/schema/components/proxy-host-object.json index 5098802b..7679d6c1 100644 --- a/backend/schema/components/proxy-host-object.json +++ b/backend/schema/components/proxy-host-object.json @@ -23,6 +23,7 @@ "locations", "hsts_enabled", "hsts_subdomains", + "ssl_key_type", "certificate" ], "additionalProperties": false, @@ -149,6 +150,11 @@ "$ref": "./access-list-object.json" } ] + }, + "ssl_key_type": { + "type": "string", + "enum": ["ecdsa", "rsa"], + "description": "Type of SSL key (either ecdsa or rsa)" } } } diff --git a/backend/schema/paths/nginx/proxy-hosts/hostID/put.json b/backend/schema/paths/nginx/proxy-hosts/hostID/put.json index 5cab6e75..5ca18f6f 100644 --- a/backend/schema/paths/nginx/proxy-hosts/hostID/put.json +++ b/backend/schema/paths/nginx/proxy-hosts/hostID/put.json @@ -79,6 +79,9 @@ }, "locations": { "$ref": "../../../../components/proxy-host-object.json#/properties/locations" + }, + "ssl_key_type": { + "$ref": "../../../../components/proxy-host-object.json#/properties/ssl_key_type" } } } diff --git a/backend/schema/paths/nginx/proxy-hosts/post.json b/backend/schema/paths/nginx/proxy-hosts/post.json index 85455fb6..24b8a410 100644 --- a/backend/schema/paths/nginx/proxy-hosts/post.json +++ b/backend/schema/paths/nginx/proxy-hosts/post.json @@ -67,6 +67,9 @@ }, "locations": { "$ref": "../../../components/proxy-host-object.json#/properties/locations" + }, + "ssl_key_type": { + "$ref": "../../../components/proxy-host-object.json#/properties/ssl_key_type" } } } diff --git a/docker/dev/letsencrypt.ini b/docker/dev/letsencrypt.ini index 93647b64..0563383f 100644 --- a/docker/dev/letsencrypt.ini +++ b/docker/dev/letsencrypt.ini @@ -1,7 +1,6 @@ text = True non-interactive = True webroot-path = /data/letsencrypt-acme-challenge -key-type = ecdsa elliptic-curve = secp384r1 preferred-chain = ISRG Root X1 server = diff --git a/docker/rootfs/etc/letsencrypt.ini b/docker/rootfs/etc/letsencrypt.ini index aae53b90..7becd3b4 100644 --- a/docker/rootfs/etc/letsencrypt.ini +++ b/docker/rootfs/etc/letsencrypt.ini @@ -1,6 +1,5 @@ text = True non-interactive = True webroot-path = /data/letsencrypt-acme-challenge -key-type = ecdsa elliptic-curve = secp384r1 preferred-chain = ISRG Root X1 diff --git a/frontend/js/app/nginx/proxy/form.ejs b/frontend/js/app/nginx/proxy/form.ejs index 8e7a2a2d..4030bcc3 100644 --- a/frontend/js/app/nginx/proxy/form.ejs +++ b/frontend/js/app/nginx/proxy/form.ejs @@ -105,6 +105,15 @@ +
+
+ + +
+