はじめに
こんにちは、WorkSpacesのログイン認証でMFAを導入する方法について検証しましたので、必要に応じて参照いただけると幸いです。
Amazon WorkSpaces で多要素認証(MFA)を導入する場合、RADIUS サーバーが必要になります。
本記事では、Amazon Linux 2023(AL2023)上に FreeRADIUS + Google Authenticator を構築し、WorkSpaces の MFA を実現する手順を解説します。
全体構成図

通信フロー
- ユーザーがWorkSpaces クライアントで ID・パスワード・MFA コードを入力
- Managed AD が パスワード認証を実施(ここで ID/PW の検証は完了)
- Managed AD が OTPコード部分だけを RADIUS サーバー(FreeRADIUS)に転送(UDP 1812)
- FreeRADIUS が PAM 経由で Google Authenticator の OTPを検証
- 認証結果(Accept / Reject)を Managed AD に返却
- WorkSpaces へのログインが許可または拒否される
ネットワーク要件
| 通信 | プロトコル | ポート | 方向 |
|---|---|---|---|
| RADIUS 認証 | UDP | 1812 | Managed AD → FreeRADIUS |
前提条件
- ディレクトリサービス: AWS Managed Microsoft AD が構築済み
- ※ Simple AD は MFA(RADIUS 連携)非対応
- EC2: Amazon Linux 2023、Managed AD と同一 VPC 内に配置
- セキュリティグループ: UDP 1812 が Managed AD の DC から許可されていること
- Managed AD: テスト用ユーザーが作成済みであること
- WorkSpaces: 少なくとも1台が起動済み(動作確認用)
- スマートフォン: Google Authenticator アプリがインストール済み
FreeRADIUS のインストール
パッケージのインストール
FreeRADIUS及びGoogle Authenticator、QRコード出力のためのパッケージをインストールします。
# FreeRADIUS 本体とユーティリティをインストール sudo dnf install -y freeradius freeradius-utils # Google Authenticator PAM モジュールをインストール sudo dnf install -y google-authenticator qrencode
尚、QRコードを出力する方法については以下ブログもご参照ください。
インストール確認
# バージョン確認 radiusd -v # 設定ファイルの場所を確認 ls /etc/raddb/
主な設定ファイル:
| ファイル | 用途 |
|---|---|
/etc/raddb/radiusd.conf |
メイン設定 |
/etc/raddb/clients.conf |
RADIUS クライアント定義 |
/etc/raddb/mods-available/pam |
PAM モジュール設定 |
/etc/raddb/sites-available/default |
認証フロー定義(sites-enabled/default はこのシンボリックリンク) |
/etc/pam.d/radiusd |
PAM 認証設定(自分で作成) |
FreeRADIUS の設定
0. 設定ファイルのバックアップ
編集前に、元の設定ファイルをバックアップしておきます。
sudo cp -rp /etc/raddb /etc/raddb.original
1. クライアント設定(clients.conf)
Managed AD のドメインコントローラーを RADIUS クライアントとして登録します。
sudo vi /etc/raddb/clients.conf
以下を末尾に追加します。構築先の環境に合わせて記載してください。 共有シークレットについては、自由に設定が可能です。 共有シークレットは後ほど WorkSpaces のディレクトリ設定でも同じ値を入力します。完全一致 が必要なので、必ずメモをしてください。
# AWS Managed Microsoft AD
client managed-ad {
# Managed AD の DC が存在するサブネットの CIDR
ipaddr = 10.0.0.0/24
secret = <共有シークレット>
}
2. EAP の無効化(起動エラー対策)
FreeRADIUS はデフォルトで EAP 認証が有効になっており、SSL/TLS 証明書がないと起動時にエラーになります。本構成では PAP のみ使用するため、EAP 関連を無効化します。
# EAP モジュールのシンボリックリンクを削除 sudo rm /etc/raddb/mods-enabled/eap # inner-tunnel サイトを無効化 sudo rm /etc/raddb/sites-enabled/inner-tunnel
3. PAM モジュールの有効化
# PAM モジュールへのシンボリックリンクを作成 sudo ln -s /etc/raddb/mods-available/pam /etc/raddb/mods-enabled/pam
4. PAM 設定ファイルの作成
FreeRADIUS 用の PAM 設定を作成します。
sudo vi /etc/pam.d/radiusd
以下の内容を記述してください。
#%PAM-1.0
auth required pam_google_authenticator.so secret=/etc/radius/google-authenticator/${USER}/.google_authenticator
account required pam_permit.so
| 設定 | 説明 |
|---|---|
secret=... |
OTPシークレットファイルの場所を指定(中央集約管理) |
pam_permit.so |
アカウント検証は常に許可(パスワード検証は Managed AD 側で完了済み) |
5. OTPシークレット用ディレクトリの作成
sudo mkdir -p /etc/radius/google-authenticator sudo chown root:root /etc/radius/google-authenticator sudo chmod 755 /etc/radius/google-authenticator
pam_google_authenticator は OTPファイル読み込み時に setuid() で対象ユーザーに切り替えます。各ユーザーがこのディレクトリを横断できる必要があるため、親ディレクトリは 755 にします。
6. radiusd を root で動作させる設定
pam_google_authenticator は内部で setuid() を実行するため、FreeRADIUS を root 権限で動作させる必要があります。
sudo vi /etc/raddb/radiusd.conf
以下の項目を変更:
user = root # デフォルト: radiusd group = root # デフォルト: radiusd
7. Auth-Type の強制設定(users ファイル)
PAM のみの構成では、authorize セクションの pap モジュールが「known good password」(ファイルや DB に保存されたパスワード)を見つけられないため、Auth-Type が自動設定されません。その結果、authenticate セクションの Auth-Type PAP { pam } が発火せず、認証が失敗します。
これを解決するため、users ファイルで Auth-Type を強制的に PAP に設定します。
sudo sh -c 'echo "DEFAULT Auth-Type := PAP" >> /etc/raddb/users'
8. 認証フロー設定(sites-available/default)
sudo vi /etc/raddb/sites-available/default
デフォルトの sites-available/default には多くのモジュールが有効になっています。EAP 関連の eap 呼び出しをすべてコメントアウトし、他のモジュールはデフォルトのまま残します。
authorize セクション
pap モジュールは Auth-Type PAP を発火させるために必須ですが、AL2023 の FreeRADIUS 3.2.5 ではデフォルト設定にすでに含まれています。
EAP ブロック(eap { ok = return })のみコメントアウトします。他のモジュールはデフォルトのまま残します。
authorize {
filter_username
preprocess
chap
mschap
digest
suffix
# eap { # ← コメントアウト(EAP ブロック全体)
# ok = return
# }
files
-sql
-ldap
expiration
logintime
pap
}
authenticate セクション
Auth-Type PAP ブロックの中身を pap から pam に変更します。
AL2023 の FreeRADIUS 3.2.5 デフォルトでは Auth-Type EAP ブロックはすでにコメントアウトされていますが、代わりに bare eap 行(Auth-Type ブロック外の単独 eap 呼び出し)が存在します。
eap モジュールを削除した状態でこの行が残っているとエラーになるため、コメントアウトが必要です。
authenticate {
Auth-Type PAP {
pam # ← pap から pam に変更(PAM で OTP検証)
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
mschap
digest
# pam # ← コメントアウトのまま(authenticate のデフォルト pam 行)
# eap # ← コメントアウト(eap モジュール削除済みのため必須)
}
post-auth / post-proxy にも bare eap 行あり: sites-available/default の post-auth(Access-Reject サブセクション)と post-proxy セクションにも eap 行があります。すべてコメントアウトが必要です。以下のコマンドで一括確認できます:
上記で出力された行をすべてコメントアウトしてください。
sudo grep -n '^\s*eap$' /etc/raddb/sites-available/default | grep -v '#'
9. 設定の構文チェックと起動確認
すべての設定が完了したら、構文チェックを行います。
# 構文チェック(エラーがなければ "Configuration appears to be OK" と出力)
sudo radiusd -XC
# 起動してポートを確認
sudo systemctl start radiusd
sudo ss -ulnp | grep radiusd
# 期待される出力:
# UNCONN 0 0 0.0.0.0:1812 0.0.0.0:* users:(("radiusd",...))
# UNCONN 0 0 0.0.0.0:1813 0.0.0.0:* users:(("radiusd",...))
ユーザーの OTPセットアップ
ユーザー追加スクリプト
各 WorkSpaces ユーザーに対して、Linux システムユーザーの作成と OTPシークレットの生成を行います。
#!/bin/bash
# add-radius-user.sh
USERNAME=$1
if [ -z "$USERNAME" ]; then
echo "Usage: $0 <username>"
exit 1
fi
# Linux システムユーザーを作成(ログイン不可・ホームディレクトリなし)
sudo useradd -r -s /sbin/nologin -M "$USERNAME" 2>/dev/null
# OTPシークレット用のディレクトリを作成
USER_DIR="/etc/radius/google-authenticator/${USERNAME}"
sudo mkdir -p "$USER_DIR"
sudo chown "$USERNAME":"$USERNAME" "$USER_DIR"
sudo chmod 700 "$USER_DIR"
# Google Authenticator シークレットを生成
sudo -u "$USERNAME" google-authenticator -t -d -f -w 3 -r 3 -R 30 \
-s "${USER_DIR}/.google_authenticator"
# ファイル権限を設定
sudo chown "$USERNAME":"$USERNAME" "${USER_DIR}/.google_authenticator"
sudo chmod 600 "${USER_DIR}/.google_authenticator"
echo "Done: ${USER_DIR}/.google_authenticator"
スクリプトの実行
chmod +x add-radius-user.sh sudo ./add-radius-user.sh testuser
実行するとQRコードが表示されるので、スマートフォンの Google Authenticator アプリでスキャンします。
動作確認
1. デバッグモードで起動
# 通常のサービスを停止(起動済みの場合) sudo systemctl stop radiusd # デバッグモードで起動(ログがリアルタイムで表示される) sudo radiusd -X
2. radtest でローカルテスト
Google Authenticator アプリで現在のOTPコードを確認してから、別のターミナルで実行します。
PAM のみの構成では、FreeRADIUS に送信されるのは OTPコードのみです。パスワードは含めません。 尚、ローカルでのテストの場合、共有シークレットは先ほど設定したものとは異なります。
/etc/raddb/clients.conf の client localhost { 内にある共有シークレットを利用してください。
# radtest <ユーザー名> <OTPコード> localhost 1812 <共有シークレット> # 例: ユーザー testuser、OTPコード 123456、共有シークレット MyRadiusSecret123 radtest testuser 123456 localhost 1812 testing123
3. デバッグログの読み方
デバックログを読み取り、結果をご確認ください。
# 成功パターン (0) pam: Using pamauth string "radiusd" for pam.conf lookup (0) pam: User "testuser" authenticated successfully Sending Access-Accept ← 認証 OK # 失敗パターン(OTPコード不一致) pam_google_authenticator: Invalid verification code for testuser Sending Access-Reject ← 認証 NG
4. サービスとして起動
動作確認が取れたらサービスを起動します。
sudo systemctl enable radiusd sudo systemctl start radiusd sudo systemctl status radiusd
WorkSpaces 側の MFA 設定
Directory Service コンソールでの設定
- AWS マネジメントコンソール → Directory Service → 対象の Managed AD を選択
- ネットワークとセキュリティ タブ → 多要素認証 セクション → アクション → 有効化
- 以下を入力:
| 項目 | 設定値 |
|---|---|
| RADIUS サーバーの IP アドレス | FreeRADIUS 用 EC2 のプライベート IP |
| ポート | 1812 |
| 共有シークレット | clients.conf に設定した値と同一 |
| プロトコル | PAP |
| サーバータイムアウト | 30(秒) |
| 最大リトライ回数 | 3 |
ログイン検証
MFA を有効化すると、WorkSpaces クライアントのログイン画面に MFA code 入力欄が追加されます。
- WorkSpaces クライアントを起動し、Registration Code を入力
- 以下の 3 つを入力:
- ユーザー名: AD 上のユーザー名
- パスワード: AD のパスワード
- MFA code: Google Authenticator の 6 桁コード
- デスクトップが起動すれば成功
まとめ
本記事では、Amazon Linux 2023 上に FreeRADIUS + Google Authenticator を構築し、WorkSpaces の MFA を実現する手順を紹介しました。
Amazon Linux2023での構築手順は調べてみると手順は多く出ますが、詰まるポイントも多いですので、ご参考までに利用していただけたらと思います。
篠﨑 勇輔(書いた記事を見る)
クロスインダストリー本部SA2課