Sawit M.
Posted on November 4, 2022
หลังจากที่ Azure ประกาศ GA Azure DNS Private Resolver ก็ได้ฤกษ์ ลองเล่นซะที หลังจากเก็บไว้ในกองดองอยู่นาน มาเข้าเรื่องกันเลยครับ
Azure DNS Private Resolver คืออะไร
สั้นๆ มันคือ resource ที่ทำหน้าที่เป็น DNS server นั้นเอง ในโลก internet DNS เป็นส่วนที่สำคัญมากๆ มันทำให้เราพิมพ์ google.co.th แล้วสามารถ connect ไปที่ google ได้เลยแทนที่จะต้องพิมพ์ 142.251.12.94
ซึ่งเป็น IP address ของ goole ที่ผม resolve ได้ในตอนที่เขียน blog นี้
โดย resource ตัวนี้จะทำงานใน private network ของเราบน Azure คอย resolve private domain name ของเราให้เป็น private IP address
แล้วก่อนหน้านี้ resolve domain name กันอย่างไรล่ะ
ใน Azure จริงๆ แล้ว มัมมี built-in DNS อยู่แล้ว เรียกว่า Azure-provided DNS มันจะเป็น configuration เนียนๆ อยู่ใน virtual network ของเรา ตรงนี้
โดย มันจะปรากฏในรูปแบบของ IP 168.63.129.16
ใน ใน VM ของเรา ที่ deploy ใน virtual network ที่ configure DNS server ไว้ตามข้างต้น โดย 168.63.129.16
สามารถ connect จาก Azure resources เท่านั้น
$ systemd-resolve --status | grep 'DNS Servers'
DNS Servers: 168.63.129.16
รายละเอียดเพิ่มเติม ของ
168.63.129.16
สามารถอ่านเพิ่มได้จาก What is IP address 168.63.129.16?
ทีนี้หากเราต้องการ เพิ่ม private domain name ก็แค่สร้าง private dns zone แล้ว link มันกับ virtual network ของเรา เท่านี้ Azure DNS ก็จะสามารถ resolve private domain name ของเราได้แล้ว
พอเราใช้ไปซักพักความต้องการเริ่มมากขึ้น เริ่มมี requirement ให้เราไปต่อกับ on-premise network ในส่วนของ connetivity นั้นก็ใช้ VPN หรือ Express Route ได้ตามปกติ แต่ในเรื่อง domain name resolution ล่ะ จะทำอย่างไรดี เพราะ on-prem ไม่สามารถ connect มาที่ 168.63.129.16
ที่อยู่บน Azure ของเราได้
ก่อนการมาของ Azure DNS Private Resolver เราใช้วิธีการสร้าง VM-Based DNS server ขึ้นมา พูดง่ายๆ สร้าง VM แล้วเอา DNS software เช่น Bind9 มา install เอง ถ้าอยากได้ SLA ที่เพิ่มขึ้นก็เอา VM มาใส่ VM Scale Set แล้ว ขั้นหน้าด้วย Load Balancer
นั่นหมายความว่าเราต้อง manage ทุกอย่างเอง ไม่ว่าจะเป็นการ hardening, OS update, Software upgrade, Backup และอื่นๆ อีกมากมาย
แล้วให้ on-premise DNS server ทำ Conditional Forward มาที่ VM-Based DNS server ของเรา
ในทางกลับกัน เราต้องต้อง configure Conditional Forward ลงไปที่ on-prem ด้วย เพื่อให้ server บน Azure สามารถ resolve domain name ของ on-premise ได้
Conditional Forward คือการ configure ใน DNS server ทำการ forward request ต่อยัง อีก DNS server หนึ่ง เช่น เรามี zone
*.example.com
อยู่ที่ server-A เราสามารถ configure ให้ DNS ของเราไปถามต่อที่ server-A ได้ หากมี client ถามว่าdemo.example.com
เป็น IP อะไร โดยที่ client ไม่ต้องรู้จัก server-A เลย
Azure DNS Private Resolver ทำงานอย่างไร
การที่จะทำ Hybrid DNS Solution บน Azure จะมี 2 resources ที่ทำงานร่วมกัน
- DNS Private Resolver
- DNS Forwarding Ruleset
DNS Private Resolver
ทำหน้าที่เป็น endpoint ในการทำ name resolution โดยประกอบด้วย 2 endpoints ที่ deploy อยู่คนละ dedicated subnet คือ
- Inbound endpoints: เป็น ingress subnet โดย 1 endpoint จะมี 1 IP address ของ Load Balancer สำหรับ รับ domain name resolution request จาก on-premise หรือ resource ใน virtual network อื่น
- Outbound endpoints: เป็น egress subnet ที่ใช้ออกไป query DNS servers อื่นๆ ใน subnet นี้จะไม่มี IP address ปรากฏ นั่นหมายความว่า outgoing IP address มีโอกาสเป็นไปได้ทั้ง subnet (ผมเดาว่าน่าจะใช้ technic เดียวกับ vnet integration ของ app service)
DNS Forwarding Ruleset
ทำหน้าที่เป็น conditional forward configuration ใน vnet ของเรา โดย Ruleset ก็ตามชื่อเลยครับ เป็นกลุ่มของ conditional forward rule โดย rule จะมีหน้าตาดังนี้
และการจะใช้งาน DNS Forwarding Ruleset ได้ ก็ต้องเอามันไป link กับ virtual network ตาม concept เดียวกับ Private DNS Zone
ยังจำได้ไหม ตัว resolver มี outbound endpoint ซึ่ง deploy ใน dedicated subnet ใน virtual network ดังนั้น ตัว outbound endpoint ก็จะทำตาม DNS Forwarding Ruleset ที่เรา link ไว้ด้วย
เอ๊ะ! ถ้าเรามีทั้ง Private DNS Zone Link และ DNS Forwarding Ruleset Link ด้วยมันจะทำงานอย่างไร ?
มันจะ resolve ตาม order นี้ครับ
- Private DNS Zone
- DNS Forwarding Ruleset
- Azure-provided DNS Servers
สรุป ถ้า resolver ได้รับ name resolution request มาจาก client ผ่านทาง inbound endpoint IP address มันจะ forward ออกไปยัง outbound endpoint IP address ซึ่งจะทำการ resolve domain name ตามลำดับข้างต้น แล้ว response สิ่งที่ได้ไปให้กับ client
ถ้าพอนึกภาพออกแล้วเรามาลองลงมือทำกันดีกว่า
Architecure ที่เราจะลองทำหน้าตาประมาณนี้ครับ
เราจะมี 3 virtual network ดังนี้
- On-Prem: เป็นตัวแทนของ on-premise
- Hub: เป็นตัวแทนของ Hub network บน Azure ที่เป็นศูนย์รวมของ connectivity ต่างๆ
- Spoke: เป็น virtual network ของ application ที่จะมา deploy ใน Azure
โดย
- ที่ On-Prem จะมี DNS server ที่มี DNS records ของ domain
*.onprem.contoso.com
และทำ conditional forward domain*.private.contoso.com
ไปที่ Resolver ที่ Hub - ที่ Hub จะมี DNS Private Resolver พระเอกของเรา, Private DNS Zone
*.private.contoso.com
และ DNS Forwarding Ruleset พระเอกของเราอีกคน เอาไว้ทำ conditional forward*.onprem.contoso.com
ลงไปที่ On-Prem โดยใน virtual network นี้จะมี VM 1 server เอาไว้ทดสอบ name resolution - ที่ Spoke มี VM 1 server เอาไว้ทดสอบ name resolution เช่นกัน
เรามาเริ่มสร้างกันเลย
Create Resource Group
az group create \
--name rg-demodns-az-asse-sbx-001 \
--location southeastasia
Create Hub
- Virtual Network
az network vnet create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vnet-demodnshub-az-asse-sbx-001 \
--address-prefixes 10.1.0.0/16
az network vnet subnet create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name snet-default-az-asse-sbx-001 \
--vnet-name vnet-demodnshub-az-asse-sbx-001 \
--address-prefixes 10.1.1.0/24
az network vnet subnet create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name snet-inbound-az-asse-sbx-001 \
--vnet-name vnet-demodnshub-az-asse-sbx-001 \
--address-prefixes 10.1.2.0/28
az network vnet subnet create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name snet-outbound-az-asse-sbx-001 \
--vnet-name vnet-demodnshub-az-asse-sbx-001 \
--address-prefixes 10.1.2.16/28
- Virtual Machine
SUBNET_ID=$(
az network vnet subnet show \
--resource-group rg-demodns-az-asse-sbx-001 \
--vnet-name vnet-demodnshub-az-asse-sbx-001 \
--name snet-default-az-asse-sbx-001 \
--query "id" \
--output tsv
)
az vm create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vm-hub-az-asse-sbx-001 \
--computer-name vm-hub-az-asse-sbx-001 \
--image UbuntuLTS \
--size Standard_D2s_v4 \
--accelerated-networking true \
--subnet ${SUBNET_ID} \
--nsg-rule SSH \
--admin-username azureuser \
--ssh-key-values /home/sawitmee/.ssh/id_rsa.pub
- Private DNS Zone
az network private-dns zone create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name private.contoso.com
az network private-dns record-set a add-record \
--resource-group rg-demodns-az-asse-sbx-001 \
--zone-name private.contoso.com \
--record-set-name test \
--ipv4-address 10.10.10.10
az network private-dns link vnet create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name link-vnet-demodnshub-az-asse-sbx-001 \
--zone-name private.contoso.com \
--virtual-network vnet-demodnshub-az-asse-sbx-001 \
-e false
- Private Resolver
VNET_ID=$(
az network vnet show \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vnet-demodnshub-az-asse-sbx-001 \
--query "id" \
--output tsv
)
az dns-resolver create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name adpr-hub-az-asse-sbx-001 \
--id ${VNET_ID}
SUBNET_ID=$(
az network vnet subnet show \
--resource-group rg-demodns-az-asse-sbx-001 \
--vnet-name vnet-demodnshub-az-asse-sbx-001 \
--name snet-inbound-az-asse-sbx-001 \
--query "id" \
--output tsv
)
az dns-resolver inbound-endpoint create \
--resource-group rg-demodns-az-asse-sbx-001 \
--dns-resolver-name adpr-hub-az-asse-sbx-001 \
--name snet-inbound-az-asse-sbx-001 \
--ip-configurations "[{private-ip-address:'',private-ip-allocation-method:'Dynamic',id:'$SUBNET_ID'}]"
SUBNET_ID=$(
az network vnet subnet show \
--resource-group rg-demodns-az-asse-sbx-001 \
--vnet-name vnet-demodnshub-az-asse-sbx-001 \
--name snet-outbound-az-asse-sbx-001 \
--query "id" \
--output tsv
)
az dns-resolver outbound-endpoint create \
--resource-group rg-demodns-az-asse-sbx-001 \
--dns-resolver-name adpr-hub-az-asse-sbx-001 \
--name snet-outbound-az-asse-sbx-001 \
--id "${SUBNET_ID}"
Create Spoke ( + Peering )
- Virtual Network
az network vnet create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vnet-demodnsspoke-az-asse-sbx-001 \
--address-prefixes 10.2.0.0/16 \
--dns-servers 10.1.2.4
az network vnet subnet create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name snet-default-az-asse-sbx-001 \
--vnet-name vnet-demodnsspoke-az-asse-sbx-001 \
--address-prefixes 10.2.1.0/24
az network vnet subnet create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name snet-inbound-az-asse-sbx-001 \
--vnet-name vnet-demodnsspoke-az-asse-sbx-001 \
--address-prefixes 10.2.2.0/28
az network vnet subnet create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name snet-outbound-az-asse-sbx-001 \
--vnet-name vnet-demodnsspoke-az-asse-sbx-001 \
--address-prefixes 10.2.2.16/28
- Peering
az network vnet peering create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vpeer-vnet-demodnsspoke-az-asse-sbx-001-vnet-demodnshub-az-asse-sbx-001 \
--vnet-name vnet-demodnsspoke-az-asse-sbx-001 \
--remote-vnet vnet-demodnshub-az-asse-sbx-001 \
--allow-vnet-access
az network vnet peering create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vpeer-vnet-demodnshub-az-asse-sbx-001-vnet-demodnsspoke-az-asse-sbx-001 \
--vnet-name vnet-demodnshub-az-asse-sbx-001 \
--remote-vnet vnet-demodnsspoke-az-asse-sbx-001 \
--allow-vnet-access
- Virtual Machine
SUBNET_ID=$(
az network vnet subnet show \
--resource-group rg-demodns-az-asse-sbx-001 \
--vnet-name vnet-demodnsspoke-az-asse-sbx-001 \
--name snet-default-az-asse-sbx-001 \
--query "id" \
--output tsv
)
az vm create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vm-spoke-az-asse-sbx-001 \
--computer-name vm-spoke-az-asse-sbx-001 \
--image UbuntuLTS \
--size Standard_D2s_v4 \
--accelerated-networking true \
--subnet ${SUBNET_ID} \
--nsg-rule SSH \
--admin-username azureuser \
--ssh-key-values /home/sawitmee/.ssh/id_rsa.pub
- Test
nslookup test.private.contoso.com
Create On-Premise ( +Peering )
- Virtual Network
az network vnet create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vnet-demodnsonprem-az-asse-sbx-001 \
--address-prefixes 10.3.0.0/16
az network vnet subnet create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name snet-default-az-asse-sbx-001 \
--vnet-name vnet-demodnsonprem-az-asse-sbx-001 \
--address-prefixes 10.3.1.0/24
- Peering
az network vnet peering create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vpeer-vnet-demodnsonprem-az-asse-sbx-001-vnet-demodnshub-az-asse-sbx-001 \
--vnet-name vnet-demodnsonprem-az-asse-sbx-001 \
--remote-vnet vnet-demodnshub-az-asse-sbx-001 \
--allow-vnet-access
az network vnet peering create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vpeer-vnet-demodnshub-az-asse-sbx-001-vnet-demodnsonprem-az-asse-sbx-001 \
--vnet-name vnet-demodnshub-az-asse-sbx-001 \
--remote-vnet vnet-demodnsonprem-az-asse-sbx-001 \
--allow-vnet-access
- DNS Server ( Windows )
SUBNET_ID=$(
az network vnet subnet show \
--resource-group rg-demodns-az-asse-sbx-001 \
--vnet-name vnet-demodnsonprem-az-asse-sbx-001 \
--name snet-default-az-asse-sbx-001 \
--query "id" \
--output tsv
)
az vm create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vm-dns-az-asse-sbx-001 \
--computer-name vmdns101s01 \
--image Win2019Datacenter \
--size Standard_D4s_v3 \
--accelerated-networking true \
--subnet ${SUBNET_ID} \
--nsg-rule RDP \
--admin-username azureuser \
--admin-password "<YOUR-PASSWORD>"
- Setup DNS server
ทำตามนี้นะครับ Install and Configure DNS Server on Windows Server 2019
- Create Zone And Conditional Forward
- Test
nslookup test.onprem.contoso.com 127.0.0.1
nslookup test.private.contoso.com 127.0.0.1
Create DNS Forwarding Ruleset
- Create Rulesets
OUTBOUND_ID=$(
az dns-resolver outbound-endpoint show \
--resource-group rg-demodns-az-asse-sbx-001 \
--dns-resolver-name adpr-hub-az-asse-sbx-001 \
--name snet-outbound-az-asse-sbx-001 \
--query id \
--output tsv
)
az dns-resolver forwarding-ruleset create \
--resource-group rg-demodns-az-asse-sbx-001 \
--dns-forwarding-ruleset-name dfrs-onpremcontosocom-az-asse-sbx-001 \
--outbound-endpoints "[{id:'${OUTBOUND_ID}'}]"
VM_ID=$(
az vm show \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vm-dns-az-asse-sbx-001 \
--query id \
--output tsv
)
VM_IPADDR=$(
az vm list-ip-addresses \
--ids ${VM_ID} \
--query '[].virtualMachine.network.privateIpAddresses' \
--output tsv
)
az dns-resolver forwarding-rule create \
--resource-group rg-demodns-az-asse-sbx-001 \
--ruleset-name dfrs-onpremcontosocom-az-asse-sbx-001 \
--forwarding-rule-name onprem-contoso-com \
--domain-name onprem.contoso.com. \
--target-dns-servers "[{ip-address:'${VM_IPADDR}',port:53}]"
- Link DNS forwarding ruleset to VNET
VNET_ID=$(
az network vnet show \
--resource-group rg-demodns-az-asse-sbx-001 \
--name vnet-demodnshub-az-asse-sbx-001 \
--query "id" \
--output tsv
)
az dns-resolver vnet-link create \
--resource-group rg-demodns-az-asse-sbx-001 \
--name link-vnet-demodnshub-az-asse-sbx-001 \
--ruleset-name dfrs-onpremcontosocom-az-asse-sbx-001 \
--id ${VNET_ID}
- Test from VM in Hub
nslookup test.private.contoso.com
nslookup test.onprem.contoso.com
- Test from VM in Spoke
nslookup test.private.contoso.com
nslookup test.onprem.contoso.com
เพิ่มเติม
ถ้าเรามี firewall ที่ Hub
- แนะนำให้ enable DNS Proxy ที่ firewall แล้วชี้ DNS Server ของ firewall มาที่ Inbound Endpoint ของ DNS Private Zone Resolver
- ส่วนที่ Spoke Virtual Network ให้ set DNS Server เป็น Private IP address ของ Firewall
References
Posted on November 4, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 28, 2024
November 24, 2024