AsteriskによるIP-PBXの構築(CentOS4.2編)

インストール・設定 − サービス

おやじは SuSE9.3 で Asterisk を動かしていますが、CentOS4.2でも動作確認はできましたので下記に示します。zaptel周り以外、Asteriskそのもののインストールや設定はSuSE9.3 と CentOS4.2 でも大きな差異はありません。テストしたのは、SuSE9.3 と同じ 1.2.0 です。
特徴としては、Asterisk は SIP サーバではなく IP-PBX という位置付けですので、単に電話をするだけではなく、転送やボイスメールなどの電話関連のサービス機能もあり実用も含めていろいろ遊べそうです。
なお、Asteriskは動的IP環境にも対応しているようなので、本情報で対応された方で動作確認ができたら情報提供をお願いします。

■Asteriskのインストール

Asteriskをインストールするには、 Asterisk からソースを落としてくる方法もありますが、今回は、最新のAsteriskをインストールするためCVSリポジトリを使用しました。
  1. Asteriskをインストールするには、以下のパッケージがインストールされていなければならないので、yum でインストールされているか確認し、インストールできていなければインストールしておくこと。

    No. パッケージ 備 考
    1 Linux 2.6 kernel-devel zaptel, libpri
    2 ncurses & ncurses-devel astman etc..
    3 zlib & zlib-devel   
    4 openssl & openssl-devel   

  2. 以降でAsteriskをインストールしていくが、Asteriskはデフォルトのままではrootで動作するので、non-rootのユーザ (今回はasterisk) で動作させるため今回はchroot対応をした。
    具体的には、pidファイルを置くディレクトリの変更とasterisk関連のディレクトリ・ファイルのアクセス権限の変更、起動スクリプトの対応である。この対応として、Asteriskを動かすasteriskグループとasteriskユーザを作成しておく。

    # groupadd asterisk
    # useradd -g asterisk -r -d /var/lib/asterisk -s /bin/false \
                 -c "Asterisk PBX" asterisk 2>/dev/null || :


  3. CVSサーバから最新版を落としてくる。おやじはStableバージョンをインストールした。

    # cd /usr/src
    # export CVSROOT=:pserver:anoncvs@cvs.digium.com:/usr/cvsroot
    # cvs login
    Logging in to :pserver:anoncvs@cvs.digium.com:2401/usr/cvsroot
    CVS password: anoncvs [Enter] <-パスワード:anoncvs
    cvs login: warning: failed to open /root/.cvspass for reading: No such file or directory
    # cvs init <-初回は上記エラーが出る場合は初期化する
    # cvs checkout zaptel libpri asterisk

    # cvs checkout -r v1-2-0 zaptel libpri asterisk <-Stableバージョンを使用する場合


    Asteriskのソースコード管理がSVNリポジトリに変更になったようです。しばらくはCVSも使えるようですが、早めに切り替えたほうがよいでしょう。
    リポリトジはいくつかあり、Asteriskの例は以下のとおりです。

    1. HEAD バージョン
      http://svn.digium.com/svn/asterisk/trunk (was CVS HEAD)
    2. ブランチの最新バージョン
      http://svn.digium.com/svn/asterisk/branches/1.2 (was CVS v1-2)
    3. バージョン指定
      http://svn.digium.com/svn/asterisk/tags/1.2.0 (was CVS v1-2-0)

    # cd /usr/src

    [HEADバージョン]
    # svn checkout http://svn.digium.com/svn/asterisk/trunk asterisk
    # svn checkout http://svn.digium.com/svn/zaptel/trunk zaptel
    # svn checkout http://svn.digium.com/svn/libpri/trunk libpri

    [バージョン指定]
    # svn checkout http://svn.digium.com/svn/asterisk/tags/1.2.1 asterisk
    # svn checkout http://svn.digium.com/svn/zaptel/tags/1.2.1 zaptel
    # svn checkout http://svn.digium.com/svn/libpri/tags/1.2.1 libpri


  4. zaptelをインストールする。ISDNカード等のVoIP用のハードを使用しないならzaptelのインストールは不要だが、電話会議(meetme)でクロックソースが必要なため、電話会議を使用するならzaptel ( ztdummy ) をインストールすること。
    まずは、ztdummyのみロードし不要なドライバをロードしないようにするパッチ(/etc/sysconfig/zaptelの変更)をあて、インストールする。
    なお、CentOS4.xはkernel2.6なので、make linux26とすること。インストールが済んだら、udev対策( install-udev )をしておく。
    ここではインストールまでで、電話会議(meetme)のところで具体的な起動設定を行う。
    Kernelのバージョンアップをしたら、zaptelを必ず再インストールすること。

    # wget http://www.aconus.com/~oyaji/centos/zaptel_co42.patch
    # patch -p0 < zaptel_co42.patch
    # cd zaptel
    # make clean
    # make linux26
    # make install
    # make install-udev


    [CentOS4.3でのmakeエラー]

    CentOS4.3では以下のようなエラーが出てmakeに失敗する。

    make -C /lib/modules/2.6.9-34.EL/build SUBDIRS=/usr/local/asterisk/zaptel XPPMOD= modules
    make[1]: Entering directory `/usr/src/kernels/2.6.9-34.EL-i686'
    CC [M] /usr/local/asterisk/zaptel/zaptel.o
    /usr/local/asterisk/zaptel/zaptel.c:384: error: 文法エラー が "zone_lock" の前にあります
    /usr/local/asterisk/zaptel/zaptel.c:384: 警告: `zone_lock' の宣言で型がデフォルトの `int' とされました
    /usr/local/asterisk/zaptel/zaptel.c:384: error: 初期化 に互換性のない型
    /usr/local/asterisk/zaptel/zaptel.c:384: error: 初期化子の要素が定数ではありません
    /usr/local/asterisk/zaptel/zaptel.c:384: 警告: データ定義が型や記憶クラスを持っていません
    /usr/local/asterisk/zaptel/zaptel.c:385: error: 文法エラー が "chan_lock" の前にあります
    /usr/local/asterisk/zaptel/zaptel.c:385: 警告: `chan_lock' の宣言で型がデフォルトの `int' とされました
    /usr/local/asterisk/zaptel/zaptel.c:385: error: 初期化 に互換性のない型
    /usr/local/asterisk/zaptel/zaptel.c:385: error: 初期化子の要素が定数ではありません
    /usr/local/asterisk/zaptel/zaptel.c:385: 警告: データ定義が型や記憶クラスを持っていません
    /usr/local/asterisk/zaptel/zaptel.c:188: 警告: 'fcstab' defined but not used
    make[2]: *** [/usr/local/asterisk/zaptel/zaptel.o] エラー 1
    make[1]: *** [_module_/usr/local/asterisk/zaptel] エラー 2
    make[1]: Leaving directory `/usr/src/kernels/2.6.9-34.EL-i686'
    make: *** [linux26] エラー 2


    これは、RedHatのkernelのバグなので、/usr/src/kernels/2.6.9-34.EL-i686/include/linux/spinlock.h の407行目を下記のように修正すればmakeできる。(赤字:追加)

    /*
    * Define the various spin_lock and rw_lock methods. Note we define these
    * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various
    * methods are defined as nops in the case they are not required.
    */
    #define spin_trylock(lock)      _spin_trylock(lock)
    #define write_trylock(lock)     _write_trylock(lock)

    #define DEFINE_SPINLOCK(x)      spinlock_t x = SPIN_LOCK_UNLOCKED
    // #define DEFINE_RWLOCK(x)     rw_lock_t x = RW_LOCK_UNLOCKED
    #define DEFINE_RWLOCK(x)        rwlock_t x = RW_LOCK_UNLOCKED

  5. ISDNのPRIインタフェースを搭載する場合、libpriをインストールする。その場合は、RPMで古いバージョンが入っている場合があるので削除してから作業する。

    # yum remove libpri
    # cd ../libpri
    # make clean ; make install


  6. 上記で示したように、今回はchrootで動作せるようにした。また、デフォルトのままだとボイスメール等のアナウンスが英語なので使いにくいが、こちらに日本語音声ファイルが用意されていたので利用させてもらった。感謝!!
    1.2.x用が公開されているのでそちらを利用する。wgetは非常に長いので画面上は複数行に見えるかもしれないので注意すること。
    以下でそれぞれのパッチをあてて、asteriskをインストールする。

    # cd ../
    # wget http://www.aconus.com/~oyaji/centos/chroot_co43.patch
    # patch -p0 < chroot_co43.patch
    # cd ./asterisk
    # wget -O say_2.c.diff \
     http://voip.gapj.net/index.php?plugin=attach\&refer=%B2%BB%C0%BC%A5%D1%A5%C3%A5%C1\&openfile=say_2.c.diff
    # patch < say_2.c.diff
    # cd apps
    # wget -O app_voicemail_2.c.diff \
     http://voip.gapj.net/index.php?plugin=attach\&refer=%B2%BB%C0%BC%A5%D1%A5%C3%A5%C1\&openfile=app_voicemail_2.c.diff
    # patch < app_voicemail_2.c.diff
    # cd ../
    # make clean ; make install


  7. 下記操作でサンプルのコンフィグファイルを作成する。/etc/asterisk配下にサンプルのコンフィグファイルが作成されるので、これをベースに変更していく。

    # make samples


  8. 続けて忘れないうちに日本語音声ファイルをインストールし、アクセス権限を変更しておく。

    # cd /var/lib/asterisk/sounds
    # wget -O asterisk-sound-jp-060317.tar.gz \
     http://voip.gapj.net/index.php?plugin=attach\&refer=%C6%FC%CB%DC%B8%EC%B2%BB%C0%BC%A5%D5%A5%A1%A5%A4%A5%EB\&openfile=asterisk-sound-jp-060317.tar.gz
    # tar zxfv asterisk-sound-jp-060317.tar.gz
    # chown -R asterisk:asterisk ./


  9. 自動起動できるように起動スクリプトをインストールする。

    # cd /usr/src/asterisk
    # make config
    # chkconfig --list asterisk
    asterisk    0:off  1:off  2:on  3:on   4:on   5:on   6:off


  10. ここで、asterisk を起動してみる。下記のようにudp:5060他が起動していればOK。起動スクリプトが "done" となっていても起動していないことがあるので、確認すること。

    # /etc/rc.d/init.d/asterisk start
    Starting Asterisk             done
    # netstat -an -udp
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address  Foreign Address  State  PID/Program name
    udp        0      0 0.0.0.0:2727   0.0.0.0:*               32085/asterisk
    udp        0      0 0.0.0.0:4520   0.0.0.0:*               32085/asterisk
    udp        0      0 0.0.0.0:5060   0.0.0.0:*               32085/asterisk
    udp        0      0 0.0.0.0:4569   0.0.0.0:*               32085/asterisk


  11. 起動が確認できたら、ここで「asterisk -vvvr」と入力してAsteriskのコンソールが起動できるか確認しておく。下記のような表示がでれば起動している。確認ができたら「quit」と入力してとりあえず終了する。

    # asterisk -vvvr
      == Parsing '/etc/asterisk/asterisk.conf': Found
      == Parsing '/etc/asterisk/extconfig.conf': Found
    Asterisk CVS-Nv1-2-0-11/23/05-12:58:21, Copyright (C) 1999 - 2005 Digium.
    Written by Mark Spencer <markster@digium.com>
    =========================================================================
    Connected to Asterisk CVS-Nv1-2-0-11/23/05-12:58:21 currently running on linux (pid = 32084)
    Verbosity was 0 and is now 3
    linux*CLI>
    quit [Enter]


    asteriskを起動スクリプトで起動すると、バックグラウンドで動作している。asteriskがバックグラウンドで動作している場合や、他のコンソールで既にasteriskを起動している場合には、"-r" スイッチを使用する。

    # asterisk -r

    これをフォアグラウンドで動かすには、"-c"スイッチを使用する。フォアグラウンドで動作させた場合は、"quit"コマンドで抜けるとasteriskも停止する。

    # asterisk -c

    なお、"-v"スイッチはvの数だけデバッグレベルが上がり詳細なログが出力されるので、テスト中は "-vvvr" や "-vvvc"ぐらいで起動すると動作状況がつかめ、テストしやくなる。

■Asteriskの設定

Asteriskはいろいろな機能があり、使いこなすにはかなり勉強が必要そうです。ここでは、おやじが確認した基本的な機能を動かすことを前提に設定していきます。なお、デフォルトのコンフィグは必ずバックアップしてから修正してください。

◆基本的な設定

ここでは、Asteriskを動かすための基本的な設定を行います。なお、コメントは「#」ではなく「;」なので注意してください。(#はダイヤルで使用するため・・・。 赤字:追加、緑字:変更、青字:削除)

  1. sip.confでサーバの基本的な設定を行う。

    [general]
    context=default
    bindport=5060
    bindaddr=0.0.0.0
    srvlookup=yes

    ;disallow=all
    ;allow=ulaw
    ;allow=alaw
    ;allow=gsm
    ;allow=ilbc

    musicclass=default

    ;language=en
    language=jp

    ; NAT
    externip = 200.201.202.203
    ;externhost=foo.dyndns.net
    ;externrefresh=10
    ;localnet=192.168.0.0/255.255.0.0


    下記内容を参考に設定する。

    1. context
      デフォルトのコンテキストを指定。基本的に変更不要。

    2. bindport
      SIP用のUDPのポートを指定。デフォルトの5060から変更すべきではない。

    3. bindaddr
      バインドするアドレスで、特段の理由がなければデフォルトの全てのアドレス( 0.0.0.0 )のままででよい。おやじの場合は、2つのドメインでサーバが2つのアドレスを持っているので、外部に公開するドメインのアドレス( 192.168.1.101 )をバインドした。

    4. srvlookup
      外部と通信する場合はDNSのSRVレコードを牽くように「yes」に設定する。この設定によりドメイン名でのアクセスが可能になるようだが、SRVレコードはほとんど普及していないのであまり意味はなく、実質はIPアドレスでの運用になる。

    5. disallow=all / allow=ulaw / allow=alaw / allow=gsm / allow=ilbc
      使用するコーデックを指定する。最初に「disallow=all」で全てのコーデックを使用不可にし、その後で許可するコーデックを指定する。国内はμlawなので上記の設定で問題ないはず。

    6. musicclass
      保留音のクラスを指定。デフォルトは「default」であり必要に応じて変更する。バージョン1.0.xでは、デフォルトのままでは「mpg123」をインストールしないと保有音は流せないが、1.2.0では設定変更により.gsmや.wavファイルを音源に流せるようになった。詳細は、保留音を参照のこと。

    7. language
      デフォルトの言語は英語。日本語対策済みならば「jp」に変更する。

    8. externip
      固定IPの場合、サーバがNAT配下にあるときにルータのWAN側のグローバルアドレスを指定。下記のexternhostでのホスト名指定でも運用できるが、固定IPの場合はDNSを牽くのは無駄な負荷になるだけなのでIP指定とすること。動的IPの場合は、下記のexternhostでホスト名指定でも運用できる。

    9. externhost / externrefresh
      動的IPの場合、externhostを使用すればでホスト名を指定できる。これにより、動的IPアドレス環境下でもDNSでルータのWAN側のグローバルアドレスを牽けるホスト名を指定することでIPアドレスが変化しても追従できるようになる。この場合、セットでexternrefreshでDNS検索する周期を秒単位で指定する。負荷になるのであまり短くしないこと。

    10. localnet
      デフォルトで、サーバと同じネットワークがローカルネットとして扱われるので家庭内なら一般的には設定は不要。ルータで他のローカルネットワークがつながっている場合は、ここで指定する。複数指定可。(以前のおやじのように、家庭内でもサーバとクライアントが異なるセグメントに存在するような場合は設定要。)

  2. rtp.confでRTPで使用するポート範囲を設定する。

    [general]
    rtpstart=10000
    rtpend=
    10009


    下記内容を参考に設定する。ここで指定したポート範囲は、前述のSIPのポート番号(5060)とともに、UDPをルータでサーバにポートマッピングするとともに、ファイヤウォールも開けなければならないので、忘れずに作業すること。ここで指定したポート範囲は、サーバがRTP中継(通話の中継)をする場合のポートのため、サーバ回線の帯域を1Callあたり15Kbps程度消費するので不用意に多く取るべきではない。

    1. rtpstart
      RTPで使用するポートの開始ポート番号を指定。

    2. rtpend
      RTPで使用するポートの終了ポート番号を指定。上記設定では10000 - 10009番までが使用される。

◆内線の登録

内線を使えるようにするには、内線の登録とダイヤルプランの設置が必要になります。内線そのものの登録は sip.conf で行い、ダイヤルプランは extensions.conf で行います。

  1. sip.conf で内線の基本的な登録を行う。下記内容を前記の sip.conf の設定に続けて設定を追加していく。 以下は、2000 - 2002 番までの内線を登録する例である。

    [2000]
    type=friend
    username=oyaji
    secret=password0
    canreinvite=no
    host=dynamic

    [2001]
    type=friend
    username=hoge1
    secret=password1
    canreinvite=no
    host=dynamic

    [2002]
    type=friend
    username=hoge1
    secret=password2
    canreinvite=no
    host=dynamic


    下記内容を参考に設定する。

    1. [2000]
      内線毎に [ ] で括って内線番号を指定。

    2. type
      typeには、"user"、"peer"、"friend"がある。
      ・user:発信専用モード。
      ・peer:着信専用モード。
      ・friend: 一般的な内線は本設定にする。発着信が可能。

    3. username
      登録ユーザ名を指定。

    4. secret
      ユーザパスワードを指定。

    5. canreinvite
      設定は "yes/no" である。本設定は、通話中にINVITE要求を送ってアドレスやポートを変更とする機能であり、RTPでの音声パケットを端末間で直接送受させる場合は"yes"とすること。"no"の場合はサーバがRTP中継することになり、常にサーバ負荷になるのと同時に両方の端末が仮にインターネット上にあった場合は、サーバ回線に2通話分の音声パケットのトラヒックが流れるので注意が必要である。
      なお、"yes"に設定しても一方が"no"の場合や、転送サービスとしてextensions.confで "t/T"オプションが指定してある場合は、サーバ中継になるので不用意にサービスを付与しないこと。

    6. host
      内線のホスト名かIPアドレスを指定する。 "dynamic" を指定するとホスト名やIPアドレスは無視されるので、モバイルアクセスや動的IP環境のクライアントは本設定とすること。

  2. 続けて、内線のダイヤルプランを extensions.conf で行う。ここでの設定が基本的な処理の流れを決めることになる。

    [default]
    exten => 2000,1,Dial(SIP/2000,30)
    exten => 2000,2,Congestion
    exten => 2000,102,Busy

    exten => 2001,1,Dial(SIP/2001,30)
    exten => 2001,2,Congestion
    exten => 2001,102,Busy

    exten => 2002,1,Dial(SIP/2002,30)
    exten => 2002,2,Congestion
    exten => 2002,102,Busy


    extensions.confの基本的なフォーマットは以下の通りである。

    exten => 内線番号,プライオリティ,アプリケーション[,arguments]

    [基本的な処理の流れ]

    処理の流れを上記設定をベースに以下に示す。

    1. プライオリティ"1"

      内線番号がダイヤルされると、ダイヤル番号にマッチしたプライオリティ"1"の設定が実行される。

      exten => 2000,1,Dial(SIP/2000,30)


      1. 2000
        対象とする内線番号を指定。

      2. 1
        プライオリティを指定であり、内線番号(2000)をダイヤルされた時に処理する優先度を示す。1は最初に実行する指定。内線が通話中の場合は、プライオリティn+101(1+101=102)にジャンプする。それ以外はプライオリティn+1(1+1=2)が実行される。

      3. Dial(SIP/2000,30)
        Dial()関数で内線の2000番(SIPの2000)を呼び出す指定。30は呼び出しタイムアウト時間(秒)で、タイムアウトしたらプライオリティn+1(1+1=2)が実行される。

    2. プライオリティ"2"

      呼出タイムアウトや内線がRegistされていない(電源断等)場合にプライオリティ"2"の設定が実行される。

      exten => 2000,2,Congestion


      1. 2000
        対象とする内線番号を指定。

      2. 2
        プライオリティを指定であり、呼出タイムアウトや内線がRegistされていない(電源断等)場合に実行される。

      3. Congestion
        Congestionを指定すると発信側の切断待ち状態になり、発信者に切断音が送出される。

    3. プライオリティ"102"

      対象内線が通話中の場合の場合、1項からプライオリティn+101(102)でジャンプしてきて実行される。

      exten => 2000,102,Busy


      1. 2000
        対象とする内線番号を指定。

      2. 102
        プライオリティを指定であり、対象内線が通話中の場合の場合、1項からプライオリティn+101(102)でジャンプしてきて実行される。

      3. Busy
        Busyを指定すると発信側の切断待ち状態になり、発信者にビジートーンが送出される。

    [ワイルドカードによるパターン指定方法]

    ダイヤルプランでは、上記のような設定を内線毎に設定していくが、一連の内線番号が同一の処理でよい場合は、設定にワイルドカードを使用できる。
    例えば、2000 - 2009までを上記と同じ処理をさせるなら下記の設定でもよい。

    exten => _200X,1,Dial(SIP/${EXTEN},30)
    exten => _200X,2,Congestion
    exten => _200X,102,Busy


    上記は、以下のような意味である。

    1. 内線番号が "_200X" のように  "_" で始まる場合は、パターン指定であることを示す。
    2. 内線番号の末尾は以下のような設定が使用できる。
       X : 0 - 9 の数字
       Z : 1 - 9 の数字
       N : 2 - 9 の数字
       [12679] : 1、2、6、7、9
        . : ワイルドカード
    3. ${EXTEN} は入力された内線番号が入る環境変数であり、"2000" とダイヤルされれば ${EXTEN} は "2000" となり、内線番号 "2000" が呼び出される。

◆DN(Ded Number) & DL(Ded Level)の設定

空き番号、空きレベルのための設定をextensions.conf で行う。本設定によりダイヤルした番号に該当する処理が無い場合は、「内線番号が間違っています。もう一度入力してください。」というガイダンス(pbx-invalid)が流れる。

[default]
; DN & DL
exten => _X,1,Answer()
exten => _X,2,Wait(1)
exten => _X,3,Playback(pbx-invalid)
exten => _X,4,Hangup
exten => _X.,1,Answer()
exten => _X.,2,Wait(1)
exten => _X.,3,Playback(pbx-invalid)
exten => _X.,4,Hangup

"_X" で1桁、"_X." で2桁以上の番号を指定している。なお、本設定は、それ以前の全てのダイヤルプランにマッチしなかったという条件で実行させるため、extensions.conf の最後に置くこと。
着信と同時に音声を発生させると、「話頭断(話初めが欠けること)」が発生することがあるので1秒waitさせている。

    インストール・設定 − サービス


    Topページへ