多数のアスタリスクを使用したIAXチャネルの管理

こんにちは



アスタリスクを少しでも管理している人は全員、いくつかのサーバーを相互に統合するタスクに直面しています。 プロトコルに関係なく、ほぼ同じアクションセットが存在するため、IAXまたはSIPのどちらのプロトコルを選択してもかまいません。 サーバーが片手で数えられる限り、これは問題ありません。 片方の手では十分ではなく、もう片方の指がすでに切れている場合は、この問題を解決するための1つの方法を確認するために、それを切り取ってください。



私は比較的小さな組織で働いていますが、この組織は非常に地理的に分散しており、多くの小さなオフィスがあり、それぞれテレフォニーが必要です。アスタリスクは各オフィスにインストールされ、すべてのサーバーが組み合わされて社内で電話をかけます。 新しいオフィスが開いたら、すべてのサーバーを構成し、追加の番号と新しいサーバーを通知する必要があります。 ある時点で、次のサーバーをセットアップするときに、それを自動化して日常的なアクションのほとんどを取り除くことができると考えました。 その結果、自動化する必要があるという結論に達しました。



  1. 新しいIAXチャネルの追加。
  2. 1つのIAXチャネルのパラメーターを変更する
  3. オフィスの番号変更
  4. 他のサーバーでの変更は不要


アスタリスクには、計画を実装するためのすべてがすでに用意されています。すべてのコンポーネントを構成して接続するだけです。 それで、私たちの計画を実行するには何が必要ですか:



  1. アスタリスク-アスタリスク13 LTS認定を使用しています
  2. リアルタイム-アスタリスクはpbx_realtimeモジュールで構築する必要があります
  3. Lua-アスタリスクでのみ使用(pbx_lua)
  4. Perl-Perlが自動化されていないが、他の言語に置き換えることができる場所
  5. PostgreSql-バージョン9.6を使用しています。 たぶん他のデータベース
  6. Bucardo-データベース複製に使用します。通常のデータベースツールがあるかもしれません


アルゴリズム



異なるソフトウェアのセットを使用する人のために、私は単にアルゴリズムを説明してから、上記のソフトウェアのセットでの実装に進みます。



ここには目立ったものは何もありません。アルゴリズムはスティックと同じくらい簡単です。 アスタリスクは、リアルタイム構成を使用するように構成されています。 新しいIAXチャネルに関する情報は、対応するデータベーステーブルに行を追加することにより追加されます。 スクリプトは特定の周期でサーバー上で実行され、データベース内の新しいIAXチャネルの存在をチェックし、検出されると、すべてのチャネルの登録を実行します。 内部番号に電話をかけると、この内部番号が属しているサーバーがチェックされ、対応するサーバーに電話が送信されます。 これがアルゴリズム全体です。詳細については、以下を参照してください。



準備する



アスタリスク 本格的で詳細なインストールを説明することは意味がありません;ネットワーク上でこれを正確かつ迅速に行う方法に関する記事が12以上あります。 問題を解決するために、どのモジュールをインストールする必要があるかのみを説明します。





これらのモジュールは、問題を解決するのに十分なはずです。もちろん、個人的に必要なすべてのモジュールを接続することを忘れないでください。 アスタリスクのビルドに必要なパッケージもインストールします。



yum install -y dmidecode ncurses-devel libxml2-devel openssl-devel newt-devel sqlite-devel libuuid-devel gtk2-devel jansson-devel binutils-devel curl-devel unixODBC unixODBC-devel spandsp-devel spandsp iksemel iksemel-devel libtool-ltdl libtool-ltdl-devel kernel-devel lua-devel perl-CPAN perl-DBD-Pg perl-DBI perl-App-cpanminus
      
      





コンパイラと関連するすべてのアプリケーションが必要になることを忘れないでください。通常、次のようにインストールします。



 yum groupinstall -y "development tools"
      
      





したがって、必要なものをすべて配置します。 その後、アスタリスクのインストールを続行できます。構成に進みます。



リアルタイム 。 まず、ODBCを構成する必要があります。これは、データベースから設定を取得するためにAsteriskによって使用されます。 実際、ここで修正する必要があるファイルはわずかです。



/etc/odbc.iniをこれに変換する必要があります。



 [asterisk] Description=PostgreSQL Driver=PostgreSQL Database=asrumoscow Servername=localhost Username=asterisk Password=password Port=5432 Protocol=7.4 Charset=utf8 ReadOnly=No RowVersioning=No ShowSystemTables=No ShowOidColumn=No Trace=No TraceFile=/var/log/asterisk/sql.log FakeOidIndex=No # Asterisk 13.8   Pooling=yes
      
      





特別な説明では、このファイルは必要ではなく、データベースへのアクセスの詳細のみを指定すると思います。



/etc/odbcinst.ini



 [PostgreSQL] Description = ODBC for PostgreSQL Driver64 = /usr/pgsql-9.6/lib/psqlodbc.so Setup64 = /usr/pgsql-9.6/lib/psqlodbcw.so FileUsage = 1
      
      





別のバージョンのPostgreSqlがある場合は、ライブラリパスを修正します。 これで、ODBCセットアップが完了しました。



アスタリスクに渡します。 彼が構成したODBCを使用してデータベース内の設定を探すには、/ etc / asterisk / res_odbc.confファイルにブロックを追加する必要があります。



 [realtime-odbc] enabled => yes dsn => asterisk ;     /etc/odbc.ini username => asterisk ;    password => password ;    pre-connect => yes
      
      





今では、アスタリスクにどのテーブルと何に使用できるかを伝える必要があります。 /etc/asterisk/extconfig.confファイルの設定セクションで、次の行を追加します。



 iax.conf => odbc,realtime-odbc,db_name_config ;    iax iaxusers => odbc,realtime-odbc,db_name_iax iaxpeers => odbc,realtime-odbc,db_name_iax sippeers => odbc,realtime-odbc,db_name_sip
      
      





db_name_ *-アスタリスクが機能するデータベース内の対応するテーブルに置き換えます

これをすべて受け入れるように、アスタリスクを再起動することを忘れないでください。 これで、実装に直接アクセスできます。



実装



まず、新しいIAXチャネルに関する情報をすべてのAsteriskサーバーに配信する方法を理解する必要があります。 すべてのサーバーがリアルタイムを使用していることを考慮して、データベースを使用します。 これを行うには、PostgreSqlで別のサーバーを構成します。 リアルタイムアスタリスクのテーブルに似たテーブルが存在するベースを作成しましょう。 これで、私のテーブルは次のようになります。



 CREATE TABLE public.iax_peers ( id serial NOT NULL, name character varying(40) COLLATE pg_catalog."default" NOT NULL, type type_values, username character varying(40) COLLATE pg_catalog."default", mailbox character varying(40) COLLATE pg_catalog."default", secret character varying(40) COLLATE pg_catalog."default", dbsecret character varying(40) COLLATE pg_catalog."default", context character varying(40) COLLATE pg_catalog."default", regcontext character varying(40) COLLATE pg_catalog."default", host character varying(40) COLLATE pg_catalog."default", ipaddr character varying(40) COLLATE pg_catalog."default", port integer, defaultip character varying(20) COLLATE pg_catalog."default", sourceaddress character varying(20) COLLATE pg_catalog."default", mask character varying(20) COLLATE pg_catalog."default", regexten character varying(40) COLLATE pg_catalog."default", regseconds integer, accountcode character varying(20) COLLATE pg_catalog."default", mohinterpret character varying(20) COLLATE pg_catalog."default", mohsuggest character varying(20) COLLATE pg_catalog."default", inkeys character varying(40) COLLATE pg_catalog."default", outkeys character varying(40) COLLATE pg_catalog."default", language character varying(10) COLLATE pg_catalog."default", callerid character varying(100) COLLATE pg_catalog."default", cid_number character varying(40) COLLATE pg_catalog."default", sendani yes_no_values, fullname character varying(40) COLLATE pg_catalog."default", trunk yes_no_values, auth character varying(20) COLLATE pg_catalog."default", maxauthreq integer, requirecalltoken iax_requirecalltoken_values, encryption iax_encryption_values, transfer iax_transfer_values, jitterbuffer yes_no_values, forcejitterbuffer yes_no_values, disallow character varying(200) COLLATE pg_catalog."default", allow character varying(200) COLLATE pg_catalog."default", deny character varying(200) COLLATE pg_catalog."default", permit character varying(200) COLLATE pg_catalog."default", codecpriority character varying(40) COLLATE pg_catalog."default", qualify character varying(10) COLLATE pg_catalog."default", qualifysmoothing yes_no_values, qualifyfreqok character varying(10) COLLATE pg_catalog."default", qualifyfreqnotok character varying(10) COLLATE pg_catalog."default", timezone character varying(20) COLLATE pg_catalog."default", adsi yes_no_values, amaflags character varying(20) COLLATE pg_catalog."default", setvar character varying(200) COLLATE pg_catalog."default", CONSTRAINT iax_peers_pkey PRIMARY KEY (id), CONSTRAINT iax_peers_name_key UNIQUE (name) ) WITH ( OIDS = FALSE ) TABLESPACE pg_default; ALTER TABLE public.iax_peers OWNER to asterisk;
      
      





テーブル構造は、すべてのサーバーで完全に同一でなければなりません。



ブカルド 。 次に、このテーブルのレプリケーションを構成します。 複製にはBucardoを使用しますが、このタスクでは十分すぎるほどです。 インストールについては説明しません。インストールされ、初期構成が作成されたと仮定します。 必要なテーブルのレプリケーションを設定するだけです。



複製に参加するデータベースの情報をBucardoに追加します。



すべてのデータのソースとなるローカルデータベースを追加する



 bucardo add database pbxMaster dbname=asterisk dbhost=127.0.0.1 dbuser=bucardo dbpass=Pa$$w0rD
      
      





リモートAsteriskサーバーのデータベースを追加します



 bucardo add database asRUmoscow dbname=asrumoscow dbhost=192.168.0.30 dbuser=bucardo dbpass=Pa$$w0rD
      
      





複製するテーブルを指定します。



 bucardo add table iax_peers --db=pbxMaster relgroup=iax_peer
      
      





データベース用のグループを作成します。



 bucardo add dbgroup asRealtime
      
      





データベースを新しいグループに追加し、その目的を示します。



データソースを指定します。



 bucardo add dbgroup asRealtime pbxMaster:source
      
      





次に、このデータの受信者を示します。



 bucardo add dbgroup asRealtime asRUmoscow:target
      
      





同期の対象と方法をお知らせします



 bucardo add sync asRealtimeSync relgroup=iax_peers dbs=asRealtime
      
      





当然、bucardoはテーブルを複製する必要があるすべてのサーバーについて知っている必要があり、3つ以上のそのようなサーバーも存在する必要があります。



asRUmoscowなど、特定の方法で各サーバーに名前を付けています。





アスタリスクのデータベースには同じ名前が付けられているため、スクリプトを簡素化できます。

ソーステーブルの名前と受信者テーブルの名前は常に異なるため、これについてBucardoに通知する必要があります。そのために、次のコマンドを実行します。



 bucardo add customname iax_peers asrumoscow_iax db=asRUmoscow
      
      





ここで、iax_peersテーブルのすべてのデータをasrumoscow_iaxテーブルに複製し、これがasRUmoscowデータベースにのみ適用されることを示しました。 Bucardoを再起動し、チャネル情報をiax_peersテーブルに追加することで複製を確認できます。これはすべてのサーバーに複製されます。



Perl 次に、サーバーに新しいIAXチャネルを登録させる必要があります。 ここではすべてが非常に簡単です。そのようなPerlスクリプトがあります 。 その本質はシンプルで、5分ごとにクラウンで実行され、データベースに接続し、hostname_configテーブルに登録行があるhostname_iaxテーブルに記録されているすべてのIAXチャネルをチェックします。 何かが足りない場合、スクリプトはそれを修正します。自分で登録するという考えはまあまあなので、ローカルサーバーのホスト名に一致する名前のIAXチャネルは自然に無視されます。



ルア 。 この段階で、チャネル情報が複製され、サーバー自体が互いに登録されていることがわかります。 コールルーティングの問題を解決するためにのみ残っています。通常の操作では、新しい内線が追加されて、次の内容の新しいサーバーへの呼び出しが行われます。



 exten => _19xx,1,noop(  ) exten => _19xx,1,dial(sip/${EXTEN},60,r) exten => _19xx,1,hangup()
      
      







サーバーが10台ある場合は、すべてのサーバーに上記のコードを追加する必要があります。 これは簡素化する必要があります。そのため、どこでどのように電話をかけるかを決定する一般的な拡張機能を1つだけ記述します。 これを行うには、このサーバーまたはそのサーバーがサービスを提供している番号に関する情報をsetvar列のIAXチャネルのテーブルに追加します。 たとえば、asRUmoscowの場合、IAXチャネルに関する基本情報は次のようになります。







ここでは、setvar列に、ユーザーがこのサーバーに番号をダイヤルしたかどうかを確認できる正規表現が表示されます。 これは、ユーザーがどこに電話をかけたいかを知るのに十分すぎるほどです。



このために、次のコードがあります。



 extensions = { office = { ["_xxxx"] = internal_sip; }; } --      function internal_sip(context, extension) local dialString = getStringDial(extension); app.Dial(dialString,60,'rTt'); end --        function isLocalPeer(extension) local query = string.format("SELECT setvar FROM %s WHERE name='%s'", hostname.."_iax",hostname); local res = assert(con:execute(query)); local regexp = res:fetch(); if (rex.find(extension, regexp)) then res:close(); return true; end res:close(); return false; end --     Dial     --     function asSystem.getStringDial(extension) local dial=nil; if (isLocalPeer(extension)) then dial = string.format("sip/%s",extension); else local query = string.format("SELECT secret FROM %s WHERE name='%s'",hostname.."_iax",hostname); local res = assert (con:execute(query)); local secret = res:fetch(); query = string.format("SELECT username,setvar FROM %s",hostname.."_iax"); res = assert (con:execute(query)); local server_list = res:fetch({},"a"); local server = nil; local findNum = extension; while server_list do if rex.find(findNum,server_list.setvar) then server = server_list.username; break; end server_list = res:fetch({},"a"); end dial = string.format("iax2/%s:%s@%s/%s",hostname,secret,server,extension); res:close(); end return dial; end
      
      





このような複雑なコードにより、新しいサーバーが追加されるたびにアスタリスク構成ファイルを編集することがなくなります。



結果



今では、新しいサーバーを追加するために何もする必要はありません。 これを行うには、単純な一連のコマンドを実行します。



新しいデータベースに関する情報を複製システムに追加します。



 bucardo add database asRUsmolensk dbname=asrusmolensk dbhost=192.168.15.30 dbuser=bucardo dbpass=Me%gaP@$$ bucardo add dbgroup asRealtime asRUsmolensk:target bucardo add customname iax_peers asrusmolensk_iax db=asRUsmolensk
      
      





新しいIAXチャネルに関する情報をメインデータベースに追加します。



 INSERT INTO public.iax_peers(name, type, username, secret, context, host, trunk, auth, deny, permit, qualify,setvar) VALUES ('asRUsmolensk','friend','asRUsmolensk', 'IAX_PAS$w0Rd','office','dynamic','yes','md5','0.0.0.0/0.0.0.0','192.168.15.30/255.255.255','yes','^[16]6\d{2,2}'),
      
      





その後、5分間待つと、IAXチャネル自体がすべてのサーバー間で上昇し、すぐに新しいサーバーを呼び出すことができます。



これらの2つのアクションはAnsibleプレイブックでラップでき、一般的にすべてが美しくファッショナブルになります。



これにより、新しいサーバーをすばやく追加できるだけでなく、IAXチャネルのパラメーターを使用してルーティングを変更できます。 これは1年以上にわたって機能しており、現在ネットワークは25個のAsteriskサーバーに成長しており、これが制限であるかどうかはわかりません。



コメントや提案がある場合は、コメントまたはPMで歓迎します。



All Articles