Ntau yam ntawm DNS kev ua haujlwm twb tau rov ua dua los ntawm tus kws sau ntawv hauv ntau tus
Txog thaum tsis ntev los no, txawm hais tias muaj qhov tsis zoo ntawm DNS kev khiav tsheb, uas tseem yog, feem ntau, kis tau los ntawm qhov tseeb, mus rau kev ua phem rau ntawm cov chaw muab kev pabcuam nrhiav kom lawv cov nyiaj tau los los ntawm kev kos cov lus tshaj tawm hauv cov ntsiab lus, tsoomfwv kev ruaj ntseg thiab censorship, zoo li tsuas yog criminals, txheej txheem
Hmoov zoo, qhov xwm txheej hloov pauv. Hauv particular, cov neeg tsim tawm ntawm qhov nrov Firefox browser
1. DNS-over-HTTPS teeb meem
Thaum xub thawj siab ib muag, qhov pib loj qhia ntawm DNS-dhau-HTTPS rau hauv Internet software ua rau tsuas yog ib tug zoo tshwm sim. Txawm li cas los xij, dab ntxwg nyoog, raws li lawv hais, yog nyob rau hauv cov ntsiab lus.
Thawj qhov teeb meem uas txwv tsis pub dhau ntawm DoH kev siv dav yog nws qhov kev tsom mus rau lub vev xaib nkaus xwb. Tseeb tiag, HTTP raws tu qauv thiab nws tam sim no version HTTP/2, uas DoH yog raws, yog lub hauv paus ntawm WWW. Tab sis Internet tsis yog lub vev xaib xwb. Muaj ntau cov kev pabcuam nrov, xws li email, ntau yam instant messengers, cov ntaub ntawv hloov chaw, multimedia streaming, thiab lwm yam, uas tsis siv HTTP. Yog li, txawm tias qhov kev nkag siab los ntawm ntau yam ntawm DoH raws li panacea, nws hloov tawm los ua tsis tau yam tsis muaj kev siv zog ntxiv (thiab tsis tsim nyog) rau lwm yam tshaj li browser thev naus laus zis. Los ntawm txoj kev, DNS-tshaj-TLS zoo li tus neeg sib tw tsim nyog rau lub luag haujlwm no, uas siv lub encapsulation ntawm tus qauv DNS tsheb nyob rau hauv kev ruaj ntseg tus qauv TLS raws tu qauv.
Qhov teeb meem thib ob, uas yog qhov muaj peev xwm ntau dua qhov tseem ceeb tshaj li thawj zaug, yog qhov tso tseg qhov tseeb ntawm qhov kev faib tawm ntawm DNS los ntawm kev tsim los ntawm kev siv ib tus neeg rau zaub mov DoH uas tau teev tseg hauv qhov browser nqis. Tshwj xeeb, Mozilla qhia siv cov kev pabcuam los ntawm Cloudflare. Ib qho kev pabcuam zoo sib xws kuj tau tsim los ntawm lwm cov duab hauv Internet, tshwj xeeb yog Google. Nws hloov tawm hais tias qhov kev siv ntawm DNS-dhau-HTTPS nyob rau hauv daim ntawv nyob rau hauv uas nws yog tam sim no tau thov tsuas yog tsub kom qhov kev cia siab ntawm cov neeg siv kawg ntawm cov kev pab cuam loj tshaj plaws. Nws tsis pub leejtwg paub tias cov ntaub ntawv uas kev tshuaj xyuas ntawm DNS cov lus nug tuaj yeem muab tau tuaj yeem sau cov ntaub ntawv ntau ntxiv txog nws, nrog rau nce nws qhov tseeb thiab qhov tseeb.
Hauv qhov no, tus sau yog thiab tseem yog tus txhawb nqa ntawm qhov kev siv loj tsis yog DNS-dhau-HTTPS, tab sis ntawm DNS-over-TLS ua ke nrog DNSSEC / DANE raws li kev siv thoob ntiaj teb, kev nyab xeeb thiab tsis tsim nyog rau kev txuas ntxiv hauv Internet txhais tau tias rau kev ruaj ntseg ntawm DNS tsheb. Hmoov tsis zoo, rau qhov laj thawj pom tseeb, ib tus tsis tuaj yeem cia siab tias yuav muaj kev qhia ceev ceev ntawm kev txhawb nqa loj rau DoH lwm txoj hauv kev rau cov neeg siv software, thiab nws tseem yog tus thawj tswj hwm ntawm kev ruaj ntseg technology enthusiasts.
Tab sis txij li tam sim no peb muaj DoH, vim li cas ho tsis siv nws tom qab khiav kev soj ntsuam los ntawm cov tuam txhab los ntawm lawv cov servers rau peb tus kheej DNS-dhau-HTTPS server?
2. DNS-over-HTTPS raws tu qauv
Yog koj saib tus qauv
Raws li tus qauv, tsuas yog HTTP / 2 thiab kev sib txuas TLS ruaj ntseg tau txais kev txhawb nqa.
Xa ib daim ntawv thov DNS tuaj yeem ua tiav siv tus qauv GET thiab POST txoj kev. Hauv thawj kis, qhov kev thov tau hloov pauv mus rau hauv txoj hlua base64URL-encoded, thiab hauv qhov thib ob, los ntawm lub cev ntawm POST thov hauv binary daim ntawv. Hauv qhov no, hom ntaub ntawv tshwj xeeb MIME yog siv thaum lub sijhawm thov DNS thiab teb application/dns-message.
root@eprove:~ # curl -H 'accept: application/dns-message' 'https://my.domaint/dns-query?dns=q80BAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE' -v
* Trying 2001:100:200:300::400:443...
* TCP_NODELAY set
* Connected to eprove.net (2001:100:200:300::400) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /usr/local/share/certs/ca-root-nss.crt
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=my.domain
* start date: Jul 22 00:07:13 2019 GMT
* expire date: Oct 20 00:07:13 2019 GMT
* subjectAltName: host "my.domain" matched cert's "my.domain"
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x801441000)
> GET /dns-query?dns=q80BAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE HTTP/2
> Host: eprove.net
> User-Agent: curl/7.65.3
> accept: application/dns-message
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (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
<
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: <FILE>" to save to a file.
* Failed writing body (0 != 45)
* stopped the pause stream!
* Connection #0 to host eprove.net left intact
Kuj xyuam xim rau lub npe cache-tswj: nyob rau hauv cov lus teb los ntawm lub web server. Nyob rau hauv parameter max-muaj muaj TTL tus nqi rau cov ntaub ntawv DNS raug xa rov qab (lossis tus nqi tsawg kawg yog tias lawv tau xa rov qab).
Raws li cov saum toj no, kev ua haujlwm ntawm DoH server muaj ntau theem.
- Tau txais HTTP thov. Yog tias qhov no yog GET ces txiav txim siab pob ntawv los ntawm base64URL encoding.
- Xa cov pob ntawv no mus rau DNS server.
- Tau txais cov lus teb los ntawm DNS server
- Nrhiav qhov tsawg kawg nkaus tus nqi TTL hauv cov ntaub ntawv tau txais.
- Rov qab teb rau tus neeg siv khoom ntawm HTTP.
3. Koj tus kheej DNS-dhau-HTTPS server
Txoj kev yooj yim tshaj plaws, ceev tshaj plaws thiab ua tau zoo tshaj plaws los khiav koj tus kheej DNS-dhau-HTTPS server yog siv HTTP / 2 web server
Qhov kev xaiv no tau txais kev txhawb nqa los ntawm qhov tseeb tias tag nrho cov cai ntawm koj tus kheej DoH server tuaj yeem ua tiav siv tus neeg txhais lus ua ke rau hauv H2O nws tus kheej.
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
ΠΠ»ΠΎΠ½ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π² Β«mruby-socketΒ»β¦
remote: Enumerating objects: 385, done.
remote: Total 385 (delta 0), reused 0 (delta 0), pack-reused 385
ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ²: 100% (385/385), 98.02 KiB | 647.00 KiB/s, Π³ΠΎΡΠΎΠ²ΠΎ.
ΠΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ: 100% (208/208), Π³ΠΎΡΠΎΠ²ΠΎ.
root@beta:/usr/ports/www/h2o/work/h2o-2.2.6/deps # ll
total 181
drwxr-xr-x 9 root wheel 18 12 Π°Π²Π³. 16:09 brotli/
drwxr-xr-x 2 root wheel 4 12 Π°Π²Π³. 16:09 cloexec/
drwxr-xr-x 2 root wheel 5 12 Π°Π²Π³. 16:09 golombset/
drwxr-xr-x 4 root wheel 35 12 Π°Π²Π³. 16:09 klib/
drwxr-xr-x 2 root wheel 5 12 Π°Π²Π³. 16:09 libgkc/
drwxr-xr-x 4 root wheel 26 12 Π°Π²Π³. 16:09 libyrmcds/
drwxr-xr-x 13 root wheel 32 12 Π°Π²Π³. 16:09 mruby/
drwxr-xr-x 5 root wheel 11 12 Π°Π²Π³. 16:09 mruby-digest/
drwxr-xr-x 5 root wheel 10 12 Π°Π²Π³. 16:09 mruby-dir/
drwxr-xr-x 5 root wheel 10 12 Π°Π²Π³. 16:09 mruby-env/
drwxr-xr-x 4 root wheel 9 12 Π°Π²Π³. 16:09 mruby-errno/
drwxr-xr-x 5 root wheel 14 12 Π°Π²Π³. 16:09 mruby-file-stat/
drwxr-xr-x 5 root wheel 10 12 Π°Π²Π³. 16:09 mruby-iijson/
drwxr-xr-x 5 root wheel 11 12 Π°Π²Π³. 16:09 mruby-input-stream/
drwxr-xr-x 6 root wheel 11 12 Π°Π²Π³. 16:09 mruby-io/
drwxr-xr-x 5 root wheel 10 12 Π°Π²Π³. 16:09 mruby-onig-regexp/
drwxr-xr-x 4 root wheel 10 12 Π°Π²Π³. 16:09 mruby-pack/
drwxr-xr-x 5 root wheel 10 12 Π°Π²Π³. 16:09 mruby-require/
drwxr-xr-x 6 root wheel 10 12 ΡΠ΅Π½Ρ. 16:10 mruby-socket/
drwxr-xr-x 2 root wheel 9 12 Π°Π²Π³. 16:09 neverbleed/
drwxr-xr-x 2 root wheel 13 12 Π°Π²Π³. 16:09 picohttpparser/
drwxr-xr-x 2 root wheel 4 12 Π°Π²Π³. 16:09 picotest/
drwxr-xr-x 9 root wheel 16 12 Π°Π²Π³. 16:09 picotls/
drwxr-xr-x 4 root wheel 8 12 Π°Π²Π³. 16:09 ssl-conservatory/
drwxr-xr-x 8 root wheel 18 12 Π°Π²Π³. 16:09 yaml/
drwxr-xr-x 2 root wheel 8 12 Π°Π²Π³. 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
...
Lub web server configuration feem ntau yog tus qauv.
root@beta:/usr/ports/www/h2o # cd /usr/local/etc/h2o/
root@beta:/usr/local/etc/h2o # cat h2o.conf
# this sample config gives you a feel for how h2o can be used
# and a high-security configuration for TLS and HTTP headers
# see https://h2o.examp1e.net/ for detailed documentation
# and h2o --help for command-line options and settings
# v.20180207 (c)2018 by Max Kostikov http://kostikov.co e-mail: [email protected]
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.rb
Qhov tsuas yog qhov tshwj xeeb yog tus tuav URL /dns-kev nug rau qhov uas peb DNS-dhau-HTTPS server, sau rau hauv mruby thiab hu los ntawm tus tuav kev xaiv, yog lub luag haujlwm tiag tiag mruby.handler-file.
root@beta:/usr/local/etc/h2o # cat h2odoh.rb
# H2O HTTP/2 web server as DNS-over-HTTP service
# v.20190908 (c)2018-2019 Max Kostikov https://kostikov.co e-mail: [email protected]
proc {|env|
if env['HTTP_ACCEPT'] == "application/dns-message"
case env['REQUEST_METHOD']
when "GET"
req = env['QUERY_STRING'].gsub(/^dns=/,'')
# base64URL decode
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' }, [ "Bad Request" ]]
else
# --- ask DNS server
sock = UDPSocket.new
sock.connect("localhost", 53)
sock.send(req, 0)
str = sock.recv(4096)
sock.close
# --- find lowest TTL in response
nans = str[6, 2].unpack1('n') # number of answers
if nans > 0 # no DNS failure
shift = 12
ttl = 0
while nans > 0
# process domain name compression
if str[shift].unpack1("C") < 192
shift = str.index("x00", shift) + 5
if ttl == 0 # skip question section
next
end
end
shift += 6
curttl = str[shift, 4].unpack1('N')
shift += str[shift + 4, 2].unpack1('n') + 6 # responce data size
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' }, [ "Unsupported Media Type" ]]
end
}
Thov nco ntsoov tias lub zos caching server yog lub luag haujlwm rau kev ua cov pob ntawv DNS, hauv qhov no
root@beta:/usr/local/etc/h2o # local-unbound verison
usage: local-unbound [options]
start unbound daemon DNS resolver.
-h this help
-c file config file to read instead of /var/unbound/unbound.conf
file format is described in unbound.conf(5).
-d do not fork into the background.
-p do not create a pidfile.
-v verbose (more times to increase verbosity)
Version 1.8.1
linked libs: mini-event internal (it uses select), OpenSSL 1.1.1a-freebsd 20 Nov 2018
linked modules: dns64 respip validator iterator
BSD licensed, see LICENSE in source package for details.
Report bugs to [email protected]
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 *:*
Txhua yam uas tseem tshuav yog rov pib H2O thiab pom dab tsi los ntawm nws.
root@beta:/usr/local/etc/h2o # service h2o restart
Stopping h2o.
Waiting for PIDS: 69871.
Starting h2o.
start_server (pid:70532) starting now...
4. Kev sim
Yog li, cia peb tshawb xyuas cov txiaj ntsig los ntawm kev xa daim ntawv thov rov qab thiab saib cov tsheb khiav hauv lub network siv cov khoom siv hluav taws xob tcp pom.
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: <FILE>" 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 kernel
Cov zis qhia tau hais tias qhov kev thov kom daws qhov chaw nyob li cas piv txwv tau txais thiab ua tiav los ntawm DNS server.
Tam sim no txhua yam uas tseem tshuav yog qhib peb lub server hauv Firefox browser. Txhawm rau ua qhov no, koj yuav tsum hloov ntau qhov chaw ntawm nplooj ntawv teeb tsa txog: config.
Ua ntej, qhov no yog qhov chaw nyob ntawm peb API uas tus browser yuav thov DNS cov ntaub ntawv hauv network.tr.ur. Nws tseem pom zoo kom qhia meej tus IP sau npe los ntawm qhov URL no kom ruaj ntseg IP daws teeb meem siv browser nws tus kheej yam tsis muaj kev nkag mus rau DNS hauv network.trr.bootstrap Chaw nyob. Thiab thaum kawg, tus parameter nws tus kheej network.tr.mode suav nrog kev siv DoH. Kev teeb tsa tus nqi rau "3" yuav yuam kom lub browser siv tshwj xeeb DNS-dhau-HTTPS rau lub npe daws teeb meem, thaum qhov kev ntseeg siab thiab ruaj ntseg "2" yuav muab qhov tseem ceeb rau DoH, tawm hauv tus qauv DNS saib raws li kev xaiv rov qab.
5. PIB!
Kab lus puas muaj txiaj ntsig? Tom qab ntawd thov tsis txhob txaj muag thiab txhawb nqa nyiaj los ntawm daim ntawv pub dawb (hauv qab).
Tau qhov twg los: www.hab.com