ラベル DHCP の投稿を表示しています。 すべての投稿を表示
ラベル DHCP の投稿を表示しています。 すべての投稿を表示

2016/05/22

akatsuki 読み会をした

2016/05/15(Sun) に akatsuki 読み会を開催しました。

akatsuki とは私の所属する琉球大学情報工学科で運用しているユーザ用 Web コンソールです。
IP/VMの申請や作成といった学科のシステム運用に必要な様々な機能が入っている Rails Application です。
2015/09 辺りに学科サーバの更新があり、それに伴い学科新システムの一部として開発しました。
学科のユーザ向けの説明会の資料はこちら
特定の人々向けなのでかなり情報を省いています。
なお、この記事を書いている段階ではソースが学科内限定公開になっています。


読み会について

読み会を行なったのは主に後輩への引き継ぎのためです。
akatsuki の機能は学科向けの機能も多く、学科システムを把握しておかないとメンテナンスがつらいかなという懸念もあったので、各機能の実装箇所の概観を把握のために読み会を開催しました。
システム管理するメンバー向け資料はこちら。さらに情報が省かれています。


この記事について

読み会の補足用です。やっぱり特定の人用になっています。
実は akatsuki で使っているノウハウを切り出してこのブログにまとめていて、


勝手にFAQ

  • どうして名前が akatsuki なの?
    • システム管理チームのメンバーのイニシャルをまとめると作れたから。
    • 名付けの時にいた人達の趣味であるという説もある。一人前のレディ的な。
  • デザインは?
    • ちゃんと bootstrap 当ててるじゃないですか。
    • それはさておきデザイン担当の人がいたのでその人が当ててくれるかも。
  • LocalRecord ってなに? Localしか無くない?
    • 元は外向けのDNSも akatsuki で管理しようかという考えもあったので
    • GlobalRecord とか SakuraRecord とか作るつもりだった名残です。
  • さくらクラウドの管理は?
    • fog-sakuracloud とかあるのでその辺でどうにかなるかも

まとめ

ということで特定の人達向けの資料を充実させるための記事でした。

2015/12/23

FreeRADIUS を使って複数のインターフェースで DHCP サーバを動かす

FreeRADIUS を使って DHCP サーバを提供している時に複数の interface を使って DHCP を提供する必要があったのでその方法とか。

前回の記事にも書いたのですが、FreeRADIUS で DHCPサービスを提供する場合は
/etc/raddb/sites-available にあるサービスを /etc/raddb/sites-enabled にリンクを貼ることで有効化する様子。

ということでまずは /etc/raddb/sites-available にある dhcp をコピーして listen する interface を変更。
そのリンクを /etc/raddb/sites-enabled に貼ると複数のインターフェースにも対応できます。

例えば /etc/raddb/sites-available/dhcp.private と /etc/raddb/sites-available/dhcp.global みたいな感じ。


これで個別の interface ごとに違う設定を適用した複数の DHCP サーバを提供することできます。

2015/11/18

FreeRADIUS 3.0.4 で DHCP サーバを立てる時に気をつけること

FreeRADIUS 3.0.4 を使って DHCP を使っているとたまに SEGV することがあったのでその原因を探ってみたメモ。
なんとなーく高負荷時くらいに発生するようですが、負荷が低い時にも発生するので core dump を取ってきちんと追ってみました。


環境

  • OS : CentOS 7.1.1503
  • FreeRADIUS : 3.0.4


abrtd の設定

SEGV だけじゃ原因が分からないのでまずは coredump を取るように設定。
abrt なるものがあるらしいので使ってみる
  • # yum install -y abrt-cli
  • # vim /etc/security/limits.d/core.conf
    • *       hard        core        unlimited
    • *       soft        core        unlimited
    • くらいに設定。 core のファイルを作るように。
  • # vim /etc/sysctl.d/50-core.conf
    • kernel.core_uses_pid = 1
    • fs.suid_dumpable = 2
    • Storage = both
    • くらいで。
  • # vim /etc/sytemd/system.conf
    • DumpCore を yes,  DefaultLimitCORE を unlimited に
  • # systemctl enable abrtd
  • # reboot

これで core が取れるようになった。
coredump の場所は abrt が設定するようで /var/spool/abrt/ くらい。


coredump から原因を追う

  • # gdb /var/spool/abrt/ccpp-2015-11-04-09\:39\:18-2478/coredump
    • すると debuginfo が無いので入れろと言ってくる
  • # yum --enablerepo='*debug*' install /usr/lib/debug/.build-id/9c/9089cc84962eae11b31e65e92af30874f83b2c
    • 言われた通りに打つと入る。便利。
どうやら
  • #0  fr_packet_cmp (a=0x7f068be885a0, b=0xcb6b5c9a1101f601) at src/lib/packet.c:45
とかで SEGV している様子。

back trace は

  • #0  fr_packet_cmp (a=0x7f068be885a0, b=0xcb6b5c9a1101f601) at src/lib/packet.c:45
  • #1  0x00007f06894c9eea in rbtree_find (tree=0x7f068bed05a0, data=data@entry=0x7fff68b1cdb8) at src/lib/rbtree.c:517
  • #2  0x00007f06894d0f8f in fr_packet_list_yank (pl=0x7f068bed0fc0, request=0x7f068be885a0) at src/lib/packet.c:559
  • #3  0x00007f0689b5e1ff in request_done (request=request@entry=0x7f068be3d070, action=action@entry=2) at src/main/process.c:636
  • #4  0x00007f0689b5e6ad in request_process_timer (request=0x7f068be3d070) at src/main/process.c:908
  • #5  0x00007f0689b624bd in request_common (request=request@entry=0x7f068be3d070, action=<optimized out>) at src/main/process.c:1122
  • #6  0x00007f0689b632a5 in request_cleanup_delay (request=0x7f068be3d070, action=<optimized out>) at src/main/process.c:1176
  • #7  0x00007f06894d1a1f in fr_event_run (el=el@entry=0x7f068bbb4f00, when=when@entry=0x7fff68b1d040) at src/lib/event.c:260
  • #8  0x00007f06894d1fd9 in fr_event_loop (el=0x7f068bbb4f00) at src/lib/event.c:482
  • #9  0x00007f0689b63d61 in radius_event_process () at src/main/process.c:4983
  • #10 0x00007f0689b42758 in main (argc=3, argv=<optimized out>) at src/main/radiusd.c:584

とか。

request の管理は rbtree でやっていて、その rbtree で find や insert する時の比較ルーチンで落ちてるみたいです。
他の dump もいくつか見るとやっぱり rbtree 周り。
request_done すると request_hash から外す時に rbtree_insert とかするっぽいですね。
コードを読んでいくと nodup なるものが true ならそのルーチンは呼ばれないみたいです

git grep nodup すると読んだ時の最新の 3.0.9 では DHCP は default で nodup が true の様子
そして CentOS7 の yum で入る 3.0.4 では nodup は true では無いみたいです。

ということで
/etc/raddb/sites-enabled/dhcp
performance { skip_duplicate_checks = yes }
を追加しておしまい。しばらく運用しても SEGV することはなくなりました。


再現してみる

とりあえず運用している radiusd は落ちなくなったのですが原因が本当にコレかチェックしてみます。


再現環境

  • OS : OSX Yosemite 10.10.5
  • Docker : 1.9
  • docker-machine : 0.5.0
  • Virtualbox : 5.0.10 r104061


再現方法

前回作った FreeRADIUS のサーバで試してみます。
Docker で container を上げると '02:42:ac:11:00:??' の mac address が自動生成されるようなのでそれに対して適当にダミーのデータを投入します
  • 256.times{|n| IpAddress.create!(address:n, mac_address: format('02:42:ac:11:00:%02x', n))}
この状態で dhclient だけが入っている container を100個くらい起動。
そうすると SEGV しました。数度再現するのでこれが原因っぽいです。
そして nodup を設定してまた負荷をかけてみます。
今度は SEGV しません。原因はやっぱりこれのようですね。


まとめ

FreeRADIUS 3.0.4 で DHCP サーバを上げる場合は nodup の設定をしておきましょう。
CentOS 7 の yum で入る FreeRADIUS は 3.0.4 です。
また、FreeRADIUS 3.0.8 ではデフォルトで有効なようなので、この設定はしばらくすると必要無くなります。


参考URL

2015/10/19

FreeRADIUS を使って DHCP サーバを立てて Rails から管理してみる

デバイスごとに静的なIPを振ってそれをDHCPで配ろう、ということに。
デバイスは多々ありそうなので静的IPの登録を Rails 経由でやってみる。
FreeRADIUS を使うと DHCP の静的IPの設定を DB 側に保存できるらしいので使ってみた。

ということでサンプル的なアプリケーションを書いてみた。(https://github.com/atton-/freeradius_dhcp_with_rails)
IP の最後のオクテットと、デバイスの MacAddress を入力すると、DHCP サーバから IP を取得できます。


環境

  • OSX Yosemite 10.10.5
  • Ruby 2.2.3
  • Rails 4.2.4
  • Docker 1.8.1
  • FreeRADIUS 3.0.4
  • PostgreSQL 9.4.5


使いかた

まず Docker で PostgreSQL と FreeRADIUS 用のコンテナを起動。
FreeRADIUS 用のコンテナに直接入って、起動しているコンテナの情報に合わせて /etc/raddb/sites-enabled/dhcp.relay を書き換えてから radiusd を起動。
Rails 側でクライアントとなるデバイスの Mac Address と IP を登録。
そうすると DHCP で特定の Mac Address 宛に Static な IP が振られます。


解説とか

まず DHCP の設定は このページを参考に FreeRADIUS の設定。
基本的な設定はデフォルトのままでもOKです。
ちょっと問題なのが mods-config/sql/main/postgresql/queries.conf の設定。
元々のサンプルは /etc/raddb/mods-config/sql/main/postgresql/setup.sql や /etc/raddb/mods-config/sql/main/postgresql/schema.sql を利用しているのですが、これで使っている attribute という column name が ActiveRecord 的にアウト。
なので適当に名前を変えます。

今回使うテーブルは radcheck と radreply 。こいつの構造を保ったまま名前を変えます。
元の schema は username, attribute, value, op の 4 column + id。
username が mac address に相当して, value, op, attribute は config の key, op, value に対応してるっぽいです。
例えば attribute = 'DHCP-Your-Address', op = '=', value = '192.168.100.1' とか。
元は DHCP-Your-Address = 192.168.100.1 みたいに書いてたんだろうなー、とか想像したり。なのでいろんな情報とか突っこめそう。
それはさておき column の name を以下に変更。 op と value は変更無し。
  • username => mac_address
  • attribute => radius_attribute
対応するように queries.conf の query を書き換えます
あとは Rails 側で radcheck 相当のモデル radius_check_information を作って、  mods-available/sql で参照している radcheck を radius_check_informations に変更
同じように radreply もやってしまいます。
これで DHCP の Static IP の情報を DB に突っこむのはできました。

あとは rails 側でよしなにフォーマットに合うようにレコードを追加してあげたらOK。


引っかかったところ

Docker 側で dhcp とかを扱おうとすると arp table とかをいじろうとしてコケることが。
その場合は docker run する時に --privileged してやると良いみたいです。
あと Docker だと FreeRADIUS の実行ユーザとグループを root にしておかないと dhcp の返事ができないっぽいです。


具体的なコマンドとか

Docker で起動時の IP を使って FreeRADIUS の設定とかをしなかったので、ある程度手動で設定する必要があります。
なので具体的なコマンドとかを載せておこうと思います。

  • $ git clone https://github.com/atton-/freeradius_dhcp_with_rails
  • $ cd freeradius_dhcp_with_rails
  • $ docker build -t pg94 docker/postgres
  • $ docker run -itd --name postgres-server -p 5432:5432 -e POSTGRES_PASSWORD=hogehoge pg94
  • $ docker build -t freeradius_with_rails/freeradius-dhcp docker/freeradius-dhcp
  • $ docker run --privileged --link postgres-server:postgres-server --name dhcp-server -it freeradius_with_rails/freeradius-dhcp
    • これで bash が起動します。
    • ip a してその IP Address を確認。 (ex: 172.17.0.50)
    •  ip r してクライアントの Router を確認 (ex: 172.17.42.1)
      • 今回はクライアントも Docker で上げてみます。
      • なので Router は Docker Private Network の gateway です
    • /etc/raddb/sites-enabled/dhcp.relay を編集
      • DHCP-Domain-Name-Server に DNS を設定します (ex: 8.8.8.8)
      • DHCP-DHCP-Server-Identifier に DHCP サーバの IP を設定します (ex: 172.17.0.50)
      • DHCP-Router-Address に DHCP クライアントのゲートウェイのIP を設定します (ex: 172.17.42.1)
      • DHCP-Subnet-Mask に DHCP クライアントのネットワークのサブネットマスクを設定します (ex: 255.255.0.0)
    • radiusd -X
      • で FreeRADIUS を起動します
  • $ docker run --privileged -it centos bash
    • DHCP クライアント相当の Docker container です
    • $ yum install -y dhclient
    • $ ip addr
      • とかして mac address を確認します (ex: 02:42:ac:11:00:37)
  • $ rake db:create db:migrate
  • $ rails server
    • mac address と IP の値を入れます。 (ex: 02:42:ac:11:00:37, 100)
      • 今回は 172.17.0.0/16 のIPを振ります。
  • $ dhclient -d
    • docker run --privileged -it centos bash のコンテナで実行します
    • 172.17.0.100 が振られます。やったね。

まとめ

これでデバイスごとに静的IPを触れるDHCPサーバを Rails で管理できました。
前の記事にも書いた KVM を Ruby から触る機能登録したIPに対応するDNSとかと連携すると、IPを申請したら静的にIPが振られてドメインが登録されたり、VMを template から clone してそのIPとドメインが自動申請されるようなシステムが作れます。やったね。


参考