🎯

TailscaleのDNSがUbuntu20.04で機能しない問題への対処

2023/06/16に公開

この記事では、Ubuntu 20.04でTailscaleを使用する際に遭遇したDNSエラーとその対策について詳細に解説します。同じ問題に直面して困っている方々の一助となれば幸いです。

エラー発生の状況

以下に、エラーが発生した時のソフトウェアのバージョンと具体的な状況を説明します。

エラー発生時のソフトウェアバージョン

  • Ubuntu: 20.04
  • NetworkManager: 1.22.10
  • Tailscale: 1.42.0

エラー発生の具体的な状況

  • NetworkManagerを使用してネットワークプロファイルの変更を試みました。
  • 有線ネットワークに接続していたWiFiルーターから、スマートフォンのテザリングWiFiへと切り替えを行いました。
  • プロファイルを選択すると、NetworkManager上では切り替えに成功しますが、直後からインターネットへの接続が不可能になりました。
  • IPアドレスを指定したping(例:ping 1.1.1.1)は成功します
  • ドメイン名を指定したping(例:ping google.com)は失敗し、Temporary failure in name resolutionというエラーメッセージが表示されます。
  • ブラウザでは、DNS_PROBE_FINISHED_BAD_CONFIGやDNS_PROBE_POSSIBLEなど、DNSに関連するエラーメッセージが表示されます。

エラーの原因

実は、TailscaleはNetworkManagerやsystemd-resolvedなどと壮絶なDNS書き換えバトルを繰り広げています。詳細はTailscaleが公開している以下の記事に記載されています。その内容を読むと、TailscaleチームがLinuxのDNS設定手順に対して詳細な調査を行ったことに感心します。普通ならこんな面倒な状況に出くわしたら挫折します。

https://tailscale.com/blog/sisyphean-dns-client-linux/

結論としては、NetworkManagerを使わず、systemd-resolvedを使用してネットワーク設定を行うことでDNSの問題が解決します。もしくは、Magic DNSを諦め、TailscaleによるDNSの操作を停止し、IPアドレスを都度入力することでこの問題を回避することも可能です。

解決策

すべての問題はネットワーク設定の混乱により引き起こされた悲劇であり、現状ではNetworkManagerを使用しないことが最善の策となります。NetworkManagerバージョン1.26.6以前では、systemd-resolvedによって設定された一部のDNS設定がNetworkManagerによって上書きされる問題が存在します。Ubuntu 20.04ではデフォルトでaptを通じてインストールされるNetworkManagerのバージョンが1.22.10であり、従って、この問題が発生します。この問題を避けるためには、最新バージョンのNetworkManagerをインストールするか、NetworkManagerを使用せずにsystemd-resolvedでネットワーク設定を行う必要があります。

しかしながら、systemd-resolvedでのネットワークの設定は手間がかかります。これまでGUIのNetworkManagerを通じてネットワーク設定を行ってきたユーザーにとって、ArchLinuxのドキュメントを参照しながら適切な設定ファイルを適切な場所に配置する作業は大変です。そこで、今回はnetplanを使用して、少し手間を減らす方法を提案します。

大まかな手順は次のとおりです:

  1. NetworkManagerを停止します。
  2. netplanを用いてネットワーク接続を可能にする設定を記述します。
  3. Tailscaleを使用するための設定を追加します。

TailscaleとNetworkManagerを停止する

Tailscaleは動作中にネットワークの設定の変更を検知し、設定ファイルを書き換える可能性があります。そのため、次に示すコマンドを実行してまずはTailscaleを停止します。

sudo tailscale down
sudo systemctl stop tailscaled

次に、次のコマンドを実行してNetworkManagerを停止します。

sudo systemctl stop NetworkManager
sudo systemctl disable NetworkManager

次に、/etc/resolv.confを確認します。

ls -l /etc/resolv.conf
lrwxrwxrwx ... /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

もし、上記のように/run/systemd/resolve/stub-resolv.confへのシンボリックリンクとなっているならば問題ありません。

それとは対照的に、シンボリックリンクではなく、中身がNetworkManagerによって自動生成される内容(例えば、以下のような内容)になっている場合は、

# Generated by NetworkManager
nameserver 127.0.0.53

その設定を削除し、シンボリックリンクを新たに貼り直します。

sudo mv /etc/resolv.conf /etc/resolv.conf.bak
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

これにより、systemd-resolvedやTailscaleがNetworkManagerを使用しないことを認識できるようになります。

Netplanを使用してネットワーク設定を行う

Netplanについては以下のリンクを参照してください。

https://netplan.io/

簡単に説明すると、Netplanはネットワーク設定をYAML形式で簡単に記述するためのツールです。

Netplanは、YAMLで記述した設定ファイルをsystemd-networkdが解釈できる形に変換します。そしてsystemd-resolvedは、名前解決に必要な部分の情報をsystemd-networkdから読み取ります。このようにして、間接的にsystemd-resolvedを利用することが可能となります。

設定ファイルは /etc/netplan/99_config.yaml に記述します。以下に一例を示します。

network:
  version: 2
  renderer: networkd
  ethernets:
    enp111s0:
      dhcp4: true
      dhcp6: true
      nameservers:
        addresses:
         - 8.8.8.8
         - 1.1.1.1
  wifis:
    wlp112s0:
      dhcp4: true
      dhcp6: true
      nameservers:
        addresses:
         - 8.8.8.8
         - 1.1.1.1
      access-points:
        "wifi-ssid":
          password: "wifi-password"

注意すべき点は、renderer: networkd を設定することです。ここをNetworkManagerに設定すると動作しません。ethernetswifis の下にある enpXsYwlpXsY などは、あなたの環境に応じて適宜書き換えてください。どのデバイスが認識されているのかわからない場合は、ip a コマンドを実行すれば確認できます。

設定が完了したら、以下のコマンドを順に実行し、netplanを適用します。

sudo systemctl enable systemd-networkd --no-pager -l
sudo systemctl restart systemd-networkd --no-pager -l
sudo systemctl status systemd-networkd --no-pager -l
sudo netplan apply

ネットワークの設定が反映されるのを待ち、以下のコマンドを実行して接続状況を確認してください。

ping 1.1.1.1
ping 8.8.8.8
ping google.com

DNSサーバーと適切なドメインへのpingが正常に通れば、Netplanを用いてネットワークの設定が正しく行われたことになります。

Tailscaleの設定をNetplanで行う

ネットワークの設定が正常に行われたら、次にTailscaleの設定を加えます。99_config.yamlethernetsの下に、以下の設定を追加します。

tailscale0:
  dhcp4: true
  dhcp6: true
  nameservers:
    addresses:
      - 100.100.100.100
    search:
      - xxx-yyy.ts.net

ここで、xxx-yyy.ts.netの部分は適宜、自分のTailnet nameに置き換えてください。Tailnet nameはTailscaleの管理画面から確認できます。

設定が完了したら、以下のコマンドでTailscaleを再起動します。

sudo systemctl enable tailscaled --no-pager -l
sudo systemctl restart tailscaled --no-pager -l
sudo systemctl status tailscaled --no-pager -l

そしてsudo netplan applyを実行して、設定を反映します。

sudo netplan apply

ネットワークの設定が反映されるのを待ち、以下のコマンドで接続状況を確認します。

ping 1.1.1.1
ping 8.8.8.8
ping google.com
ping 100.100.100.100
ping xxx-yyy.ts.net
ping your-tailscale-machine

pingが通れば成功です。この方法ならUbuntu 20.04でも、TailscaleのMagic DNSを使用しながらネットワークに接続できるようになります。

Discussion