How to set up systemd-resolved + dnssec (by quqi99)

作者:張華 發表於:2020-02-25
版權聲明:可以任意轉載,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本版權聲明

Set up test env

#first let us know 8.8.8.8 supports dnssec, while 114.114.114.114 doesn't support
dig paypal.com +dnssec @8.8.8.8 |grep RRSIG
dig paypal.com +dnssec @114.114.114.114 |grep RRSIG

#set up dnsmasq as upstream dns server
IFACE=dummy0
SUBNET=10.0.0
sudo ip link add $IFACE type dummy
sudo ifconfig $IFACE ${SUBNET}.1/24
#https://www.cnblogs.com/taoyuxuan/p/11205491.html
#sudo dnsmasq -h -R -d -C /dev/null -z -i $IFACE -I lo --host-record=test.test,${SUBNET}.1 -2 $IFACE &
#sudo dnsmasq -h -R -d -C /dev/null -z -i $IFACE -I lo -S /test/ --host-record=test.test,${SUBNET}.1 -2 $IFACE &

#sudo dnsmasq --no-hosts --no-resolv --no-daemon --no-dhcp-interface==$IFACE --bind-interfaces --interface=$IFACE \
    --except-interface=lo --server=/test/ --host-record=test.test,${SUBNET}.1 --conf-file=/dev/null --log-queries &
sudo dnsmasq --no-hosts --no-resolv --no-daemon --no-dhcp-interface==$IFACE --bind-interfaces --interface=$IFACE \
    --except-interface=lo --server=/test/10.0.0.1 --host-record=test.test,${SUBNET}.1 --log-queries \
    --dnssec --conf-file=/usr/share/dnsmasq-base/trust-anchors.conf --dnssec-check-unsigned --dnssec-debug --server=8.8.8.8 &
dig paypal.com +dnssec @10.0.0.1 |grep RRSIG

#test dns server with dig
ubuntu@bastion:~$ dig -t a test.test @10.0.0.1 | grep EDNS
; EDNS: version: 0, flags:; udp: 4096
ubuntu@bastion:~$ dig -t aaaa test.test @10.0.0.1 | grep EDNS
# again, should return "; EDNS ..." but doesn't

#configure systemd-resolved to look at only 10.0.0.1
ubuntu@bastion:~$ grep -Ev '#|^$' /etc/systemd/resolved.conf
[Resolve]
DNS=10.0.0.1
DNSSEC=yes
Cache=no
ubuntu@bastion:~$ grep -Ev '#|^$'  /etc/resolv.conf 
nameserver 127.0.0.53
options edns0

#debug with systemd-resolved
sudo systemctl disable systemd-resolved   #seems systemd-resolved always restart if not disable it as well
sudo systemctl stop systemd-resolved
sudo SYSTEMD_LOG_LEVEL=debug script -c /lib/systemd/systemd-resolved /tmp/debug.txt
systemd-resolve --status --no-pager |egrep 'DNSSEC|DNS Servers'
#repeat the following 3 lines to test every time - ./src/resolve/resolved-dns-server.c
sudo systemd-resolve --flush-caches; sudo systemd-resolve --reset-server-features; systemd-resolve test.test -t A
sudo systemd-resolve --flush-caches; sudo systemd-resolve --reset-server-features; systemd-resolve paypal.com -t A
systemd-resolve test.test -t A   #don't reset, try directly
systemd-resolve paypal.com -t A
systemd-resolve example.com ubuntu.com us.archive.ubuntu.com packages.icinga.com mirror.steadfast.net archive.ubuntu.com ppa.launchpad.net private-ppa.launchpad.net sigok.verteiltesysteme.net sigfail.verteiltesysteme.net verisign.com www.verisign.com

一些術語

  • LLMNR: 當dns服務不可用時, 支持使用組播dns協議(mDNS)繼續在子網內局部查詢dns直至網絡連接還原爲止.
  • Knot-DNS: 類似於dnsmasq, bind9的dns server
  • EDNS:允許將DNS消息大小從標準的512字節擴展(當UDP用作傳輸協議時),而無需切換到TCP. 它能提升訪問CDN的性能,因爲:標準DNS協議只能傳遞域名參數查IP, 而不能傳遞域名+用戶參數來源查IP.查詢下游的CDN, DNS服務器應該是根據用戶的來源查詢,而不是將上游DNS服務做爲來源查詢.由於國內的運營商之間互聯的帶寬是很低的, 所以造成訪問速度超慢.
  • EDNS0:可以將UDP包從512字節擴展到4096字節從而可以容納DNSEC包, systemd-resolved通過/etc/resovled.conf裏的’options edns0’通知dns server可以edns0, server再回的時候會將其+1, 所以: 雖然是EDNS0 封包,可是不代表這是 DNSSEC 封包,在EDNS0 中有一個 bit: DO 被設定為 1 的時候,才代表這是 DNSSEC 封包 (通過: dig +dnssec example.com ns |grep EDNS 命令可以查看)

Some bugs

1, https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1857639
upstream dns能力被檢測正確讓dnssec工作(現在一旦突然檢查錯了, resovle就停止work了), 或者允許disable能力檢查
https://github.com/systemd/systemd/issues/6490
https://github.com/systemd/systemd/issues/14435
https://github.com/systemd/systemd/pull/8849
a, 第一種解決方案
resolve不能看到timeout or error了就降級(tcp->dns over tls -> edns0)聲稱不支持某個特性, 它的特性應該獨立於實際查詢
https://github.com/systemd/systemd/issues/9384
b, 允許disable dnsec能力檢查
https://github.com/systemd/systemd/issues/14435
c, 從resolved中移除dnssec

如有些咖啡廳等公共網絡不支持ends0查詢,會響應domain not found, 即收到'NXDOMAIN when queried with EDNS0'消息時(the query is with EDNS0 enabled and D0 bit set to zero)需要繼續只根據EDNS0繼續重試
https://github.com/systemd/systemd/pull/8608
https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1727237
https://github.com/systemd/systemd/commit/7abcaa93ab13b1a7b11d50fcd43938de44687970 - 代碼
journalctl -b -u systemd-resolve | grep DVE-2018 - 確診
Workaround:
sudo systemctl disable systemd-resolved.service
sudo service systemd-resolved stop
sudo rm /etc/resolv.conf
sudo nano /etc/NetworkManager/NetworkManager.conf
then add “dns=default” under [main]
sudo service network-manager restart

上面的降級(resolved-Mitigate-DVE-2018-0001-by-retrying-NXDOMAIN-with.patch)應該只在DNSSEC=allow-downgrade or DNSSEC=no時運行.在真實世界中,NetworkManager’s在無法降級時會告訴用戶關掉dnssec
https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1796501

2, https://github.com/systemd/systemd/pull/9264/commits/844c58fb27b4420f5f8b07070fe2319af6537ae3
systemd-resolved只是一個stub resovler, 它只是轉發dns請求到upstream dns server並等待請求(等待時間爲RTT),它沒有考慮到上游遞歸dns服務器(interative resolver, eg: dnsmasq)的query timeout(authoritative server是用內存來存儲dns記錄所以它快,但也不是所有的都快),這樣systemd-resolved會經常錯誤的降級(Therefore it often mistakenly degrades the feature set of its upstream resolvers if it takes them longer than usual to answer a query),特別當DNSSEC=yes不充許降級時就更嚴重,所以systemd-resolved應該使用RTT+上游的查詢時間,而不是隻用RTT (DNS_TIMEOUT_MAX_USEC=DNS_SERVER_FEATURE_RETRY_ATTEMPTS * DNS_TIMEOUT_MAX_USEC = 15s),當然,這也不是解決根本問題,但可以緩解.

3, https://github.com/systemd/systemd/commit/7abcaa93ab13b1a7b11d50fcd43938de44687970
https://github.com/systemd/systemd/issues/11171
https://github.com/systemd/systemd/issues/4315 - https://github.com/poettering/systemd/commit/fc50d3f20d56862520635c3703fd90725b288afb
https://github.com/systemd/systemd/pull/8608
https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1727237
這個commit (7abcaa93ab - debian/patches/resolved-Mitigate-DVE-2018-0001-by-retrying-NXDOMAIN-with.patch)可以解決上面關於降級的問題,但是它又引入了迴歸bug, 沒DNSSEC=yes時沒有做安全檢查 (爲DNSSEC=yes時不從UDP+ends0(DNS_SERVER_FEATURE_LEVEL_EDNS0)降級互UDP(DNS_SERVER_FEATURE_LEVEL_UDP)但upstream還未接受patch,故先在debian/patches/resolved_disable-connection-downgrade-when-DNSSEC-yes.patch

4, https://github.com/dns-violations/dns-violations/issues/62
https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1785383
dnsmasq 2.79當返回空時省略了EDNS0 OPT記錄 (例如訪問無AAAA記錄時 - patch - 1682d15a744880b0398af75eadf68fe66128af78)) , systemd-resolved能hang (但只是使用了dnsmasq的router會如此)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章