mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
dns/bind: full zone management (#1276)
This commit is contained in:
+1
-2
@@ -1,6 +1,5 @@
|
||||
PLUGIN_NAME= bind
|
||||
PLUGIN_VERSION= 1.4
|
||||
PLUGIN_REVISION= 1
|
||||
PLUGIN_VERSION= 1.5.d
|
||||
PLUGIN_COMMENT= BIND domain name service
|
||||
PLUGIN_DEPENDS= bind912
|
||||
PLUGIN_MAINTAINER= m.muenz@gmail.com
|
||||
|
||||
@@ -8,6 +8,10 @@ necessary for asking and answering name service questions.
|
||||
Plugin Changelog
|
||||
================
|
||||
|
||||
1.5
|
||||
|
||||
* Add basic zone management
|
||||
|
||||
1.4
|
||||
|
||||
* Add Bing and DuckDuckGo Strict Search
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2019 Michael Muenz <m.muenz@gmail.com>
|
||||
* Copyright (C) 2019 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OPNsense\Bind\Api;
|
||||
|
||||
use \OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use \OPNsense\Core\Backend;
|
||||
|
||||
class DomainController extends ApiMutableModelControllerBase
|
||||
{
|
||||
protected static $internalModelName = 'domain';
|
||||
protected static $internalModelClass = '\OPNsense\Bind\Domain';
|
||||
|
||||
public function searchDomainAction()
|
||||
{
|
||||
return $this->searchBase('domains.domain', array(
|
||||
"enabled", "type", "masterip", "domainname", "allowtransfer", "allowquery", "ttl",
|
||||
"refresh", "retry", "expire", "negative", "mailadmin", "dnsserver"
|
||||
));
|
||||
}
|
||||
|
||||
public function getDomainAction($uuid = null)
|
||||
{
|
||||
$this->sessionClose();
|
||||
return $this->getBase('domain', 'domains.domain', $uuid);
|
||||
}
|
||||
|
||||
public function addDomainAction($uuid = null)
|
||||
{
|
||||
return $this->addBase('domain', 'domains.domain');
|
||||
}
|
||||
|
||||
public function delDomainAction($uuid)
|
||||
{
|
||||
return $this->delBase('domains.domain', $uuid);
|
||||
}
|
||||
|
||||
public function setDomainAction($uuid = null)
|
||||
{
|
||||
return $this->setBase('domain', 'domains.domain', $uuid);
|
||||
}
|
||||
|
||||
public function toggleDomainAction($uuid)
|
||||
{
|
||||
return $this->toggleBase('domains.domain', $uuid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2019 Michael Muenz <m.muenz@gmail.com>
|
||||
* Copyright (C) 2019 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OPNsense\Bind\Api;
|
||||
|
||||
use \OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use \OPNsense\Bind\Domain;
|
||||
use \OPNsense\Core\Config;
|
||||
|
||||
class RecordController extends ApiMutableModelControllerBase
|
||||
{
|
||||
protected static $internalModelName = 'record';
|
||||
protected static $internalModelClass = '\OPNsense\Bind\Record';
|
||||
|
||||
/**
|
||||
* update parent domain serial
|
||||
* @param $uuid string
|
||||
* @throws \OPNsense\Base\ModelException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
private function setDomainSerial($uuid)
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$record = $this->getModel()->getRecord($uuid);
|
||||
if ($record !== null) {
|
||||
(new Domain)->updateSerial((string)$record->domain)->serializeToConfig();
|
||||
Config::getInstance()->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function searchRecordAction()
|
||||
{
|
||||
$domain = $this->request->get('domain');
|
||||
$filter_funct = null;
|
||||
if (!empty($domain)) {
|
||||
$filter_funct = function($record) use ($domain) {
|
||||
return $record->domain == $domain;
|
||||
};
|
||||
}
|
||||
|
||||
return $this->searchBase('records.record',
|
||||
array("enabled", "domain", "name", "type", "value"), null, $filter_funct
|
||||
);
|
||||
}
|
||||
|
||||
public function getRecordAction($uuid = null)
|
||||
{
|
||||
$this->sessionClose();
|
||||
$domain = $this->request->get('domain');
|
||||
$result = $this->getBase('record', 'records.record', $uuid);
|
||||
if ($uuid == null && !empty($result['record']['domain'])) {
|
||||
// set domain selection
|
||||
foreach ($result['record']['domain'] as $key => &$value) {
|
||||
if ($key == $domain) {
|
||||
$value['selected'] = 1;
|
||||
} else {
|
||||
$value['selected'] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function addRecordAction()
|
||||
{
|
||||
$result = $this->addBase('record', 'records.record');
|
||||
if (!empty($result['uuid'])) {
|
||||
$this->setDomainSerial($result['uuid']);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function delRecordAction($uuid)
|
||||
{
|
||||
$result = $this->delBase('records.record', $uuid);
|
||||
if ($result['result'] == 'deleted') {
|
||||
$this->setDomainSerial($uuid);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function setRecordAction($uuid = null)
|
||||
{
|
||||
$result = $this->setBase('record', 'records.record', $uuid);
|
||||
if ($result['result'] == 'saved') {
|
||||
$this->setDomainSerial($uuid);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function toggleRecordAction($uuid)
|
||||
{
|
||||
$result = $this->toggleBase('records.record', $uuid);
|
||||
if (!empty($result['changed'])) {
|
||||
$this->setDomainSerial($uuid);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2018 Michael Muenz <m.muenz@gmail.com>
|
||||
Copyright (C) 2018-2019 Michael Muenz <m.muenz@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -35,6 +35,8 @@ class GeneralController extends \OPNsense\Base\IndexController
|
||||
$this->view->generalForm = $this->getForm("general");
|
||||
$this->view->dnsblForm = $this->getForm("dnsbl");
|
||||
$this->view->formDialogEditBindAcl = $this->getForm("dialogEditBindAcl");
|
||||
$this->view->formDialogEditBindDomain = $this->getForm("dialogEditBindDomain");
|
||||
$this->view->formDialogEditBindRecord = $this->getForm("dialogEditBindRecord");
|
||||
$this->view->pick('OPNsense/Bind/general');
|
||||
}
|
||||
}
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>domain.enabled</id>
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>This will enable or disable the ACL.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.type</id>
|
||||
<label>Type</label>
|
||||
<type>dropdown</type>
|
||||
<help>Set the type for this domain.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.masterip</id>
|
||||
<label>Master IP</label>
|
||||
<type>text</type>
|
||||
<help>Set the IP address of master server when using slave mode.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.domainname</id>
|
||||
<label>Domain Name</label>
|
||||
<type>text</type>
|
||||
<help>Set the name for this ACL.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.allowtransfer</id>
|
||||
<label>Allow Transfer</label>
|
||||
<type>dropdown</type>
|
||||
<help>Define an ACL where you allow which server can retrieve your zone.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.allowquery</id>
|
||||
<label>Allow Query</label>
|
||||
<type>dropdown</type>
|
||||
<help>Define an ACL where you allow which client are allowed to query this domain.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.ttl</id>
|
||||
<label>TTL</label>
|
||||
<type>text</type>
|
||||
<help>Set the general TTL for this domain.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.refresh</id>
|
||||
<label>Refresh Time</label>
|
||||
<type>text</type>
|
||||
<help>Set the time in seconds.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.retry</id>
|
||||
<label>Retry Time</label>
|
||||
<type>text</type>
|
||||
<help>Set the time in seconds.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.expire</id>
|
||||
<label>Expire Time</label>
|
||||
<type>text</type>
|
||||
<help>Set the time in seconds.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.negative</id>
|
||||
<label>Negative TTL</label>
|
||||
<type>text</type>
|
||||
<help>Set the time in seconds.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.mailadmin</id>
|
||||
<label>Mail Admin</label>
|
||||
<type>text</type>
|
||||
<help>Set the mail address of domain admin. Please replace @ with a dot.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>domain.dnsserver</id>
|
||||
<label>DNS Server</label>
|
||||
<type>text</type>
|
||||
<help>Set the DNS Server hosting this file. This should be the FQDN of your Firewall.</help>
|
||||
</field>
|
||||
</form>
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>record.enabled</id>
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>This will enable or disable the ACL.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>record.domain</id>
|
||||
<label>Domain</label>
|
||||
<type>dropdown</type>
|
||||
<help>Set the type for this record.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>record.name</id>
|
||||
<label>Name</label>
|
||||
<type>text</type>
|
||||
<help>Set the name for this ACL.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>record.type</id>
|
||||
<label>Type</label>
|
||||
<type>dropdown</type>
|
||||
<help>Set the time in seconds.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>record.value</id>
|
||||
<label>Value</label>
|
||||
<type>text</type>
|
||||
<help>Set the time in seconds.</help>
|
||||
</field>
|
||||
</form>
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2019 Michael Muenz <m.muenz@gmail.com>
|
||||
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\Bind;
|
||||
|
||||
use OPNsense\Base\BaseModel;
|
||||
|
||||
class Domain extends BaseModel
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serializeToConfig($validateFullModel = false, $disable_validation = false)
|
||||
{
|
||||
$serialsToSet = array();
|
||||
// collected changed records
|
||||
foreach ($this->getFlatNodes() as $key => $node) {
|
||||
if ($node->isFieldChanged() && (string)$node !== "") {
|
||||
$domain = $node->getParentNode();
|
||||
if (empty($serialsToSet[$domain->getAttribute('uuid')])) {
|
||||
$serialsToSet[$domain->getAttribute('uuid')] = $domain;
|
||||
}
|
||||
}
|
||||
}
|
||||
// new serials on changed records
|
||||
foreach ($serialsToSet as $domain) {
|
||||
$domain->serial = (string)date("YmdHis");
|
||||
}
|
||||
return parent::serializeToConfig($validateFullModel, $disable_validation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $uuid string domain uuid to update
|
||||
* @return Domain
|
||||
*/
|
||||
public function updateSerial($uuid)
|
||||
{
|
||||
foreach ($this->domains->domain->iterateItems() as $domain) {
|
||||
if ($domain->getAttribute('uuid') == $uuid) {
|
||||
$domain->serial = (string)date("YmdHis");
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<model>
|
||||
<mount>//OPNsense/bind/domain</mount>
|
||||
<description>BIND domain configuration</description>
|
||||
<version>1.0.0</version>
|
||||
<items>
|
||||
<domains>
|
||||
<domain type="ArrayField">
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<type type="OptionField">
|
||||
<default>master</default>
|
||||
<Required>Y</Required>
|
||||
<OptionValues>
|
||||
<master>master</master>
|
||||
<slave>slave</slave>
|
||||
</OptionValues>
|
||||
</type>
|
||||
<masterip type="HostnameField">
|
||||
<Required>N</Required>
|
||||
</masterip>
|
||||
<domainname type="TextField">
|
||||
<default></default>
|
||||
<Required>Y</Required>
|
||||
</domainname>
|
||||
<allowtransfer type="ModelRelationField">
|
||||
<Model>
|
||||
<template>
|
||||
<source>OPNsense.Bind.Acl</source>
|
||||
<items>acls.acl</items>
|
||||
<display>name</display>
|
||||
</template>
|
||||
</Model>
|
||||
<Multiple>N</Multiple>
|
||||
<Required>N</Required>
|
||||
</allowtransfer>
|
||||
<allowquery type="ModelRelationField">
|
||||
<Model>
|
||||
<template>
|
||||
<source>OPNsense.Bind.Acl</source>
|
||||
<items>acls.acl</items>
|
||||
<display>name</display>
|
||||
</template>
|
||||
</Model>
|
||||
<Multiple>N</Multiple>
|
||||
<Required>N</Required>
|
||||
</allowquery>
|
||||
<serial type="TextField">
|
||||
<Required>N</Required>
|
||||
</serial>
|
||||
<ttl type="IntegerField">
|
||||
<default>86400</default>
|
||||
<Required>Y</Required>
|
||||
<MinimumValue>60</MinimumValue>
|
||||
<MaximumValue>86400</MaximumValue>
|
||||
<ValidationMessage>Set a value between 60 and 86400.</ValidationMessage>
|
||||
</ttl>
|
||||
<refresh type="IntegerField">
|
||||
<default>21600</default>
|
||||
<Required>Y</Required>
|
||||
<MinimumValue>60</MinimumValue>
|
||||
<MaximumValue>86400</MaximumValue>
|
||||
<ValidationMessage>Set a value between 60 and 86400.</ValidationMessage>
|
||||
</refresh>
|
||||
<retry type="IntegerField">
|
||||
<default>3600</default>
|
||||
<Required>Y</Required>
|
||||
<MinimumValue>60</MinimumValue>
|
||||
<MaximumValue>86400</MaximumValue>
|
||||
<ValidationMessage>Set a value between 60 and 86400.</ValidationMessage>
|
||||
</retry>
|
||||
<expire type="IntegerField">
|
||||
<default>3542400</default>
|
||||
<Required>Y</Required>
|
||||
<MinimumValue>60</MinimumValue>
|
||||
<MaximumValue>10000000</MaximumValue>
|
||||
<ValidationMessage>Set a value between 60 and 10000000.</ValidationMessage>
|
||||
</expire>
|
||||
<negative type="IntegerField">
|
||||
<default>3600</default>
|
||||
<Required>Y</Required>
|
||||
<MinimumValue>60</MinimumValue>
|
||||
<MaximumValue>86400</MaximumValue>
|
||||
<ValidationMessage>Set a value between 60 and 86400.</ValidationMessage>
|
||||
</negative>
|
||||
<mailadmin type="TextField">
|
||||
<default>mail.opnsense.localdomain</default>
|
||||
<Required>Y</Required>
|
||||
</mailadmin>
|
||||
<dnsserver type="HostnameField">
|
||||
<default>opnsense.localdomain</default>
|
||||
<Required>Y</Required>
|
||||
</dnsserver>
|
||||
</domain>
|
||||
</domains>
|
||||
</items>
|
||||
</model>
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
Copyright (C) 2019 Michael Muenz <m.muenz@gmail.com>
|
||||
Copyright (C) 2019 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.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Bind;
|
||||
|
||||
use OPNsense\Base\BaseModel;
|
||||
|
||||
class Record extends BaseModel
|
||||
{
|
||||
/**
|
||||
* @param $uuid string record uuid
|
||||
* @return mixed record
|
||||
*/
|
||||
public function getRecord($uuid)
|
||||
{
|
||||
foreach ($this->records->record->iterateItems() as $record) {
|
||||
if ($record->getAttribute('uuid') == $uuid) {
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<model>
|
||||
<mount>//OPNsense/bind/record</mount>
|
||||
<description>BIND record configuration</description>
|
||||
<version>1.0.0</version>
|
||||
<items>
|
||||
<records>
|
||||
<record type="ArrayField">
|
||||
<enabled type="BooleanField">
|
||||
<default>1</default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<domain type="ModelRelationField">
|
||||
<Required>Y</Required>
|
||||
<Model>
|
||||
<template>
|
||||
<source>OPNsense.Bind.Domain</source>
|
||||
<items>domains.domain</items>
|
||||
<display>domainname</display>
|
||||
</template>
|
||||
</Model>
|
||||
</domain>
|
||||
<name type="TextField">
|
||||
<default></default>
|
||||
<Required>N</Required>
|
||||
</name>
|
||||
<type type="OptionField">
|
||||
<default>A</default>
|
||||
<Required>Y</Required>
|
||||
<OptionValues>
|
||||
<A>A</A>
|
||||
<AAAA>AAAA</AAAA>
|
||||
<CNAME>CNAME</CNAME>
|
||||
<MX>MX</MX>
|
||||
<NS>NS</NS>
|
||||
<PTR>PTR</PTR>
|
||||
<SRV>SRV</SRV>
|
||||
<TXT>TXT</TXT>
|
||||
</OptionValues>
|
||||
</type>
|
||||
<value type="TextField">
|
||||
<Required>Y</Required>
|
||||
</value>
|
||||
</record>
|
||||
</records>
|
||||
</items>
|
||||
</model>
|
||||
@@ -1,7 +1,7 @@
|
||||
{#
|
||||
|
||||
OPNsense® is Copyright © 2014 – 2018 by Deciso B.V.
|
||||
This file is Copyright © 2018 by Michael Muenz <m.muenz@gmail.com>
|
||||
OPNsense® is Copyright © 2014 – 2019 by Deciso B.V.
|
||||
This file is Copyright © 2018 - 2019 by Michael Muenz <m.muenz@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
@@ -32,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
<li class="active"><a data-toggle="tab" href="#general">{{ lang._('General') }}</a></li>
|
||||
<li><a data-toggle="tab" href="#dnsbl">{{ lang._('DNSBL') }}</a></li>
|
||||
<li><a data-toggle="tab" href="#acls">{{ lang._('ACLs') }}</a></li>
|
||||
<li><a data-toggle="tab" href="#domains">{{ lang._('Domains') }}</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content content-box tab-content">
|
||||
@@ -81,19 +82,80 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
<br /><br />
|
||||
</div>
|
||||
</div>
|
||||
<div id="domains" class="tab-pane fade in">
|
||||
<table id="grid-domains" class="table table-responsive" data-editDialog="dialogEditBindDomain">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="enabled" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
|
||||
<th data-column-id="type" data-type="string" data-visible="true">{{ lang._('Type') }}</th>
|
||||
<th data-column-id="domainname" data-type="string" data-visible="true">{{ lang._('Domain') }}</th>
|
||||
<th data-column-id="ttl" data-type="string" data-visible="true">{{ lang._('TTL') }}</th>
|
||||
<th data-column-id="refresh" data-type="string" data-visible="true">{{ lang._('Refresh') }}</th>
|
||||
<th data-column-id="retry" data-type="string" data-visible="true">{{ lang._('Retry') }}</th>
|
||||
<th data-column-id="expire" data-type="string" data-visible="true">{{ lang._('Expire') }}</th>
|
||||
<th data-column-id="negative" data-type="string" data-visible="true">{{ lang._('Negative TTL') }}</th>
|
||||
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
|
||||
<th data-column-id="commands" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="5"></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<hr/>
|
||||
<div id="record-area">
|
||||
<table id="grid-records" class="table table-responsive" data-editDialog="dialogEditBindRecord">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="enabled" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
|
||||
<th data-column-id="domain" data-type="string" data-visible="true">{{ lang._('Domain') }}</th>
|
||||
<th data-column-id="name" data-type="string" data-visible="true">{{ lang._('Name') }}</th>
|
||||
<th data-column-id="type" data-type="string" data-visible="true">{{ lang._('Type') }}</th>
|
||||
<th data-column-id="value" data-type="string" data-visible="true">{{ lang._('Value') }}</th>
|
||||
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
|
||||
<th data-column-id="commands" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="5"></td>
|
||||
<td>
|
||||
<button id="recordAddBtn" data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<hr />
|
||||
<button class="btn btn-primary" id="saveAct_domain" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_domain_progress"></i></button>
|
||||
<br /><br />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogEditBindAcl,'id':'dialogEditBindAcl','label':lang._('Edit ACL')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogEditBindDomain,'id':'dialogEditBindDomain','label':lang._('Edit Domains')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogEditBindRecord,'id':'dialogEditBindRecord','label':lang._('Edit Records')])}}
|
||||
|
||||
<script>
|
||||
$( document ).ready(function() {
|
||||
var data_get_map = {'frm_general_settings':"/api/bind/general/get"};
|
||||
let data_get_map = {'frm_general_settings':"/api/bind/general/get"};
|
||||
mapDataToFormUI(data_get_map).done(function(data){
|
||||
formatTokenizersUI();
|
||||
$('.selectpicker').selectpicker('refresh');
|
||||
});
|
||||
|
||||
var data_get_map2 = {'frm_dnsbl_settings':"/api/bind/dnsbl/get"};
|
||||
let data_get_map2 = {'frm_dnsbl_settings':"/api/bind/dnsbl/get"};
|
||||
mapDataToFormUI(data_get_map2).done(function(data){
|
||||
formatTokenizersUI();
|
||||
$('.selectpicker').selectpicker('refresh');
|
||||
@@ -110,6 +172,53 @@ $( document ).ready(function() {
|
||||
'toggle':'/api/bind/acl/toggleAcl/'
|
||||
}
|
||||
);
|
||||
$("#grid-domains").UIBootgrid({
|
||||
'search':'/api/bind/domain/searchDomain',
|
||||
'get':'/api/bind/domain/getDomain/',
|
||||
'set':'/api/bind/domain/setDomain/',
|
||||
'add':'/api/bind/domain/addDomain/',
|
||||
'del':'/api/bind/domain/delDomain/',
|
||||
'toggle':'/api/bind/domain/toggleDomain/',
|
||||
options:{
|
||||
selection: true,
|
||||
multiSelect: false,
|
||||
rowSelect: true,
|
||||
}
|
||||
}).on("selected.rs.jquery.bootgrid", function(e, rows) {
|
||||
$("#grid-records").bootgrid('reload');
|
||||
}).on("deselected.rs.jquery.bootgrid", function(e, rows) {
|
||||
$("#grid-records").bootgrid('reload');
|
||||
}).on("loaded.rs.jquery.bootgrid", function (e) {
|
||||
let ids = $("#grid-domains").bootgrid("getCurrentRows");
|
||||
if (ids.length > 0) {
|
||||
$("#grid-domains").bootgrid('select', [ids[0].uuid]);
|
||||
}
|
||||
});
|
||||
|
||||
$("#grid-records").UIBootgrid({
|
||||
'search':'/api/bind/record/searchRecord',
|
||||
'get':'/api/bind/record/getRecord/',
|
||||
'set':'/api/bind/record/setRecord/',
|
||||
'add':'/api/bind/record/addRecord/',
|
||||
'del':'/api/bind/record/delRecord/',
|
||||
'toggle':'/api/bind/record/toggleRecord/',
|
||||
options:{
|
||||
useRequestHandlerOnGet: true,
|
||||
requestHandler: function() {
|
||||
let request = {'domain': 'not_found'};
|
||||
let ids = $("#grid-domains").bootgrid("getSelectedRows");
|
||||
if (ids.length > 0) {
|
||||
request['domain'] = ids[0];
|
||||
$("#recordAddBtn").show();
|
||||
$("#record-area").show();
|
||||
} else {
|
||||
$("#recordAddBtn").hide();
|
||||
$("#record-area").hide();
|
||||
}
|
||||
return request;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("#saveAct").click(function(){
|
||||
saveFormToEndpoint(url="/api/bind/general/set", formid='frm_general_settings',callback_ok=function(){
|
||||
@@ -143,5 +252,12 @@ $( document ).ready(function() {
|
||||
});
|
||||
});
|
||||
|
||||
$("#saveAct_domain").click(function(){
|
||||
$("#saveAct_domain_progress").addClass("fa fa-spinner fa-pulse");
|
||||
ajaxCall("/api/bind/service/reconfigure", {}, function(data,status) {
|
||||
updateServiceControlUI('bind');
|
||||
$("#saveAct_domain_progress").removeClass("fa fa-spinner fa-pulse");
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
bing.db:/usr/local/etc/namedb/master/bing.db
|
||||
blacklist.db:/usr/local/etc/namedb/master/blacklist.db
|
||||
domain.db:/usr/local/etc/namedb/master/[OPNsense.bind.domain.domains.domain.%.domainname].db
|
||||
duckduckgo.db:/usr/local/etc/namedb/master/duckduckgo.db
|
||||
google.db:/usr/local/etc/namedb/master/google.db
|
||||
named:/etc/rc.conf.d/named
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{% if helpers.exists('OPNsense.bind.general.enabled') and OPNsense.bind.general.enabled == '1' %}
|
||||
{% if helpers.exists('OPNsense.bind.domain.domains.domain') %}
|
||||
{% for domaindb in helpers.toList('OPNsense.bind.domain.domains.domain') %}
|
||||
{% if TARGET_FILTERS['OPNsense.bind.domain.domains.domain.' ~ loop.index0] %}
|
||||
{% if domaindb.enabled == '1' and domaindb.type == 'master' %}
|
||||
$TTL {{ domaindb.ttl }}
|
||||
@ IN SOA {{ domaindb.dnsserver }}. {{ domaindb.mailadmin }}. ( {{ domaindb.serial|trim }} {{ domaindb.refresh }} {{ domaindb.retry }} {{ domaindb.expire }} {{ domaindb.negative }} )
|
||||
{% for record in helpers.sortDictList(OPNsense.bind.record.records.record, 'name', 'type' ) %}
|
||||
{% if record.domain == domaindb['@uuid'] %}
|
||||
{{ record.name }} {{ record.type }} {{ record.value }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -103,6 +103,18 @@ zone "rpzyoutube" { type master; file "/usr/local/etc/namedb/master/youtube.db";
|
||||
zone "rpzbing" { type master; file "/usr/local/etc/namedb/master/bing.db"; notify no; check-names ignore; };
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if helpers.exists('OPNsense.bind.domain.domains.domain') %}
|
||||
{% for domain in helpers.toList('OPNsense.bind.domain.domains.domain') %}
|
||||
{% if domain.enabled == '1' %}
|
||||
{% set allow_transfer = helpers.getUUID(domain.allowtransfer) %}
|
||||
{% set allow_query = helpers.getUUID(domain.allowquery) %}
|
||||
zone "{{ domain.domainname }}" { type {{ domain.type }}; {% if domain.type == 'slave' %}masters { {{ domain.masterip }}; }; file "/usr/local/etc/namedb/slave/{{ domain.domainname }}.db"; {% else %}file "/usr/local/etc/namedb/master/{{ domain.domainname }}.db"; {% endif %}{% if domain.allowtransfer is defined %} allow-transfer { {{ allow_transfer.name }}; };{% endif %}{% if domain.allowquery is defined %} allow-query { {{ allow_query.name }}; };{% endif %} };
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
logging {
|
||||
channel default_log {
|
||||
file "/var/log/named/named.log" versions 3 size {{ OPNsense.bind.general.logsize }}m;
|
||||
|
||||
Reference in New Issue
Block a user