mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
www/nginx: allow to generate the fingerprint database from config.xml (#1086)
* www/nginx: allow to generate the fingerprint database from config.xml * www/nginx: add missing file * www/nginx: run bmake style-fix
This commit is contained in:
@@ -374,6 +374,33 @@ class SettingsController extends ApiMutableModelControllerBase
|
||||
return $this->setBase('limit_zone', 'limit_zone', $uuid);
|
||||
}
|
||||
|
||||
// TLS fingerprints for MITM detection
|
||||
public function searchtls_fingerprintAction()
|
||||
{
|
||||
return $this->searchBase('tls_fingerprint', array('description'));
|
||||
}
|
||||
|
||||
public function gettls_fingerprintAction($uuid = null)
|
||||
{
|
||||
$this->sessionClose();
|
||||
return $this->getBase('tls_fingerprint', 'tls_fingerprint', $uuid);
|
||||
}
|
||||
|
||||
public function addtls_fingerprintAction()
|
||||
{
|
||||
return $this->addBase('tls_fingerprint', 'tls_fingerprint');
|
||||
}
|
||||
|
||||
public function deltls_fingerprintAction($uuid)
|
||||
{
|
||||
return $this->delBase('tls_fingerprint', $uuid);
|
||||
}
|
||||
|
||||
public function settls_fingerprintAction($uuid)
|
||||
{
|
||||
return $this->setBase('tls_fingerprint', 'tls_fingerprint', $uuid);
|
||||
}
|
||||
|
||||
// limit_request_connection
|
||||
public function searchlimit_request_connectionAction()
|
||||
{
|
||||
@@ -477,6 +504,7 @@ class SettingsController extends ApiMutableModelControllerBase
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
// IP / Network based ACLs
|
||||
public function searchipaclAction()
|
||||
{
|
||||
|
||||
@@ -60,6 +60,7 @@ class IndexController extends \OPNsense\Base\IndexController
|
||||
$this->view->cache_path = $this->getForm("cache_path");
|
||||
$this->view->sni_hostname_map = $this->getForm("sni_hostname_map");
|
||||
$this->view->ipacl = $this->getForm("ipacl");
|
||||
$this->view->tls_fingerprint = $this->getForm("tls_fingerprint");
|
||||
$nginx = new Nginx();
|
||||
$this->view->show_naxsi_download_button =
|
||||
count($nginx->custom_policy->iterateItems()) == 0 && count($nginx->naxsi_rule->iterateItems()) == 0;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>tls_fingerprint.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
<help>Enter a useful description for your entry.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>tls_fingerprint.trusted</id>
|
||||
<label>Trusted</label>
|
||||
<type>checkbox</type>
|
||||
<help>If you check this box, this entry will be added to the configuration of trusted fingerprints.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>tls_fingerprint.user_agent</id>
|
||||
<label>User Agent</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>tls_fingerprint.ciphers</id>
|
||||
<label>Cipher Suits</label>
|
||||
<type>text</type>
|
||||
<help>Enter a list of elliptic curves supported by the client in a standard configuration in OpenSSL syntax (cipher1:cipher2:0x0001).</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>tls_fingerprint.curves</id>
|
||||
<label>Elliptic Curves</label>
|
||||
<type>text</type>
|
||||
<help>Enter a list of elliptic curves supported by the client in a standard configuration in OpenSSL syntax (curve1:curve2:0x0001).</help>
|
||||
</field>
|
||||
</form>
|
||||
@@ -1274,6 +1274,29 @@
|
||||
</rate>
|
||||
</limit_zone>
|
||||
|
||||
<tls_fingerprint type="ArrayField">
|
||||
<description type="TextField">
|
||||
<Required>Y</Required>
|
||||
</description>
|
||||
<user_agent type="TextField">
|
||||
<Required>Y</Required>
|
||||
</user_agent>
|
||||
<trusted type="BooleanField">
|
||||
<default>0</default>
|
||||
<Required>Y</Required>
|
||||
</trusted>
|
||||
<curves type="TextField">
|
||||
<!-- OpenSSL curve list like the one used for configuring the supported ciphers by the web server -->
|
||||
<Required>N</Required>
|
||||
<mask>/^(0x[0-9a-fA-F]{4,4}|[a-zA-Z_\-0-9]+)(?::((0x[0-9a-fA-F]{4,4}|[a-zA-Z_\-0-9]+)))*$/</mask>
|
||||
</curves>
|
||||
<ciphers type="TextField">
|
||||
<!-- OpenSSL cipher list like the one used for configuring the supported ciphers by the web server -->
|
||||
<Required>Y</Required>
|
||||
<mask>/^(0x[0-9a-fA-F]{4,4}|[a-zA-Z_\-0-9]+)(?::((0x[0-9a-fA-F]{4,4}|[a-zA-Z_\-0-9]+)))*$/</mask>
|
||||
</ciphers>
|
||||
</tls_fingerprint>
|
||||
|
||||
<limit_request_connection type="ArrayField">
|
||||
<limit_zone type="ModelRelationField">
|
||||
<Model>
|
||||
|
||||
@@ -124,6 +124,9 @@
|
||||
<li>
|
||||
<a data-toggle="tab" id="subtab_item_nginx-http-cache_path" href="#subtab_nginx-http-cache_path">{{ lang._('Cache Path')}}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a data-toggle="tab" id="subtab_item_nginx-http-tls-fingerprint" href="#subtab_nginx-http-tls-fingerprint">{{ lang._('TLS Fingerprint (Advanced)')}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="presentation" class="dropdown">
|
||||
@@ -574,6 +577,27 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div id="subtab_nginx-http-tls-fingerprint" class="tab-pane fade">
|
||||
<table id="grid-tls_fingerprint" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="tls_fingerprint_dlg">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="description" 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>
|
||||
|
||||
|
||||
@@ -593,3 +617,4 @@
|
||||
{{ partial("layout_partials/base_dialog",['fields': cache_path,'id':'cache_pathdlg', 'label':lang._('Edit Cache Path')]) }}
|
||||
{{ partial("layout_partials/base_dialog",['fields': sni_hostname_map,'id':'sni_hostname_mapdlg', 'label':lang._('Edit SNI Hostname Mapping')]) }}
|
||||
{{ partial("layout_partials/base_dialog",['fields': ipacl,'id':'ipacl_dlg', 'label':lang._('Edit IP ACL')]) }}
|
||||
{{ partial("layout_partials/base_dialog",['fields': tls_fingerprint,'id':'tls_fingerprint_dlg', 'label':lang._('Edit TLS Fingerprint')]) }}
|
||||
|
||||
@@ -241,3 +241,24 @@ foreach ($nginx->userlist->iterateItems() as $user_list) {
|
||||
foreach ($nginx->cache_path->iterateItems() as $cache_path) {
|
||||
@mkdir((string)$cache_path->path, 0755, true);
|
||||
}
|
||||
|
||||
// export TLS fingerprint database for MitM detection
|
||||
$tls_fingerprint_database = array();
|
||||
foreach ($nginx->tls_fingerprint->iterateItems() as $tls_fingerprint) {
|
||||
if ((string)$tls_fingerprint->trusted == '1') {
|
||||
$ciphers = explode(':', (string)$tls_fingerprint->ciphers);
|
||||
if (!empty((string)$tls_fingerprint->curves)) {
|
||||
$curves = explode(':', (string)$tls_fingerprint->ciphers);
|
||||
} else {
|
||||
$curves = array();
|
||||
}
|
||||
$tls_fingerprint_database[(string)$tls_fingerprint->user_agent] =
|
||||
array('ciphers' => $ciphers, 'curves' => $curves);
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents(
|
||||
'/usr/local/etc/nginx/tls_fingerprints.json',
|
||||
empty($tls_fingerprint_database) ? '{}' : json_encode($tls_fingerprint_database)
|
||||
);
|
||||
chmod('/usr/local/etc/nginx/tls_fingerprints.json', 0644);
|
||||
|
||||
@@ -6,6 +6,7 @@ include mime.types;
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
log_format handshake '"$http_user_agent" "$ssl_ciphers" "$ssl_curves"';
|
||||
log_format anonymized ':: - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
@@ -101,6 +102,7 @@ server {
|
||||
charset {{ server.charset }};
|
||||
{% endif %}
|
||||
access_log /var/log/nginx/{{ server.servername }}.access.log {{ server.access_log_format }};
|
||||
access_log /var/log/nginx/tls_handshake.log handshake;
|
||||
error_log /var/log/nginx/{{ server.servername }}.error.log;
|
||||
{% if server.root is defined and server.root != '' %}
|
||||
root "{{server.root}}";
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -68,6 +68,7 @@ function init_grids() {
|
||||
'cache_path',
|
||||
'limit_request_connection',
|
||||
'snifwd',
|
||||
'tls_fingerprint',
|
||||
'naxsirule'].forEach(function (element) {
|
||||
$("#grid-" + element).UIBootgrid(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user