概要
ある装置を利用する際、必要な権限が付与されているか確認するために認証が行われる。一台だったら、あるいは数台ならそこまで大きな問題にはならない。でも、それが数十台の機器で、何人ものユーザがいて、しかもそのユーザが頻繁に入れ替わるのなら? 一台ごとに設定することは現実的でなくなる。共通パスワードにすることでメンテナンス問題は回避できるが、「誰が触ったかわからない」「流出してもすぐに対応できない」といった問題が残る。
というわけで認証をまとめて行う認証サーバの需要が発生する。
認証方式
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-enabled
へSQL
モジュールを登録する必要がある。
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が決まってくれているのなら、色々と楽かもしれない。server
やcommunity
は調査中。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監視はできるだけ避けたい。