Skip to content

Commit

Permalink
Adding enhanced nameserver validation (#277)
Browse files Browse the repository at this point in the history
  • Loading branch information
shibayan authored Feb 6, 2021
1 parent f78884c commit 6afeec7
Showing 1 changed file with 45 additions and 5 deletions.
50 changes: 45 additions & 5 deletions AppService.Acmebot/Functions/SharedActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,53 @@ public async Task Dns01Precondition([ActivityTrigger] IReadOnlyList<string> dnsN
// Azure DNS が存在するか確認
var zones = await _dnsManagementClient.Zones.ListAllAsync();

var notFoundZones = dnsNames.Where(x => zones.All(xs => !string.Equals(x, xs.Name, StringComparison.OrdinalIgnoreCase) && !x.EndsWith($".{xs.Name}", StringComparison.OrdinalIgnoreCase)))
.ToArray();
var foundZones = new HashSet<Zone>();
var zoneNotFoundDnsNames = new List<string>();

// マッチする DNS zone が見つからない DNS name があった場合はエラー
if (notFoundZones.Length > 0)
foreach (var dnsName in dnsNames)
{
throw new PreconditionException($"DNS zone(s) are not found. {string.Join(",", notFoundZones)}");
var zone = zones.Where(x => string.Equals(dnsName, x.Name, StringComparison.OrdinalIgnoreCase) || dnsName.EndsWith($".{x.Name}", StringComparison.OrdinalIgnoreCase))
.OrderByDescending(x => x.Name.Length)
.FirstOrDefault();

// マッチする DNS zone が見つからない場合はエラー
if (zone == null)
{
zoneNotFoundDnsNames.Add(dnsName);
continue;
}

foundZones.Add(zone);
}

if (zoneNotFoundDnsNames.Count > 0)
{
throw new PreconditionException($"DNS zone(s) are not found. DnsNames = {string.Join(",", zoneNotFoundDnsNames)}");
}

// DNS zone に移譲されている Name servers が正しいか検証
foreach (var zone in foundZones)
{
// DNS provider が Name servers を返していなければスキップ
if (zone.NameServers == null || zone.NameServers.Count == 0)
{
continue;
}

// DNS provider が Name servers を返している場合は NS レコードを確認
var queryResult = await _lookupClient.QueryAsync(zone.Name, QueryType.NS);

// 最後の . が付いている場合があるので削除して統一
var expectedNameServers = zone.NameServers.Select(x => x.TrimEnd('.'));
var actualNameServers = queryResult.Answers
.OfType<DnsClient.Protocol.NsRecord>()
.Select(x => x.NSDName.Value.TrimEnd('.'));

// 処理対象の DNS zone から取得した NS と実際に引いた NS の値が一つも一致しない場合はエラー
if (!actualNameServers.Intersect(expectedNameServers, StringComparer.OrdinalIgnoreCase).Any())
{
throw new PreconditionException($"The delegated name server is not correct. DNS zone = {zone.Name}, Name Servers = {string.Join(",", zone.NameServers)}");
}
}
}

Expand Down

0 comments on commit 6afeec7

Please sign in to comment.