www/nginx: add request size limitation, satisfy and fix some generic bugs (#1009)

This commit is contained in:
Fabian Franz BSc
2018-11-21 22:46:33 +01:00
committed by GitHub
parent 5d0b18be05
commit a66f6c97b4
7 changed files with 105 additions and 6 deletions
+1
View File
@@ -14,6 +14,7 @@ Plugin Changelog
* add TCP load balancing [1]
* add support for IP based ACLs
* add log rotation (contributed by Julius Cesar Camargo [2]
* add support for satisfy, body size limitation
* change: allow to disable internal bot protection (contributed by @fzoske) [3]
* change: do not save when no change in the list happened to prevent filling the log history
* fix: translate a german string in upstream server to english
@@ -34,6 +34,20 @@
<label>File System Root</label>
<type>text</type>
</field>
<field>
<id>httpserver.max_body_size</id>
<label>Maximum Body Size</label>
<type>text</type>
<advanced>true</advanced>
<help>If the request is larger, it will be rejectet with error 413 (Request Entity Too Large). For example, you can enter 200m.</help>
</field>
<field>
<id>httpserver.body_buffer_size</id>
<label>Body Buffer Size</label>
<type>text</type>
<advanced>true</advanced>
<help>If the request exceeds this size, it will be written to disk. Enter a number and a unit like 1m.</help>
</field>
<field>
<id>httpserver.certificate</id>
<label>TLS Certificate</label>
@@ -83,7 +97,7 @@
<id>httpserver.disable_bot_protection</id>
<label>Disable Bot Protection</label>
<type>checkbox</type>
<advanced>false</advanced>
<advanced>true</advanced>
<help>Blocks the request when a possibly bad bot is detected and adds the originating IP to the managed firewall alias for permanent blocking.</help>
</field>
<field>
@@ -93,6 +107,14 @@
<style>selectpicker</style>
<help>If you select an IP ACL, the client can only access this service if it fulfills this requirement.</help>
</field>
<field>
<id>httpserver.satisfy</id>
<label>Satisfy</label>
<type>dropdown</type>
<advanced>true</advanced>
<style>selectpicker</style>
<help>All: All access restrictions must be fulfilled; Any: Any of the access restrictions must be fulfilled.</help>
</field>
<field>
<id>httpserver.naxsi_extensive_log</id>
<label>Extensive Naxsi Log</label>
@@ -131,10 +131,26 @@
<type>text</type>
<help>Enter the file system root from which the files are served.</help>
</field>
<field>
<id>location.max_body_size</id>
<label>Maximum Body Size</label>
<type>text</type>
<advanced>true</advanced>
<help>If the request is larger, it will be rejectet with error 413 (Request Entity Too Large). For example, you can enter 200m.</help>
</field>
<field>
<id>location.body_buffer_size</id>
<label>Body Buffer Size</label>
<type>text</type>
<advanced>true</advanced>
<help>If the request exceeds this size, it will be written to disk. Enter a number and a unit like 1m.</help>
</field>
<field>
<id>location.index</id>
<label>Index File</label>
<type>select_multiple</type>
<allownew>true</allownew>
<style>tokenize</style>
<help>Enter a list of file extensions, which are served instead of a directory. It is common to use index.html or index.php here.</help>
</field>
<field>
@@ -168,6 +184,14 @@
<style>selectpicker</style>
<help>If you select an IP ACL, the client can only access this service if it fulfills this requirement.</help>
</field>
<field>
<id>location.satisfy</id>
<label>Satisfy</label>
<type>dropdown</type>
<style>selectpicker</style>
<advanced>true</advanced>
<help>All: All access restrictions must be fulfilled; Any: Any of the access restrictions must be fulfilled.</help>
</field>
<field>
<id>location.force_https</id>
<label>Force HTTPS</label>
@@ -330,6 +330,16 @@
<Required>N</Required>
<multiple>Y</multiple>
</limit_request_connections>
<max_body_size type="TextField">
<Required>N</Required>
<mask>/^\d+[kmg]$/i</mask>
<ValidationMessage>Enter a number followed by k, m or g.</ValidationMessage>
</max_body_size>
<body_buffer_size type="TextField">
<Required>N</Required>
<mask>/^\d+[kmg]$/i</mask>
<ValidationMessage>Enter a number followed by k, m or g.</ValidationMessage>
</body_buffer_size>
<honeypot type="BooleanField">
<Required>Y</Required>
<default>0</default>
@@ -354,6 +364,13 @@
<Required>N</Required>
<multiple>N</multiple>
</ip_acl>
<satisfy type="OptionField">
<OptionValues>
<any>Any</any>
<all>All</all>
</OptionValues>
<Required>N</Required>
</satisfy>
</location>
<custom_policy type="ArrayField">
@@ -594,6 +611,16 @@
<Required>N</Required>
<multiple>Y</multiple>
</limit_request_connections>
<max_body_size type="TextField">
<Required>N</Required>
<mask>/^\d+[kmg]$/i</mask>
<ValidationMessage>Enter a number followed by k, m or g.</ValidationMessage>
</max_body_size>
<body_buffer_size type="TextField">
<Required>N</Required>
<mask>/^\d+[kmg]$/i</mask>
<ValidationMessage>Enter a number followed by k, m or g.</ValidationMessage>
</body_buffer_size>
<ip_acl type="ModelRelationField">
<Model>
<template>
@@ -606,6 +633,13 @@
<Required>N</Required>
<multiple>N</multiple>
</ip_acl>
<satisfy type="OptionField">
<OptionValues>
<any>Any</any>
<all>All</all>
</OptionValues>
<Required>N</Required>
</satisfy>
</http_server>
<stream_server type="ArrayField">
@@ -91,6 +91,15 @@ server {
error_log /var/log/nginx/{{ server.servername }}.error.log;
{% if server.root is defined and server.root != '' %}
root "{{server.root}}";
{% endif %}
{% if server.max_body_size is defined %}
client_max_body_size {{ server.max_body_size }};
{% endif %}
{% if server.body_buffer_size is defined %}
client_body_buffer_size {{ server.body_buffer_size }};
{% endif %}
{% if server.satisfy is defined %}
satisfy {{ server.satisfy }};
{% endif %}
#include tls.conf;
error_page 404 /opnsense_error_404.html;
@@ -47,6 +47,15 @@ location {{ location.matchtype }} {{ location.urlpattern }} {
{% if location.root is defined %}
root {{ location.root }};
{% endif %}
{% if location.max_body_size is defined %}
client_max_body_size {{ location.max_body_size }};
{% endif %}
{% if location.body_buffer_size is defined %}
client_body_buffer_size {{ location.body_buffer_size }};
{% endif %}
{% if location.satisfy is defined %}
satisfy {{ location.satisfy }};
{% endif %}
{% if location.index is defined %}
index {{ location.index.replace(",", " ") }};
{% endif %}
@@ -23,15 +23,15 @@ const actioncollection = new Backbone.Collection([
function bind_save_buttons() {
// form save event handlers for all defined forms
$('[id*="save_"]').each(function () {
$(this).click(function (event) {
$(this).click(function () {
let frm_id = $(this).closest("form").attr("id");
let frm_title = $(this).closest("form").attr("data-title");
// save data for General TAB
saveFormToEndpoint(url = "/api/nginx/settings/set", formid = frm_id, callback_ok = function () {
saveFormToEndpoint("/api/nginx/settings/set", frm_id, function () {
// on correct save, perform reconfigure. set progress animation when reloading
$("#" + frm_id + "_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url = "/api/nginx/service/reconfigure", sendData = {}, callback = function (data, status) {
ajaxCall("/api/nginx/service/reconfigure", {}, function (data, status) {
// when done, disable progress animation.
$("#" + frm_id + "_progress").removeClass("fa fa-spinner fa-pulse");
@@ -116,7 +116,7 @@ $( document ).ready(function() {
// update history on tab state and implement navigation
if(window.location.hash !== "") {
$('a[href="' + window.location.hash + '"]').click()
$('a[href="' + window.location.hash + '"]').click();
}
$('.nav-tabs a').on('shown.bs.tab', function (e) {
history.pushState(null, null, e.target.hash);
@@ -124,7 +124,7 @@ $( document ).ready(function() {
$('.reload_btn').click(function() {
$(".reloadAct_progress").addClass("fa-spin");
ajaxCall(url="/api/nginx/service/reconfigure", sendData={}, callback=function(data,status) {
ajaxCall("/api/nginx/service/reconfigure", {}, function() {
$(".reloadAct_progress").removeClass("fa-spin");
});
});