Skip to content

Commit 5a2548c

Browse files
committed
WIP: complete control of new passthrough host type
1 parent 5b1f0ce commit 5a2548c

File tree

19 files changed

+126
-85
lines changed

19 files changed

+126
-85
lines changed

backend/app.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,10 @@ app.use(function (err, req, res, next) {
7474
}
7575

7676
// Not every error is worth logging - but this is good for now until it gets annoying.
77-
if (typeof err.stack !== 'undefined' && err.stack) {
78-
if (process.env.NODE_ENV === 'development' || process.env.DEBUG) {
79-
log.debug(err.stack);
80-
} else if (typeof err.public == 'undefined' || !err.public) {
81-
log.warn(err.message);
82-
}
77+
if (process.env.NODE_ENV === 'development' || process.env.DEBUG) {
78+
log.debug(err);
79+
} else if (typeof err.stack !== 'undefined' && err.stack && (typeof err.public == 'undefined' || !err.public)) {
80+
log.warn(err.message);
8381
}
8482

8583
res

backend/internal/host.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,14 +206,21 @@ const internalHost = {
206206

207207
if (existing_rows && existing_rows.length) {
208208
existing_rows.map(function (existing_row) {
209-
existing_row.domain_names.map(function (existing_hostname) {
209+
210+
function checkHostname(existing_hostname) {
210211
// Does this ___domain match?
211212
if (existing_hostname.toLowerCase() === hostname.toLowerCase()) {
212213
if (!ignore_id || ignore_id !== existing_row.id) {
213214
is_taken = true;
214215
}
215216
}
216-
});
217+
}
218+
219+
if (existing_row.domain_names) {
220+
existing_row.domain_names.map(checkHostname);
221+
} else if (existing_row.domain_name) {
222+
checkHostname(existing_row.domain_name);
223+
}
217224
});
218225
}
219226

backend/internal/nginx.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,8 @@ const internalNginx = {
236236
host = {
237237
all_passthrough_hosts: allHosts.map((host) => {
238238
// Replace dots in ___domain
239-
host.escaped_name = host.domain_name.replace(/\./, '_');
240239
host.forwarding_host = internalNginx.addIpv6Brackets(host.forwarding_host);
240+
return host;
241241
}),
242242
}
243243
} else {

backend/internal/ssl-passthrough-host.js

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,12 @@ const internalPassthroughHost = {
1919
create: (access, data) => {
2020
return access.can('ssl_passthrough_hosts:create', data)
2121
.then(() => {
22-
// Get a list of the ___domain names and check each of them against existing records
23-
let domain_name_check_promises = [];
24-
25-
data.domain_names.map(function (domain_name) {
26-
domain_name_check_promises.push(internalHost.isHostnameTaken(domain_name));
27-
});
28-
29-
return Promise.all(domain_name_check_promises)
30-
.then((check_results) => {
31-
check_results.map(function (result) {
32-
if (result.is_taken) {
33-
throw new error.ValidationError(result.hostname + ' is already in use');
34-
}
35-
});
22+
// Get the ___domain name and check it against existing records
23+
return internalHost.isHostnameTaken(data.domain_name)
24+
.then((result) => {
25+
if (result.is_taken) {
26+
throw new error.ValidationError(result.hostname + ' is already in use');
27+
}
3628
});
3729
}).then((/*access_data*/) => {
3830
data.owner_user_id = access.token.getUserId(1);
@@ -57,7 +49,7 @@ const internalPassthroughHost = {
5749
// Add to audit log
5850
return internalAuditLog.add(access, {
5951
action: 'created',
60-
object_type: 'ssl_passthrough_host',
52+
object_type: 'ssl-passthrough-host',
6153
object_id: row.id,
6254
meta: data
6355
})
@@ -76,21 +68,13 @@ const internalPassthroughHost = {
7668
update: (access, data) => {
7769
return access.can('ssl_passthrough_hosts:update', data.id)
7870
.then((/*access_data*/) => {
79-
// Get a list of the ___domain names and check each of them against existing records
80-
let domain_name_check_promises = [];
81-
82-
if (typeof data.domain_names !== 'undefined') {
83-
data.domain_names.map(function (domain_name) {
84-
domain_name_check_promises.push(internalHost.isHostnameTaken(domain_name, 'ssl_passthrough', data.id));
85-
});
86-
87-
return Promise.all(domain_name_check_promises)
88-
.then((check_results) => {
89-
check_results.map(function (result) {
90-
if (result.is_taken) {
91-
throw new error.ValidationError(result.hostname + ' is already in use');
92-
}
93-
});
71+
// Get the ___domain name and check it against existing records
72+
if (typeof data.domain_name !== 'undefined') {
73+
return internalHost.isHostnameTaken(data.domain_name, 'ssl_passthrough', data.id)
74+
.then((result) => {
75+
if (result.is_taken) {
76+
throw new error.ValidationError(result.hostname + ' is already in use');
77+
}
9478
});
9579
}
9680
}).then((/*access_data*/) => {
@@ -116,7 +100,7 @@ const internalPassthroughHost = {
116100
// Add to audit log
117101
return internalAuditLog.add(access, {
118102
action: 'updated',
119-
object_type: 'ssl_passthrough_host',
103+
object_type: 'ssl-passthrough-host',
120104
object_id: row.id,
121105
meta: data
122106
})
@@ -207,7 +191,7 @@ const internalPassthroughHost = {
207191
// Add to audit log
208192
return internalAuditLog.add(access, {
209193
action: 'deleted',
210-
object_type: 'ssl_passthrough_host',
194+
object_type: 'ssl-passthrough-host',
211195
object_id: row.id,
212196
meta: _.omit(row, omissions())
213197
});
@@ -256,7 +240,7 @@ const internalPassthroughHost = {
256240
// Add to audit log
257241
return internalAuditLog.add(access, {
258242
action: 'enabled',
259-
object_type: 'ssl_passthrough_host',
243+
object_type: 'ssl-passthrough-host',
260244
object_id: row.id,
261245
meta: _.omit(row, omissions())
262246
});
@@ -305,7 +289,7 @@ const internalPassthroughHost = {
305289
// Add to audit log
306290
return internalAuditLog.add(access, {
307291
action: 'disabled',
308-
object_type: 'ssl_passthrough_host',
292+
object_type: 'ssl-passthrough-host',
309293
object_id: row.id,
310294
meta: _.omit(row, omissions())
311295
});

backend/migrations/20211010141200_ssl_passthrough_host.js

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,30 @@ exports.up = function (knex/*, Promise*/) {
2020
table.integer('owner_user_id').notNull().unsigned();
2121
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
2222
table.string('domain_name').notNull();
23-
table.string('forward_ip').notNull();
23+
table.string('forwarding_host').notNull();
2424
table.integer('forwarding_port').notNull().unsigned();
25+
table.integer('enabled').notNull().unsigned().defaultTo(1);
2526
table.json('meta').notNull();
27+
}).then(() => {
28+
logger.info('[' + migrate_name + '] Table created');
2629
})
27-
.then(() => {
28-
logger.info('[' + migrate_name + '] Table created');
29-
});
30+
.then(() => {
31+
return knex.schema.table('user_permission', (table) => {
32+
table.string('ssl_passthrough_hosts').notNull();
33+
})
34+
.then(() => {
35+
return knex('user_permission').update('ssl_passthrough_hosts', knex.ref('streams'));
36+
})
37+
.then(() => {
38+
return knex.schema.alterTable('user_permission', (table) => {
39+
table.string('ssl_passthrough_hosts').notNullable().alter();
40+
});
41+
})
42+
.then(() => {
43+
logger.info('[' + migrate_name + '] permissions updated');
44+
});
45+
})
46+
;
3047
};
3148

3249
/**
@@ -39,8 +56,12 @@ exports.up = function (knex/*, Promise*/) {
3956
exports.down = function (knex/*, Promise*/) {
4057
logger.info('[' + migrate_name + '] Migrating Down...');
4158

42-
return knex.schema.dropTable('stream')
59+
return knex.schema.dropTable('stream').then(() => {
60+
return knex.schema.table('user_permission', (table) => {
61+
table.dropColumn('ssl_passthrough_hosts');
62+
})
63+
})
4364
.then(function () {
44-
logger.info('[' + migrate_name + '] Table altered');
65+
logger.info('[' + migrate_name + '] Table altered and permissions updated');
4566
});
4667
};

backend/routes/api/nginx/ssl_passthrough_hosts.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ router
7373
* /api/nginx/ssl-passthrough-hosts/123
7474
*/
7575
router
76-
.route('/:ssl_passthrough_host_id')
76+
.route('/:host_id')
7777
.options((req, res) => {
7878
res.sendStatus(204);
7979
})
@@ -86,7 +86,7 @@ router
8686
*/
8787
.get((req, res, next) => {
8888
validator({
89-
required: ['ssl_passthrough_host_id'],
89+
required: ['host_id'],
9090
additionalProperties: false,
9191
properties: {
9292
host_id: {

backend/schema/endpoints/ssl-passthrough-hosts.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "http://json-schema.org/draft-07/schema#",
3-
"$id": "endpoints/ssl-passthough-hosts",
3+
"$id": "endpoints/ssl-passthrough-hosts",
44
"title": "SSL Passthrough Hosts",
55
"description": "Endpoints relating to SSL Passthrough Hosts",
66
"stability": "stable",

backend/setup.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,15 @@ const setupDefaultUser = () => {
107107
})
108108
.then(() => {
109109
return userPermissionModel.query().insert({
110-
user_id: user.id,
111-
visibility: 'all',
112-
proxy_hosts: 'manage',
113-
redirection_hosts: 'manage',
114-
dead_hosts: 'manage',
115-
streams: 'manage',
116-
access_lists: 'manage',
117-
certificates: 'manage',
110+
user_id: user.id,
111+
visibility: 'all',
112+
proxy_hosts: 'manage',
113+
redirection_hosts: 'manage',
114+
dead_hosts: 'manage',
115+
ssl_passthrough_hosts: 'manage',
116+
streams: 'manage',
117+
access_lists: 'manage',
118+
certificates: 'manage',
118119
});
119120
});
120121
})
@@ -229,7 +230,7 @@ const setupLogrotation = () => {
229230
* @returns {Promise}
230231
*/
231232
const setupSslPassthrough = () => {
232-
return internalNginx.configure(passthroughHostModel, 'ssl_passthrough_host', {});
233+
return internalNginx.configure(passthroughHostModel, 'ssl_passthrough_host', {}).then(() => internalNginx.reload());
233234
};
234235

235236
module.exports = function () {

backend/templates/ssl_passthrough_host.conf

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44

55
map $ssl_preread_server_name $name {
66
{% for host in all_passthrough_hosts %}
7-
{% if enabled %}
8-
{{ host.domain_name }} ssl_passthrough_{{ host.escaped_name }}
7+
{% if host.enabled %}
8+
{{ host.domain_name }} ssl_passthrough_{{ host.domain_name }};
99
{% endif %}
1010
{% endfor %}
1111
default https_default_backend;
1212
}
1313

1414
{% for host in all_passthrough_hosts %}
15-
{% if enabled %}
16-
upstream ssl_passthrough_{{ host.escaped_name }} {
15+
{% if host.enabled %}
16+
upstream ssl_passthrough_{{ host.domain_name }} {
1717
server {{host.forwarding_host}}:{{host.forwarding_port}};
1818
}
1919
{% endif %}
@@ -34,6 +34,8 @@ server {
3434
proxy_pass $name;
3535
ssl_preread on;
3636

37+
error_log /data/logs/ssl-passthrough-hosts_error.log warn;
38+
3739
# Custom
3840
include /data/nginx/custom/server_ssl_passthrough[.]conf;
3941
}

docker/docker-compose.dev.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ services:
2323
DB_MYSQL_USER: "npm"
2424
DB_MYSQL_PASSWORD: "npm"
2525
DB_MYSQL_NAME: "npm"
26-
ENABLE_SSL_PASSTHROUGH: "true"
26+
# ENABLE_SSL_PASSTHROUGH: "true"
2727
# DB_SQLITE_FILE: "/data/database.sqlite"
2828
# DISABLE_IPV6: "true"
2929
volumes:
@@ -41,6 +41,8 @@ services:
4141
container_name: npm_db
4242
networks:
4343
- nginx_proxy_manager
44+
ports:
45+
- 33306:3306
4446
environment:
4547
MYSQL_ROOT_PASSWORD: "npm"
4648
MYSQL_DATABASE: "npm"

0 commit comments

Comments
 (0)