Secure DNS with DoH client authentication 【無料枠パブリッククラウドに TLS/SSL 認証する自分専用の DoH サーバを建てる】

  • 自分の DNS 検索を見られるのが恥ずかしいので、パブリッククラウド上に DoH サーバを建てる

  • 費用かけられないので DoH サーバは GCP の無料枠の Micro を使う

  • 移動したり複数の端末から使うので、IP アドレスでの接続制限はできない、が、オープンリゾルバにはしたくない

  • せっかくの HTTPS なので TLS のクライアント認証をはめて DNS を自分専用にする 

  • この時点でのクライアント側の DoH + TLS クライアント認証対応状況の例 --> Mozilla 不可、curl 不可、dnscrypt-proxy(v2.0.40 ~) 可能

  • クライアントは dnscrypt-proxy 一択

  • サーバは Nginx で TLS 認証、doh-proxy から Unbound あたりが手っ取り早いか(多段だけど)

  • Windows 10 に dnscrypt-proxy を入れたが、そんなにもっさりした感じはしない(ブラウザが DNS Prefetching やってくれているおかげか?)

  • GCP 無料枠がアメリカなのでネットワーク遅延はある。。。

 

This post is a quick example of secure DNS lookup in public clouds.

 

The latest release of dnscrypt-proxy (v2.0.40) has added TLS client authentication for DoH. DoH client like firefox or curl don't look to support this yet, so using dnscrypt-proxy would be one of the easiest way to make our personal DoH servers more private at the moment. 

https://github.com/dnscrypt/dnscrypt-proxy/releases/tag/2.0.40

 

0. topology

 

 [your PC]  -- DoH + Auth --> [your personal DoH server in a public cloud] -- DNS --> (DNS tree)

 

f:id:kslugger:20200517013805j:plain

1. DoH server 

  - nginx (TLS termintation + authentication) https://github.com/nginx/nginx

  - doh-proxy (DoH + forwarder to localhost)  https://github.com/jedisct1/rust-doh

  - unbound (full service resolver especially for localhost + qname minimization) https://github.com/NLnetLabs/unbound

 

  # Any other softwares can be used, of course. ;-)

 

2. DoH client

  - dnscrypt-proxy (v2.0.40, TLS client authentication enabled) https://github.com/DNSCrypt/dnscrypt-proxy

 

3. DoH client configuration

  - calculate your personal DoH server's DNS stamp  https://dnscrypt.info/stamps/

  - copy your TLS public and private key into dnscrypt-proxy directory 

  - adjust dnscrypt-proxy configuration something like below:

  

    ##################################
    # Global settings #
    ##################################

    
    server_names = ['myserver']

     

    ################################
    # TLS Client Authentication #
    ################################

    [tls_client_auth]

    creds = [
    { server_name='myserver', client_cert='user1.pem', client_key='user1.key' },
    ]

    
    ################################
    # Anonymized DNS #
    ################################

    [static]

    [static. 'myserver']
    stamp = 'sdns://MY_SERVERS_STAMP'

 

4. Logs

  - DoH client (dnscrypt-proxy) log

    [NOTICE] dnscrypt-proxy 2.0.40
    [NOTICE] Network connectivity detected
    [NOTICE] Source [relays] loaded
    [NOTICE] Source [public-resolvers] loaded
    [NOTICE] Firefox workaround initialized
    [NOTICE] Now listening to 127.0.0.1:53 [UDP]
    [NOTICE] Now listening to 127.0.0.1:53 [TCP]
    [NOTICE] [myserver] Cert: user1.pem, Key: user1.key
    [NOTICE] [myserver] OK (DoH) - rtt: 219ms
    [NOTICE] Server with the lowest initial latency: myserver (rtt: 219ms)
    [NOTICE] dnscrypt-proxy is ready - live servers: 1 

 

f:id:kslugger:20200517184759j:plain

Delay (JP-US)

 

5. Next steps

  - move the server from Oregon to Tokyo, but it isn't free..

  - remove nginx from the server and offload tls_auth to CDN local pops, but it may not be free..