diff --git a/security/q-feeds-connector/Makefile b/security/q-feeds-connector/Makefile
index 70ee9f0eb..f690fad92 100644
--- a/security/q-feeds-connector/Makefile
+++ b/security/q-feeds-connector/Makefile
@@ -1,6 +1,5 @@
PLUGIN_NAME= q-feeds-connector
-PLUGIN_VERSION= 1.4
-PLUGIN_REVISION= 1
+PLUGIN_VERSION= 1.5
PLUGIN_COMMENT= Connector for Q-Feeds threat intel
PLUGIN_MAINTAINER= devel@qfeeds.com
PLUGIN_TIER= 2
diff --git a/security/q-feeds-connector/pkg-descr b/security/q-feeds-connector/pkg-descr
index 08c3c9cb7..699c60849 100644
--- a/security/q-feeds-connector/pkg-descr
+++ b/security/q-feeds-connector/pkg-descr
@@ -3,6 +3,14 @@ Connector for Q-Feeds threat intel
Plugin Changelog
================
+1.5
+
+* Feature: Add passlist option for unbound
+* Feature: Add effective networks for unbound
+* Feature: Add NXDOMAIN option for unbound
+* Feature: Add dest address for unbound
+
+
1.4
* Feature: Added DNSCrypt-Proxy integration
diff --git a/security/q-feeds-connector/src/opnsense/mvc/app/controllers/OPNsense/QFeeds/forms/settings.xml b/security/q-feeds-connector/src/opnsense/mvc/app/controllers/OPNsense/QFeeds/forms/settings.xml
index 0469ed6ca..acb834253 100644
--- a/security/q-feeds-connector/src/opnsense/mvc/app/controllers/OPNsense/QFeeds/forms/settings.xml
+++ b/security/q-feeds-connector/src/opnsense/mvc/app/controllers/OPNsense/QFeeds/forms/settings.xml
@@ -15,4 +15,42 @@
checkbox
Use domain feeds in Unbound DNS blocklist, requires blocklists to be enabled in order to have effect
+
+ header
+
+
+
+
+ connect.unbound.allowlists
+
+ select_multiple
+
+ true
+ List of domains to allow. You can use regular expressions. This allow list only applies to blocklist matches on items in this policy.
+
+
+ connect.unbound.source_nets
+
+ select_multiple
+
+ true
+ Source networks to apply policy on. Examples are 192.168.1.0/24 or 192.168.1.1. Leave empty to apply on everything. All specified networks should use the same protocol family and have equal sizes to avoid priority issues.
+
+
+ connect.unbound.address
+
+ text
+ true
+
+ Destination ip address for entries in the blocklist (leave empty to use default: 0.0.0.0).
+ Not used when "Return NXDOMAIN" is checked.
+
+
+
+ connect.unbound.nxdomain
+
+ checkbox
+ true
+ Use the DNS response code NXDOMAIN instead of a destination address.
+
diff --git a/security/q-feeds-connector/src/opnsense/mvc/app/models/OPNsense/QFeeds/Connector.xml b/security/q-feeds-connector/src/opnsense/mvc/app/models/OPNsense/QFeeds/Connector.xml
index fb158adcf..d748a54ef 100644
--- a/security/q-feeds-connector/src/opnsense/mvc/app/models/OPNsense/QFeeds/Connector.xml
+++ b/security/q-feeds-connector/src/opnsense/mvc/app/models/OPNsense/QFeeds/Connector.xml
@@ -7,5 +7,21 @@
+
+
+
+ Y
+ Y
+ Please specify a valid network segment or address (IPv4/IPv6). If a mask is provided, please omit the host bits.
+ N
+ N
+ Y
+
+
+ N
+ ipv4
+
+
+
diff --git a/security/q-feeds-connector/src/opnsense/mvc/app/views/OPNsense/QFeeds/index.volt b/security/q-feeds-connector/src/opnsense/mvc/app/views/OPNsense/QFeeds/index.volt
index 21d3b54c7..c015c8094 100644
--- a/security/q-feeds-connector/src/opnsense/mvc/app/views/OPNsense/QFeeds/index.volt
+++ b/security/q-feeds-connector/src/opnsense/mvc/app/views/OPNsense/QFeeds/index.volt
@@ -99,6 +99,13 @@ POSSIBILITY OF SUCH DAMAGE.
}
});
+ $("#connect\\.general\\.enable_unbound_bl").change(function(){
+ if ($(this).is(':checked')) {
+ $(".unbound_options").closest('table').show();
+ } else {
+ $(".unbound_options").closest('table').hide();
+ }
+ });
let selected_tab = window.location.hash != "" ? window.location.hash : "#settings";
$('a[href="' +selected_tab + '"]').tab('show');
diff --git a/security/q-feeds-connector/src/opnsense/scripts/unbound/blocklists/qfeeds_bl.py b/security/q-feeds-connector/src/opnsense/scripts/unbound/blocklists/qfeeds_bl.py
index d880d1e86..1675557ba 100755
--- a/security/q-feeds-connector/src/opnsense/scripts/unbound/blocklists/qfeeds_bl.py
+++ b/security/q-feeds-connector/src/opnsense/scripts/unbound/blocklists/qfeeds_bl.py
@@ -27,12 +27,19 @@
"""
import os
+import re
+import syslog
+import uuid
from . import BaseBlocklistHandler
-class DefaultBlocklistHandler(BaseBlocklistHandler):
+class QFeedsBlocklistHandler(BaseBlocklistHandler):
def __init__(self):
super().__init__('/usr/local/etc/unbound/qfeeds-blocklists.conf')
self.priority = 50
+ self._compat_id = str(uuid.uuid4())
+
+ def _is_enabled(self):
+ return self.cnf and self.cnf.has_section('settings') and self.cnf.has_option('settings', 'filenames')
def get_config(self):
# do not use, unbound worker settings
@@ -41,11 +48,10 @@ class DefaultBlocklistHandler(BaseBlocklistHandler):
def get_blocklist(self):
# Only return domains if integration is enabled (filenames are offered)
qfeeds_filenames = []
- if self.cnf and self.cnf.has_section('settings'):
- if self.cnf.has_option('settings', 'filenames'):
- qfeeds_filenames = self.cnf.get('settings', 'filenames').split(',')
- # touch a file to help qfeedsctl detect the current instance uses its list
- open('/tmp/qfeeds-unbound-bl.stat', 'w').write('')
+ if self._is_enabled():
+ qfeeds_filenames = self.cnf.get('settings', 'filenames').split(',')
+ # touch a file to help qfeedsctl detect the current instance uses its list
+ open('/tmp/qfeeds-unbound-bl.stat', 'w').write('')
result = {}
for filename in qfeeds_filenames:
@@ -58,3 +64,35 @@ class DefaultBlocklistHandler(BaseBlocklistHandler):
def get_passlist_patterns(self):
return []
+
+ def get_policies(self):
+ if not self._is_enabled():
+ return []
+
+ cfg = {
+ 'source_nets': [],
+ 'address': '',
+ 'rcode': '',
+ 'id': self._compat_id,
+ 'allowlists': []
+ }
+ for k,v in self.cnf['settings'].items():
+ if k in cfg and v.strip() != '':
+ if type(cfg[k]) is list:
+ cfg[k] = v.split(',')
+ else:
+ cfg[k] = v.strip()
+
+ if cfg['allowlists']:
+ compiled_passlist = set()
+ for pattern in cfg['allowlists']:
+ try:
+ re.compile(pattern, re.IGNORECASE)
+ compiled_passlist.add(pattern)
+ except re.error:
+ syslog.syslog(syslog.LOG_ERR,'Q-Feeds : skip invalid whitelist exclude pattern "%s"' % pattern)
+
+ cfg['passlist'] = '|'.join(compiled_passlist)
+ del cfg['allowlists']
+
+ return [cfg]
\ No newline at end of file
diff --git a/security/q-feeds-connector/src/opnsense/service/templates/OPNsense/QFeeds/qfeeds-blocklists.conf b/security/q-feeds-connector/src/opnsense/service/templates/OPNsense/QFeeds/qfeeds-blocklists.conf
index 611317775..fb4bbd7e4 100644
--- a/security/q-feeds-connector/src/opnsense/service/templates/OPNsense/QFeeds/qfeeds-blocklists.conf
+++ b/security/q-feeds-connector/src/opnsense/service/templates/OPNsense/QFeeds/qfeeds-blocklists.conf
@@ -2,4 +2,11 @@
not helpers.empty('OPNsense.QFeedsConnector.general.enable_unbound_bl') %}
[settings]
filenames=/var/db/qfeeds-tables/malware_domains.txt
+{% if not helpers.empty('OPNsense.QFeedsConnector.unbound') %}
+allowlists={{OPNsense.QFeedsConnector.unbound.allowlists|default('')}}
+source_nets={{OPNsense.QFeedsConnector.unbound.source_nets|default('')}}
+address={{OPNsense.QFeedsConnector.unbound.address|default('0.0.0.0')}}
+rcode={% if OPNsense.QFeedsConnector.unbound.nxdomain|default('0') == '1' %}NXDOMAIN{%else%}NOERROR{%endif +%}
+cache_ttl={{OPNsense.QFeedsConnector.unbound.cache_ttl|default('72000')}}
+{% endif %}
{% endif %}