2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWSで学ぶ:RADIUSサーバ構築+CloudWatchによる可視化

Last updated at Posted at 2025-06-22

はじめに

AWS 環境の EC2 インスタンス (Amazon Linux 2023) を利用して、オープンソースで最も広く利用されている RADIUS サーバー「FreeRADIUS」を構築する手順を解説します。
さらに発展編として、実運用で役立つ CloudWatch を使ったログの可視化までをやってみます。

全体構成図

structure.png

同じ VPC 内に RADIUS サーバーとクライアントを配置し、クライアントからサーバーへ認証リクエストを送信するシンプルな構成です。

構築手順

ステップ1: AWS環境の準備

まず、サーバーとクライアントとして利用する2台のEC2インスタンスを準備します。
以下の設定で2台のEC2インスタンスを作成します。

設定項目 補足
名前 RADIUS-Server と RADIUS-Client それぞれの役割が分かるように命名します。
AMI Amazon Linux 2023 AMI -
インスタンスタイプ t2.micro デモ用途には十分なスペックです。
ネットワーク 同じVPC、同じパブリックサブネット 2台のインスタンスが相互に通信できるようにします。
パブリックIPの自動割り当て 有効化 SSH接続用

次にRADIUS-SG という名前で新しいセキュリティグループを作成し、2台のインスタンスにアタッチします。以下のインバウンドルールを設定してください。

タイプ プロトコル ポート範囲 ソース 説明
SSH TCP 22 マイIP 管理用のSSH接続
カスタムUDP UDP 1812 RADIUS-SG のID RADIUS認証通信
カスタムUDP UDP 1813 RADIUS-SG のID RADIUSアカウンティング通信
  • プライベートIPアドレスの確認
    後ほどの設定で利用するため、作成した2台のインスタンスのプライベートIPアドレスを控えておきます。

ステップ2: RADIUSサーバーの構築

  1. FreeRADIUSのインストール
    RADIUS-Server インスタンスにEC2 Instance ConnectでSSH接続し、FreeRADIUS をインストール・設定します。

    bash
    sudo dnf update -y
    sudo dnf install -y freeradius freeradius-utils
    

    タイムゾーンを日本時間 (Asia/Tokyo) に設定します。

    bash
    sudo timedatectl set-timezone Asia/Tokyo
    
  2. クライアント情報の登録 (clients.conf)
    RADIUS サーバーがどのクライアントからのリクエストを受け付けるかを設定します。
    sudo vi /etc/raddb/clients.conf を開き、ファイルの末尾に RADIUS-Client の情報を追記します。 <RADIUS-ClientのプライベートIP> は控えておいたIPアドレスに置き換えてください。

    # /etc/raddb/clients.conf
    # (...ファイルのもともとの内容...)
    # 自前のRADIUSクライアントを追加
    client radius_client {
        ipaddr = <RADIUS-ClientのプライベートIP>
        secret = hands-on  # サーバーとクライアント間の合い言葉
    }
    

この secret (共有シークレット) は非常に重要です。

3. ユーザー情報の登録 ( users )
認証に利用するユーザーを登録します。
sudo vi /etc/raddb/users を開き、ファイルの先頭にテストユーザーの情報を追記します。

# /etc/raddb/users
# テストユーザーを追加 (ユーザー名: testuser, パスワード: testpassword)
testuser Cleartext-Password := "testpassword"
# 複数人登録する場合は同様に追記する
hanako.yamada   Cleartext-Password := "P@ssword_Yamada123"
taro.suzuki     Cleartext-Password := "P@ssword_Suzuki456"
# (...ファイルのもともとの内容...)

ステップ3: EAP無効化

FreeRADIUS は、インストール直後の状態では高度な認証方式 (EAP) が有効になっています。しかし、これらの機能はSSL証明書などを必要とするため、シンプルなID/パスワード認証を行う際には、これが原因で起動エラーが発生します。

今回のデモでは、より簡単にするためにあらかじめEAPを無効化しておきます。

  1. eap モジュールを無効化
    EAP はセキュアな認証方式ですが、証明書がないと起動に失敗します。以下のコマンドで無効化します。

    sudo rm /etc/raddb/mods-enabled/eap
    
  2. inner-tunnel サイトを無効化
    inner-tunnel は EAP のトンネル処理で使われる設定ですが、今回は不要なので無効化します。

    bash
    sudo rm /etc/raddb/sites-enabled/inner-tunnel
    
  3. default サイトの修正

    モジュールを無効化しても、メインの設定ファイル ( default ) からの呼び出しが残っているため、それらもコメントアウトします。

    sudo vi /etc/raddb/sites-enabled/default で開いて、2箇所修正します。

    • authorize セクションの修正(419行目)
      ※eapだけでなく、{ }の部分もコメントアウトすることを忘れないでください。起動時に構文エラーとなります。

      /etc/raddb/sites-enabled/default
      # 編集前
      authorize {
          ...
          eap {
                 ok = return
          #       updated = return
          }
      }
      
      # 編集後
      authorize {
          ...
          #eap {
          #       ok = return
          #       updated = return
          #}
      }
      
  • authenticate セクションの修正(603行目)

    /etc/raddb/sites-enabled/default
    # 編集前
    authenticate {
        ...
        eap
        ...
    }
    
    # 編集後
    authenticate {
        ...
    #   eap
        ...
    }
    

Tips:以下のコマンドで編集すべき行数を予め知ることができます。
sudo grep -n '^\s*eap' /etc/raddb/sites-enabled/default
これで、シンプルなPAP認証(ID/パスワード認証)に必要な設定だけが残った状態になりました。

ステップ4: サーバーの起動とクライアントの準備

  1. FreeRADIUSサービスの起動
    RADIUS-Server で以下のコマンドを実行し、サービスを起動・自動起動設定します。

    bash
    sudo systemctl start radiusd
    sudo systemctl enable radiusd
    

    以下のコマンドで active (running) となっていれば成功です。

    bash
    [ec2-user@ip-10-0-14-102 ~]# sudo systemctl status radiusd
    ● radiusd.service - FreeRADIUS high performance RADIUS server.
     Loaded: loaded (/usr/lib/systemd/system/radiusd.service; enabled; preset: disabled)
     Active: active (running) since Sun 2025-06-22 11:29:19 UTC; 12s ago
     Main PID: 31373 (radiusd)
      Tasks: 6 (limit: 1111)
     Memory: 40.5M
        CPU: 80ms
     CGroup: /system.slice/radiusd.service
             └─31373 /usr/sbin/radiusd -d /etc/raddb
    
  2. クライアントツールのインストール

    RADIUS-Client インスタンスに SSH で接続し、テストツールをインストールします。

    bash
    sudo dnf update -y
    sudo dnf install -y freeradius-utils
    

    タイムゾーンを日本時間 (Asia/Tokyo) に設定します。

    bash
    sudo timedatectl set-timezone Asia/Tokyo
    

ステップ5: 認証テスト

RADIUS-Client から radtest コマンドを使い、認証テストを実行します。

  1. 認証成功テスト
    正しい共有シークレット ( hands-on ) を使ってテストします。
    bash
    radtest testuser testpassword <RADIUS-ServerのプライベートIP>:1812 0 hands-on
    
    以下のように Received Access-Accept と返ってくれば認証成功です!
    bash
    Sent Access-Request Id 95 from 0.0.0.0:55186 to 10.0.14.102:1812 length 78
        User-Name = "testuser"
        User-Password = "testpassword"
        NAS-IP-Address = 10.0.8.100
        NAS-Port = 0
        Message-Authenticator = 0x00
        Cleartext-Password = "testpassword"
    Received Access-Accept Id 95 from 10.0.14.102:1812 to 10.0.8.100:55186 length 38
        Message-Authenticator = 0xf224b42683d891fa7fcf3193349935ad
    
  2. 認証失敗テスト (共有シークレット不一致)
    わざと間違った共有シークレット ( hands-off ) を使ってみましょう。
    bash
    radtest testuser testpassword <RADIUS-ServerのプライベートIP>:1812 0 hands-off
    
    今度はサーバーから何の応答もなく、最終的にタイムアウトエラーになります。
    bash
    Sent Access-Request Id 27 from 0.0.0.0:56334 to 10.0.14.102:1812 length 78
        User-Name = "testuser"
        User-Password = "testpassword"
        NAS-IP-Address = 10.0.8.100
        NAS-Port = 0
        Message-Authenticator = 0x00
        Cleartext-Password = "testpassword"
    Sent Access-Request Id 27 from 0.0.0.0:56334 to 10.0.14.102:1812 length 78
        User-Name = "testuser"
        User-Password = "testpassword"
        NAS-IP-Address = 10.0.8.100
        NAS-Port = 0
        Message-Authenticator = 0x00
        Cleartext-Password = "testpassword"
    Sent Access-Request Id 27 from 0.0.0.0:56334 to 10.0.14.102:1812 length 78
        User-Name = "testuser"
        User-Password = "testpassword"
        NAS-IP-Address = 10.0.8.100
        NAS-Port = 0
        Message-Authenticator = 0x00
        Cleartext-Password = "testpassword"
    (0) No reply from server for ID 27 socket 3.
    

登録されたクライアントからでも共有シークレットが違う場合、サーバーは不正なリクエストとみなし、パケットを破棄します。

【発展】AWSサービスのワンポイント:認証ログの可視化

ステップ6: FreeRADIUSの設定ファイル radiusd.conf を編集

設定ファイルをテキストエディタで開きます。

bash
sudo vi /etc/raddb/radiusd.conf

log セクション内の authの設定(348行目)をnoからyesへ変更します。

/etc/raddb/radiusd.conf
#編集前
#  Log all (accept and reject) authentication results to the log file.
#
#  This is the same as setting "auth_accept = yes" and
#  "auth_reject = yes"
#
#  allowed values: {no, yes}
#
auth = no

#編集後
#  Log all (accept and reject) authentication results to the log file.
#
#  This is the same as setting "auth_accept = yes" and
#  "auth_reject = yes"
#
#  allowed values: {no, yes}
#
auth = yes

デフォルトの設定では取得できなかった成功時のログも吐き出し可能となりました。

ステップ7: CloudWatch Agentのインストールと設定

  1. IAMロールのアタッチ
    RADIUS-Server のEC2インスタンスに、CloudWatch Agentがログを送信するための権限が必要です。

    1-1. IAMコンソールで新しいロールを作成します。
    1-2. 信頼されたエンティティタイプ: AWSのサービス
    1-3. ユースケース: EC2
    1-4. 許可ポリシーとして CloudWatchAgentServerPolicy をアタッチします。
    1-5. ロール名(例: EC2-CloudWatchAgent-Role)を付けて作成します。
    1-6. EC2ダッシュボードに戻り、RADIUS-Server インスタンスにこのIAMロールをアタッチします。

  2. CloudWatch Agentのインストール
    RADIUS-Server にSSHで接続し、以下のコマンドでAgentをインストールします。

    bash
    sudo dnf install -y amazon-cloudwatch-agent
    
  3. Agent設定ファイルの作成
    どのログファイルをCloudWatchに送信するかを定義する設定ファイルを作成します。FreeRADIUSは認証結果を /var/log/radius/radius.log に出力するので、これを対象とします。
    sudo vi /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json を実行し、以下の内容を貼り付けます。

amazon-cloudwatch-agent.json
{
  "agent": {
    "metrics_collection_interval": 60,
    "run_as_user": "root",
    "debug": true
  },
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/var/log/radius/radius.log",
            "log_group_class": "STANDARD",
            "log_group_name": "/aws/ec2/freeradius-logs",
            "log_stream_name": "{instance_id}",
            "retention_in_days": 7,
            "timestamp_format": "%a %b %d %H:%M:%S %Y",
            "timezone": "LOCAL"
          }
        ]
      }
    }
  },
  "metrics": {
    "aggregation_dimensions": [
      [
        "InstanceId"
      ]
    ],
    "append_dimensions": {
      "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
      "ImageId": "${aws:ImageId}",
      "InstanceId": "${aws:InstanceId}",
      "InstanceType": "${aws:InstanceType}"
    },
    "metrics_collected": {
      "disk": {
        "measurement": [
          "used_percent"
        ],
        "metrics_collection_interval": 60,
        "resources": [
          "*"
        ]
      },
      "mem": {
        "measurement": [
          "mem_used_percent"
        ],
        "metrics_collection_interval": 60
      },
      "statsd": {
        "metrics_aggregation_interval": 60,
        "metrics_collection_interval": 10,
        "service_address": ":8125"
      }
    }
  }
}

log_group_name: CloudWatch Logs内でログを格納するグループ名です。分かりやすい名前をつけましょう。
参考までに上記jsonは以下の内容となっています。変更したいパラメータ等あれば、自由に調整してください。

CloudWatch Agent パラメータ設定

  • エージェント共通 (agent)
パラメータ 設定値 説明
run_as_user root エージェントを実行するユーザー。rootで実行することでファイルアクセス権限の問題を回避します。
metrics_collection_interval 60 (デフォルト値) メトリクスを収集する基本間隔(秒)。
debug TRUE デバッグモードを有効化。詳細な動作ログが出力され、トラブルシューティングに役立ちます。本番環境ではfalseを推奨します。
  • ログ収集 (logs)
パラメータ 設定値 説明
file_path /var/log/radius/radius.log 収集対象のログファイルへのフルパス。
log_group_name /aws/ec2/freeradius-logs ログを格納するCloudWatch Logsのロググループ名。
log_stream_name {instance_id} ロググループ内のログストリーム名。{instance_id}とすることで、実行したEC2インスタンスのIDが自動的に設定されます。
retention_in_days 7 CloudWatch Logsでのログ保持期間(日数)。7日経過後に自動で削除されます。
timestamp_format %a %b %d %H:%M:%S %Y ログファイル内のタイムスタンプを解釈するための書式。
timezone LOCAL ログのタイムスタンプに使用するタイムゾーン。LOCALはEC2インスタンスのOS設定に従います。
log_group_class STANDARD ロググループのストレージクラス。標準のアクセス頻度に適しています。
  • メトリクス共通 (metrics)
パラメータ 設定値 説明
aggregation_dimensions InstanceId 収集したメトリクスをInstanceId単位で集約します。
append_dimensions.AutoScalingGroupName ${aws:AutoScalingGroupName} 全てのメトリクスにAuto Scalingグループ名のディメンション(タグ)を付与します。
append_dimensions.ImageId ${aws:ImageId} 全てのメトリクスにAMIのIDのディメンション(タグ)を付与します。
append_dimensions.InstanceId ${aws:InstanceId} 全てのメトリクスにインスタンスIDのディメンション(タグ)を付与します。
append_dimensions.InstanceType ${aws:InstanceType} 全てのメトリクスにインスタンスタイプのディメンション(タグ)を付与します。
  • 収集メトリクス (ディスク・メモリ)
パラメータ 設定値 説明
measurement used_percent 収集するディスクの指標。ディスク使用率(%)を収集します。
resources * 収集対象のリソース。*は全てのマウント済みディスクパーティションを意味します。
metrics_collection_interval 60 このメトリクスの収集間隔(秒)。
measurement mem_used_percent 収集するメモリの指標。メモリ使用率(%)を収集します。
metrics_collection_interval 60 このメトリクスの収集間隔(秒)。
  • 収集メトリクス (StatsD)
パラメータ 設定値 説明
service_address :8125 アプリケーションからカスタムメトリクスを受け付けるStatsDリスナーのアドレスとポート。
metrics_collection_interval 10 StatsDプロトコルでデータを受け付ける間隔(秒)。
metrics_aggregation_interval 60 受け付けたデータを集約し、CloudWatchへ送信する間隔(秒)。

 4. CloudWatch Agentの起動
以下のコマンドで設定ファイルを読み込み、Agentを起動します。

bash
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json -s

これで、RADIUS-Server で認証が発生するたびに、そのログが自動でCloudWatch Logsに送信されるようになります。
左がCloudWatchエージェントが取得した情報で、右側がRADIUSサーバ内の radius.log です。かなり見にくいですが、きちんとログを収集できることがわかります。
cwagentlog.png

ステップ8: CloudWatch Logs Insightsでのログ分析

radtest コマンドで何度か認証を成功・失敗させてログを生成した後、AWSコンソールのCloudWatch画面を開きます。

  1. 左側のメニューから「ログ」>「Logs Insights」を選択します。
  2. 「ロググループを選択」で、先ほど設定した RadiusServer/radius.log を選びます。
  3. クエリエディタに、SQLライクなクエリを入力してログを分析できます。

クエリ

  • 最新の認証ログ取得
SQL
fields @timestamp, @message
| sort by @timestamp desc
| limit 10
  • 認証成功(Access-Accept)と失敗(Access-Reject)の件数を集計
SQL
fields @timestamp, @message
| filter @message like /Login OK/ or @message like /error/
| stats count(*) as event_count by if(@message like /Login OK/, 'Login OK', 'Error') as event_type
| sort by event_type asc
  • 認証数の推移
SQL
fields @timestamp, @message
| filter @message like /Login OK/ or @message like /error/
| stats sum(if(@message like /Login OK/, 1, 0)) as LoginOK_Count, sum(if(@message like /error/, 1, 0)) as Error_Count by bin(1m) as interval
| sort by interval asc

ステップ9: CloudWatch Dashboardでの可視化

Logs Insightsのクエリ結果は、そのままダッシュボードのウィジェットとして追加できます。

  1. Logs Insightsで上記のクエリを実行した後、「アクション」>「ダッシュボードに追加」をクリックします。
  2. 「新しいダッシュボードを作成」を選び、ダッシュボード名(例: RADIUS-Monitoring)を入力します。
  3. ウィジェットの種類(折れ線グラフ、円グラフ、数値など)を選択し、「ダッシュボードに追加」をクリックします。

これを繰り返すことで、以下のようなウィジェットを持つダッシュボードを作成できます。
みなさんもお好きなメトリクスを収集して、オリジナルを作ってみてください!

image.png

おわりに

今回は AWS 環境で RADIUS サーバーを構築し、認証テストを行うまでの一連の流れを解説しました。
エラーがでそうなところは可能な限りフォローしましたが、こんなエラーがでる!等ありましたらご連絡ください~!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?