dns: no separate zonefiles for ismainbutsubto domains 3/3

replace iteration over $domains array by recursive walkDomainList()
This commit is contained in:
Daniel Reichelt
2016-06-17 20:15:44 +02:00
parent 631e36f4d5
commit 50317da185
3 changed files with 138 additions and 76 deletions

View File

@@ -14,7 +14,7 @@
* @package Functions
*
*/
function createDomainZone($domain_id, $froxlorhostname = false)
function createDomainZone($domain_id, $froxlorhostname = false, $isMainButSubTo = false)
{
if (!$froxlorhostname)
{
@@ -49,7 +49,9 @@ function createDomainZone($domain_id, $froxlorhostname = false)
addRequiredEntry('@', 'A', $required_entries);
addRequiredEntry('@', 'AAAA', $required_entries);
addRequiredEntry('@', 'NS', $required_entries);
if (! $isMainButSubTo) {
addRequiredEntry('@', 'NS', $required_entries);
}
if ($domain['isemaildomain'] === '1') {
addRequiredEntry('@', 'MX', $required_entries);
if (Settings::Get('system.dns_createmailentry')) {
@@ -96,20 +98,6 @@ function createDomainZone($domain_id, $froxlorhostname = false)
addRequiredEntry('www.' . str_replace('.' . $domain['domain'], '', $subdomain['domain']), 'AAAA', $required_entries);
}
}
// additional required records for main-but-subdomain-to
$mainbutsub_stmt = Database::prepare("
SELECT `domain` FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `ismainbutsubto` = :domainid
");
Database::pexecute($mainbutsub_stmt, array(
'domainid' => $domain_id
));
while ($mainbutsubtodomain = $mainbutsub_stmt->fetch(PDO::FETCH_ASSOC)) {
// Add NS entry for subdomain-records of "main-but-subdomain-to"-domains, they get their own Zone
addRequiredEntry(str_replace('.' . $domain['domain'], '', $mainbutsubtodomain['domain']), 'NS', $required_entries);
}
}
// additional required records for SPF and DKIM if activated
@@ -272,30 +260,32 @@ function createDomainZone($domain_id, $froxlorhostname = false)
$primary_ns = Settings::Get('system.hostname');
}
$date = date('Ymd');
$domain['bindserial'] = (preg_match('/^' . $date . '/', $domain['bindserial']) ?
$domain['bindserial'] + 1 :
$date . '00');
if (!$froxlorhostname) {
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
`bindserial` = :serial
WHERE `id` = :id
");
Database::pexecute($upd_stmt, array('serial' => $domain['bindserial'], 'id' => $domain['id']));
if (! $isMainButSubTo) {
$date = date('Ymd');
$domain['bindserial'] = (preg_match('/^' . $date . '/', $domain['bindserial']) ?
$domain['bindserial'] + 1 :
$date . '00');
if (!$froxlorhostname) {
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
`bindserial` = :serial
WHERE `id` = :id
");
Database::pexecute($upd_stmt, array('serial' => $domain['bindserial'], 'id' => $domain['id']));
}
$soa_content = $primary_ns . " " . escapeSoaAdminMail(Settings::Get('panel.adminmail')) . " (" . PHP_EOL;
$soa_content .= $domain['bindserial'] . "\t; serial" . PHP_EOL;
// TODO for now, dummy time-periods
$soa_content .= "1800\t; refresh (30 mins)" . PHP_EOL;
$soa_content .= "900\t; retry (15 mins)" . PHP_EOL;
$soa_content .= "604800\t; expire (7 days)" . PHP_EOL;
$soa_content .= "1200\t)\t; minimum (20 mins)";
$soa_record = new DnsEntry('@', 'SOA', $soa_content);
array_unshift($zonerecords, $soa_record);
}
$soa_content = $primary_ns . " " . escapeSoaAdminMail(Settings::Get('panel.adminmail')) . " (" . PHP_EOL;
$soa_content .= $domain['bindserial'] . "\t; serial" . PHP_EOL;
// TODO for now, dummy time-periods
$soa_content .= "1800\t; refresh (30 mins)" . PHP_EOL;
$soa_content .= "900\t; retry (15 mins)" . PHP_EOL;
$soa_content .= "604800\t; expire (7 days)" . PHP_EOL;
$soa_content .= "1200\t)\t; minimum (20 mins)";
$soa_record = new DnsEntry('@', 'SOA', $soa_content);
array_unshift($zonerecords, $soa_record);
$zone = new DnsZone((int) Settings::Get('system.defaultttl'), $domain['domain'], $domain['bindserial'], $zonerecords);
return $zone;

View File

@@ -19,6 +19,8 @@ if (! defined('MASTER_CRONJOB'))
class bind extends DnsBase
{
private $_bindconf_file = "";
public function writeConfigs()
{
// tell the world what we are doing
@@ -43,35 +45,67 @@ class bind extends DnsBase
$bindconf_file = '# ' . Settings::Get('system.bindconf_directory') . 'froxlor_bind.conf' . "\n" . '# Created ' . date('d.m.Y H:i') . "\n" . '# Do NOT manually edit this file, all changes will be deleted after the next domain change at the panel.' . "\n\n";
foreach ($domains as $domain) {
if ($domain['ismainbutsubto'] > 0) {
// domains with ismainbutsubto>0 are handled by recursion within walkDomainList()
continue;
}
$this->walkDomainList($domain, $domains);
}
$bindconf_file_handler = fopen(makeCorrectFile(Settings::Get('system.bindconf_directory') . '/froxlor_bind.conf'), 'w');
fwrite($bindconf_file_handler, $this->_bindconf_file);
fclose($bindconf_file_handler);
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'froxlor_bind.conf written');
safe_exec(escapeshellcmd(Settings::Get('system.bindreload_command')));
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Bind9 reloaded');
$domains_dir = makeCorrectDir(Settings::Get('system.bindconf_directory') . '/domains/');
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Task4 finished');
}
private function walkDomainList($domain, $domains)
{
$zoneContent = '';
$subzones = '';
foreach ($domain['children'] as $child_domain_id) {
$subzones .= $this->walkDomainList($domains[$child_domain_id], $domains);
}
if ($domain['zonefile'] == '') {
// check for system-hostname
$isFroxlorHostname = false;
if (isset($domain['froxlorhost']) && $domain['froxlorhost'] == 1) {
$isFroxlorHostname = true;
}
// create zone-file
$this->_logger->logAction(CRON_ACTION, LOG_DEBUG, 'Generating dns zone for ' . $domain['domain']);
$zone = createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname);
$zonefile = (string)$zone;
$domain['zonefile'] = 'domains/' . $domain['domain'] . '.zone';
$zonefile_name = makeCorrectFile(Settings::Get('system.bindconf_directory') . '/' . $domain['zonefile']);
$zonefile_handler = fopen($zonefile_name, 'w');
fwrite($zonefile_handler, $zonefile);
fclose($zonefile_handler);
$this->_logger->logAction(CRON_ACTION, LOG_INFO, '`' . $zonefile_name . '` zone written');
// generate config
$bindconf_file .= $this->_generateDomainConfig($domain);
if ($domain['ismainbutsubto'] == 0) {
$zoneContent = (string) createDomainZone(($domain['id'] == 'none') ?
$domain :
$domain['id'],
$isFroxlorHostname);
$domain['zonefile'] = 'domains/' . $domain['domain'] . '.zone';
$zonefile_name = makeCorrectFile(Settings::Get('system.bindconf_directory') . '/' .
$domain['zonefile']);
$zonefile_handler = fopen($zonefile_name, 'w');
fwrite($zonefile_handler, $zoneContent . $subzones);
fclose($zonefile_handler);
$this->_logger->logAction(CRON_ACTION, LOG_INFO, '`' . $zonefile_name . '` written');
$this->_bindconf_file .= $this->_generateDomainConfig($domain);
} else {
return (string) createDomainZone(($domain['id'] == 'none') ?
$domain :
$domain['id'],
$isFroxlorHostname,
true);
}
} else {
$this->_logger->logAction(CRON_ACTION, LOG_INFO,
'Added zonefile ' . $domain['zonefile'] . ' for domain ' . $domain['domain'] .
' - Note that you will also have to handle ALL records for ALL subdomains.');
$this->_bindconf_file .= $this->_generateDomainConfig($domain);
}
// write config
$bindconf_file_handler = fopen(makeCorrectFile(Settings::Get('system.bindconf_directory') . '/froxlor_bind.conf'), 'w');
fwrite($bindconf_file_handler, $bindconf_file);
fclose($bindconf_file_handler);
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'froxlor_bind.conf written');
// reload Bind
safe_exec(escapeshellcmd(Settings::Get('system.bindreload_command')));
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Bind9 reloaded');
}
private function _generateDomainConfig($domain = array())

View File

@@ -30,7 +30,7 @@ class pdns extends DnsBase
$this->_connectToPdnsDb();
// clean up
$this->_cleanZonefiles();
$this->_clearZoneTables();
$domains = $this->getDomainList();
@@ -39,22 +39,12 @@ class pdns extends DnsBase
return;
}
foreach ($domains as $domain) {
// check for system-hostname
$isFroxlorHostname = false;
if (isset($domain['froxlorhost']) && $domain['froxlorhost'] == 1) {
$isFroxlorHostname = true;
if ($domain['ismainbutsubto'] > 0) {
// domains with ismainbutsubto>0 are handled by recursion within walkDomainList()
continue;
}
// create zone-file
$this->_logger->logAction(CRON_ACTION, LOG_DEBUG, 'Generating dns zone for ' . $domain['domain']);
$zone = createDomainZone(($domain['id'] == 'none') ? $domain : $domain['id'], $isFroxlorHostname);
$dom_id = $this->_insertZone($zone->origin, $zone->serial);
$this->_insertRecords($dom_id, $zone->records, $zone->origin);
$this->_insertAllowedTransfers($dom_id);
$this->_logger->logAction(CRON_ACTION, LOG_INFO, '`' . $domain['domain'] . '` zone written');
$this->walkDomainList($domain, $domains);
}
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Database updated');
@@ -64,7 +54,50 @@ class pdns extends DnsBase
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'pdns reloaded');
}
private function _cleanZonefiles()
private function walkDomainList($domain, $domains)
{
$zoneContent = '';
$subzones = array();
foreach ($domain['children'] as $child_domain_id) {
$subzones[] = $this->walkDomainList($domains[$child_domain_id], $domains);
}
if ($domain['zonefile'] == '') {
// check for system-hostname
$isFroxlorHostname = false;
if (isset($domain['froxlorhost']) && $domain['froxlorhost'] == 1) {
$isFroxlorHostname = true;
}
if ($domain['ismainbutsubto'] == 0) {
$zoneContent = createDomainZone(($domain['id'] == 'none') ?
$domain :
$domain['id'],
$isFroxlorHostname);
if (count($subzones)) {
array_push($zoneContent->records, ...$subzones);
}
$pdnsDomId = $this->_insertZone($zoneContent->origin, $zoneContent->serial);
$this->_insertRecords($pdnsDomId, $zoneContent->records, $zoneContent->origin);
$this->_insertAllowedTransfers($pdnsDomId);
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'DB entries stored for zone `' . $domain['domain'] . '`');
} else {
return createDomainZone(($domain['id'] == 'none') ?
$domain :
$domain['id'],
$isFroxlorHostname,
true);
}
} else {
$this->_logger->logAction(CRON_ACTION, LOG_ERROR,
'Zonefiles are NOT supported when PowerDNS is selected as DNS daemon (triggered by: ' .
$domain['domain'] . ')');
$this->_bindconf_file .= $this->_generateDomainConfig($domain);
}
}
private function _clearZoneTables()
{
$this->_logger->logAction(CRON_ACTION, LOG_INFO, 'Cleaning dns zone entries from database');
@@ -99,6 +132,11 @@ class pdns extends DnsBase
foreach ($records as $record)
{
if ($record instanceof DnsZone) {
$this->_insertRecords($domainid, $record->records, $record->origin);
continue;
}
if ($record->record == '@') {
$_record = $origin;
}