1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PostgreSQL をバックエンドとした FreeRADIUS を構築する

Last updated at Posted at 2021-04-04

概要

ある装置を利用する際、必要な権限が付与されているか確認するために認証が行われる。一台だったら、あるいは数台ならそこまで大きな問題にはならない。でも、それが数十台の機器で、何人ものユーザがいて、しかもそのユーザが頻繁に入れ替わるのなら? 一台ごとに設定することは現実的でなくなる。共通パスワードにすることでメンテナンス問題は回避できるが、「誰が触ったかわからない」「流出してもすぐに対応できない」といった問題が残る。

というわけで認証をまとめて行う認証サーバの需要が発生する。

認証方式

Network 機器の認証方式としては

  • RADIUS
  • TACACS+
  • LDAP
  • Diameter

をよく見かける。この資料では、RADIUS の Open Source 実装である FreeRADIUSを使用した構築を行う。

認証以外にも認可を精密に制御するとなると、TACACS+が候補に挙がる。Open Source 実装としては tac_plus があるが、2015年1月を最後に更新が止まっており、Ubuntu では 18.04から、CentOS でも 7からはそれぞれのパッケージ管理システムから外されている。いくらOSSとはいえ、メンテナンスが止まっている実装は使いたくない。そもそも自分でビルドして行うことになる。プロプライエタリの実装として Cisco も出していたが、そっちも販売が終わっている。

Diameter は 3GPP な世界でよく使われている。追加属性を容易に定義できるので、RADIUSよりも使い勝手が良いらしい。ただ、ピュアな Network 機器としてはあまり見かけない。OSS 実装として FreeDiameter があるが、CentOS系がターゲットとして開発されており、Ubuntu だとビルドが困難な印象。私が以前試した限りではビルドできなかった。
LDAP はもともとサーバ系で使われていたが、近年 Network機器でも対応されるようになってきた。つまり、古い奴だと対応していない。

構築

前提となる環境

主なソフト Version 備考
Ubuntu 20.04 検証時最新安定版
FreeRADIUS 3.0.20 aptから入手
PostgreSQL 12.6 aptから入手

PostgreSQL は Optional であり、FreeRADIUS単体で動作する。この場合、ユーザアカウントはconfファイルに書いていくことになるが、ユーザ数が増えると管理が煩雑になる。それを見越して Database と連携させた。

FreeRADIUS の設定は基本的にコマンドラインで頑張ることになるが、GUIをサポートさせた拡張パッケージ、daloRADIUS も存在する。これを利用するには Database 連携が必須となる。daloRADIUS, FreeRADIUS で使用する Database で対応しているものは事実上 MySQL のみ。公式サイトには PostgreSQL も含まれていた。有償サポートで捻じ込めば対応してもらえるのかもだが、かなりハードルは高そう。

パッケージのインストール

全て APTから落とせる。野良ファイルは不要。

sudo apt install freeradius freeradius-utils freeradius-postgresql 
sudo apt install postgresql

モジュールの有効化

PostgreSQLに限らず、DBと連携させる際はmods-enabledSQLモジュールを登録する必要がある。

sudo ln -s ../mods-available/sql /etc/freeradius/3.0/mods-enabled/sql

PostgreSQLの用意

FreeRADIUS用アカウント & DB作成

sudo -u postgres createuser radius --createdb --pwprompt

ここでは新しいユーザとしてradiusを作成。FreeRADIUSからのアクセス用としてパスワードも合わせて設定。

createdb -U radius radius
sudo cp /etc/freeradius/3.0/mods-config/sql/main/postgresql/schema.sql .
sudo chown 自アカウント ./schema.sql
psql radius -u radius < ./schema.sql

FreeRADIUSで必要となるスキーマファイルはすでに用意されている。ただ、アクセス権の都合で直接は流し込み出来ない。そのため、schema.sqlを自分の操作できるディレクトリにコピーし、適切な権限を与えた上で流し込みを実施する。
ただ、このあたりの設定はPostgreSQLのセキュリティの壁に阻まれて結構面倒くさい。実際にはpostgres権限でschema.sqlを流し込み、ALTER TABLEでradiusユーザにオーナ変更した。あるべき姿が分かったら別途更新。

RADIUS の Config修正

sites-available/default と inner-tunnel

コメントアウト(# SQL)や-されたところ(-SQL)をすべて有効化(SQL)に変更する。これを有効にすることで、mods-enabledにシンボリックリンクを張ったSQLモジュールが参照されるようになる。

sudo vi /etc/freeradius/3.0/sites-available/default
sudo vi /etc/freeradius/3.0/sites-available/inner-tunnel

mods-available/sql

実際、どこのPostgreSQLと接続するかを設定する。

sudo vi /etc/freeradius/3.0/mods-available/sql
変数 設定値 備考
dialect postgresql
driver rlm_sql_postgresql
server localhost
port 5432
login radius
password radpass
radius_db radius
read_clients yes
client_table nas

driverの設定値サンプルがConfig内にいくつかあった。postgresqlはサンプルになかったが、設定できた。

動作テスト

デバッグモードでの実行

sudo systemctl stop freeradius
sudo freeradius -X
(snip)
Ready to process requests ← これがでれば成功

freeradius -Xはデバッグモードでの実行。UbuntuではFreeRADIUSが自動起動されているため、明示的に止めてあげる。Ready to process requestsが出ていれば正しく動作している。

sudo systemctl restart freeradius

デバッグモードをCtrl+Cで一度停止し、再実行。

サンプルアカウントの登録

psql -U radius radius
radius=# \dt
             List of relations
 Schema |     Name      | Type  |  Owner
--------+---------------+-------+----------
 public | nas           | table | radius
 public | radacct       | table | radius
 public | radcheck      | table | radius
 public | radgroupcheck | table | radius
 public | radgroupreply | table | radius
 public | radpostauth   | table | radius
 public | radreply      | table | radius
 public | radusergroup  | table | radius
(8 rows)

radius=# \d radcheck
                                    Table "public.radcheck"
  Column   |         Type         | Collation | Nullable |               Default
-----------+----------------------+-----------+----------+--------------------------------------
 id        | integer              |           | not null | nextval('radcheck_id_seq'::regclass)
 username  | text                 |           | not null | ''::text
 attribute | text                 |           | not null | ''::text
 op        | character varying(2) |           | not null | '=='::character varying
 value     | text                 |           | not null | ''::text
Indexes:
    "radcheck_pkey" PRIMARY KEY, btree (id)
    "radcheck_username" btree (username, attribute)

radius=# INSERT INTO radcheck VALUES (1, 'shakapon', 'Cleartext-Password', ':=', '12345');
INSERT 0 1
radius=# select * from radcheck;
 id | username |     attribute      | op | value
----+----------+--------------------+----+-------
    1 | shakapon | Cleartext-Password | := | 12345
(1 rows)

radius=# \q

認証テスト

sudo radtest shakapon 12345 localhost 10 testing123
Sent Access-Request Id 210 from 0.0.0.0:53286 to 127.0.0.1:1812 length 74
        User-Name = "shakapon"
        User-Password = "12345"
        NAS-IP-Address = 127.0.1.1
        NAS-Port = 10
        Message-Authenticator = 0x00
        Cleartext-Password = "12345"
Received Access-Accept Id 114 from 127.0.0.1:1812 to 127.0.0.1:46494 length 20

動作テストが終わったらCtrl+Cで止めた後、プロセスを再起動すること(startでも良いと思うけど、検証ではrestartとした)。

sudo systemctl restart freeradius

Database上に作られるTableの意味

MySQL/PostgreSQLとも、作られるテーブルに差分なし(多分)。インストール用のschema.sqlを見る限り差分なかった。

テーブル名 設定内容 備考
nas RADIUSクライアントを定義 NASアドレスとshared keyもここで定義
radacct アカウンティングログ 利用開始/終了の時間とか
radcheck 認証するユーザとパスワード 検証では平文を使用
radgroupcheck グループごとのradcheck 多分、NAS側から投げられたパケットの属性と思われる
radgroupreply リプライに設定する設定値をグループごとに設定
radpostauth 認証結果ログ
radreply リプライに設定する設定値をグループごとに設定
radusergroup ユーザとGroupを紐づけ 1ユーザを複数グループに紐づけられるかは未調査

NASテーブル

列名 タイプ 意味 サンプル
id integer ID 1
nasname text 接続元NASアドレス 192.168.1.0/24
shortname text NASアドレス名称 HOME-LAB
type text NASの種類 other
ports integer Port番号
secret text 共通鍵 Shakapon
server text 調査中
community text 調査中
description text デスクリプション

各列名の意味は/etc/freeradius/3.0/clients.confと共通。typeとかはデフォルトotherだが、ほかにもciscoとかjuniperとかが入る。ここでアドレスごとにVSAが決まってくれているのなら、色々と楽かもしれない。servercommunityは調査中。PPPoEとかの認証でも使えるため、より大規模な利用目的があるのかな?

他のテーブルは、見ればまぁなんとか。

Network機器からの認証

Network機器検証用追加データ入力

認証の検証を行うNetwork機器として今回はVyOSを採用した。ただし検証時点で下記をケアする必要がある。

If you want to have admin users to authenticate via RADIUS it is essential to sent the Cisco-AV-Pair shell:priv-lvl=15 attribute. Without the attribute you will only get regular, non privilegued, system users.
https://docs.vyos.io/en/latest/configuration/system/login.html?highlight=login

とのことで、VSAとしてCisco-AVPair=shell:priv-lvl=15を設定する必要がある。これをやらないとshow configurationすらできなかった。

この紐づけを行うにはradreplyテーブルか、radgroupreplyテーブルで属性を定義する必要がある。radreplyテーブルはユーザごと、radgroupreplyはグループごと。ラボなのでそう増えることもないが、将来を見越してradgroupreplyを使用する。

  • ユーザShakaponはグループHomeLABに所属する。
  • グループHomeLABは属性値Cisco-AVPair='shell:priv-lvl=15'を持つ。
    という感じ。Operatorとして:=とする必要があった。
INSERT INTO NAS(id, nasname, shortname,type,secret) values(1, '192.168.1.0/24', 'HomeLAB','other','Shakapon')
INSERT INTO radusergroup values(1, 'shakapon' ,'HomeLAB' ,0);
INSERT INTO radgroupreply values(1, 'HomeLAB', 'Cisco-AVPair',':=','shell:priv-lvl=15');

NASテーブルをいじっても即時反映はされない(多分)。FreeRADIUSの再起動が必要だった。

VyOSの設定

# 帯域外監視設定
set vrf name Mgmt
set vrf name Mgmt table 100
set interface ethernet eth0 address 192.168.1.249/24
set interface ethernet eth0 description "Out-Of-Band Management"
set interface ethernet eth0 vrf Mgmt
set protocols static route 0.0.0.0/0 next-hop 192.168.1.1 vrf Mgmt 

# 認証設定
set system login radius server 192.168.1.250 key Shakapon
set system login radius vrf Mgmt

気が付いたらVyOSで帯域外監視ができるようになっていた。せっかくなので使う。Inbound監視はできるだけ避けたい。

1
3
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
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?