TailscaleのServe機能でVaultwardenを利用

先日、CaddyとVaultwardenでパスワード管理する方法を紹介しましたが、個人で利用するだけなら、わざわざCaddyを導入しなくても、Tailscale Serve機能だけでも十分です。面倒なリバースプロキシ設定やファイアウォールのポート開放(ポートマッピング)をすることなく、安全にVaultwardenを外部に公開できます。

TailscaleのServe機能とは

話が前後してしまいますが、ここでTailscale Serve機能についてもう少し詳しく。先日のCaddyもTailscale導入環境ならTailscale Serve機能を利用しています。

Tailscale Serve機能を利用するには、Tailscaleの管理画面で、「DNS」項目内の一番下にある「HTTPS Certificates」を有効化します。
なお、有効化すると、証明書取得時にデバイス名がインターネットに公開される旨のメッセージが表示されます。デバイス名に個人情報や機密性の高い単語(例: tanaka-iphone や secret-project-server)を含めている場合、それが外部から推測される可能性があるので、有効にするなら、管理画面からデバイス名を web-srv-01 のような、個人や用途が特定されにくい名前に変更することをお勧めします。

TailscaleのHTTPS化メリット・デメリット

1. HTTPS化のメリット

  • ブラウザの警告を排除: 自宅サーバー等にアクセスする際、ブラウザの「保護されていない通信」という警告が出なくなり、スムーズにアクセス可能。
  • 証明書管理の完全自動化: Let’s Encryptの証明書をTailscaleが自動で取得・更新。独自ドメイン取得や複雑な設定は一切不要。
  • セキュアなブラウザ機能の解放: HTTPS必須の機能(位置情報、マイク/カメラ、PWA、セキュアCookie等)がVPN経由でも利用可能に。
  • 多層防御: VPN(WireGuard)による経路暗号化に加え、HTTPS(TLS)でデータ自体も暗号化。

2. 注意すべきデメリット

  • ドメイン名の公開(CTログ): 証明書発行時に「デバイス名.Tailnet名.ts.net」が公開ログに記録される。デバイス名に個人情報を含めない工夫が必要。
  • MagicDNSへの依存: Tailscale独自のドメインを利用するため、既存のDNS環境と競合する場合がある。
  • ポートの競合: ポート443をTailscaleが管理する場合、Nginx等他のリバースプロキシとの棲み分け(設定変更)が必要になる。

3. 「HTTPS Certificates」の挙動

「設定は一括、発行は個別」という仕組みがポイントです。

  • 管理画面の設定(一括): HTTPS機能を「有効」にしても、全マシンに即座に証明書が配布されるわけではない。あくまで「発行を許可する」というフラグ。
  • 証明書の発行(マシンごと):
    • tailscale cert コマンドを実行したマシンだけが証明書を取得。
    • または tailscale serve 等でHTTPS機能を呼び出したマシンのみが動的に取得。

つまり、必要なマシンだけでHTTPS化を完結できるため、セキュリティリスク(CTログへの露出)を最小限に抑えたいマシンは放置しておけばOK。管理画面での有効化は一括(全台対象)ですが、実際に証明書が作られるのはコマンドを叩いたマシンだけです。有効化しただけでは証明書発行を申請しても良いですよ、という許可だけで、実際に発行するのは各マシンで、tailscale cert コマンドやtailscale serveコマンド、tailscale funnelコマンドを実行した時です。

TailscaleのServe機能の使用方法

たとえば

tailscale serve https 443 http://localhost:3000

これで、https://<ホスト名>.<tailnet>.ts.netにアクセスすれば、証明書は自動発行され、localhost:3000 に HTTPS でリバースプロキシされます。(ホスト名だけでなくTailnet名も含めたフルドメイン名でのアクセスになります)。Ubuntuの場合、再起動しても自動で有効になります。

Tailscale Serve機能を無効にする方法

設定を無効化するには、以下のコマンドを実施します。

全て削除する

tailscale serve reset

特定のポートのみ削除する

443ポートだけ消す場合

tailscale serve https 443 off

ポートごとに異なるサービスを指定

各ポートごとに異なるサービスを指定する方法があります。

sudo tailscale serve --https=443 http://localhost:8080

ポート 8443 でローカルの 9000 を公開

sudo tailscale serve --https=8443 http://localhost:9000

パス(URL)ごとにサービスを分ける

サービスが増えてきたら、パスごとに分けたほうが分かりやすいですね。

/app1 をローカル 8080 へ、/app2 をローカル 9000 へ

sudo tailscale serve /app1 http://localhost:8080
sudo tailscale serve /app2 http://localhost:9000

TailscaleのServe機能でVaultwardenを利用

さて、それではTailscaleのServe機能を使って、8080ポートで動いているVaultwardenをインターネット(Tailnet)に公開するには。

sudo tailscale serve https:443 / http://127.0.0.1:8080

このコマンドを実行すると、以下の設定が自動で行われます。

  • Tailscaleが提供するTLS証明書(HTTPS)が適用される。
  • Tailscaleノード名のサブドメイン(例: my-server.tail-net.ts.net)でアクセス可能になる。

確認:
管理画面で対象ノードのServe設定が緑色(有効)になっていることを確認します。


注意点・ポイント

  • URLの確認: Vaultwardenへのアクセスは https://<your-machine-name>.<your-tailnet>.ts.net となります。
  • iOS/Androidアプリ: スマホ側でもTailscaleを常時接続(Always-on)にしておくことで、アプリからアクセスできます。
  • セキュリティ: Serve機能で公開されたサービスは、基本的にTailscaleネットワークに参加しているデバイスからのみアクセス可能です(完全なパブリック公開ではありません)。
  • 解除: 公開を停止したい場合は sudo tailscale serve off を実行します。 

上記手順で、非常に簡単にセキュアなパスワード管理環境を構築できます。

導入手順

もしこれからVaultwardenを導入しようとしている場合、Tailscale ServeでVaultwardenを構築する手順を説明します。

前提確認

  • Docker & Docker Compose インストール済み
  • Tailscale インストール済み・ログイン済み
  • インストール先: /opt/docker/vaultwarden

1. ディレクトリ作成

sudo mkdir -p /opt/docker/vaultwarden/data
cd /opt/docker/vaultwarden

2. docker-compose.yml 作成

sudo nano /opt/docker/vaultwarden/docker-compose.yml
services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      - SIGNUPS_ALLOWED=true        # 初期登録後は false に変更推奨
      - DOMAIN=https://<あなたのTailscaleホスト名>
    volumes:
      - ./data:/data
    ports:
      - "127.0.0.1:8080:80"         # ローカルループバックのみ公開

DOMAIN は次のステップで確認するTailscale MagicDNS名を入れます(例: https://myserver.tail1234.ts.net


3. Tailscaleホスト名の確認

tailscale status
# または
tailscale cert --help  # MagicDNS名を確認
# MagicDNS名の確認
tailscale status | head -5

ホスト名は <マシン名>.<テールネット名>.ts.net 形式です。


4. Tailscale Serve の設定

Tailscale ServeはHTTPS終端とリバースプロキシを自動で行います。

sudo tailscale serve --bg http://127.0.0.1:8080

設定確認:

tailscale serve status
```

以下のような出力になればOKです:
```

https://<
ホスト名>.ts.net (tailnet only) |-- / proxy http://127.0.0.1:8080 |-- /notifications/hub proxy http://127.0.0.1:3012

5. Vaultwarden起動

cd /opt/docker/vaultwarden
sudo docker compose up -d

# ログ確認
sudo docker compose logs -f

6. docker-compose.ymlのDOMAINを更新

ステップ3で確認したホスト名を記入して再起動:

sudo nano docker-compose.yml
# DOMAIN=https://myserver.tail1234.ts.net  ← 実際のホスト名に変更

sudo docker compose up -d
```

---

## 7. 動作確認

ブラウザで以下にアクセス(**Tailscaleに接続済みのデバイスから**):
```
https://<ホスト名>.ts.net

TailscaleがLet’s Encrypt証明書を自動発行するため、HTTPSが有効になります。


初期設定後のセキュリティ強化

アカウント作成後、docker-compose.yml の環境変数を変更して再起動:

environment:
  - SIGNUPS_ALLOWED=false    # 新規登録を無効化
  - ADMIN_TOKEN=             # 管理画面が不要なら空欄のまま
sudo docker compose up -d

まとめ

役割担当
HTTPS終端・証明書Tailscale Serve(自動)
リバースプロキシTailscale Serve
アクセス制御Tailnet(VPN内のみ)
アプリ本体Vaultwarden(Docker)

CaddyもNginxも不要で、Tailscale Serveだけでセキュアなアクセスが実現できます。

おまけ:Tailscale MagicDNS名の取得も自動化、1コピペで

一気にやる方法も。

#!/bin/bash
set -e

# ── 設定 ──────────────────────────────────────────
INSTALL_DIR="/opt/docker/vaultwarden"
PORT="8080"
# ──────────────────────────────────────────────────

echo "==> Tailscale MagicDNS名を取得中..."
TAILSCALE_DOMAIN=$(tailscale status --json | python3 -c "
import json,sys
d=json.load(sys.stdin)
print(d['Self']['DNSName'].strip('.'))
")

if [ -z "$TAILSCALE_DOMAIN" ]; then
  echo "ERROR: Tailscale MagicDNS名を取得できませんでした。"
  echo "  tailscale status で接続状態を確認してください。"
  exit 1
fi

echo "    取得したドメイン: https://${TAILSCALE_DOMAIN}"

echo "==> ディレクトリ作成: ${INSTALL_DIR}"
sudo mkdir -p "${INSTALL_DIR}/data"

echo "==> docker-compose.yml を生成中..."
sudo tee "${INSTALL_DIR}/docker-compose.yml" > /dev/null <<EOF
services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      - SIGNUPS_ALLOWED=true
      - DOMAIN=https://${TAILSCALE_DOMAIN}
    volumes:
      - ./data:/data
    ports:
      - "127.0.0.1:${PORT}:80"
EOF

echo "==> Vaultwarden コンテナを起動中..."
cd "${INSTALL_DIR}"
sudo docker compose up -d

echo "==> Tailscale Serve を設定中..."
sudo tailscale serve reset 2>/dev/null || true
sudo tailscale serve --bg http://127.0.0.1:${PORT}

echo "==> 設定確認..."
tailscale serve status

echo ""
echo "✅ セットアップ完了!"
echo "   ブラウザで開く: https://${TAILSCALE_DOMAIN}"
echo ""
echo "⚠️  アカウント作成後は SIGNUPS_ALLOWED を false に変更してください:"
echo "   sudo sed -i 's/SIGNUPS_ALLOWED=true/SIGNUPS_ALLOWED=false/' ${INSTALL_DIR}/docker-compose.yml"
echo "   cd ${INSTALL_DIR} && sudo docker compose up -d"

実行内容の流れ

ステップ内容
1tailscale cert / tailscale status でMagicDNS名を自動取得
2/opt/docker/vaultwarden/ を作成
3取得したドメインを埋め込んだ docker-compose.yml を生成
4コンテナ起動
5tailscale serve でHTTPS公開
6完了URLを表示

MagicDNS名の取得に失敗した場合はエラーで停止するので、中途半端な状態になりません。

タイトルとURLをコピーしました