Authentik Forward AuthでDockerコンテナを保護:10分でSSOとMFAを追加

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

課題:便利なアプリに潜むセキュリティの「穴」

GitHubで見つけた素晴らしいセルフホストツール、例えばシステム監視ダッシュボードのGlancesやファイルマネージャーなどを、Dockerを使ってVPSに即座にデプロイしたとします。しかし、そこで大きな欠陥に気づくはずです。**「このアプリにはログイン画面がない」**ということに。これはセキュリティ上の脆弱性となり得ます。

IPアドレスさえ知っていれば、誰でもアクセスしてデータを閲覧したり削除したりできてしまいます。保護なしでこれらのアプリをインターネットに公開するのは、泥棒にドアを開け放しているようなものです。Dockerホストの脆弱性も同様に無視できないリスクです。以前はNginxのBasic Authで代用していましたが、UIが古臭く、MFAも使えず、ユーザーを追加するたびに設定ファイルを書き換えてサーバーをリロードする必要があり、非常に不便でした。

なぜ今、Authentikが最適な選択肢なのか?

ログイン機能のないアプリを保護するために、いくつかの選択肢が考えられます。

  • Basic Auth: 簡単ですが、時代遅れで安全性が低いです。
  • Authelia: 軽量ですが、初心者にはYAMLファイルの構成が少し複雑です。
  • OAuth2 Proxy: 強力ですが、アプリごとに個別の設定を行うのは時間がかかります。
  • Authentik: これが私の一押しのオールインワン・ソリューションです。GoogleやOktaのようなIDプロバイダー(IdP)として機能するだけでなく、モダンな管理画面でForward Authもサポートしています。

Authentikに移行してからは、20以上の内部アプリに対して覚えるパスワードは1つ(SSO)だけで済むようになりました。さらに重要なのは、すべてのアクセスにスマホからのOTP(ワンタイムパスワード)を強制できるため、アカウントがハックされるリスクをほぼゼロに抑えられる点です。

Forward Authの仕組みとは?

Authentikをバー(あなたのアプリ)の入り口に立つ用心棒、リバースプロキシ(Traefik)をチケットの確認係だと想像してください。

  1. 客が来ると、TraefikはAuthentikに「この人は会員証を持っていますか?」と尋ねます。
  2. 持っていない場合:Authentikは客を受付(ログインページ)へ案内します。
  3. 持っている場合:Authentikが頷き、Traefikがアプリへの扉を開けます。

このプロセス全体は元のアプリの外側で行われます。アプリのコードを一行も書き換えることなく、エンタープライズ級のセキュリティを導入できるのです。

導入手順の詳細

本記事では、ラベルによるコンテナの自動認識が非常にスマートな Traefik を使用します。あらかじめDocker Compose v2がインストールされていることを確認してください(LazyDockerなどのツールを使うと管理がスムーズになります)。

ステップ1:Authentikの初期化

管理用のディレクトリを作成します。コンテナ間の安定した接続のために、Docker Compose v2の使用を推奨します。

mkdir authentik && cd authentik
wget https://goauthentik.io/docker-compose.yml -O docker-compose.yml

# データベース用のランダムパスワードを自動生成
echo "PG_PASS=$(openssl rand -base64 36)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 36)" >> .env

docker compose up -d

約1分後、http://<あなたのIPアドレス>:9000/if/flow/initial-setup/ にアクセスして管理者アカウントを設定してください。

ステップ2:Provider and Applicationの設定

特定のアプリを保護するには、管理画面で以下の2つのステップを実行します。

  1. Resources -> Providers -> Create を開き、Proxy Provider を選択します。
  2. Forward auth (single application) モードを選択し、アプリのドメイン(例:https://uptime.example.com)を入力します。
  3. Resources -> Applications -> Create を開き、アプリ名を付けて、先ほど作成したProviderを紐付けます。

ステップ3:Dockerコンテナに「用心棒」を配置する

ここが魔法の瞬間です。以下は whoami アプリの設定例です。保護したいアプリの docker-compose.yml にこれらのラベルを追加するだけです。

services:
  whoami:
    image: traefik/whoami
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`uptime.example.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls=true"
      
      # Authentikミドルウェアを有効化
      - "traefik.http.routers.whoami.middlewares=authentik@docker"
      
      # Authentikサーバーに接続するためのミドルウェア設定
      - "traefik.http.middlewares.authentik.forwardauth.address=http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
      - "traefik.http.middlewares.authentik.forwardauth.trustForwardHeader=true"
      - "traefik.http.middlewares.authentik.forwardauth.authResponseHeaders=X-authentik-username,X-authentik-groups,X-authentik-email"

ヒント: AuthentikとTraefikを同じDockerネットワーク内に配置しましょう。これによりデータが内部で完結し、パブリックIP経由で呼び出すよりもレスポンス速度が約20〜30ms向上します。

設定後の成果

アプリにアクセスすると、プロフェッショナルなログイン画面が表示されるようになります。Authentikেরユーザー設定で MFA (TOTP) を有効にすれば、スマホの6桁のコードを持つ人だけがシステムに入れます。また、誰がいつ、どのIPからログインしたかという詳細なログも確認可能です。

よくあるエラーの解決方法

「Too many redirects(リダイレクトが多すぎます)」 というエラーが出た場合は、ProviderのExternal Host設定を再確認してください。Traefikで宣言したドメイン(https:// を含む)と100%一致する必要があります。また、authResponseHeaders の行が欠けていると、後続のアプリが「誰がアクセスしているか」を判別できず、権限エラーが発生することがあります。

Authentikの導入は最初は少し複雑に感じるかもしれません。しかし、それによって得られるセキュリティと利便性は、手間をかける価値が十分にあります。これで、新しいアプリをインターネットに公開するたびに不安を感じることはなくなるでしょう。

Share: