DNS-i kasutamise erinevad aspektid on autori poolt korduvalt käsitletud mitmetes blogi raames. Peamine rõhk on alati pandud selle olulise internetiteenuse turvalisuse parandamisele.

Viimase ajani, vaatamata DNS-i liikluse haavatavuse ilmsele olemusele, mis suuresti edastatakse endiselt avatud kujul, on olnud keeruline kaitse tugevdamise protsess. See on tingitud pahatahtlikest toimingutest teenusepakkujate poolt, kes püüavad oma tulu tõsta reklaami sissetoomise kaudu sisusse, riiklike jõuorganite ja tsensuuri ning lihtsalt kurjategijate tegevusest. , vaatamata erinevatele tehnoloogiatele nagu DNSSEC/DANE, DNScrypt, DNS-over-TLS ja DNS-over-HTTPS, on jäänud sageli tegemata. Kuigi serverilahendused, millest mõned on olnud juba mõnda aega laialdaselt tuntud ja saadaval, ei ole kliendipoolne tarkvara nende toetuses sama heal tasemel.
Õnneks on olukord muutumas. Eelkõige on populaarse brauseri Firefox teatanud DNS-over-HTTPS režiimi.
1. DNS-over-HTTPS probleemid
Esmapilgul näib, et DNS-over-HTTPS laialdane kasutuselevõtt Interneti-tarkvaras toob kaasa ainult positiivseid reaktsioone. Siiski, nagu öeldakse, on diabolus detailides.
Esimene probleem, mis piirab DoH-i laiemat kasutamist, on selle keskendumine ainult veebiliiklusele. Tõepoolest, protokoll HTTP ja selle praegune versioon HTTP/2, millele DoH toetub, on WWW alus. Kuid internet ei ole ainult veeb. Eksisteerib palju populaarseid teenuseid, nagu e-post, erinevad sõnumirakendused, failide edastamise süsteemid, multimeedia voogedastus jne, mis ei kasuta HTTP-d. Seega, vaatamata paljude DoH-i kui imerohi tajumisele, osutub see teiste, mitte ainult brauseritehnoloogiate jaoks kasutamatuks, nõudes tarbetuid lisajõupingutusi. Ütleme nii, et DNS-over-TLS näib selle rolli jaoks palju sobivam kandidaat, kuna see rakendab standardse DNS-i liikluse kapseldamist kaitstud standardse protokolli TLS.
Teine probleem, mis võib olla potentsiaalselt veelgi olulisem kui esimene, on tegelik loobumine DNS-i loomulikust detsentraliseeritusest, et kasutada brauseri seadetest määratud ühte DoH-serverit. Eriti soovitab Mozilla kasutada Cloudflare'i teenust. Sarnase teenuse käivitasid ka teised tuntud Interneti tegelased, sealhulgas Google. Tundub, et DNS-over-HTTPS-i rakendamine sellisel kujul, nagu see praegu ette nähakse, suurendab lõppkasutajate sõltuvust suurimatest teenustest. Pole saladus, et DNS-päringute analüüs võib koguda veelgi rohkem teavet ning parandada andmete täpsust ja asjakohasust.
Sellega seoses on autor olnud ja jääb massilise rakendamise pooldaja mitte DNS-over-HTTPS, vaid DNS-over-TLS koos DNSSEC/DANE-ga kui universaalse, turvalise ja Interneti edasise tsentraliseerimisele mitte soodustava vahendi jaoks DNS-i liikluse turvamiseks. Kahjuks ei saa arvestada kiiret massilise toe saamist DoH alternatiivide jaoks kliendirakendustes nähtavatel põhjustel, ja nende saatuseks jäävad hetkel turvatehnoloogiate entusiastid.
Aga kuna me nüüd saame DoH, siis miks mitte kasutada seda, liikudes potentsiaalse jälgimise vältimiseks ettevõtete serverite kaudu enda DNS-over-HTTPS serverisse?
2. Protokoll DNS-over-HTTPS
Kui vaadata standardit , mis kirjeldab DNS-over-HTTPS protokolli, võib näha, et see on põhimõtteliselt veeb API, mis võimaldab tavat DNS-paketi kapseldamist HTTP/2 protokolli. See teostatakse spetsiaalsete HTTP-pealkirjade kaudu ning edastatavate DNS-andmete binaarformaadi (vt. ja järgmised dokumendid) konverteerimise kaudu kujule, mis võimaldab nende edastamist ja vastuvõtmist ning vajalikku metainformatsiooni töötlust.
Standardi kohaselt toetatakse ainult HTTP/2 ja turvalist TLS-ühendust.
DNS-päringu saatmine võib toimuda tavapäraste GET ja POST meetodite kaudu. Esimesel juhul muudetakse päring base64URL-kodeeritud stringiks, teisel juhul aga POST-päringu kehaga binaarses vormis. Samuti kasutatakse DNS-päringu ja vastuse puhul spetsiaalset MIME-tüüpi andmete jaoks. application/dns-message.
root@eprove:~ # curl -H 'accept: application/dns-message' 'https://my.domaint/dns-query?dns=q80BAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE' -v
* Üritus 2001:100:200:300::400:443...
* TCP_NODELAY seadistatud
* Ühendatud eprove.net (2001:100:200:300::400) sadamasse 443 (#0)
* ALPN, pakub h2
* ALPN, pakub http/1.1
* sertifikaadi kontrollimise asukohad on edukalt seadistatud:
* CAfail: /usr/local/share/certs/ca-root-nss.crt
CAtee: ei ole
* TLSv1.3 (VÄLJAS), TLS-käeulatus, Klient tere (1):
* TLSv1.3 (SISSE), TLS-käeulatus, Serveri tere (2):
* TLSv1.3 (SISSE), TLS-käeulatus, Krüpteeritud laiendused (8):
* TLSv1.3 (SISSE), TLS-käeulatus, Tunnistus (11):
* TLSv1.3 (SISSE), TLS-käeulatus, TUNNISTUS kontrollida (15):
* TLSv1.3 (SISSE), TLS-käeulatus, Lõpetatud (20):
* TLSv1.3 (VÄLJAS), TLS muutus krüpteerimiseks, Muuta krüpteerimist (1):
* TLSv1.3 (VÄLJAS), TLS-käeulatus, Lõpetatud (20):
* SSL-ühendus kasutades TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server aktsepteeris h2 kasutamist
* Serveri sertifikaat:
* teema: CN=my.domain
* alguskuupäev: Juul 22 00:07:13 2019 GMT
* lõppkuupäev: Okt 20 00:07:13 2019 GMT
* subjectAltName: host "my.domain" vastab sertifikaadi "my.domain"
* väljastaja: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL-sertifikaat on õigustatud.
* Kasutatakse HTTP2, server toetab mitme kasutuse korral
* Ühenduse olek muutus (HTTP/2 kinnitatud)
* Kopeeritakse HTTP/2 andmed voos olevasse puhvriühendusse pärast uuendamist: len=0
* Kasutades voolu ID: 1 (lihtne käepide 0x801441000)
> GET /dns-query?dns=q80BAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE HTTP/2
> Host: eprove.net
> User-Agent: curl/7.65.3
> accept: application/dns-message
>
* TLSv1.3 (SISSE), TLS-käeulatus, Uus sessiooni pilet (4):
* Ühenduse olek muutus (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200
< server: h2o/2.3.0-beta2
< content-type: application/dns-message
< cache-control: max-age=86274
< date: Thu, 12 Sep 2019 13:07:25 GMT
< strict-transport-security: max-age=15768000; includeSubDomains; preload
< content-length: 45
<
Hoiatus: Binaarne väljund võib häirida teie terminali. Kasutage "--output -" , et öelda
Hoiatus: curl alustada väljundi edastamist teie terminalisse, või kaaluge "--output
Hoiatus: <FILE>" salvestamiseks faili.
* Keha kirjutamine ebaõnnestus (0 != 45)
* peatatud peatus voog!
* Ühendus #0 hostiga eprove.net jäi puutumatuksPöörake tähelepanu ka pealkirjale cache-control: veebiserveri vastuses. Parameeter max-age sisaldab TTL väärtust tagastatud DNS-kirjetele (või minimaalset väärtust, kui tagastatakse mitu).
Tuginedes eeltoodule, koosneb DoH serveri toimimine mitmest etapist.
- Saada HTTP päring. Kui see on GET, siis dekodeeri pakett base64URL kodeeringust.
- Saada see pakett DNS serverile.
- Saada vastus DNS serverilt.
- Leida minimaalne TTL väärtus saadud kirjetes.
- Tagastada kliendile vastus HTTP kaudu.
3. Oma DNS-over-HTTPS server
Oma isikliku DNS-over-HTTPS serveri kõige lihtsam, kiire ja tõhusam käivitamine tundub olevat HTTP/2 veebiserveri kasutamine , millest autor on juba lühidalt kirjutanud (vt '«).
Selle valiku kasuks räägib see, et kogu oma DoH serveri kood võib olla täielikult rakendatud H2O integreeritud tõlkija kaudu . Lisaks standardraamatukogudele on vajalik DNS serveriga andmete vahetamiseks biblioteek (mrbgem) Socket, mis on õnneks juba kaasatud praegusesse arenduse versiooni H2O 2.3.0-beta2 FreeBSD sadamad. Kuid ei ole raske seda lisada ka mistahes varasemale versioonile, kloonides hoidla kausta /deps enne kompileerimist.
root@beta:~ # uname -v
FreeBSD 12.0-RELEASE-p10 GENERIC
root@beta:~ # cd /usr/ports/www/h2o
root@beta:/usr/ports/www/h2o # make extract
=== License MIT BSD2CLAUSE accepted by the user
=== h2o-2.2.6 depends on file: /usr/local/sbin/pkg - found
=== Fetching all distfiles required by h2o-2.2.6 for building
=== Extracting for h2o-2.2.6.
=> SHA256 Checksum OK for h2o-h2o-v2.2.6_GH0.tar.gz.
=== h2o-2.2.6 depends on file: /usr/local/bin/ruby26 - found
root@beta:/usr/ports/www/h2o # cd work/h2o-2.2.6/deps/
root@beta:/usr/ports/www/h2o/work/h2o-2.2.6/deps # git clone https://github.com/iij/mruby-socket.git
Klonimine 'mruby-socket'…
remote: Enumerating objects: 385, done.
remote: Total 385 (delta 0), reused 0 (delta 0), pack-reused 385
Obtaining objects: 100% (385/385), 98.02 KiB | 647.00 KiB/s, ready.
Determining changes: 100% (208/208), ready.
root@beta:/usr/ports/www/h2o/work/h2o-2.2.6/deps # ll
total 181
drwxr-xr-x 9 root wheel 18 12 aug. 16:09 brotli/
drwxr-xr-x 2 root wheel 4 12 aug. 16:09 cloexec/
drwxr-xr-x 2 root wheel 5 12 aug. 16:09 golombset/
drwxr-xr-x 4 root wheel 35 12 aug. 16:09 klib/
drwxr-xr-x 2 root wheel 5 12 aug. 16:09 libgkc/
drwxr-xr-x 4 root wheel 26 12 aug. 16:09 libyrmcds/
drwxr-xr-x 13 root wheel 32 12 aug. 16:09 mruby/
drwxr-xr-x 5 root wheel 11 12 aug. 16:09 mruby-digest/
drwxr-xr-x 5 root wheel 10 12 aug. 16:09 mruby-dir/
drwxr-xr-x 5 root wheel 10 12 aug. 16:09 mruby-env/
drwxr-xr-x 4 root wheel 9 12 aug. 16:09 mruby-errno/
drwxr-xr-x 5 root wheel 14 12 aug. 16:09 mruby-file-stat/
drwxr-xr-x 5 root wheel 10 12 aug. 16:09 mruby-iijson/
drwxr-xr-x 5 root wheel 11 12 aug. 16:09 mruby-input-stream/
drwxr-xr-x 6 root wheel 11 12 aug. 16:09 mruby-io/
drwxr-xr-x 5 root wheel 10 12 aug. 16:09 mruby-onig-regexp/
drwxr-xr-x 4 root wheel 10 12 aug. 16:09 mruby-pack/
drwxr-xr-x 5 root wheel 10 12 aug. 16:09 mruby-require/
drwxr-xr-x 6 root wheel 10 12 sept. 16:10 mruby-socket/
drwxr-xr-x 2 root wheel 9 12 aug. 16:09 neverbleed/
drwxr-xr-x 2 root wheel 13 12 aug. 16:09 picohttpparser/
drwxr-xr-x 2 root wheel 4 12 aug. 16:09 picotest/
drwxr-xr-x 9 root wheel 16 12 aug. 16:09 picotls/
drwxr-xr-x 4 root wheel 8 12 aug. 16:09 ssl-conservatory/
drwxr-xr-x 8 root wheel 18 12 aug. 16:09 yaml/
drwxr-xr-x 2 root wheel 8 12 aug. 16:09 yoml/
root@beta:/usr/ports/www/h2o/work/h2o-2.2.6/deps # cd ../../../
root@beta:/usr/ports/www/h2o # make install clean
...Veebiserveri konfiguratsioon on üldiselt standardne.
root@beta:/usr/ports/www/h2o # cd /usr/local/etc/h2o/
root@beta:/usr/local/etc/h2o # cat h2o.conf
# see this sample config to understand how h2o is set up
# and a secure configuration for TLS and HTTP headers
# visit https://h2o.examp1e.net/ for comprehensive documentation
# and refer to h2o --help for command-line options and settings
# v.20180207 (c)2018 by Max Kostikov http://kostikov.co e-mail: max@kostikov.co
user: www
pid-file: /var/run/h2o.pid
access-log:
path: /var/log/h2o/h2o-access.log
format: "%h %v %l %u %t "%r" %s %b "%{Referer}i" "%{User-agent}i""
error-log: /var/log/h2o/h2o-error.log
expires: off
compress: on
file.dirlisting: off
file.send-compressed: on
file.index: [ 'index.html', 'index.php' ]
listen:
port: 80
listen:
port: 443
ssl:
cipher-suite: ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
cipher-preference: server
dh-file: /etc/ssl/dhparams.pem
certificate-file: /usr/local/etc/letsencrypt/live/eprove.net/fullchain.pem
key-file: /usr/local/etc/letsencrypt/live/my.domain/privkey.pem
hosts:
"*.my.domain":
paths: &go_tls
"/":
redirect:
status: 301
url: https://my.domain/
"my.domain:80":
paths: *go_tls
"my.domain:443":
header.add: "Strict-Transport-Security: max-age=15768000; includeSubDomains; preload"
paths:
"/dns-query":
mruby.handler-file: /usr/local/etc/h2o/h2odoh.rbErandiks on vaid URL-i töötleja /dns-query , mille eest vastutab meie DNS-over-HTTPS server, kirjutatud mruby keeles ja kutsutud välja töötleja valiku kaudu mruby.handler-file.
root@beta:/usr/local/etc/h2o # cat h2odoh.rb
# H2O HTTP/2 veebiserver DNS-over-HTTP teenusena
# v.20190908 (c)2018-2019 Max Kostikov https://kostikov.co e-post: max@kostikov.co
proc {|env|
if env['HTTP_ACCEPT'] == "application/dns-message"
case env['REQUEST_METHOD']
when "GET"
req = env['QUERY_STRING'].gsub(/^dns=/,'')
# base64URL dekodeerimine
req = req.tr("-_", "+/")
if !req.end_with?("=") && req.length % 4 != 0
req = req.ljust((req.length + 3) & ~3, "=")
end
req = req.unpack1("m")
when "POST"
req = env['rack.input'].read
else
req = ""
end
if req.empty?
[400, { 'content-type' => 'text/plain' }, [ "Vale nõue" ]]
else
# --- küsi DNS serverilt
sock = UDPSocket.new
sock.connect("localhost", 53)
sock.send(req, 0)
str = sock.recv(4096)
sock.close
# --- leia madalaim TTL vastuses
nans = str[6, 2].unpack1('n') # vastuste arv
if nans > 0 # DNS ebaõnnestumist pole
shift = 12
ttl = 0
while nans > 0
# töötle domeeninime kompressioon
if str[shift].unpack1("C") < 192
shift = str.index("x00", shift) + 5
if ttl == 0 # hüppa küsimuse ossa
next
end
end
shift += 6
curttl = str[shift, 4].unpack1('N')
shift += str[shift + 4, 2].unpack1('n') + 6 # vastuse andmete suurus
if ttl == 0 or ttl > curttl
ttl = curttl
end
nans -= 1
end
cc = 'max-age=' + ttl.to_s
else
cc = 'no-cache'
end
[200, { 'content-type' => 'application/dns-message', 'content-length' => str.size, 'cache-control' => cc }, [ str ] ]
end
else
[415, { 'content-type' => 'text/plain' }, [ "Toetamata meediumitüüp" ]]
end
}Pöörake tähelepanu, et DNS-paketid töödeldakse kohalikus vahemälu serveris, antud juhul FreeBSD standardpaketist. Turvalisuse seisukohalt on see optimaalne lahendus. Siiski ei takista miski teise DNS-i aadressi asendamist, mida kavatsete kasutada. localhost Teise DNS-i aadressiga.
root@beta:/usr/local/etc/h2o # local-unbound versioon
kasutamine: local-unbound [valikud]
käivita unbound teenuse DNS resolvija.
-h see abi
-c fail konfigureerimisfail, mida lugeda selle asemel, et /var/unbound/unbound.conf
failivormingut kirjeldatakse unbound.conf(5) dokumendis.
-d ei forkita taustale.
-p ei loo pidifaili.
-v detailne (rohkem kordi, et suurendada detailitaset)
Versioon 1.8.1
seotud teegid: mini-event internal (kasutab select), OpenSSL 1.1.1a-freebsd 20 Nov 2018
seotud moodulid: dns64 respip validator iterator
BSD litsents, vaata LITSENTS allika pakendis üksikasjade jaoks.
Teata vigadest aadressil unbound-bugs@nlnetlabs.nl
root@eprove:/usr/local/etc/h2o # sockstat -46 | grep unbound
unbound local-unbo 69749 3 udp6 ::1:53 *:*
unbound local-unbo 69749 4 tcp6 ::1:53 *:*
unbound local-unbo 69749 5 udp4 127.0.0.1:53 *:*
unbound local-unbo 69749 6 tcp4 127.0.0.1:53 *:*Nüüd tuleb H2O taas käivitada ja vaadata, mis sellest välja tuleb.
root@beta:/usr/local/etc/h2o # service h2o restart
H2O peatamine.
Ootamine PIDS: 69871.
H2O käivitamine.
start_server (pid:70532) käivitamine ...4. Testimine
Nüüd kontrollime tulemusi, saates uuesti proovipäringu ja vaadates võrgu liiklust utiliidiga tcpdump.
root@beta/usr/local/etc/h2o # curl -H 'accept: application/dns-message' 'https://my.domain/dns-query?dns=q80BAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE'
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: " to save to a file.
...
root@beta:~ # tcpdump -n -i lo0 udp port 53 -xx -XX -vv
tcpdump: listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes
16:32:40.420831 IP (tos 0x0, ttl 64, id 37575, offset 0, flags [none], proto UDP (17), length 57, bad cksum 0 (->e9ea)!)
127.0.0.1.21070 > 127.0.0.1.53: [bad udp cksum 0xfe38 -> 0x33e3!] 43981+ A? example.com. (29)
0x0000: 0200 0000 4500 0039 92c7 0000 4011 0000 ....E..9....@...
0x0010: 7f00 0001 7f00 0001 524e 0035 0025 fe38 ........RN.5.%.8
0x0020: abcd 0100 0001 0000 0000 0000 0765 7861 .............exa
0x0030: 6d70 6c65 0363 6f6d 0000 0100 01 mple.com.....
16:32:40.796507 IP (tos 0x0, ttl 64, id 37590, offset 0, flags [none], proto UDP (17), length 73, bad cksum 0 (->e9cb)!)
127.0.0.1.53 > 127.0.0.1.21070: [bad udp cksum 0xfe48 -> 0x43fa!] 43981 q: A? example.com. 1/0/0 example.com. A 93.184.216.34 (45)
0x0000: 0200 0000 4500 0049 92d6 0000 4011 0000 ....E..I....@...
0x0010: 7f00 0001 7f00 0001 0035 524e 0035 fe48 .........5RN.5.H
0x0020: abcd 8180 0001 0001 0000 0000 0765 7861 .............exa
0x0030: 6d70 6c65 0363 6f6d 0000 0100 01c0 0c00 mple.com........
0x0040: 0100 0100 0151 8000 045d b8d8 22 .....Q...].."
^C
2 packets captured
23 packets received by filter
0 packets dropped by kernelVäljundis on näha, kuidas päring aadressi lahendamiseks example.com oli vastu võetud ja DNS-serveri poolt edukalt töödeldud.
Nüüd on jäänud vaid aktiveerida meie server brauseris Firefox. Selleks tuleb konfiguratsioonilehelt muuta mõningaid seadeid. about:config.

Esiteks, see on meie API aadress, mille kaudu brauser küsib DNS teavet. network.trr.uri. Soovitav on ka määrata selle URL-i domeeni IP, et turvaliselt lahendada IP ilma DNS-i päringuteta. network.trr.bootstrapAddress. Ja lõpuks, ise see parameeter. network.trr.mode millel on DoH kasutamine. Väärtuse seadmine ‘3’ sundib brauserit kasutama ainult DNS-over-HTTPS nimede lahendamiseks, kuid usaldusväärsem ja turvalisem ‘2’ eelistab DoH, jättes standardse DNS-päringu varuvariantideks.
5. TULU!
Kas artikkel oli kasulik? Siis palun ärge häbenege ja toetage meid rahaga, kasutades allolevat annetamise vormi.
Allikas: habr.com
