Skip to content

Commit 15b629e

Browse files
committed
Add drop_unauthorized parameter to proxy hosts
drop_unauthorized returns 444 when a client is not authorized as opposed to 403. It can be used with Client Certificate authorization.
1 parent 14ab156 commit 15b629e

File tree

11 files changed

+89
-4
lines changed

11 files changed

+89
-4
lines changed

backend/doc/api.swagger.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
"ssl_forced": 0,
8383
"caching_enabled": 0,
8484
"block_exploits": 0,
85+
"drop_unauthorized": 0,
8586
"advanced_config": "sdfsdfsdf",
8687
"meta": {
8788
"letsencrypt_agree": false,
@@ -124,6 +125,7 @@
124125
"ssl_forced": 0,
125126
"caching_enabled": 0,
126127
"block_exploits": 0,
128+
"drop_unauthorized": 0,
127129
"advanced_config": "",
128130
"meta": {
129131
"letsencrypt_agree": false,
@@ -204,6 +206,7 @@
204206
"ssl_forced": 0,
205207
"caching_enabled": 0,
206208
"block_exploits": 0,
209+
"drop_unauthorized": 0,
207210
"advanced_config": "",
208211
"meta": {
209212
"letsencrypt_agree": false,
@@ -1117,6 +1120,7 @@
11171120
"ssl_forced",
11181121
"caching_enabled",
11191122
"block_exploits",
1123+
"drop_unauthorized",
11201124
"advanced_config",
11211125
"meta",
11221126
"allow_websocket_upgrade",
@@ -1184,6 +1188,9 @@
11841188
"block_exploits": {
11851189
"type": "integer"
11861190
},
1191+
"drop_unauthorized": {
1192+
"type": "integer"
1193+
},
11871194
"advanced_config": {
11881195
"type": "string"
11891196
},

backend/internal/nginx.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ const internalNginx = {
153153
const locationRendering = async () => {
154154
for (let i = 0; i < host.locations.length; i++) {
155155
let locationCopy = Object.assign({}, {access_list_id: host.access_list_id}, {certificate_id: host.certificate_id},
156-
{ssl_forced: host.ssl_forced}, {caching_enabled: host.caching_enabled}, {block_exploits: host.block_exploits},
156+
{ssl_forced: host.ssl_forced}, {caching_enabled: host.caching_enabled}, {block_exploits: host.block_exploits}, {drop_unauthorized: host.drop_unauthorized},
157157
{allow_websocket_upgrade: host.allow_websocket_upgrade}, {http2_support: host.http2_support},
158158
{hsts_enabled: host.hsts_enabled}, {hsts_subdomains: host.hsts_subdomains}, {access_list: host.access_list},
159159
{certificate: host.certificate}, host.locations[i]);
@@ -205,6 +205,16 @@ const internalNginx = {
205205
let origLocations;
206206

207207
// Manipulate the data a bit before sending it to the template
208+
if (typeof host.drop_unauthorized === 'undefined') {
209+
// Only proxy-hosts can have drop_unauthorized, but all hosts share
210+
// the templates.
211+
host.drop_unauthorized = false;
212+
}
213+
214+
if (typeof host.drop_unauthorized === 'number') {
215+
host.drop_unauthorized = !!host.drop_unauthorized;
216+
}
217+
208218
if (nice_host_type !== 'default') {
209219
host.use_default_location = true;
210220
if (typeof host.advanced_config !== 'undefined' && host.advanced_config) {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const migrate_name = 'drop_unauthorized';
2+
const logger = require('../logger').migrate;
3+
4+
/**
5+
* Migrate
6+
*
7+
* @see http://knexjs.org/#Schema
8+
*
9+
* @param {Object} knex
10+
* @param {Promise} Promise
11+
* @returns {Promise}
12+
*/
13+
exports.up = function (knex/*, Promise*/) {
14+
15+
logger.info('[' + migrate_name + '] Migrating Up...');
16+
17+
return knex.schema.table('proxy_host', function(proxy_host) {
18+
proxy_host.integer('drop_unauthorized').notNull().unsigned().defaultTo(0);
19+
}).then(() =>{
20+
logger.info('[' + migrate_name + '] Migrating Up Complete');
21+
});
22+
};
23+
24+
/**
25+
* Undo Migrate
26+
*
27+
* @param {Object} knex
28+
* @param {Promise} Promise
29+
* @returns {Promise}
30+
*/
31+
exports.down = function (knex/*, Promise*/) {
32+
logger.info('[' + migrate_name + '] Migrating Down...');
33+
34+
return knex.schema.table('proxy_host', function(proxy_host) {
35+
proxy_host.dropColumn('drop_unauthorized');
36+
}).then(() =>{
37+
logger.info('[' + migrate_name + '] Migrating Up Complete');
38+
});
39+
};

backend/schema/definitions.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,11 @@
231231
"example": true,
232232
"type": "boolean"
233233
},
234+
"drop_unauthorized": {
235+
"description": "Close TCP connection with no response when authorization fails",
236+
"example": true,
237+
"type": "boolean"
238+
},
234239
"caching_enabled": {
235240
"description": "Should we cache assets",
236241
"example": true,

backend/schema/endpoints/proxy-hosts.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@
5050
"block_exploits": {
5151
"$ref": "../definitions.json#/definitions/block_exploits"
5252
},
53+
"drop_unauthorized": {
54+
"$ref": "../definitions.json#/definitions/drop_unauthorized"
55+
},
5356
"caching_enabled": {
5457
"$ref": "../definitions.json#/definitions/caching_enabled"
5558
},
@@ -149,6 +152,9 @@
149152
"block_exploits": {
150153
"$ref": "#/definitions/block_exploits"
151154
},
155+
"drop_unauthorized": {
156+
"$ref": "#/definitions/drop_unauthorized"
157+
},
152158
"caching_enabled": {
153159
"$ref": "#/definitions/caching_enabled"
154160
},
@@ -239,6 +245,9 @@
239245
"block_exploits": {
240246
"$ref": "#/definitions/block_exploits"
241247
},
248+
"drop_unauthorized": {
249+
"$ref": "#/definitions/drop_unauthorized"
250+
},
242251
"caching_enabled": {
243252
"$ref": "#/definitions/caching_enabled"
244253
},
@@ -312,6 +321,9 @@
312321
"block_exploits": {
313322
"$ref": "#/definitions/block_exploits"
314323
},
324+
"drop_unauthorized": {
325+
"$ref": "#/definitions/drop_unauthorized"
326+
},
315327
"caching_enabled": {
316328
"$ref": "#/definitions/caching_enabled"
317329
},

backend/templates/_access.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{% if access_list.clientcas.size > 0 %}
33
# TLS Client Certificate Authorization
44
if ($ssl_client_verify != "SUCCESS") {
5-
return 403;
5+
return {% if drop_unauthorized == true %}444{% else %}403{% endif %};
66
}
77
{% endif %}
88
{% if access_list.items.length > 0 %}

frontend/js/app/nginx/proxy/form.ejs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
</label>
7373
</div>
7474
</div>
75-
<div class="col-sm-12 col-md-12">
75+
<div class="col-sm-6 col-md-6">
7676
<div class="form-group">
7777
<label class="custom-switch">
7878
<input type="checkbox" class="custom-switch-input" name="allow_websocket_upgrade" value="1"<%- allow_websocket_upgrade ? ' checked' : '' %>>
@@ -81,7 +81,15 @@
8181
</label>
8282
</div>
8383
</div>
84-
84+
<div class="col-sm-6 col-md-6">
85+
<div class="form-group">
86+
<label class="custom-switch">
87+
<input type="checkbox" class="custom-switch-input" name="drop_unauthorized" value="1"<%- drop_unauthorized ? ' checked' : '' %>>
88+
<span class="custom-switch-indicator"></span>
89+
<span class="custom-switch-description"><%- i18n('all-hosts', 'drop-unauthorized') %></span>
90+
</label>
91+
</div>
92+
</div>
8593
<div class="col-sm-12 col-md-12">
8694
<div class="form-group">
8795
<label class="form-label"><%- i18n('proxy-hosts', 'access-list') %></label>

frontend/js/app/nginx/proxy/form.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ module.exports = Mn.View.extend({
161161
// Manipulate
162162
data.forward_port = parseInt(data.forward_port, 10);
163163
data.block_exploits = !!data.block_exploits;
164+
data.drop_unauthorized = !!data.drop_unauthorized;
164165
data.caching_enabled = !!data.caching_enabled;
165166
data.allow_websocket_upgrade = !!data.allow_websocket_upgrade;
166167
data.http2_support = !!data.http2_support;

frontend/js/i18n/messages.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"domain-names": "Domain Names",
7676
"cert-provider": "Certificate Provider",
7777
"block-exploits": "Block Common Exploits",
78+
"drop-unauthorized": "Drop Unauthorized (444)",
7879
"caching-enabled": "Cache Assets",
7980
"ssl-certificate": "SSL Certificate",
8081
"none": "None",

frontend/js/models/proxy-host.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const model = Backbone.Model.extend({
2020
caching_enabled: false,
2121
allow_websocket_upgrade: false,
2222
block_exploits: false,
23+
drop_unauthorized: false,
2324
http2_support: false,
2425
advanced_config: '',
2526
enabled: true,

test/cypress/integration/api/Hosts.spec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ describe('Hosts endpoints', () => {
2727
advanced_config: '',
2828
locations: [],
2929
block_exploits: false,
30+
drop_unauthorized: false,
3031
caching_enabled: false,
3132
allow_websocket_upgrade: false,
3233
http2_support: false,

0 commit comments

Comments
 (0)