WIP: complete control of new passthrough host type

This commit is contained in:
chaptergy
2021-10-10 23:49:57 +02:00
parent 5b1f0cead1
commit 5a2548c89d
19 changed files with 126 additions and 85 deletions

View File

@ -74,12 +74,10 @@ app.use(function (err, req, res, next) {
}
// Not every error is worth logging - but this is good for now until it gets annoying.
if (typeof err.stack !== 'undefined' && err.stack) {
if (process.env.NODE_ENV === 'development' || process.env.DEBUG) {
log.debug(err.stack);
} else if (typeof err.public == 'undefined' || !err.public) {
log.warn(err.message);
}
if (process.env.NODE_ENV === 'development' || process.env.DEBUG) {
log.debug(err);
} else if (typeof err.stack !== 'undefined' && err.stack && (typeof err.public == 'undefined' || !err.public)) {
log.warn(err.message);
}
res

View File

@ -206,14 +206,21 @@ const internalHost = {
if (existing_rows && existing_rows.length) {
existing_rows.map(function (existing_row) {
existing_row.domain_names.map(function (existing_hostname) {
function checkHostname(existing_hostname) {
// Does this domain match?
if (existing_hostname.toLowerCase() === hostname.toLowerCase()) {
if (!ignore_id || ignore_id !== existing_row.id) {
is_taken = true;
}
}
});
}
if (existing_row.domain_names) {
existing_row.domain_names.map(checkHostname);
} else if (existing_row.domain_name) {
checkHostname(existing_row.domain_name);
}
});
}

View File

@ -236,8 +236,8 @@ const internalNginx = {
host = {
all_passthrough_hosts: allHosts.map((host) => {
// Replace dots in domain
host.escaped_name = host.domain_name.replace(/\./, '_');
host.forwarding_host = internalNginx.addIpv6Brackets(host.forwarding_host);
return host;
}),
}
} else {

View File

@ -19,20 +19,12 @@ const internalPassthroughHost = {
create: (access, data) => {
return access.can('ssl_passthrough_hosts:create', data)
.then(() => {
// Get a list of the domain names and check each of them against existing records
let domain_name_check_promises = [];
data.domain_names.map(function (domain_name) {
domain_name_check_promises.push(internalHost.isHostnameTaken(domain_name));
});
return Promise.all(domain_name_check_promises)
.then((check_results) => {
check_results.map(function (result) {
if (result.is_taken) {
throw new error.ValidationError(result.hostname + ' is already in use');
}
});
// Get the domain name and check it against existing records
return internalHost.isHostnameTaken(data.domain_name)
.then((result) => {
if (result.is_taken) {
throw new error.ValidationError(result.hostname + ' is already in use');
}
});
}).then((/*access_data*/) => {
data.owner_user_id = access.token.getUserId(1);
@ -57,7 +49,7 @@ const internalPassthroughHost = {
// Add to audit log
return internalAuditLog.add(access, {
action: 'created',
object_type: 'ssl_passthrough_host',
object_type: 'ssl-passthrough-host',
object_id: row.id,
meta: data
})
@ -76,21 +68,13 @@ const internalPassthroughHost = {
update: (access, data) => {
return access.can('ssl_passthrough_hosts:update', data.id)
.then((/*access_data*/) => {
// Get a list of the domain names and check each of them against existing records
let domain_name_check_promises = [];
if (typeof data.domain_names !== 'undefined') {
data.domain_names.map(function (domain_name) {
domain_name_check_promises.push(internalHost.isHostnameTaken(domain_name, 'ssl_passthrough', data.id));
});
return Promise.all(domain_name_check_promises)
.then((check_results) => {
check_results.map(function (result) {
if (result.is_taken) {
throw new error.ValidationError(result.hostname + ' is already in use');
}
});
// Get the domain name and check it against existing records
if (typeof data.domain_name !== 'undefined') {
return internalHost.isHostnameTaken(data.domain_name, 'ssl_passthrough', data.id)
.then((result) => {
if (result.is_taken) {
throw new error.ValidationError(result.hostname + ' is already in use');
}
});
}
}).then((/*access_data*/) => {
@ -116,7 +100,7 @@ const internalPassthroughHost = {
// Add to audit log
return internalAuditLog.add(access, {
action: 'updated',
object_type: 'ssl_passthrough_host',
object_type: 'ssl-passthrough-host',
object_id: row.id,
meta: data
})
@ -207,7 +191,7 @@ const internalPassthroughHost = {
// Add to audit log
return internalAuditLog.add(access, {
action: 'deleted',
object_type: 'ssl_passthrough_host',
object_type: 'ssl-passthrough-host',
object_id: row.id,
meta: _.omit(row, omissions())
});
@ -256,7 +240,7 @@ const internalPassthroughHost = {
// Add to audit log
return internalAuditLog.add(access, {
action: 'enabled',
object_type: 'ssl_passthrough_host',
object_type: 'ssl-passthrough-host',
object_id: row.id,
meta: _.omit(row, omissions())
});
@ -305,7 +289,7 @@ const internalPassthroughHost = {
// Add to audit log
return internalAuditLog.add(access, {
action: 'disabled',
object_type: 'ssl_passthrough_host',
object_type: 'ssl-passthrough-host',
object_id: row.id,
meta: _.omit(row, omissions())
});

View File

@ -20,13 +20,30 @@ exports.up = function (knex/*, Promise*/) {
table.integer('owner_user_id').notNull().unsigned();
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
table.string('domain_name').notNull();
table.string('forward_ip').notNull();
table.string('forwarding_host').notNull();
table.integer('forwarding_port').notNull().unsigned();
table.integer('enabled').notNull().unsigned().defaultTo(1);
table.json('meta').notNull();
}).then(() => {
logger.info('[' + migrate_name + '] Table created');
})
.then(() => {
logger.info('[' + migrate_name + '] Table created');
});
.then(() => {
return knex.schema.table('user_permission', (table) => {
table.string('ssl_passthrough_hosts').notNull();
})
.then(() => {
return knex('user_permission').update('ssl_passthrough_hosts', knex.ref('streams'));
})
.then(() => {
return knex.schema.alterTable('user_permission', (table) => {
table.string('ssl_passthrough_hosts').notNullable().alter();
});
})
.then(() => {
logger.info('[' + migrate_name + '] permissions updated');
});
})
;
};
/**
@ -39,8 +56,12 @@ exports.up = function (knex/*, Promise*/) {
exports.down = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Down...');
return knex.schema.dropTable('stream')
return knex.schema.dropTable('stream').then(() => {
return knex.schema.table('user_permission', (table) => {
table.dropColumn('ssl_passthrough_hosts');
})
})
.then(function () {
logger.info('[' + migrate_name + '] Table altered');
logger.info('[' + migrate_name + '] Table altered and permissions updated');
});
};

View File

@ -73,7 +73,7 @@ router
* /api/nginx/ssl-passthrough-hosts/123
*/
router
.route('/:ssl_passthrough_host_id')
.route('/:host_id')
.options((req, res) => {
res.sendStatus(204);
})
@ -86,7 +86,7 @@ router
*/
.get((req, res, next) => {
validator({
required: ['ssl_passthrough_host_id'],
required: ['host_id'],
additionalProperties: false,
properties: {
host_id: {

View File

@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "endpoints/ssl-passthough-hosts",
"$id": "endpoints/ssl-passthrough-hosts",
"title": "SSL Passthrough Hosts",
"description": "Endpoints relating to SSL Passthrough Hosts",
"stability": "stable",

View File

@ -107,14 +107,15 @@ const setupDefaultUser = () => {
})
.then(() => {
return userPermissionModel.query().insert({
user_id: user.id,
visibility: 'all',
proxy_hosts: 'manage',
redirection_hosts: 'manage',
dead_hosts: 'manage',
streams: 'manage',
access_lists: 'manage',
certificates: 'manage',
user_id: user.id,
visibility: 'all',
proxy_hosts: 'manage',
redirection_hosts: 'manage',
dead_hosts: 'manage',
ssl_passthrough_hosts: 'manage',
streams: 'manage',
access_lists: 'manage',
certificates: 'manage',
});
});
})
@ -229,7 +230,7 @@ const setupLogrotation = () => {
* @returns {Promise}
*/
const setupSslPassthrough = () => {
return internalNginx.configure(passthroughHostModel, 'ssl_passthrough_host', {});
return internalNginx.configure(passthroughHostModel, 'ssl_passthrough_host', {}).then(() => internalNginx.reload());
};
module.exports = function () {

View File

@ -4,16 +4,16 @@
map $ssl_preread_server_name $name {
{% for host in all_passthrough_hosts %}
{% if enabled %}
{{ host.domain_name }} ssl_passthrough_{{ host.escaped_name }}
{% if host.enabled %}
{{ host.domain_name }} ssl_passthrough_{{ host.domain_name }};
{% endif %}
{% endfor %}
default https_default_backend;
}
{% for host in all_passthrough_hosts %}
{% if enabled %}
upstream ssl_passthrough_{{ host.escaped_name }} {
{% if host.enabled %}
upstream ssl_passthrough_{{ host.domain_name }} {
server {{host.forwarding_host}}:{{host.forwarding_port}};
}
{% endif %}
@ -34,6 +34,8 @@ server {
proxy_pass $name;
ssl_preread on;
error_log /data/logs/ssl-passthrough-hosts_error.log warn;
# Custom
include /data/nginx/custom/server_ssl_passthrough[.]conf;
}