adding new dns resolver setting for let's encrypt

Signed-off-by: Maurice Preuß (envoyr) <envoyr@froxlor.org>
Co-authored-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Maurice Preuß (envoyr)
2023-01-18 13:57:47 +01:00
parent 1e013d9e9a
commit 4c6ebde58c
15 changed files with 165 additions and 44 deletions

View File

@@ -559,7 +559,7 @@ class Domains extends ApiCommand implements ResourceEntity
// validate dns if lets encrypt is enabled to check whether we can use it at all
if ($letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
$domain_ips = PhpHelper::gethostbynamel6($domain);
$domain_ips = PhpHelper::gethostbynamel6($domain, true, Settings::Get('system.le_domain_dnscheck_resolver'));
$selected_ips = $this->getIpsFromIdArray($ssl_ipandports);
if ($domain_ips == false || count(array_intersect($selected_ips, $domain_ips)) <= 0) {
Response::standardError('invaliddnsforletsencrypt', '', true);
@@ -1523,7 +1523,7 @@ class Domains extends ApiCommand implements ResourceEntity
// validate dns if lets encrypt is enabled to check whether we can use it at all
if ($letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
$domain_ips = PhpHelper::gethostbynamel6($result['domain']);
$domain_ips = PhpHelper::gethostbynamel6($domain, true, Settings::Get('system.le_domain_dnscheck_resolver'));
$selected_ips = $this->getIpsFromIdArray($ssl_ipandports);
if ($domain_ips == false || count(array_intersect($selected_ips, $domain_ips)) <= 0) {
Response::standardError('invaliddnsforletsencrypt', '', true);

View File

@@ -262,7 +262,7 @@ class SubDomains extends ApiCommand implements ResourceEntity
// validate dns if lets encrypt is enabled to check whether we can use it at all
if ($letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
$our_ips = Domain::getIpsOfDomain($domain_check['id']);
$domain_ips = PhpHelper::gethostbynamel6($completedomain);
$domain_ips = PhpHelper::gethostbynamel6($domain, true, Settings::Get('system.le_domain_dnscheck_resolver'));
if ($domain_ips == false || count(array_intersect($our_ips, $domain_ips)) <= 0) {
Response::standardError('invaliddnsforletsencrypt', '', true);
}
@@ -738,7 +738,7 @@ class SubDomains extends ApiCommand implements ResourceEntity
// validate dns if lets encrypt is enabled to check whether we can use it at all
if ($result['letsencrypt'] != $letsencrypt && $letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
$our_ips = Domain::getIpsOfDomain($result['parentdomainid']);
$domain_ips = PhpHelper::gethostbynamel6($result['domain']);
$domain_ips = PhpHelper::gethostbynamel6($domain, true, Settings::Get('system.le_domain_dnscheck_resolver'));
if ($domain_ips == false || count(array_intersect($our_ips, $domain_ips)) <= 0) {
Response::standardError('invaliddnsforletsencrypt', '', true);
}

View File

@@ -521,7 +521,7 @@ EOC;
foreach ($loop_domains as $idx => $domain) {
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Validating DNS of " . $domain);
// ips according to NS
$domain_ips = PhpHelper::gethostbynamel6($domain);
$domain_ips = PhpHelper::gethostbynamel6($domain, true, Settings::Get('system.le_domain_dnscheck_resolver'));
if ($domain_ips == false || count(array_intersect($our_ips, $domain_ips)) <= 0) {
// no common ips...
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $domain . " due to no system known IP address via DNS check");

View File

@@ -34,7 +34,7 @@ final class Froxlor
const VERSION = '2.0.8';
// Database version (YYYYMMDDC where C is a daily counter)
const DBVERSION = '202301120';
const DBVERSION = '202301180';
// Distribution branding-tag (used for Debian etc.)
const BRANDING = '';

View File

@@ -101,7 +101,7 @@ class Preconfig
$agree = [
'title' => 'Check',
'fields' => [
'update_changesagreed' => ['type' => 'checkbox', 'value' => 1, 'label' => '<strong>I have read the update notifications above and I am aware of the changes made to my system.</strong>'],
'update_changesagreed' => ['mandatory' => true, 'type' => 'checkrequired', 'value' => 1, 'label' => '<strong>I have read the update notifications above and I am aware of the changes made to my system.</strong>'],
'update_preconfig' => ['type' => 'hidden', 'value' => 1]
]
];

View File

@@ -27,6 +27,8 @@ namespace Froxlor;
use Exception;
use Froxlor\UI\Panel\UI;
use Net_DNS2_Exception;
use Net_DNS2_Resolver;
use Throwable;
use voku\helper\AntiXSS;
@@ -244,45 +246,60 @@ class PhpHelper
* ipv6 aware gethostbynamel function
*
* @param string $host
* @param boolean $try_a
* default true
* @param boolean $try_a default true
* @param string|null $nameserver set additional resolver nameserver to use (e.g. 1.1.1.1)
* @return boolean|array
*/
public static function gethostbynamel6($host, $try_a = true)
public static function gethostbynamel6(string $host, bool $try_a = true, string $nameserver = null)
{
$dns6 = @dns_get_record($host, DNS_AAAA);
if (!is_array($dns6)) {
// no record or failed to check
$dns6 = [];
}
if ($try_a == true) {
$dns4 = @dns_get_record($host, DNS_A);
if (!is_array($dns4)) {
// no record or failed to check
$dns4 = [];
}
$dns = array_merge($dns4, $dns6);
} else {
$dns = $dns6;
}
$ips = [];
foreach ($dns as $record) {
if ($record["type"] == "A") {
// always use compressed ipv6 format
$ip = inet_ntop(inet_pton($record["ip"]));
$ips[] = $ip;
try {
// set the default nameservers to use, use the system default if none are provided
$resolver = new Net_DNS2_Resolver($nameserver ? ['nameservers' => [$nameserver]] : []);
// get all ip addresses from the A record
if ($try_a) {
try {
$answer = $resolver->query($host, 'A')->answer;
foreach ($answer as $rr) {
$ips[] = $rr->address;
}
} catch (Net_DNS2_Exception $e) {
// we can't do anything here, just continue
}
}
if ($record["type"] == "AAAA") {
// always use compressed ipv6 format
$ip = inet_ntop(inet_pton($record["ipv6"]));
$ips[] = $ip;
// get all ip addresses from the AAAA record
try {
$answer = $resolver->query($host, 'AAAA')->answer;
foreach ($answer as $rr) {
$ips[] = $rr->address;
}
} catch (Net_DNS2_Exception $e) {
// we can't do anything here, just continue
}
} catch (Net_DNS2_Exception $e) {
// fallback to php's dns_get_record if Net_DNS2 has no resolver available, but this may cause
// problems if the system's dns is not configured correctly; for example, the acme pre-check
// will fail because some providers put a local ip in /etc/hosts
// get all ip addresses from the A record
if ($try_a) {
$answer = @dns_get_record($host, DNS_A);
foreach ($answer as $rr) {
$ips[] = $rr['ip'];
}
}
// get all ip addresses from the AAAA record
$answer = @dns_get_record($host, DNS_AAAA);
foreach ($answer as $rr) {
$ips[] = $rr['ipv6'];
}
}
if (count($ips) < 1) {
return false;
} else {
return $ips;
}
return count($ips) > 0 ? $ips : false;
}
/**