*/ class DnsHelper { use \ThurData\Servers\KerioEmail\Core\UI\Traits\WhmcsParams; public function __construct() { $this->params = $this->getWhmcsParamsByKeys(['domain', 'userid', 'serverhostname', 'serverusername', 'serverpassword', 'domainid', 'serverid', 'pid']); $this->server = Server::select('id', 'nameserver1ip', 'nameserver2ip')->findOrFail($this->params['serverid']); $this->nameserver = array(trim($this->server->nameserver1ip), trim($this->server->nameserver2ip)); // $this->nameserver = array('127.0.0.1', '127.0.0.2'); //test $this->resolver = new \Net_DNS2_Resolver(array('nameservers' => $this->nameserver)); } /** * @param string $domain * @return array */ public function getRecords($domain) { $zoneID = $this->selfDns($domain); if($zoneID) { return $this->getLocalRecords($zoneID); } return $this->getResolverRecords($domain); } private function selfDns($domain){ $zoneIDcollection = Capsule::table('dns_manager2_zone') ->select('id') ->where('name', '=', $domain) ->get(); $zoneIDobj = $zoneIDcollection[0]; if(!isset($zoneIDobj->{'id'})) { return false; } return $zoneIDobj->{'id'}; } private function getResolverRecords($domain) { $vars['mx'] = array(); $vars['spf'] = array(); $vars['dmarc'] = array(); $vars['dkim'] = array(); $vars['selfDNS'] = false; try { $responseMX = $this->resolver->query($domain, 'MX'); $responseTXT = $this->resolver->query($domain, 'TXT'); } catch(\Net_DNS2_Exception $e) { echo "::query() failed: ", $e->getMessage(), "\n"; } $domainMX = $responseMX->answer; $domainTXT = $responseTXT->answer; foreach($domainMX as $mxRecord) { array_push($vars['mx'], $mxRecord->exchange); } foreach($domainTXT as $txtRecord) { foreach($txtRecord->text as $txtData) { if(strstr($txtData,'v=spf')) { array_push($vars['spf'],$txtData); } if(strstr($txtData,'v=DMARC')) { array_push($vars['dmarc'],$txtData); } if(strstr($txtData,'v=DKIM')) { array_push($vars['dkim'],$txtData); } } } return $vars; } private function getLocalRecords($zoneID) { $vars['mx'] = array(); $vars['spf'] = array(); $vars['dmarc'] = array(); $vars['dkim'] = array(); $vars['selfdns'] = $zoneID; $dnsZone = localAPI('dnsmanager', array( 'dnsaction' => 'getZone', 'zone_id' => $zoneID)); if($dnsZone['result'] != 'success') { return 'Error: cloud not fetch zone for ID ' . $zoneID; } foreach($dnsZone['data']->records as $localRecord) { if($localRecord->type == 'MX'){ array_push($vars['mx'], $localRecord->rdata->exchange); } if($localRecord->type == 'TXT'){ if(strstr($localRecord->rdata->txtdata,'v=spf')) { array_push($vars['spf'], trim($localRecord->rdata->txtdata, '"')); } if(strstr($localRecord->rdata->txtdata,'v=DMARC')) { array_push($vars['dmarc'], trim($localRecord->rdata->txtdata, '"')); } if(strstr($localRecord->rdata->txtdata,'v=DKIM')) { array_push($vars['dkim'], trim($localRecord->rdata->txtdata, '"')); } } } return $vars; } public function updateDNS($zoneID,$dnsParams) { $dnsZone = localAPI('dnsmanager', array( 'dnsaction' => 'getZone', 'zone_id' => $zoneID)); if($dnsZone['result'] != 'success') { return 'Error: cloud not fetch zone for ID ' . $zoneID; } $zoneRecords = array(); $mxtargets = explode(' ', $dnsParams['mx']); $preference = 10; foreach($mxtargets as $mxtarget) { $mxRecord = array( 'name' => '@', 'type' => 'MX', 'class' => 'IN', 'data' => array( 'preference' => $preference, 'exchange' => $mxtarget, ), ); array_push($zoneRecords, $mxRecord); $preference += 10; } $spfRecord = array( 'name' => '@', 'type' => 'TXT', 'class' => 'IN', 'data' => $dnsParams['spf'] ); array_push($zoneRecords, $spfRecord); $dmarcRecord = array( 'name' => '@', 'type' => 'TXT', 'class' => 'IN', 'data' => $dnsParams['dmarc'] ); array_push($zoneRecords, $dmarcRecord); $dkimRecord = array( 'name' => $dnsParams['dkimname'], 'type' => 'TXT', 'class' => 'IN', 'data' => $dnsParams['dkim'] ); array_push($zoneRecords, $dkimRecord); foreach($dnsZone['data']->records as $record) { if($record->type == 'MX') continue; if($record->type == 'SOA') continue; if($record->type === 'TXT') { // skip dmarc if(preg_match('/^v=DMARC1(.*)$/i', trim($record->rdata->txtdata,'"'))) continue; // skip spf if(preg_match('/^v=spf(.*)$/i', trim($record->rdata->txtdata,'"'))) continue; // skip dkim if($dnsParams['dkimname'] == $record->name) continue; }; if($record->type == 'NS'){ $nsrecord = array( 'name' => '@', 'type' => 'NS', 'class' => 'IN', 'data' => $record->rdata->nsdname ); $record = $nsrecord; } array_push($zoneRecords, $record); } logModuleCall( 'kerioEmail', __FUNCTION__, $this->params, 'DEbug', $zoneRecords ); $result = localAPI('dnsmanager' , array( 'dnsaction' => 'updateZone', 'zone_id' => $zoneID, 'records' => $zoneRecords, ) ); if($result['result'] != 'success') { return 'Error: cloud not update zone for ID ' . $zoneID; } return 'success'; } function KerioEmailunsetMX($maildomain) { $zoneIDcollection = Capsule::table('dns_manager2_zone') ->select('id') ->where('name', '=', $maildomain) ->get(); $zoneIDobj = $zoneIDcollection[0]; $zoneID = $zoneIDobj->{'id'}; if(!isset($zoneID)) { return 'Error: zone ID not found for domain ' . $this->params['domain']; } $dnsZone = localAPI('dnsmanager', array( 'dnsaction' => 'getZone', 'zone_id' => $zoneID)); if($dnsZone['result'] != 'success') { return 'Error: cloud not fetch zone for ID ' . $zoneID; } $zoneRecords = array(); foreach($dnsZone['data']->records as $record) { if($record->type == 'MX') continue; array_push($zoneRecords, $record); } $result = localAPI('dnsmanager' , array( 'dnsaction' => 'updateZone', 'zone_id' => $zoneID, 'records' => $zoneRecords, ) ); if($result['result'] != 'success') { return 'Error: cloud not update zone for ID ' . $zoneID; } return 'success'; } }