mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
www/nginx: new features (#828)
* www/nginx: add initial permanent ban feature * www/nginx: write data to model and add blocks to fw * www/nginx: add permanent ban script; change some settings to be advanced * www/nginx: change cron fix * www/nginx: a network field is needed * www/nginx: allow ws/wss * www/nginx: hostname bugfix * www/nginx: remove hack to get uuid * www/nginx: update blacklist * www/nginx: hook cron automatically * www/nginx: add support for HTTP/2 preloading * www/nginx imrove permanent ban feature * www/nginx: cleanup and add cache helper * www/nginx: webgui - enable HTTP/2 server push * www/nginx: add cache * www/nginx: more options for caching * www/nginx: export fullchain * www/nginx: run bmake style-fix * www/nginx: shorten name
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2018 Fabian Franz
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
function nginx_cron()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'autocron' => array('/usr/local/opnsense/scripts/nginx/ngx_autoblock.php', '*')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function nginx_services()
|
||||
{
|
||||
|
||||
return array(
|
||||
array(
|
||||
'description' => gettext('Reverse Proxy and Web Server'),
|
||||
'configd' => array(
|
||||
'restart' => array('nginx restart'),
|
||||
'start' => array('nginx start')
|
||||
),
|
||||
'name' => 'nginx',
|
||||
'pidfile' => '/var/run/nginx.pid'
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/*
|
||||
|
||||
Copyright (C) 2018 Fabian Franz
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
namespace OPNsense\Nginx\Api;
|
||||
|
||||
use OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use OPNsense\Core\Backend;
|
||||
|
||||
class BansController extends ApiMutableModelControllerBase
|
||||
{
|
||||
static protected $internalModelClass = '\OPNsense\Nginx\Nginx';
|
||||
static protected $internalModelName = 'nginx';
|
||||
public function searchbanAction()
|
||||
{
|
||||
return $this->searchBase('ban', array('ip', 'time'));
|
||||
}
|
||||
public function delbanAction($uuid)
|
||||
{
|
||||
if ($this->request->isPost() || $this->request->isDelete()) {
|
||||
$mdl = $this->getModel();
|
||||
$node = $mdl->getNodeByReference('ban.' . $uuid);
|
||||
$backend = new Backend();
|
||||
$backend->configdRun('nginx unlock ' . (string)$node->ip);
|
||||
return $this->delBase('ban', $uuid);
|
||||
} else {
|
||||
return array('result' => 'most be called via POST');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,11 +31,11 @@ use OPNsense\Base\ApiControllerBase;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Nginx\Nginx;
|
||||
|
||||
|
||||
class LogsController extends ApiControllerBase
|
||||
{
|
||||
private $nginx;
|
||||
public function accessesAction($uuid = null) {
|
||||
public function accessesAction($uuid = null)
|
||||
{
|
||||
$this->nginx = new Nginx();
|
||||
if (!isset($uuid)) {
|
||||
// emulate REST API -> /accesses delivers a list of servers with access logs
|
||||
@@ -46,7 +46,8 @@ class LogsController extends ApiControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
public function errorsAction($uuid = null) {
|
||||
public function errorsAction($uuid = null)
|
||||
{
|
||||
$this->nginx = new Nginx();
|
||||
if (!isset($uuid)) {
|
||||
// emulate REST API -> /errors delivers a list of servers with error logs
|
||||
@@ -57,7 +58,8 @@ class LogsController extends ApiControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
private function call_configd($type, $uuid) {
|
||||
private function call_configd($type, $uuid)
|
||||
{
|
||||
if (!$this->vhost_exists($uuid)) {
|
||||
$this->response->setStatusCode(404, "Not Found");
|
||||
}
|
||||
@@ -67,7 +69,8 @@ class LogsController extends ApiControllerBase
|
||||
return json_decode($data, true);
|
||||
}
|
||||
|
||||
private function list_vhosts() {
|
||||
private function list_vhosts()
|
||||
{
|
||||
$data = [];
|
||||
foreach ($this->nginx->http_server->__items as $item) {
|
||||
$data[] = array('id' => $item->getAttributes()['uuid'], 'server_name' => (string)$item->servername);
|
||||
@@ -75,7 +78,8 @@ class LogsController extends ApiControllerBase
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function vhost_exists($uuid) {
|
||||
private function vhost_exists($uuid)
|
||||
{
|
||||
$data = $this->nginx->getNodeByReference('http_server.'. $uuid);
|
||||
return isset($data);
|
||||
}
|
||||
|
||||
+37
-4
@@ -309,8 +309,10 @@ class SettingsController extends ApiMutableModelControllerBase
|
||||
// access limit zone headers
|
||||
public function searchlimit_zoneAction()
|
||||
{
|
||||
return $this->searchBase('limit_zone',
|
||||
array('description', 'key', 'size', 'rate', 'rate_unit'));
|
||||
return $this->searchBase(
|
||||
'limit_zone',
|
||||
array('description', 'key', 'size', 'rate', 'rate_unit')
|
||||
);
|
||||
}
|
||||
|
||||
public function getlimit_zoneAction($uuid = null)
|
||||
@@ -337,8 +339,10 @@ class SettingsController extends ApiMutableModelControllerBase
|
||||
// limit_request_connection
|
||||
public function searchlimit_request_connectionAction()
|
||||
{
|
||||
return $this->searchBase('limit_request_connection',
|
||||
array('description', 'limit_zone', 'nodelay', 'burst', 'connection_count'));
|
||||
return $this->searchBase(
|
||||
'limit_request_connection',
|
||||
array('description', 'limit_zone', 'nodelay', 'burst', 'connection_count')
|
||||
);
|
||||
}
|
||||
|
||||
public function getlimit_request_connectionAction($uuid = null)
|
||||
@@ -361,4 +365,33 @@ class SettingsController extends ApiMutableModelControllerBase
|
||||
{
|
||||
return $this->setBase('limit_request_connection', 'limit_request_connection', $uuid);
|
||||
}
|
||||
// cache path
|
||||
public function searchcache_pathAction()
|
||||
{
|
||||
return $this->searchBase(
|
||||
'cache_path',
|
||||
array('path', 'inactive', 'size', 'max_size')
|
||||
);
|
||||
}
|
||||
|
||||
public function getcache_pathAction($uuid = null)
|
||||
{
|
||||
$this->sessionClose();
|
||||
return $this->getBase('cache_path', 'cache_path', $uuid);
|
||||
}
|
||||
|
||||
public function addcache_pathAction()
|
||||
{
|
||||
return $this->addBase('cache_path', 'cache_path');
|
||||
}
|
||||
|
||||
public function delcache_pathAction($uuid)
|
||||
{
|
||||
return $this->delBase('cache_path', $uuid);
|
||||
}
|
||||
|
||||
public function setcache_pathAction($uuid)
|
||||
{
|
||||
return $this->setBase('cache_path', 'cache_path', $uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +56,23 @@ class IndexController extends \OPNsense\Base\IndexController
|
||||
$this->view->security_headers = $this->getForm("security_headers");
|
||||
$this->view->limit_request_connection = $this->getForm("limit_request_connection");
|
||||
$this->view->limit_zone = $this->getForm("limit_zone");
|
||||
$this->view->cache_path = $this->getForm("cache_path");
|
||||
$this->view->pick('OPNsense/Nginx/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* show the nginx logs page /ui/nginx/index/logs
|
||||
*/
|
||||
public function logsAction() {
|
||||
public function logsAction()
|
||||
{
|
||||
$this->view->pick('OPNsense/Nginx/logs');
|
||||
}
|
||||
|
||||
/**
|
||||
* display a viewer for banned IPs.
|
||||
*/
|
||||
public function banAction()
|
||||
{
|
||||
$this->view->pick('OPNsense/Nginx/ban');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>cache_path.path</id>
|
||||
<label>Path</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>cache_path.size</id>
|
||||
<label>Size (MB)</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>cache_path.inactive</id>
|
||||
<label>Inactive Time (Minutes)</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>cache_path.use_temp_path</id>
|
||||
<label>Use Temp Path</label>
|
||||
<type>checkbox</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>cache_path.max_size</id>
|
||||
<label>Maximum Size (GB)</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
</form>
|
||||
@@ -48,6 +48,7 @@
|
||||
<id>httpserver.verify_client</id>
|
||||
<label>Verify Client Certificate</label>
|
||||
<type>dropdown</type>
|
||||
<advanced>true</advanced>
|
||||
<help><![CDATA[<ul><li>On: the certificate is requested and validated. Use this option to protect a service with TLS authentication.</li><li>Off: The certificate is not requested. Choose this option for a normal website.</li><li>Optional: The certificate is requested and validated if existing. Choose this option for websites, with TLS login support or mixed TLS protected API and web content.</li><li>Optional, don't verify: Do accept the certificate and let the application choose what to do. Choose this option, for the same reasons as optional but in this case, the request is passed to the backend without rejecting untrusted certificates.</li></ul>]]></help>
|
||||
</field>
|
||||
<field>
|
||||
@@ -75,18 +76,21 @@
|
||||
<id>httpserver.block_nonpublic_data</id>
|
||||
<label>Block Configuration Files</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Blocks files like .htaccess files or other files not intended for the public.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>httpserver.naxsi_extensive_log</id>
|
||||
<label>Extensive Naxsi Log</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Provide a more verbose WAF log for fixing false positives before going live.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>httpserver.sendfile</id>
|
||||
<label>Enable Sendfile</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Allow the daemon to use the sendfile function.</help>
|
||||
</field>
|
||||
<field>
|
||||
|
||||
@@ -61,11 +61,62 @@
|
||||
<style>selectpicker</style>
|
||||
<help>Select an upstream to proxy to or connect via FastCGI if chosen.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.cache_path</id>
|
||||
<label>Cache: Directory</label>
|
||||
<type>dropdown</type>
|
||||
<help>Choose a cache directory if you want to cache responses.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.cache_use_stale</id>
|
||||
<label>Cache: Use Stale</label>
|
||||
<type>select_multiple</type>
|
||||
<style>selectpicker</style>
|
||||
<advanced>true</advanced>
|
||||
<help>If you enable this option, a stale response will be sent when in cases the original server is unable to (for example if it is down).</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.cache_min_uses</id>
|
||||
<label>Cache: Minimum Uses</label>
|
||||
<type>text</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Enter how often the resource must be hit before adding it to the cache.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.cache_background_update</id>
|
||||
<label>Cache: Background Update</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Return a stale response to the client and update the cache.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.cache_lock</id>
|
||||
<label>Cache: Lock Backend on Update</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Only allow a single request to call the backend on the same URL at a single time.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.cache_revalidate</id>
|
||||
<label>Cache: Revalidate</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Only request a new version, if the content has changed since the last cache update.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.cache_methods</id>
|
||||
<label>Cache: HTTP Verbs</label>
|
||||
<type>select_multiple</type>
|
||||
<style>selectpicker</style>
|
||||
<advanced>true</advanced>
|
||||
<help>Select the HTTP verbs to cache. GET and HEAD will be always cached.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.limit_request_connections</id>
|
||||
<label>Limit Requests</label>
|
||||
<type>select_multiple</type>
|
||||
<style>selectpicker</style>
|
||||
<advanced>true</advanced>
|
||||
<help>If you choose multiple limits, the strictest will be used.</help>
|
||||
</field>
|
||||
<field>
|
||||
@@ -110,6 +161,12 @@
|
||||
<type>checkbox</type>
|
||||
<help>Force encrypted connections.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.http2_push_preload</id>
|
||||
<label>Enable HTTP/2 Preloading</label>
|
||||
<type>checkbox</type>
|
||||
<help>If you check this box, you can use the link header to send resources to the client before they are requested. You can boost your performance with this setting. This requires that your application sets the "Link" header correctly.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.php_enable</id>
|
||||
<label>Pass Request To Local PHP Interpreter / Threat Upstream As FastCGI</label>
|
||||
@@ -122,4 +179,18 @@
|
||||
<type>text</type>
|
||||
<help>If you set this setting, all requests are sent to this script instead of the request path (URL). Not using this setting on a remote instance can be dangerous.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.honeypot</id>
|
||||
<label>Honeypot</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>If you enable the honeypot, all requests to this location will go to a special temporary log which will be used to block the IP. This is dangerous because you may accidentally block legitimate users or search engines. The result is available as a special alias in the firewall section. For example you can trigger on locations of Wordpress for phpMyAdmin if you are not using it.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>location.websocket</id>
|
||||
<label>WebSocket</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>If you enable the WebSocket option, nginx will pass the upgrade header to the backed server.</help>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<field>
|
||||
<id>upstream.tls_client_certificate</id>
|
||||
<label>TLS: Client Certificate</label>
|
||||
<advanced>true</advanced>
|
||||
<help>Authenticate on the Server using a client certificate.</help>
|
||||
<style>selectpicker</style>
|
||||
<type>dropdown</type>
|
||||
@@ -50,17 +51,20 @@
|
||||
<id>upstream.tls_verify</id>
|
||||
<label>TLS: Verify Certificate</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Don't turn it off unless you really know what you are doing! Never do it because a random website tells you to do.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>upstream.tls_verify_depth</id>
|
||||
<label>TLS: Verify Depth</label>
|
||||
<type>text</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Choose how many sub-CAs can be between the server certificate and a trusted CA. 1 means the certificate has to be signed directly by a CA.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>upstream.store</id>
|
||||
<label>Store</label>
|
||||
<advanced>true</advanced>
|
||||
<type>checkbox</type>
|
||||
<help>Store the response on the local storage.</help>
|
||||
</field>
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<field>
|
||||
<id>upstream_server.no_use</id>
|
||||
<label>Do Not Use</label>
|
||||
<advanced>true</advanced>
|
||||
<type>dropdown</type>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
namespace OPNsense\Nginx;
|
||||
|
||||
|
||||
class AccessLogLine
|
||||
{
|
||||
public $remote_ip;
|
||||
|
||||
@@ -42,7 +42,8 @@ class AccessLogParser
|
||||
$this->lines = file($this->file_name);
|
||||
$this->result = array_map([$this, 'parse_line'], $this->lines);
|
||||
}
|
||||
private function parse_line($line) {
|
||||
private function parse_line($line)
|
||||
{
|
||||
$container = new AccessLogLine();
|
||||
if (preg_match(self::LogLineRegex, $line, $data)) {
|
||||
$container->remote_ip = $data[1];
|
||||
@@ -58,8 +59,8 @@ class AccessLogParser
|
||||
return $container;
|
||||
}
|
||||
|
||||
public function get_result() {
|
||||
public function get_result()
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ class ErrorLogParser
|
||||
$this->lines = file($this->file_name);
|
||||
$this->result = array_map([$this, 'parse_line'], $this->lines);
|
||||
}
|
||||
private function parse_line($line) {
|
||||
private function parse_line($line)
|
||||
{
|
||||
$container = new ErrorLogLine();
|
||||
if (preg_match(self::LogLineRegex, $line, $data)) {
|
||||
$container->date = $data[1];
|
||||
@@ -54,7 +55,8 @@ class ErrorLogParser
|
||||
return $container;
|
||||
}
|
||||
|
||||
public function get_result() {
|
||||
public function get_result()
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<Nginx cssClass="fa fa-shield fa-fw">
|
||||
<Configuration url="/ui/nginx" />
|
||||
<Logs url="/ui/nginx/index/logs" />
|
||||
<Banned url="/ui/nginx/index/ban" />
|
||||
</Nginx>
|
||||
</Services>
|
||||
</menu>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<model>
|
||||
<mount>//OPNsense/Nginx</mount>
|
||||
<version>1.1.1</version>
|
||||
<version>1.1.2</version>
|
||||
<description>nginx web server, reverse proxy and waf</description>
|
||||
<items>
|
||||
<general>
|
||||
@@ -205,6 +205,65 @@
|
||||
<Required>N</Required>
|
||||
<multiple>N</multiple>
|
||||
</upstream>
|
||||
<cache_path type="ModelRelationField">
|
||||
<Model>
|
||||
<template>
|
||||
<source>OPNsense.Nginx.Nginx</source>
|
||||
<items>cache_path</items>
|
||||
<display>path</display>
|
||||
</template>
|
||||
</Model>
|
||||
<ValidationMessage>Selected cache directory not found</ValidationMessage>
|
||||
<Required>N</Required>
|
||||
<multiple>N</multiple>
|
||||
</cache_path>
|
||||
<cache_use_stale type="OptionField">
|
||||
<multiple>Y</multiple>
|
||||
<OptionValues>
|
||||
<error>Error</error>
|
||||
<timeout>Timeout</timeout>
|
||||
<invalid_header>Invalid_header</invalid_header>
|
||||
<updating>Updating</updating>
|
||||
<http_403>HTTP Status Code 403</http_403>
|
||||
<http_404>HTTP Status Code 404</http_404>
|
||||
<http_429>HTTP Status Code 429</http_429>
|
||||
<http_500>HTTP Status Code 500</http_500>
|
||||
<http_502>HTTP Status Code 502</http_502>
|
||||
<http_503>HTTP Status Code 503</http_503>
|
||||
<http_504>HTTP Status Code 504</http_504>
|
||||
</OptionValues>
|
||||
<Required>N</Required>
|
||||
</cache_use_stale>
|
||||
<cache_methods type="OptionField">
|
||||
<multiple>Y</multiple>
|
||||
<OptionValues>
|
||||
<POST>Post</POST>
|
||||
<!-- it seems like it does not like the others required for REST - syntax error
|
||||
<PUT>Put</PUT>
|
||||
<DELETE>Delete</DELETE>
|
||||
<CONNECT>Connect</CONNECT>
|
||||
<OPTIONS>Options</OPTIONS>
|
||||
<TRACE>Trace</TRACE>
|
||||
<PATCH>Patch</PATCH>-->
|
||||
</OptionValues>
|
||||
<Required>N</Required>
|
||||
</cache_methods>
|
||||
<cache_min_uses type="IntegerField">
|
||||
<Required>Y</Required>
|
||||
<default>1</default>
|
||||
</cache_min_uses>
|
||||
<cache_background_update type="BooleanField">
|
||||
<Required>Y</Required>
|
||||
<default>0</default>
|
||||
</cache_background_update>
|
||||
<cache_lock type="BooleanField">
|
||||
<Required>Y</Required>
|
||||
<default>0</default>
|
||||
</cache_lock>
|
||||
<cache_revalidate type="BooleanField">
|
||||
<Required>Y</Required>
|
||||
<default>0</default>
|
||||
</cache_revalidate>
|
||||
<root type="TextField">
|
||||
<Required>N</Required>
|
||||
</root>
|
||||
@@ -267,6 +326,18 @@
|
||||
<Required>N</Required>
|
||||
<multiple>Y</multiple>
|
||||
</limit_request_connections>
|
||||
<honeypot type="BooleanField">
|
||||
<Required>Y</Required>
|
||||
<default>0</default>
|
||||
</honeypot>
|
||||
<websocket type="BooleanField">
|
||||
<Required>Y</Required>
|
||||
<default>0</default>
|
||||
</websocket>
|
||||
<http2_push_preload type="BooleanField">
|
||||
<Required>Y</Required>
|
||||
<default>0</default>
|
||||
</http2_push_preload>
|
||||
</location>
|
||||
|
||||
<custom_policy type="ArrayField">
|
||||
@@ -922,5 +993,36 @@
|
||||
<Required>Y</Required>
|
||||
</description>
|
||||
</limit_request_connection>
|
||||
<ban type="ArrayField">
|
||||
<ip type="NetworkField">
|
||||
<Required>Y</Required>
|
||||
</ip>
|
||||
<time type="IntegerField">
|
||||
<Required>N</Required>
|
||||
<MinimumValue>0</MinimumValue>
|
||||
</time>
|
||||
</ban>
|
||||
<cache_path type="ArrayField">
|
||||
<path type="TextField">
|
||||
<Required>Y</Required>
|
||||
<mask>/\/(srv|var|tmp|mnt)[a-z0-9\-\._\:\,\/]+[a-z0-9\-\._\:\,]+/i</mask>
|
||||
</path>
|
||||
<size type="IntegerField">
|
||||
<MinimumValue>10</MinimumValue>
|
||||
<default>10</default>
|
||||
</size>
|
||||
<inactive type="IntegerField">
|
||||
<Required>N</Required>
|
||||
<MinimumValue>1</MinimumValue>
|
||||
</inactive>
|
||||
<use_temp_path type="BooleanField">
|
||||
<Required>Y</Required>
|
||||
<default>0</default>
|
||||
</use_temp_path>
|
||||
<max_size type="IntegerField">
|
||||
<Required>N</Required>
|
||||
<MinimumValue>1</MinimumValue>
|
||||
</max_size>
|
||||
</cache_path>
|
||||
</items>
|
||||
</model>
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
{#
|
||||
# Copyright (C) 2017-2018 Fabian Franz
|
||||
# Copyright (C) 2014-2015 Deciso B.V.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#}
|
||||
|
||||
<div class="content-box">
|
||||
<table id="grid-ban" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="limit_request_connectiondlg">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="ip" data-type="string" data-sortable="true" data-visible="true">{{ lang._('IP Address / Network') }}</th>
|
||||
<th data-column-id="time" data-type="timestamp" data-sortable="true" data-visible="true">{{ lang._('Time') }}</th>
|
||||
<th data-column-id="button" data-width="7em" data-formatter="delbtn" data-sortable="false">{{ lang._('Unlock') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
$(function () {
|
||||
$("#grid-ban").UIBootgrid(
|
||||
{ 'search':'/api/nginx/bans/searchban',
|
||||
'del':'/api/nginx/bans/delban/',
|
||||
'options': {
|
||||
selection:false,
|
||||
multiSelect:false,
|
||||
formatters: {
|
||||
"delbtn": function (column, row) {
|
||||
return `<button type="button" class="btn btn-xs btn-default command-delete" data-row-id="${row.uuid}"><span class=\"fa fa-unlock-alt\"></span></button>`;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
@@ -28,7 +28,7 @@
|
||||
<script>
|
||||
$( document ).ready(function() {
|
||||
|
||||
var data_get_map = {'frm_nginx':'/api/nginx/settings/get'};
|
||||
let data_get_map = {'frm_nginx':'/api/nginx/settings/get'};
|
||||
|
||||
// load initial data
|
||||
mapDataToFormUI(data_get_map).done(function(){
|
||||
@@ -44,12 +44,6 @@ $( document ).ready(function() {
|
||||
$('.nav-tabs a').on('shown.bs.tab', function (e) {
|
||||
history.pushState(null, null, e.target.hash);
|
||||
});
|
||||
$('#nginx\\.general\\.enable_redis_plugin').change(function (evt) {
|
||||
$('#missing_redis_plugin').hide();
|
||||
if (!window.redis_installed && $(this).is(':checked')) {
|
||||
$('#missing_redis_plugin').show();
|
||||
}
|
||||
});
|
||||
|
||||
$('.reload_btn').click(function() {
|
||||
$(".reloadAct_progress").addClass("fa-spin");
|
||||
@@ -98,6 +92,7 @@ $( document ).ready(function() {
|
||||
'custompolicy',
|
||||
'security_header',
|
||||
'limit_zone',
|
||||
'cache_path',
|
||||
'limit_request_connection',
|
||||
'naxsirule'].forEach(function(element) {
|
||||
$("#grid-" + element).UIBootgrid(
|
||||
@@ -159,6 +154,9 @@ $( document ).ready(function() {
|
||||
<li>
|
||||
<a data-toggle="tab" id="subtab_item_nginx-http-security_header" href="#subtab_nginx-http-security_header">{{ lang._('Security Headers')}}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a data-toggle="tab" id="subtab_item_nginx-http-cache_path" href="#subtab_nginx-http-cache_path">{{ lang._('Cache Path')}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="presentation" class="dropdown">
|
||||
@@ -417,6 +415,30 @@ $( document ).ready(function() {
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div id="subtab_nginx-http-cache_path" class="tab-pane fade">
|
||||
<table id="grid-cache_path" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="cache_pathdlg">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="path" data-type="string" data-sortable="true" data-visible="true">{{ lang._('Path') }}</th>
|
||||
<th data-column-id="size" data-type="string" data-sortable="true" data-visible="true">{{ lang._('Description') }}</th>
|
||||
<th data-column-id="inactive" data-type="string" data-sortable="true" data-visible="true">{{ lang._('Description') }}</th>
|
||||
<th data-column-id="max_size" data-type="string" data-sortable="true" data-visible="true">{{ lang._('Description') }}</th>
|
||||
<th data-column-id="commands" data-width="7em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
|
||||
<button type="button" class="btn btn-xs reload_btn btn-primary"><span class="fa fa-refresh reloadAct_progress"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div id="subtab_nginx-access-request-limit" class="tab-pane fade">
|
||||
<table id="grid-limit_zone" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="limit_zonedlg">
|
||||
<thead>
|
||||
@@ -483,3 +505,4 @@ $( document ).ready(function() {
|
||||
{{ partial("layout_partials/base_dialog",['fields': security_headers,'id':'security_headersdlg', 'label':lang._('Edit Security Headers')]) }}
|
||||
{{ partial("layout_partials/base_dialog",['fields': limit_request_connection,'id':'limit_request_connectiondlg', 'label':lang._('Edit Request Connection Limit')]) }}
|
||||
{{ partial("layout_partials/base_dialog",['fields': limit_zone,'id':'limit_zonedlg', 'label':lang._('Edit Limit Zone')]) }}
|
||||
{{ partial("layout_partials/base_dialog",['fields': cache_path,'id':'cache_pathdlg', 'label':lang._('Edit Cache Path')]) }}
|
||||
|
||||
@@ -27,6 +27,6 @@
|
||||
|
||||
<div id="logapplication"></div>
|
||||
|
||||
<script src="/ui/js/nginx/lib/lodash.min.js"></script>
|
||||
<script src="/ui/js/nginx/lib/backbone-min.js"></script>
|
||||
<script src="/ui/js/nginx/dist/bundle.js"></script>
|
||||
<script src="{{ cache_safe('/ui/js/nginx/lib/lodash.min.js') }}"></script>
|
||||
<script src="{{ cache_safe('/ui/js/nginx/lib/backbone-min.js') }}"></script>
|
||||
<script src="{{ cache_safe('/ui/js/nginx/dist/bundle.js') }}"></script>
|
||||
|
||||
@@ -36,12 +36,12 @@ if (stristr($_SERVER['CONTENT_TYPE'], 'json') === false) {
|
||||
}
|
||||
|
||||
if ($json_data = json_decode(file_get_contents('php://input'), true)) {
|
||||
http_response_code(204);
|
||||
http_response_code(204);
|
||||
// inject some data for a log viewer to get a relation with the server entry
|
||||
$json_data['server_time'] = time();
|
||||
$json_data['server_uuid'] = $_SERVER['SERVER-UUID'];
|
||||
$json_data = json_encode($json_data);
|
||||
file_put_contents($log_file, $json_data . PHP_EOL, FILE_APPEND | LOCK_EX);
|
||||
$json_data['server_time'] = time();
|
||||
$json_data['server_uuid'] = $_SERVER['SERVER-UUID'];
|
||||
$json_data = json_encode($json_data);
|
||||
file_put_contents($log_file, $json_data . PHP_EOL, FILE_APPEND | LOCK_EX);
|
||||
} else {
|
||||
http_response_code(400);
|
||||
echo "Your request data cannot be decoded. Please send compliant JSON data.";
|
||||
|
||||
@@ -36,14 +36,18 @@ $method = $_SERVER['Original-METHOD'];
|
||||
$is_https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on';
|
||||
$server_uuid = $_SERVER['SERVER-UUID'];
|
||||
|
||||
function password_auth_test($username, $password, $auth_server) {
|
||||
function password_auth_test($username, $password, $auth_server)
|
||||
{
|
||||
$authFactory = new OPNsense\Auth\AuthenticationFactory;
|
||||
$authenticator = $authFactory->get($auth_server);
|
||||
return $authenticator->authenticate($username, $password);
|
||||
}
|
||||
|
||||
function password_auth($auth_server = 'Local Database') {
|
||||
if (!isset($_SERVER['PHP_AUTH_PW']) || !isset($_SERVER['PHP_AUTH_PW'])) return false;
|
||||
function password_auth($auth_server = 'Local Database')
|
||||
{
|
||||
if (!isset($_SERVER['PHP_AUTH_PW']) || !isset($_SERVER['PHP_AUTH_PW'])) {
|
||||
return false;
|
||||
}
|
||||
return password_auth_test($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], $auth_server);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user