Skip to content

Commit 02d3093

Browse files
committed
Finalizes SSL Passthrough hosts
1 parent ab026e5 commit 02d3093

File tree

13 files changed

+95
-25
lines changed

13 files changed

+95
-25
lines changed

backend/internal/nginx.js

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const internalNginx = {
2525
*/
2626
configure: (model, host_type, host) => {
2727
let combined_meta = {};
28+
const sslPassthroughEnabled = internalNginx.sslPassthroughEnabled();
2829

2930
return internalNginx.test()
3031
.then(() => {
@@ -33,7 +34,25 @@ const internalNginx = {
3334
return internalNginx.deleteConfig(host_type, host); // Don't throw errors, as the file may not exist at all
3435
})
3536
.then(() => {
36-
return internalNginx.generateConfig(host_type, host);
37+
if(host_type === 'ssl_passthrough_host' && !sslPassthroughEnabled){
38+
// ssl passthrough is disabled
39+
const meta = {
40+
nginx_online: false,
41+
nginx_err: 'SSL passthrough is not enabled in environment'
42+
};
43+
44+
return passthroughHostModel
45+
.query()
46+
.where('is_deleted', 0)
47+
.andWhere('enabled', 1)
48+
.patch({
49+
meta
50+
}).then(() => {
51+
return internalNginx.deleteConfig('ssl_passthrough_host', host, false);
52+
});
53+
} else {
54+
return internalNginx.generateConfig(host_type, host);
55+
}
3756
})
3857
.then(() => {
3958
// Test nginx again and update meta with result
@@ -46,11 +65,17 @@ const internalNginx = {
4665
});
4766

4867
if(host_type === 'ssl_passthrough_host'){
49-
return passthroughHostModel
50-
.query()
51-
.patch({
52-
meta: combined_meta
53-
});
68+
// If passthrough is disabled we have already marked the hosts as offline
69+
if (sslPassthroughEnabled) {
70+
return passthroughHostModel
71+
.query()
72+
.where('is_deleted', 0)
73+
.andWhere('enabled', 1)
74+
.patch({
75+
meta: combined_meta
76+
});
77+
}
78+
return Promise.resolve();
5479
}
5580

5681
return model
@@ -84,6 +109,18 @@ const internalNginx = {
84109
nginx_err: valid_lines.join('\n')
85110
});
86111

112+
if(host_type === 'ssl_passthrough_host'){
113+
return passthroughHostModel
114+
.query()
115+
.where('is_deleted', 0)
116+
.andWhere('enabled', 1)
117+
.patch({
118+
meta: combined_meta
119+
}).then(() => {
120+
return internalNginx.deleteConfig('ssl_passthrough_host', host, true);
121+
});
122+
}
123+
87124
return model
88125
.query()
89126
.where('id', host.id)
@@ -241,7 +278,7 @@ const internalNginx = {
241278
}),
242279
}
243280
} else {
244-
internalNginx.deleteConfig(host_type, host)
281+
internalNginx.deleteConfig(host_type, host, false)
245282
}
246283

247284
} else if (host_type !== 'default') {
@@ -470,7 +507,7 @@ const internalNginx = {
470507
return (enabled === 'on' || enabled === 'true' || enabled === '1' || enabled === 'yes');
471508
}
472509

473-
return true;
510+
return false;
474511
},
475512

476513
/**

backend/routes/api/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ router.use('/nginx/certificates', require('./nginx/certificates'));
4242

4343
router.get('/ssl-passthrough-enabled', (req, res/*, next*/) => {
4444
res.status(200).send({
45-
status: 'OK',
45+
status: 'OK',
4646
ssl_passthrough_enabled: internalNginx.sslPassthroughEnabled()
4747
});
4848
});

backend/setup.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ const setupLogrotation = () => {
230230
* @returns {Promise}
231231
*/
232232
const setupSslPassthrough = () => {
233-
return internalNginx.configure(passthroughHostModel, 'ssl_passthrough_host', {}).then(() => internalNginx.reload());
233+
return internalNginx.configure(passthroughHostModel, 'ssl_passthrough_host', {});
234234
};
235235

236236
module.exports = function () {

docker/rootfs/etc/nginx/nginx.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ http {
8585

8686
stream {
8787
# Files generated by NPM
88-
include /data/nginx/ssl_passthrough_host/hosts.conf;
88+
include /data/nginx/ssl_passthrough_host/hosts[.]conf;
8989
include /data/nginx/stream/*.conf;
9090

9191
# Custom

docs/advanced-config/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,28 @@ value by specifying it as a Docker environment variable. The default if not spec
172172
X_FRAME_OPTIONS: "sameorigin"
173173
...
174174
```
175+
176+
## SSL Passthrough
177+
178+
SSL Passthrough will allow you to proxy a server without [SSL termination](https://en.wikipedia.org/wiki/TLS_termination_proxy). This means the SSL encryption of the server will be passed right through the proxy, retaining the original certificate.
179+
180+
Because of the SSL encryption the proxy does not know anything about the traffic and it just relies on an SSL feature called [Server Name Indication](https://en.wikipedia.org/wiki/Server_Name_Indication) to know where to send this network packet. This also means if the client does not provide this additional information, accessing the site through the proxy won't be possible. But most modern browsers include this information a HTTPS requests.
181+
182+
Due to nginx constraints using SSL Passthrough comes with **a performance penalty for other hosts**, since all hosts (including normal proxy hosts) now have to pass through this additional step and basically being proxied twice. If you want to retain the upstream SSL certificate but do not need your service to be available on port 443, it is recommended to use a stream host instead.
183+
184+
To enable SSL Passthrough on your npm instance you need to do two things: add the environment variable `ENABLE_SSL_PASSTHROUGH` with the value `"true"`, and expose port 444 instead of 443 to the outside as port 443.
185+
186+
```yml
187+
version: '3'
188+
services:
189+
app:
190+
...
191+
ports:
192+
- '80:80'
193+
- '81:81'
194+
- '443:444' # Expose internal port 444 instead of 443 as SSL port
195+
environment:
196+
...
197+
ENABLE_SSL_PASSTHROUGH: "true" # Enable SSL Passthrough
198+
...
199+
```

frontend/js/app/controller.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ module.exports = {
253253
*
254254
* @param model
255255
*/
256-
showNginxSslPassthroughConfirm: function (model) {
256+
showNginxSslPassthroughDeleteConfirm: function (model) {
257257
if (Cache.User.isAdmin() || Cache.User.canManage('ssl_passthrough_hosts')) {
258258
require(['./main', './nginx/ssl-passthrough/delete'], function (App, View) {
259259
App.UI.showModalDialog(new View({model: model}));

frontend/js/app/nginx/ssl-passthrough/form.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<div class="row">
99
<div class="col-sm-12 col-md-12">
1010
<div class="form-group">
11-
<label class="form-label"><%- i18n('all-hosts', '___domain-names') %> <span class="form-required">*</span></label>
11+
<label class="form-label"><%- i18n('all-hosts', '___domain-name') %> <span class="form-required">*</span></label>
1212
<input type="text" name="domain_name" class="form-control" id="input-___domain" placeholder="example.com" value="<%- domain_name %>" required>
1313
</div>
1414
</div>

frontend/js/app/nginx/ssl-passthrough/form.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ module.exports = Mn.View.extend({
1212
className: 'modal-dialog',
1313

1414
ui: {
15-
form: 'form',
15+
form: 'form',
1616
forwarding_host: 'input[name="forwarding_host"]',
17-
buttons: '.modal-footer button',
18-
cancel: 'button.cancel',
19-
save: 'button.save'
17+
buttons: '.modal-footer button',
18+
cancel: 'button.cancel',
19+
save: 'button.save'
2020
},
2121

2222
events: {

frontend/js/app/nginx/ssl-passthrough/list/main.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<thead>
22
<th width="30">&nbsp;</th>
3-
<th><%- i18n('ssl-passthrough-hosts', '___domain-name') %></th>
3+
<th><%- i18n('all-hosts', '___domain-name') %></th>
44
<th><%- i18n('str', 'destination') %></th>
55
<th><%- i18n('str', 'status') %></th>
66
<% if (canManage) { %>

frontend/js/app/nginx/ssl-passthrough/main.ejs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
<div class="card">
2-
<div class="card-status bg-blue"></div>
2+
<div class="card-status bg-dark"></div>
33
<div class="card-header">
44
<h3 class="card-title"><%- i18n('ssl-passthrough-hosts', 'title') %></h3>
55
<div class="card-options">
66
<a href="#" class="btn btn-outline-secondary btn-sm ml-2 help"><i class="fe fe-help-circle"></i></a>
77
<% if (showAddButton) { %>
8-
<a href="#" class="btn btn-outline-blue btn-sm ml-2 add-item"><%- i18n('ssl-passthrough-hosts', 'add') %></a>
8+
<a href="#" class="btn btn-outline-dark btn-sm ml-2 add-item"><%- i18n('ssl-passthrough-hosts', 'add') %></a>
99
<% } %>
1010
</div>
1111
</div>
1212
<div class="card-body no-padding min-100">
13-
<div id="ssl-passthrough-disabled-info">
14-
Disabled
13+
<div id="ssl-passthrough-disabled-info" class="alert alert-danger rounded-0 mb-0">
14+
<%= i18n('ssl-passthrough-hosts', 'is-disabled-warning', {url: 'https://nginxproxymanager.com/advanced-config/#ssl-passthrough'}) %>
1515
</div>
1616
<div class="dimmer active">
1717
<div class="loader"></div>

0 commit comments

Comments
 (0)