□FreeRADIUSでSQLベースでの同時接続制限(Simultaneous-Use := 1)
前の投稿を参照すること!!
FreeRADIUSでSQLベースでの同時接続制限(Simultaneous-Use := 1)をしようとしたら、どうしてもうまくいかない。
手順としては
・MySQL(MariaDB)のインストール
・FreeRADIUS用のDBの設定
・FreeRADIUS用のDBにテーブルの設定
・FreeRADIUSのsqlモジュールを有効化&設定
なのだが、
/etc/raddb/sites-enabled/default
/etc/raddb/sites-enabled/inner-tunnel
などでsqlだけにすれば同時接続制限ができる…と言いたいところだが、これだと問題が発生する。
Alan DeKokも「Because it’s fail-safe.」と言っているように、何らかの理由でFreeRADIUSに切断情報(Acct-Status-Type = Stop)が来ない時があるからなのだが、まぁそういう時には既存の接続中という情報をradzapで削除すればいいんだけど、sqlだけにするとradzapが使えなくなる。
なぜかというと、sqlだけにするとradutmpが出力されないのでradwhoが使えない。
でもって、radzapは単なるシェルスクリプトで、中では
radwho -ZR $RADDB $NAS_IP_ADDR $NAS_PORT $USER_NAME | radclient $DEBUG $RADDB -f - $SERVER acct $SECRET
こんなコマンドを発行しているだけ。
何をしているかというと、radwho -ZR USER-IDで、
-------------------------------- User-Name = "USER-ID" Acct-Session-Id = "11111111" Acct-Status-Type = Stop NAS-IP-Address = 127.0.0.1 NAS-Port = 1 Service-type = Login-User Framed-IP-Address = 1.1.1.1 Acct-Session-Time = 23 Calling-Station-Id = "1111111111" --------------------------------
のような出力を得たら、それをそのままradclientを使ってFreeRADIUSに投げているだけなのだが、sqlだけを有効にするとradwhoがそもそも情報を取得できない(こいつはSQLを見ていない)ので、radzapもできない、というわけ。
じゃあ、というわけでradutmpとsqlと併用すればいいのだけれど、rlm_sqlにさらなる問題がある。
実は上記のセッション情報は、
cat > /test_login
-------------------------------- Acct-Status-Type = Start Acct-Session-Id = 1111111111 User-Name = USER-ID NAS-Port = 1 Framed-IP-Address = 1.1.1.1 Caller-Id = 1111111111 --------------------------------
radclient -x -f ./test_login localhost acct gotorun
で接続中にした情報だが、「Acct-Session-Id」に注目してもらいたい。
そう…こちら(つまりNAS)はセッションIDとして10文字をFreeRADIUSに投げたのに、radwhoで取得したセッションIDは8文字しかない。
もしかしてRFC?とか思って調べたけど、もちろん8文字までなんて言う制限はない。
(4文字以上にしろ、とはある)
しかも、FreeRADIUSのサイトでも
http://freeradius.org/rfc/acct_session_id_uniqueness.html
ここに書いてあるけど…8文字から64文字までにしろ、でないと動作が怪しくなるかもしれない、って…
で結論から言うと、勝手にセッションIDを短くしているのは
radwho
だった。ソースを見ると、
/usr/src/freeradius-server-3.0.4/src/main/radwho.c
-------------------------------- : int main(int argc, char **argv) { CONF_SECTION *maincs, *cs; FILE *fp; struct radutmp rt; char othername[256]; char nasname[1024]; char session_id[sizeof(rt.session_id)+1]; : --------------------------------
ふむ…で、この「rt.session_id」(つまり「struct radutmp rt」)は?というと
/usr/src/freeradius-server-3.0.4/src/include/radutmp.h
-------------------------------- struct radutmp { char login[32]; /* Loginname */ /* FIXME: extend to 48 or 64 bytes */ unsigned int nas_port; /* Port on the terminal server (32 bits). */ char session_id[8]; /* Radius session ID (first 8 bytes at least)*/ /* FIXME: extend to 16 or 32 bytes */ unsigned int nas_address; /* IP of portmaster. */ unsigned int framed_address; /* SLIP/PPP address or login-host. */ int proto; /* Protocol. */ time_t time; /* Time entry was last updated. */ time_t delay; /* Delay time of request */ int type; /* Type of entry (login/logout) */ char porttype; /* Porttype (I=ISDN A=Async T=Async-ISDN */ char res1,res2,res3; /* Fills up to one int */ char caller_id[16]; /* Calling-Station-ID */ char reserved[12]; /* 3 ints reserved */ }; --------------------------------
セッションIDを8文字に制限しているのは、お・ま・え・か・!!
…( ゚д゚)ハッ!
ここで賢明な人は気が付いただろう…つまるところFreeRADIUSでは
『FIXME』なところは各自変更した方がいいかもよ?
ということ。つまり、パッケージを落としてきてそのまま希望通りに動いたらラッキーなわけで、実際にはバイナリを作り直さないといけない、という話だ。
すでに同時接続制限での件もあるし、NASによってはセッションIDが8文字より大きい場合もあるだろう。
やれやれ…┐(´д`)┌ヤレヤレ
※自分はsrc.rpmをゴニョりますけどね。