Fix SSL custom certificates being saved, nginx errors being reported and leaking custom certs in api calls

This commit is contained in:
Jamie Curnow 2018-09-04 10:33:09 +10:00
parent 5ac0e3dc95
commit ac9d9cdddd
7 changed files with 108 additions and 21 deletions

View File

@ -1,6 +1,6 @@
{
"name": "nginx-proxy-manager",
"version": "2.0.1",
"version": "2.0.2",
"description": "A beautiful interface for creating Nginx endpoints",
"main": "src/backend/index.js",
"devDependencies": {

View File

@ -183,10 +183,7 @@ const internalCertificate = {
});
});
} else {
return internalCertificate.writeCustomCert(certificate)
.then(() => {
return certificate;
});
}
}).then(certificate => {
@ -409,6 +406,10 @@ const internalCertificate = {
* @returns {Promise}
*/
writeCustomCert: certificate => {
if (debug_mode) {
logger.info('Writing Custom Certificate:', certificate);
}
let dir = '/data/custom_ssl/npm-' + certificate.id;
return new Promise((resolve, reject) => {
@ -549,8 +550,13 @@ const internalCertificate = {
id: data.id,
expires_on: certificateModel.raw('FROM_UNIXTIME(' + validations.certificate.dates.to + ')'),
domain_names: [validations.certificate.cn],
meta: row.meta
});
meta: _.clone(row.meta) // Prevent the update method from changing this value that we'll use later
})
.then(certificate => {
console.log('ROWMETA:', row.meta);
certificate.meta = row.meta;
return internalCertificate.writeCustomCert(certificate);
})
})
.then(() => {
return _.pick(row.meta, internalCertificate.allowed_ssl_files);

View File

@ -189,7 +189,9 @@ const internalDeadHost = {
.then(row => {
// Configure nginx
return internalNginx.configure(deadHostModel, 'dead_host', row)
.then(() => {
.then(new_meta => {
row.meta = new_meta;
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
});
});
@ -235,6 +237,7 @@ const internalDeadHost = {
})
.then(row => {
if (row) {
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
} else {
throw new error.ItemNotFoundError(data.id);
@ -322,6 +325,13 @@ const internalDeadHost = {
}
return query;
})
.then(rows => {
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
return internalHost.cleanAllRowsCertificateMeta(rows);
}
return rows;
});
},

View File

@ -6,6 +6,36 @@ const deadHostModel = require('../models/dead_host');
const internalHost = {
/**
* used by the getAll functions of hosts, this removes the certificate meta if present
*
* @param {Array} rows
* @returns {Array}
*/
cleanAllRowsCertificateMeta: function (rows) {
rows.map(function (row, idx) {
if (typeof rows[idx].certificate !== 'undefined' && rows[idx].certificate) {
rows[idx].certificate.meta = {};
}
});
return rows;
},
/**
* used by the get/update functions of hosts, this removes the certificate meta if present
*
* @param {Object} row
* @returns {Object}
*/
cleanRowCertificateMeta: function (row) {
if (typeof row.certificate !== 'undefined' && row.certificate) {
row.certificate.meta = {};
}
return row;
},
/**
* This returns all the host types with any domain listed in the provided domain_names array.
* This is used by the certificates to temporarily disable any host that is using the domain

View File

@ -25,6 +25,8 @@ const internalNginx = {
* @returns {Promise}
*/
configure: (model, host_type, host) => {
let combined_meta = {};
return internalNginx.test()
.then(() => {
// Nginx is OK
@ -39,30 +41,46 @@ const internalNginx = {
return internalNginx.test()
.then(() => {
// nginx is ok
combined_meta = _.assign({}, host.meta, {
nginx_online: true,
nginx_err: null
});
return model
.query()
.where('id', host.id)
.patch({
meta: _.assign({}, host.meta, {
nginx_online: true,
nginx_err: null
})
meta: combined_meta
});
})
.catch(err => {
// Remove the error_log line because it's a docker-ism false positive that doesn't need to be reported.
// It will always look like this:
// nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (6: No such device or address)
let valid_lines = [];
let err_lines = err.message.split("\n");
err_lines.map(function (line) {
if (line.indexOf('/var/log/nginx/error.log') === -1) {
valid_lines.push(line);
}
});
if (debug_mode) {
logger.error('Nginx test failed:', err.message);
logger.error('Nginx test failed:', valid_lines.join("\n"));
}
// config is bad, update meta and delete config
combined_meta = _.assign({}, host.meta, {
nginx_online: false,
nginx_err: valid_lines.join("\n")
});
return model
.query()
.where('id', host.id)
.patch({
meta: _.assign({}, host.meta, {
nginx_online: false,
nginx_err: err.message
})
meta: combined_meta
})
.then(() => {
return internalNginx.deleteConfig(host_type, host, true);
@ -71,7 +89,10 @@ const internalNginx = {
})
.then(() => {
return internalNginx.reload();
});
})
.then(() => {
return combined_meta;
})
},
/**
@ -82,7 +103,7 @@ const internalNginx = {
logger.info('Testing Nginx configuration');
}
return utils.exec('/usr/sbin/nginx -t');
return utils.exec('/usr/sbin/nginx -t -g "error_log off;"');
},
/**

View File

@ -190,7 +190,9 @@ const internalProxyHost = {
.then(row => {
// Configure nginx
return internalNginx.configure(proxyHostModel, 'proxy_host', row)
.then(() => {
.then(new_meta => {
row.meta = new_meta;
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
});
});
@ -236,6 +238,7 @@ const internalProxyHost = {
})
.then(row => {
if (row) {
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
} else {
throw new error.ItemNotFoundError(data.id);
@ -323,6 +326,13 @@ const internalProxyHost = {
}
return query;
})
.then(rows => {
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
return internalHost.cleanAllRowsCertificateMeta(rows);
}
return rows;
});
},

View File

@ -189,7 +189,9 @@ const internalRedirectionHost = {
.then(row => {
// Configure nginx
return internalNginx.configure(redirectionHostModel, 'redirection_host', row)
.then(() => {
.then(new_meta => {
row.meta = new_meta;
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
});
});
@ -235,6 +237,7 @@ const internalRedirectionHost = {
})
.then(row => {
if (row) {
row = internalHost.cleanRowCertificateMeta(row);
return _.omit(row, omissions());
} else {
throw new error.ItemNotFoundError(data.id);
@ -322,6 +325,13 @@ const internalRedirectionHost = {
}
return query;
})
.then(rows => {
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
return internalHost.cleanAllRowsCertificateMeta(rows);
}
return rows;
});
},