DNS暗号化！ DNS over TLS (DoT) in Ubuntu 24.04

インターネットと切っても切り離せない存在であるDNSですが、その通信は**平文でされているという脆弱性**を持っています。

そのため、そのまま使うと**盗聴・なりすまし・改ざん**の危険が生じ、最悪の場合IDとパスワードを窃盗されることになります。

そこで、今回は**DNS通信を暗号化**し、こうした危険性から身を守る方法を伝えていきます。

::: note info
この記事は[こちら](https://manacra.com/dot-in-linux/)でもご紹介しています。
:::

## DNSとは？

ドメインの情報（qiita.com）からIPアドレス（18.65.207.34）を教えてくれる電話帳みたいな存在です。DNSがなければIPアドレスで直接アクセスしなければならず、SSLサーバ証明書の取得に必要な認証もできません。DNSはインターネットと切っても切り離せない存在です。

## DNSの危険性

DNSは平文で通信しています。つまり、暗号化されていないため、**盗聴・なりすまし・改ざん**の危険が生じます。改ざんされた場合、同じドメインでも全く異なるIPアドレス、つまり意図しないサーバに接続される可能性が出てきます。もし改ざんされた先でログインすると、IDとパスワードを窃盗されることになるわけです。

## DNS over TLS (DoT) とは？

DNS over TLS (DoT) とはDNSクエリを暗号化通信にすることで、**盗聴・なりすまし・改ざん**を防ぐ技術です。これによりDNSキャッシュポイズニングなどから**部分的に**身を守ることが可能です（完全に安全と言えないのがDNSの難しいところです）。

## DNS over HTTPS (DoH) とは？

DoTに類似した技術としてDNS over HTTPS (DoH) も存在します。こちらはHTTPS暗号化通信を利用します。DoTがポート853を利用するのに対し、DoHはHTTPSと同じポート443を使用するということです。目的や効果などは同様です。

## Ubuntu 24.04 でのDoT設定

実際にサーバでどのようにDoTを設定するか、Ubuntu 24.04を例に実例を示します。

まず、DNS設定を確認します。

```
$ resolvectl status
```

DHCPで配布されたDNSが設定されていると思います。ここからDNS設定を変えていきます。

`systemd-resolved` を設定していきます。現在の設定ファイルの記述を確認します。

```
$ cat /etc/systemd/resolved.conf
```

このような記述になっています。

```conf
[Resolve]
#DNS=
#FallbackDNS=
#Domains=
#LLMNR=no
#MulticastDNS=no
#DNSSEC=no
#DNSOverTLS=no
#Cache=yes
#DNSStubListener=yes
#ReadEtcHosts=yes
```

ここから `/etc/systemd/resolved.conf` を変更していきます。

```conf
[Resolve]
DNS=1.1.1.1 1.0.0.1
FallbackDNS=8.8.8.8 8.8.4.4
#Domains=
#LLMNR=no
#MulticastDNS=no
DNSSEC=yes
DNSOverTLS=yes
#Cache=yes
#DNSStubListener=yes
#ReadEtcHosts=yes
```

サービスを再起動します。

```
$ sudo systemctl restart systemd-networkd
$ sudo systemctl restart systemd-resolved
```

再びDNS設定を確認します。

```
$ resolvectl status
```

このようになっているはずです。

```
Global
           Protocols: -LLMNR -mDNS +DNSOverTLS DNSSEC=yes/supported
    resolv.conf mode: stub
  Current DNS Server: 1.1.1.1
         DNS Servers: 1.1.1.1 1.0.0.1
Fallback DNS Servers: 8.8.8.8 8.8.4.4

Link 2 (ens3)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS +DNSOverTLS DNSSEC=yes/supported
Current DNS Server: 172.25.252.9
       DNS Servers: 172.25.252.9 172.25.252.8
        DNS Domain: openstacklocal
```

DoT設定が反映されました。

ここでDHCPで配布されたDNS設定が `ens3` でされています。組織内のサーバの場合、ローカルDNSサーバが設定されていることが多く、ローカルな名前解決に利用されるため、変えない方が利便性は高いです。ローカルDNSサーバとの通信は多くの場合信頼して良いので、DoTを設定するメリットは薄いです。ここではパブリックDNSサーバでDoT設定をするとします。

`netplan` での現在の設定を確認します。

```
sudo cat /etc/netplan/50-cloud-init.yaml 
```

このような設定になっていました（`macaddress` は変更してあります）。

```yaml
network:
    version: 2
    ethernets:
        ens3:
            dhcp4: true
            match:
                macaddress: ff:ff:ff:ff:ff:ff
            mtu: 1450
            set-name: ens3
```

新しく `/etc/netplan/99-dns.yaml` ファイルを作成しDHCP4の設定を上書きします。

```yaml
network:
    version: 2
    ethernets:
        ens3:
            dhcp4-overrides:
                use-dns: false
                use-domains: false
```

設定を適応します。

```
$ sudo chmod 600 /etc/netplan/99-dns.yaml
$ sudo netplan apply
```

再びDNS設定を確認します。

```
$ resolvectl status
```

このようになっているはずです。

```
Global
           Protocols: -LLMNR -mDNS +DNSOverTLS DNSSEC=yes/supported
    resolv.conf mode: stub
  Current DNS Server: 1.1.1.1
         DNS Servers: 1.1.1.1 1.0.0.1
Fallback DNS Servers: 8.8.8.8 8.8.4.4

Link 2 (ens3)
    Current Scopes: none
         Protocols: -DefaultRoute -LLMNR -mDNS +DNSOverTLS DNSSEC=yes/supported
```

これでDoT設定が完了しました。

DNSが使えるか確認します。

```
$ nslookup one.one.one.one
```

このようにCloudflareのIPアドレスが取得できれば正常に稼働しています。

```
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	one.one.one.one
Address: 1.1.1.1
Name:	one.one.one.one
Address: 1.0.0.1
Name:	one.one.one.one
Address: 2606:4700:4700::1111
Name:	one.one.one.one
Address: 2606:4700:4700::1001
```

ブラウザが使えれば [https://one.one.one.one/help/](https://one.one.one.one/help/) にアクセスすることでDoHやDoTを使っていることを確認できるので、お試しください。