| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- awx
- HTML
- KVM
- Ansible
- repository
- Arch
- Kubernetes
- Kubeflow
- cloud-init
- yum
- terraform
- nfs-provisioner
- kolla
- pacman
- ceph
- golang
- Linux
- kolla-ansible
- ubuntu
- OpenStack
- Docker
- Octavia
- cephadm
- grafana-loki
- i3
- k8s
- libvirt
- ceph-ansible
- port open
- archlinux
- Today
- Total
YJWANG
cloudflare.com으로 알아보는 DNSSEC 동작 원리 본문
Root NS부터 .COM 까지는 DS와 KSK를 검증하는 과정이 동일합니다.
따라서 이번 문서에서는 더 나은 이해를 위해 범위를 좁혀 'com' ~ 'cloudflare.com' 구간만을 기준으로 설명하고 있는 점 참고 부탁드립니다.

검증 과정을 위 그림을 토대로 설명하겠습니다.
1. cloudflare.com DS
resolver는 cloudflare.com 의 A 레코드를 검증하기 위해 가장 먼저 .com의 NS에서 cloudflare.com에 대한 DS 레코드를 가져옵니다.
이후에 가져올 cloudflare.com 레코드에 대한 신뢰성 체인을 .com과 비교하여 확보하기 위해서입니다.
dig @a.gtld-servers.net. cloudflare.com ds +short
2371 13 2 32996839A6D808AFE3EB4A795A0E6A7A39A76FC52FF228B22B76F6D6 3826F2B9
2. cloudflare.com KSK
이후 cloudflare.com의 NS에서 MYKEY 레코드를 가져옵니다.
dig DNSKEY cloudflare.com +dnssec +multiline
; <<>> DiG 9.10.6 <<>> DNSKEY cloudflare.com +dnssec +multiline
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4223
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;cloudflare.com. IN DNSKEY
;; ANSWER SECTION:
cloudflare.com. 3600 IN DNSKEY 257 3 13 (
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+Gq
JxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==
) ; KSK; alg = ECDSAP256SHA256 ; key id = 2371
cloudflare.com. 3600 IN DNSKEY 256 3 13 (
oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeq
CYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==
) ; ZSK; alg = ECDSAP256SHA256 ; key id = 34505
cloudflare.com. 3600 IN RRSIG DNSKEY 13 2 3600 (
20260228045509 20251229045509 2371 cloudflare.com.
lc1UKiy434Ac/gaF5kElLaOrf696NCaHJG4kwp4gyK5S
sQ37EECuJeq1lqLpp5aQ68Um1VFw7bgCxbTFR8dNeQ== )
;; Query time: 15 msec
;; SERVER: 168.126.63.1#53(168.126.63.1)
;; WHEN: Tue Jan 06 16:03:17 KST 2026
;; MSG SIZE rcvd: 313
레코드 내부에 있는 KSK와 이전에 가져왔던 DS레코드와 비교합니다.
DS레코드는 KSK의 해쉬 값으로 두 레코드의 일치 여부를 검증하는 것을 통해 신뢰성을 확보할 수 있습니다.
두 값이 일치한다면 Resolver가 현재 알고 있는 .com 가 저장 중인 cloudflare.com 의 KSK의 해쉬 정보와 (DS) cloudflare.com NS가 저장 중인 KSK의 정보가 일치한다는 의미이기 때문에 두 NS의 체인 신뢰가 보장됩니다.
만약 일치하지 않는다면 레코드를 잘못 설정했거나 Resolver가 잘못된 값을 캐싱하고 있는 것을 의심해볼 수 있습니다.
검증 과정은 수동으로도 진행해볼 수 있으며 bind-utils 패키지에 있는 dnssec-dsfromkey 명령을 통해 확인할 수 있습니다. 하기 명령 예시를 보았을 때 KSK를 이용하여 해쉬 계산을 했을 때 32996839A6D808AFE3EB4A795A0E6A7A39A76FC52FF228B22B76F6D63826F2B9 값이 출력됨을 확인할 수 있으며 이는 이전에 확인했던 DS와 일치하는 것을 볼 수 있습니다.
dig DNSKEY cloudflare.com | dnssec-dsfromkey -2 -f - cloudflare.com
cloudflare.com. IN DS 2371 13 2 32996839A6D808AFE3EB4A795A0E6A7A39A76FC52FF228B22B76F6D63826F2B9
3. cloudflare.com MYKEY RRSIG
위의 과정을 통해 .com과 cloudflare.com 간의 체인 신뢰성은 검증이 됐습니다. 그럼 이제 방금 사용한 KSK가 위조되지 않았는지 추가 검증을 진행해야합니다.
설명에 앞서 KSK, ZSK 키는 모두 MYKEY 레코드에 포함된 데이터로 비대칭 암호화를 사용합니다. 잘 아시고 있는 TLS와 마찬가지로 개인키 공개키가 있으며 개인키로 암호화된 것은 공개키로 복호화할 수 있으며 공개키로 암호화된 것은 개인키로만 복호화할 수 있습니다. 개인키는 NS 내부에 위치합니다. 이전에 MYKEY를 통해 얻은 KSK, ZSK는 공개키로 MYKEY의 RRSIG는 KSK의 개인키로 암호화돼있습니다.
이 시점에서 KSK가 왜 Key-Signing Keys임을 이해할 수 있었으며 제 경우에 (MY)key-signing key 로 이해했습니다.
Resolver는 가지고 있는 공개 KSK로 MYKEY의 RRSIG를 복호화하여 검증을 진행합니다. 해당 과정은 수동으로 진행하기 어려우며 Resolver가 정해진 알고리즘에 따라 진행합니다. 검증이 성공하면 현재 갖고 있는 공개 KSK, ZSK의 정보가 위조되지 않은 것을 신뢰할 수 있습니다.
dig DNSKEY cloudflare.com +dnssec +multiline
; <<>> DiG 9.10.6 <<>> DNSKEY cloudflare.com +dnssec +multiline
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4223
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;cloudflare.com. IN DNSKEY
;; ANSWER SECTION:
cloudflare.com. 3600 IN DNSKEY 257 3 13 (
mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+Gq
JxpVXckHAeF+KkxLbxILfDLUT0rAK9iUzy1L53eKGQ==
) ; KSK; alg = ECDSAP256SHA256 ; key id = 2371
cloudflare.com. 3600 IN DNSKEY 256 3 13 (
oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeq
CYKD5ar0IRd8KqXXFJkqmVfRvMGPmM1x8fGAa2XhSA==
) ; ZSK; alg = ECDSAP256SHA256 ; key id = 34505
cloudflare.com. 3600 IN RRSIG DNSKEY 13 2 3600 (
20260228045509 20251229045509 2371 cloudflare.com.
lc1UKiy434Ac/gaF5kElLaOrf696NCaHJG4kwp4gyK5S
sQ37EECuJeq1lqLpp5aQ68Um1VFw7bgCxbTFR8dNeQ== )
;; Query time: 15 msec
;; SERVER: 168.126.63.1#53(168.126.63.1)
;; WHEN: Tue Jan 06 16:03:17 KST 2026
;; MSG SIZE rcvd: 313
4. cloudflare.com ZSK
앞선 단계에서 공개 KSK에 대한 검증도 완료를 했습니다. 이제 공개 ZSK에 대한 검증도 진행해야합니다. ZSK는 Zone-Signing Keys 이므로 이름에서 이제 역할을 특정하실 수 있을 것이라 추정됩니다.
제 이해로 개인 ZSK로 Zone내부에 있는 레코드를 암호화하기에 Zone-Signing Key 이구나! 로 생각했습니다. 검증을 위해서는 최종 목적지인 cloudflare.com A 레코드의 RRSIG를 확인해야합니다.
5. cloudflare.com A
최종 목적지 A레코드의 RRSIG를 확인할 수 있습니다. 해당 레코드의 RRSIG는 개인 ZSK로 암호화돼있으며 저희는 이를 복호화할 수 있는 공개 ZSK는 이미 검증이 완료된 상태임을 알고 있습니다. 공개 ZSK로 해당 RRSIG를 복호화하여 검증합니다.
dig +dnssec cloudflare.com
; <<>> DiG 9.10.6 <<>> +dnssec cloudflare.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 740
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;cloudflare.com. IN A
;; ANSWER SECTION:
cloudflare.com. 95 IN A 104.16.132.229
cloudflare.com. 95 IN A 104.16.133.229
cloudflare.com. 95 IN RRSIG A 13 2 300 20260108005728 20260105225728 34505 cloudflare.com. VwqzNs0nCcrwIoc2TUMt50Ypc1I1YvJb1o9hy1GWirUEQkjgD9A3Smz/ WdrTeMWpORKOv8QliqlrkUqEl1GcyQ==
;; Query time: 11 msec
;; SERVER: 168.126.63.1#53(168.126.63.1)
;; WHEN: Wed Jan 07 09:00:57 KST 2026
;; MSG SIZE rcvd: 185
이로써 A 레코드 검증 과정을 통해 DNSSEC동작 과정에대해 확인해보았습니다.
NSEC3 등 NXDOMAIN에 대한 암호화 과정도 있지만 관련 내용은 속편에서 다시 소개 드리겠습니다.
https://dnsviz.net/d/cloudflare.com/dnssec/ 사이트에서 트리 형태로 DNSSEC 구조를 확인해볼 수 있습니다.
DNS 위변조 공격을 어떻게 방어할 수 있는가?
위의 예시로 DNS 포이즈닝 공격을 위해 Resolver에있는 cloudflare.com을 위조했다고 가정해봅시다.
cloudflare.com이 DNSSEC을 적용한 상태라면 공격자는 A레코드의 RRSIG도 위조해야합니다. RRSIG는 질의 때마다 내부 알고리즘에 의해 계속 변경되기 때문에 위조가 쉽지 않습니다. 만약 개인 ZSK를 어떻게든 탈취한 상태로 RRSIG를 위조했다고 가정합시다.
허나 아직 넘어야할 산이 많습니다. 공격자는 개인 KSK도 탈취해야합니다. 그렇지 않으면 MYKEY 레코드에있는 RRSIG 검증 과정을 통해 또 위조된 응답임이 들통나기 때문입니다. 만약 가짜 KSK를 사용하여 암호 값을 강제로 입력한 경우에도 공개 KSK와 상위 .com에 있는 DS또 일치해야 하기 때문에 범위가 커집니다.
즉 DNSSEC이 적용된 zone에 대해 DNS 위변조 공격은 쉽지 않습니다.
많이 사용하는가?
많이 사용하지 않는 듯 합니다. 사용하는 곳을 찾는 것이 더 어려웠습니다.
dig google.com +dnssec +multiline +short - 미사용
142.250.196.14
dig kakao.com +dnssec +multiline +short - 미사용
211.242.11.41
121.53.93.60
211.249.251.46
dig naver.com +dnssec +multiline +short - 미사용
223.130.192.247
223.130.200.236
223.130.200.219
223.130.192.248
dig aws.amazon.com +dnssec +multiline +short - 미사용
tp.8e49140c2-frontier.amazon.com.
dr49lng3n1n2s.cloudfront.net.
3.170.221.105
3.170.221.32
3.170.221.69
3.170.221.92
dig gov.kr +dnssec +short - 미사용
125.60.35.230
dig www.president.go.kr +dnssec +short - 미사용
www.president.go.kr.edgesuite.net.
a776.dscw39.akamai.net.
23.67.53.26
23.67.53.25
dig www.akamai.com +dnssec +short - 사용
www.akamai.com.edgekey.net.
CNAME 8 3 3600 20260109041047 20260106031047 63091 akamai.com. EDaaz/nfWYWXVGGKvX3s90sekuqWI1QgHG5JHgAIpauo22qYyMnR9Wyv nTVFDTF21ZC2g6lwKS21LFw4V04NCM7R40pHHtRWaG253SIDtMZDg6Sw UrQME+ADlqYZOJVpk+OI7m6AgJOjrJbSoVmlunvZsSN/WagrWH2MRw/l OM4=
www.akamai.com.edgekey.net.globalredir.akadns.net.
e259222.dscx.akamaiedge.net.
23.211.117.202
23.211.117.113
dig kr DNSKEY +dnssec +multiline - 사용
; <<>> DiG 9.10.6 <<>> kr DNSKEY +dnssec +multiline
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38851
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;kr. IN DNSKEY
;; ANSWER SECTION:
kr. 14338 IN DNSKEY 257 3 8 (
AwEAAb2fqd9U3SbhbId4KV3sdcG0QhTd4o9LRM/nLvDA
DpIvRiFBci7lsrRdPyt+zQv2duJLw8QcOChPwWyH/rQt
Qj0SkQ4ey9Z/nxbLb8OyQjLsR6WTlS/iR7vdHyP+6JS1
dJ6L3HcN//j6NYiBHQECm31q4yl3C5FfsQJjfzZjyzu7
cy8VuEhCmEZ7f07gj9lNWZm2ASh+UCN6jIJkuz7JHkIa
VD4D8LbeaNh+vpyUh1fov9B03po3OROBpEVnvjT2xdnc
/fFbxiOROHaIxLY56H7G5XHUt3bErk1AY3TqKMB7GR2i
4dUEOyq5tSWDvB4sJZpwA2CheCZ/EFK7/zAh3i0=
) ; KSK; alg = RSASHA256 ; key id = 61615
kr. 14338 IN DNSKEY 256 3 8 (
AwEAAbztIuV/yu5cHaa/q4LXJ6hQt3S3VifuDZfWoWe3
imJYJUFVHV2A7O6VfKp7p7N8JVX1oj3ken6UnsmWso54
/iycYD9v8m+5XppZusfMboJPWZiDJqLhmWqNLM/+I6JN
PqDjbQkXgDbuzDCzZnSGmExx0sirChWPV6g1RnkvDoJ1
) ; ZSK; alg = RSASHA256 ; key id = 61206
kr. 14338 IN RRSIG DNSKEY 8 1 86400 (
20260204202134 20260105192135 61615 kr.
XcfqWJI5xhmNGfJ9Ez4uQREhCNM2GRec/qR9e2gJaTfm
ZL1KXL5ctoBpEguz71/6A+8VulKS+j26ecbJznB2plZD
J1NHn9CEdRDTdVEjx/NrLcsftaM2bDZs9zbTWMoTDo7y
pSBvOP8rkxWfSPK1iOVN2kzeEh3XwiU2kERVushbjMwT
nss4oKaOLuh5yDvzbDloP9m3VfYrTO6fnUaUnpIQhcjg
IhEmd1bEnrE3YSqkDVvbrVOBzDSB1UXgAbXAK7Cvdaja
WxyjDvw51lRuV+GHjsCZjr2y98kQMyfYtNvFq4AILQsD
cTjVH3uxF9O4UllPL7aGDHlKOU9sX8gyBw== )
;; Query time: 13 msec
;; SERVER: 168.126.63.1#53(168.126.63.1)
;; WHEN: Wed Jan 07 09:27:03 KST 2026
;; MSG SIZE rcvd: 745
왜 많이 사용하지 않을까?
지극히 제 개인적인 의견입니다. 이해를 위해 나름 머리를 굴려본 것으로 더 나은 이해가 있다면 서로를 위해 공유 부탁드립니다.
zone을 관리하는 입장에서는 관리 포인트가 늘고 dnssec을 사용하여 질의하는 경우 더 많은 데이터를 가져와야하기 때문에 페이로드 부담도 더 커집니다. 내가 관리하는 zone의 DNSSEC을 활성화한다하여도 resolver가 DNSSEC을 역시 지원해야하며 누군가가 공격으로 특정 Resolver의 레코드를 위변조 했다 하더라도 zone 관리자의 책임은 아니게됩니다. client가 사용하는 resolver에 대한 책임까지는 없으니까요. 오히려 관리 부담만 증가하고 이로인한 보안 효과를 가시적으로 확인할 수 있는 작업은 아니여보입니다.
다만 많은 zone에서 DNSSEC을 활성화하고 인터넷 전반적으로 도입된다면 공격자가 어떤 Resolver의 데이터를 위변조 하고 싶더라도 그러기 어려운 아름다운 세상이 되지 않을까 라는 현실성과 다소 거리가 있는 생각도 해보았습니다.
akamai 및 cloudflare는 DNSSEC을 사용하고 있는 것으로 확인되기에 책임 의무가 없지만 DNS 강자로서 보안을 지키고 있는 것으로 생각됩니다. 또한 kr 도메인도 사용 중이라 다행이라는 생각도 했습니다.
이번 주제를 공부하며 저도 개인 도메인을 사용하게 된다면 DNSSEC 사용을 할 마음이 생기게되는 시간이였습니다.
참고 자료
https://www.cloudflare.com/learning/dns/dnssec/how-dnssec-works/
https://repost.aws/ko/knowledge-center/route-53-configure-dnssec-domain