Я запускаю DNS-серверы BIND9 и разрешаю динамическое обновление DNS от моих клиентов с помощью ключа TSIG.
Один из моих клиентов использует только среду Windows и, следовательно, PowerShell для запуска скриптов. Он хочет использовать PowerShell для отправки динамических обновлений на мои серверы.
Сделать это для тестирования из оболочки Linux очень просто: используйте nsupdate.
из: https://www.freeipa.org/page/Howto/DNS_updates_and_zone_transfers_with_TSIG
Клиент
Для nsupdate из пакета bind-utils вы должны либо использовать опцию -y алгоритм: keyname: keyvalue, либо опцию -k keyfilename. Например.
$ nsupdate -y hmac-sha512:keyname:keyvalue
или
$ nsupdate -k Kkeyname.+165+0316.private
затем сделайте свое обновление:
из https://linux.die.net/man/8/nsupdate:
# nsupdate > update delete oldhost.example.com A > update add newhost.example.com 86400 A 172.16.1.1 > send
Чтобы сделать обновление из Powershell без TSIG ... довольно просто ... я думаю ?: используйте командлет (например) Add-DnsServerResourceRecordA
Add-DnsServerResourceRecordA -Name "host23" -ZoneName "contoso.com" - AllowUpdateAny -IPv4Address "172.18.99.23" -TimeToLive 01:00:00
После просмотра документации я не вижу никаких ссылок на подписи транзакций или использование ключа TSIG.
Как отправить динамическое обновление с помощью ключа TISG на сервер BIND9 из Powershell?
Это очень сложно найти пример. Большинство примеров, которые я могу найти, используют PowerShell для отправки обновлений через API, который затем (возможно) выполняет какое-то развертывание или динамическое обновление внутри черного ящика. Я хочу просто создать обновление DDNS и отправить его с помощью PowerShell.
Им нужно будет загрузить nsupdate из BIND (https://www.isc.org/downloads/). Можно вызвать nsupdate с хоста PowerShell.
Решение для тех, у кого нет статического IP-адреса и нужно динамически обновлять IP-адрес для зоны DNS и обратных записей DNS PTR.
$Server = "your server"; $Hostname = "mail"; $Zonename = "your zone";
$MZone = $Hostname + "." + $Zonename
<# No need to edit below unless you have to change some internal component #>
$oldobj = get-dnsserverresourcerecord -ComputerName $Server -name $Hostname -zonename $zonename -rrtype "A"
$newobj = get-dnsserverresourcerecord -ComputerName $Server -name $Hostname -zonename $zonename -rrtype "A"
$ip = (Invoke-WebRequest ifconfig.me/ip).Content.Trim()
$oip = $oldobj.recorddata.Ipv4address.IpAddressToString
$oipSplit = $oip.Split("."); $oipr = $oipSplit[2] + "." + $oipSplit[1] + "." + $oipSplit[0] + ".in-addr.arpa"
$ipSplit = $ip.Split("."); $ipr = $ipSplit[2] + "." + $ipSplit[1] + "." + $ipSplit[0] + ".in-addr.arpa"
$newobj.recorddata.ipv4address=[System.Net.IPAddress]::parse($ip)
if ($oip -ne $ip) {
Set-dnsserverresourcerecord -ComputerName $Server -newinputobject $newobj -oldinputobject $oldobj -zonename $zonename -passthru
echo "updated A record"
}
$oiprZ = Resolve-DnsName -Name $oipr -Server $Server; $oiprR = 0;
if ($oiprZ.count -gt 0) {
$oiprR = get-dnsserverresourcerecord -ComputerName $Server -ZoneName $oipr -rrtype "PTR" -Name $oipSplit[3] | Select-Object HostName, @{Name='RecordData';Expression={$MZone}}
if ($oiprR -ne 0 -And $oiprR -ne $null -and -not ($oiprR[0].HostName -eq $ipSplit[3] -and $oiprR[0].RecordData -eq $MZone -and $oipr -eq $ipr ) ){
Remove-DnsServerResourceRecord -ComputerName $Server -ZoneName $oipr -rrtype "PTR" -Name $oipSplit[3] -RecordData $MZone -Force
echo "removing existing ptr record"
echo $oiprR
echo "removed existing ptr record"
}
$oiprR =get-dnsserverresourcerecord -ComputerName $Server -ZoneName $oipr -rrtype "PTR"
if (((($oiprR) -eq $null) -or (($oiprR).Count -eq 0)) -And $oipr -ne $ipr ) {
Remove-DnsServerZone -ComputerName $Server $oipr -PassThru -Verbose -Force
echo "Removing RDNS Zone"
echo $oiprZ
echo "Removing RDNS Zone"
}
}
$ipNID = $ipSplit[0] + "." + $ipSplit[1] + "." + $ipSplit[2] + ".0/24"
$iprZ = Resolve-DnsName -Name $ipr -Server $Server; $iprR = 0;
if ($iprZ.count -gt 0) {
$iprR = get-dnsserverresourcerecord -ComputerName $Server -ZoneName $ipr -rrtype "PTR" -Name $ipSplit[3] | Select-Object HostName, @{Name='RecordData';Expression={$MZone}}
if ($iprR -eq $null ){
Add-DnsServerResourceRecordPtr -ComputerName $Server -Name $ipSplit[3] -ZoneName $ipr -AllowUpdateAny -TimeToLive 01:00:00 -AgeRecord -PtrDomainName $MZone
echo "adding ptr record"
echo $iprR
echo "added ptr record"
}
else
{
}
}
if ($iprZ.count -eq 0) {
Add-DnsServerPrimaryZone -ComputerName $Server -DynamicUpdate Secure -NetworkId $ipNID -ReplicationScope Domain
Add-DnsServerResourceRecordPtr -ComputerName $Server -Name $ipSplit[3] -ZoneName $ipr -AllowUpdateAny -TimeToLive 01:00:00 -AgeRecord -PtrDomainName $MZone
}
Вот сценарий, который будет создавать и отправлять запросы DDNS, если предоставлен файл tsig. Убедитесь, что разрешения NTFS установлены для предотвращения доступа неавторизованных пользователей (включая других администраторов) к этому файлу.
Это предполагает, что вы установили nsupdate.exe и связанную с ним dll в C: \ windows \ system32, но его можно изменить для других путей.
Я приветствую любые запросы на включение. https://github.com/ACiDGRiM/UsefulScripts/blob/master/Update-DNS.ps1
Param (
[String]$KeyPath = "C:\Windows\System32\drivers\etc\windows-update-client.txt",
[String]$NSScriptPath = "$env:Temp\nsupdate.txt",
[String]$NSUpdatePath = "$env:SystemRoot\System32"
)
begin {
#Gather status of system IP Addresses, DNS Servers, and domains
$IPAddresses = Get-NetIPAddress | Where-Object -FilterScript { ($_.InterfaceAlias -like "Ethernet*" -or $_.InterfaceAlias -like "Wi-Fi*") -and $_.IPAddress -notlike "fe*"}
$DNSServers = Get-DnsClientServerAddress | Where-Object -FilterScript { $_.InterfaceAlias -like "Ethernet*" -or $_.InterfaceAlias -like "Wi-Fi*"}
$DNSClient = Get-DnsClient | Where-Object -FilterScript { $_.InterfaceAlias -like "Ethernet*" -or $_.InterfaceAlias -like "Wi-Fi*"}
}
process {
[array]$RequestOutput = @()
#Parse network status into simplified objects
foreach ( $if in $IPAddresses ) {
$requesthash = @{
IPAddress = @{Address = $if.IPAddress;AddressFamily = $if.AddressFamily}
Zone = $DNSClient | Where-Object -FilterScript { $_.InterfaceAlias -eq $if.InterfaceAlias } | Select-Object -ExpandProperty "ConnectionSpecificSuffix" -First 1
Servers = $DnsServers | Where-Object -FilterScript { $_.InterfaceAlias -eq $if.InterfaceAlias } | Select-Object -ExpandProperty "ServerAddresses"
}
$RequestObj = New-Object -TypeName psobject -Property $requesthash
$RequestOutput += $RequestObj
}
#Condense zones from multiple interfaces
[array]$UniqueZones = ($RequestOutput.Zone|Sort-Object -Unique)
#Combine IPv6 and IPv4 addresses into a single object property for each zone
[array]$CombinedOutput = @()
for ($i=0;$i -lt $UniqueZones.count;$i++) {
$Combinedhash = @{
Addresses = $RequestOutput | Where-Object -FilterScript {$_.Zone -eq $UniqueZones[$i]} | Select-Object -ExpandProperty "IPAddress"
Servers = $RequestOutput | Where-Object -FilterScript {$_.Zone -eq $UniqueZones[$i]} | Select-Object -ExpandProperty "Servers" | Sort-Object -Unique
Zone = $UniqueZones[$i]
}
$CombinedObj = New-Object -TypeName psobject -Property $Combinedhash
$CombinedOutput += $CombinedObj
}
foreach ( $o in $CombinedOutput ) {
foreach ( $s in $o.Servers ) {
$CurrentRecords = Resolve-DnsName $env:COMPUTERNAME`.$($o.Zone) -Server $s -Type "A_AAAA" -DnsOnly -DnssecOK -QuickTimeout -ErrorAction "SilentlyContinue" | Select-Object -ExpandProperty "IPAddress" -ErrorAction "SilentlyContinue"
if ( $CurrentRecords ) {
$CurrentState = Compare-Object $IPAddresses.IPAddress $CurrentRecords -ErrorAction "SilentlyContinue"
} else {
$CurrentState = $true
}
if ( $CurrentState ) {
$script += "server $s
"
foreach ( $a in $o.Addresses ) {
if ( $a.AddressFamily -eq "IPv4" ) {
$PTR = $a.Address -replace '^(\d+)\.(\d+)\.\d+\.(\d+)$','$3.$2.$1.in-addr.arpa.'
} else {
$PTR = (([char[]][BitConverter]::ToString(([IPAddress]$a.Address).GetAddressBytes())-ne'-')[31..0]-join".")+'.ip6.arpa.'
}
$script += "update delete $env:COMPUTERNAME.$($o.Zone). $(if($a.AddressFamily -eq "IPv4"){"A"}else{"AAAA"})
update add $env:COMPUTERNAME.$($o.Zone). 60 $(if($a.AddressFamily -eq "IPv4"){"A"}else{"AAAA"}) $($a.Address)
update delete $PTR PTR
update add $PTR 60 PTR $env:COMPUTERNAME.$($o.Zone).
"
}
}
}
}
}
end {
$script | Out-File -FilePath $NSScriptPath -Encoding "ascii" -Force
Start-Process -FilePath (Join-Path -Path $NSUpdatePath -ChildPath "nsupdate.exe") -ArgumentList "-d -k `"$KeyPath`" `"$NSScriptPath`"" -Wait -NoNewWindow -RedirectStandardError "$env:TEMP\nsstderr" -RedirectStandardOutput "$env:TEMP\nsstdout" -WorkingDirectory $NSUpdatePath | Out-Null
}