mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2025-08-04 16:33:32 +00:00
Fully support client CAs with access-lists
This commit changes access-list IP directives to be implemented using the nginx "geo" directive. This allows IP-based blocks to return 444 (drop connection) on authorization failure when the "Drop Unauthorized" is enabled. It also allows the implementation of "Satisfy Any" with the new client CA certificate support - i.e. Satisfy Any can allow clients from the local network to skip client certificate challenge, or drop down to requesting basic authentication. It should be noted that including basic authentication requirements in Satisfy Any mode does prevent a 444 response from being sent, as the basic auth challenge requires the server to respond.
This commit is contained in:
@@ -11,6 +11,7 @@ const accessListClientCAsModel = require('../models/access_list_clientcas');
|
||||
const proxyHostModel = require('../models/proxy_host');
|
||||
const internalAuditLog = require('./audit-log');
|
||||
const internalNginx = require('./nginx');
|
||||
const config = require('../lib/config');
|
||||
|
||||
function omissions () {
|
||||
return ['is_deleted'];
|
||||
@@ -392,6 +393,26 @@ const internalAccessList = {
|
||||
// do nothing
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// delete the client CA file
|
||||
let clientca_file = internalAccessList.getClientCAFilename(row);
|
||||
|
||||
try {
|
||||
fs.unlinkSync(clientca_file);
|
||||
} catch (err) {
|
||||
// do nothing
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// delete the client geo file file
|
||||
let client_file = internalAccessList.getClientFilename(row);
|
||||
|
||||
try {
|
||||
fs.unlinkSync(client_file);
|
||||
} catch (err) {
|
||||
// do nothing
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// 4. audit log
|
||||
return internalAuditLog.add(access, {
|
||||
@@ -541,6 +562,15 @@ const internalAccessList = {
|
||||
return '/data/clientca/' + list.id;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} list
|
||||
* @param {Integer} list.id
|
||||
* @returns {String}
|
||||
*/
|
||||
getClientFilename: (list) => {
|
||||
return '/data/nginx/client/' + list.id + '.conf';
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} list
|
||||
* @param {Integer} list.id
|
||||
@@ -550,6 +580,7 @@ const internalAccessList = {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
build: (list) => {
|
||||
const renderEngine = utils.getRenderEngine();
|
||||
|
||||
const htPasswdBuild = new Promise((resolve, reject) => {
|
||||
logger.info('Building Access file #' + list.id + ' for: ' + list.name);
|
||||
@@ -630,8 +661,45 @@ const internalAccessList = {
|
||||
}
|
||||
});
|
||||
|
||||
const clientBuild = new Promise((resolve, reject) => {
|
||||
logger.info('Building Access client file #' + list.id + ' for: ' + list.name);
|
||||
|
||||
let template = null;
|
||||
const client_file = internalAccessList.getClientFilename(list);
|
||||
const data = {
|
||||
access_list: list
|
||||
};
|
||||
|
||||
try {
|
||||
template = fs.readFileSync(__dirname + '/../templates/access.conf', {encoding: 'utf8'});
|
||||
} catch (err) {
|
||||
reject(new error.ConfigurationError(err.message));
|
||||
return;
|
||||
}
|
||||
|
||||
return renderEngine
|
||||
.parseAndRender(template, data)
|
||||
.then((config_text) => {
|
||||
fs.writeFileSync(client_file, config_text, {encoding: 'utf8'});
|
||||
|
||||
if (config.debug()) {
|
||||
logger.success('Wrote config:', client_file, config_text);
|
||||
}
|
||||
|
||||
resolve(true);
|
||||
})
|
||||
.catch((err) => {
|
||||
if (config.debug()) {
|
||||
logger.warn('Could not write ' + client_file + ':', err.message);
|
||||
}
|
||||
|
||||
reject(new error.ConfigurationError(err.message));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Execute both promises concurrently
|
||||
return Promise.all([htPasswdBuild, caCertificateBuild]);
|
||||
return Promise.all([htPasswdBuild, caCertificateBuild, clientBuild]);
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user