Add template support for all host types to do client CA authorization

When an access list contains client CAs, the combined CA auth file is
added to all location blocks via an `if` statement. This allows
LetsEncrypt and other support paths to work, while correctly denying
access to the protected resources.
This commit is contained in:
Will Rouesnel
2023-05-29 02:29:42 +10:00
parent fb766d14e9
commit 366efc8ac2
4 changed files with 17 additions and 7 deletions

View File

@@ -264,7 +264,6 @@ const internalAccessList = {
}, true /* <- skip masking */); }, true /* <- skip masking */);
}) })
.then((row) => { .then((row) => {
console.log(row);
return internalAccessList.build(row) return internalAccessList.build(row)
.then(() => { .then(() => {
if (row.proxy_host_count) { if (row.proxy_host_count) {
@@ -603,7 +602,6 @@ const internalAccessList = {
}); });
const caCertificateBuild = new Promise((resolve, reject) => { const caCertificateBuild = new Promise((resolve, reject) => {
// TODO: we need to ensure this rebuild is run if any certificates change
logger.info('Building Client CA file #' + list.id + ' for: ' + list.name); logger.info('Building Client CA file #' + list.id + ' for: ' + list.name);
let clientca_file = internalAccessList.getClientCAFilename(list); let clientca_file = internalAccessList.getClientCAFilename(list);

View File

@@ -74,7 +74,7 @@ const internalProxyHost = {
// re-fetch with cert // re-fetch with cert
return internalProxyHost.get(access, { return internalProxyHost.get(access, {
id: row.id, id: row.id,
expand: ['certificate', 'owner', 'access_list.[clients,items]'] expand: ['certificate', 'owner', 'access_list.[clientcas.certificate,clients,items]']
}); });
}) })
.then((row) => { .then((row) => {
@@ -188,7 +188,7 @@ const internalProxyHost = {
.then(() => { .then(() => {
return internalProxyHost.get(access, { return internalProxyHost.get(access, {
id: data.id, id: data.id,
expand: ['owner', 'certificate', 'access_list.[clients,items]'] expand: ['owner', 'certificate', 'access_list.[clientcas.certificate,clients,items]']
}) })
.then((row) => { .then((row) => {
if (!row.enabled) { if (!row.enabled) {
@@ -225,7 +225,7 @@ const internalProxyHost = {
.query() .query()
.where('is_deleted', 0) .where('is_deleted', 0)
.andWhere('id', data.id) .andWhere('id', data.id)
.allowGraph('[owner,access_list,access_list.[clients,items],certificate]') .allowGraph('[owner,access_list.[clientcas.certificate,clients,items],certificate]')
.first(); .first();
if (access_data.permission_visibility !== 'all') { if (access_data.permission_visibility !== 'all') {
@@ -308,7 +308,7 @@ const internalProxyHost = {
.then(() => { .then(() => {
return internalProxyHost.get(access, { return internalProxyHost.get(access, {
id: data.id, id: data.id,
expand: ['certificate', 'owner', 'access_list'] expand: ['certificate', 'owner', 'access_list.[clientcas.certificate]']
}); });
}) })
.then((row) => { .then((row) => {

View File

@@ -1,4 +1,10 @@
{% if access_list_id > 0 %} {% if access_list_id > 0 %}
{% if access_list.clientcas.size > 0 %}
# TLS Client Certificate Authorization
if ($ssl_client_verify != "SUCCESS") {
return 403;
}
{% endif %}
{% if access_list.items.length > 0 %} {% if access_list.items.length > 0 %}
# Authorization # Authorization
auth_basic "Authorization required"; auth_basic "Authorization required";

View File

@@ -11,4 +11,10 @@
ssl_certificate_key /data/custom_ssl/npm-{{ certificate_id }}/privkey.pem; ssl_certificate_key /data/custom_ssl/npm-{{ certificate_id }}/privkey.pem;
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if access_list_id > 0 -%}
{% if access_list.clientcas.size > 0 %}
# Client Certificate Authorization ({{access_list.clientcas.size}} CAs)
ssl_client_certificate /data/clientca/{{ access_list_id }};
ssl_verify_client optional;
{% endif %}
{% endif %}