Tailscaleと独自ドメインでVPN内の名前解決をより便利にする

2021-02-23T16:00:37+0900
tailscale, network

QNAP NASにTailscaleをインストールしてVPN接続できるようにするで解説したように、とても便利なTailscaleには、Magic DNSというパブリックベータの機能があり、これを利用するとVPNで名前解決によってそれぞれのマシンへアクセスさせることもできます。

VPNで名前解決が利用できると、IPアドレスよりも覚えやすい上に、もしIPアドレスが変更されても影響がなくなるので、大変便利な機能です。

このMagic DNSの機能を利用して、更に色々とできないかを模索してみました。

CNAMEによる独自ドメインの利用 #

まず最初に思いついたは、CNAMEによる独自ドメインの利用で、イメージとしてはこんな感じです。

TailscaleとパブリックDNSの運用イメージ

パブリックDNSを利用するとドメイン名は一般公開されますが、VPNに接続しないかぎり各端末へのアクセスはできません。そのため、公開して問題ない名前であれば、パブリックDNSを利用しても問題ないと言えます。

TailscaleのMagic DNSで各マシンに割り当てられるドメイン名は、次のようなフォーマットになっています。

<マシン名>.<ドメイン>.beta.tailscale.net

「ドメイン」部分は、無料プランであればログイン認証に利用しているメールアドレスになります。もちろん、これでも覚えられないわけではないのですが、CNAMEを使えば独自ドメインを利用してアクセスできるのではないかと思い試してみました。

具体的にはDNSに次のようなCNAMEレコードを追加してみました。

NAME                     TYPE  VALUE
mbp-2019.vpn.tomoya.dev. CNAME mbp-2019.tomoya-ton.gmail.com.beta.tailscale.net.

DNSの伝搬を待ってから、確認してみると次のような応答が返ってきました。

$ dog mbp-2019.vpn.tomoya.dev CNAME
CNAME mbp-2019.vpn.tomoya.dev. 1h00m00s   "mbp-2019.tomoya-ton.gmail.com.beta.tailscale.net."

ちなみに、dogコマンドはRustで書かれたdigライクなDNSクライアントです。

DNSが伝搬していることを確認できたら他のマシンから独自ドメインを利用してアクセスできるかを試してみました。

macOSにVNCでログインする #

macOSは標準でVNCによるログインをサポートしています。Tailscale+独自ドメインを使って、自宅にあるMacBookに、外部ネットワークのiPhoneからVPCでログインできるかを試してみます。

iPhoneのWiFiをオフにして、VNC ViewerのAddress BookからAddressに独自ドメインを入力してログインしてみます。

VNC接続

Tailscale VPNに接続するとログインされ、接続を切るとログインできないことを確認しました。

Windowsにリモートデスクトップでログインする #

Windows 10 Proであればリモートデスクトップが使えます。こちらもTailscale+独自ドメインでログインできるか試してみます。

再びiPhoneでWiFiをオフにして、RD Clientから独自ドメインを入力してログインしてみます。

リモートデスクトップ接続

Tailscale VPNに接続するとログインされ、接続を切るとログインできないことを確認しました。

WindowsにSSHでログインする #

自宅のWindowsマシンはSSHでログインできるようにしているので、こちらも試してみましょう。

MacBookをiPhoneでテザリングしてSSH接続を試してみます。

# Tailscale VPNに接続済み
$ ssh tomoya@minipc-2020.vpn.tomoya.dev
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新しいクロスプラットフォームの PowerShell をお試しください https://aka.ms/pscore6

PS C:\Users\tomoya> exit
Connection to minipc-2020.vpn.tomoya.dev closed.

# Tailscale VPNを切断
$ ssh tomoya@minipc-2020.vpn.tomoya.dev
ssh: Could not resolve hostname minipc-2020.vpn.tomoya.dev: nodename nor servname provided, or not known

Tailscale VPNに接続するとログインされ、接続を切るとログインできないことを確認しました。

独自ドメインでHTTPS接続する #

最後に独自ドメインでSSL証明書を取得して、ウェブサーバーにHTTPS接続できるかを試してみます。

Let’s Encrypt(以下、LE)の証明書発行は初挑戦だったのですが、vim-jp Slackでmattnさんに教えてもらったlegoを使ってみました。

$ lego --server=https://acme-staging-v02.api.letsencrypt.org/directory --email="<メールアドレス>" --domains="<ドメイン>" --dns manual run

まずは上記のようにステージング環境を利用して問題なく発行できるかを試してみました。なお、.devドメインはHTTP接続を強制的にHTTPSにリダイレクトするためHTTP-01チャレンジは利用できないので、DNS-01チャレンジを利用する必要がありました。

legoには各DNSプロバイダ向けのプラグインが備わっていますが、僕が利用しているGoogle Domainsはプラグインが使えないため、マニュアル(手動)で挑戦しました。

コマンド実行後は指示に従って操作を行うだけですんなりとチャレンジに成功したので、--serverオプションを外して本番環境で証明書の発行を行いました。

$ lego --email="<メールアドレス>" --domains="<ドメイン>" --dns manual run
(中略)
$ ls -l ~/.lego/certificates
.rw------- 3.2k tomoya 17 2  0:03 <ドメイン>.crt
.rw------- 1.6k tomoya 17 2  0:03 <ドメイン>.issuer.crt
.rw-------  244 tomoya 17 2  0:03 <ドメイン>.json
.rw-------  227 tomoya 17 2  0:03 <ドメイン>.key

本番環境でも無事に成功して、LEから発行されたSSL証明書が~/.lego/certificatesに保存されました。

あとは、nginxで次のような設定ファイルでサーバーを起動して、ブラウザから独自ドメインでアクセスしてみました。

    server {
       listen       443 ssl;
       server_name  localhost;

       ssl_certificate      /<SSL証明書ディレクトリのパス>/<ドメイン>.crt;
       ssl_certificate_key  /<SSL証明書ディレクトリのパス>/<ドメイン>.key;

Tailscale VPNに接続するとHTTPSでウェブページが表示され、接続を切ると何も表示されないことを確認しました。

VPN接続時

VPN切断時

なお、SSL証明書を発行するとCN(
Common Name)が公開されてcrt.shなどから簡単に検索できるようになるので、公開前のサービス名をドメイン名に含めることも避けたほうが良いでしょう。

まとめ #

VPNでも名前解決したいと思うことはあるのですが、自分でDNSサーバーを立てて運用するのはそれなりのコストがかかるため、なかなか気軽には導入できません。

ですが、TailscaleのMagic DNSとパブリックDNSを組み合わせれば、運用コストなしでVPNで名前解決を利用できることが分かりました。

注意点としてパブリックDNSやSSL証明書を使うとドメイン名が一般公開されるため、秘密にすべき名前は使わないようにする必要がありますが、公開して良い名前であれば独自ドメインだけで無料で使えるのは本当にお手軽で、ライフチェンジングだと思いました。

もし、秘密のドメイン名を使ってVPNで名前解決したいというのであれば、やはり自分でDNSサーバーを立てて運用することになりますが、そうでなければTailscaleとパブリックDNSで運用するのが現状でのベストソリューションだと思いました。

というわけで、これからもしばらくTailscaleで遊んでみつつ、どういうところでお金を落そうかを模索していきたいと思います。