The GNU Gatekeeper

Maintainer of this manual: Jan Willamowius <jan@willamowius.de>

Version 3.6, May 2014


This User Manual explains how to compile, install, configure and monitor the GNU Gatekeeper (GnuGk).

1. Introduction

1.1 About

The GNU Gatekeeper is an open-source project that implements a H.323 gatekeeper. A gatekeeper provides call control services to H.323 endpoints and is an integral part of most telephony or video conferencing installations that are based on the H.323 standard.

According to the H.323 standard, a gatekeeper shall provide the following services:

The GNU Gatekeeper implements all of these functions and a number of additional features. For the protocol handling and encoding and decoding of the messages, it uses the H323Plus library (a continuation of the now defunct OpenH323 project).

H.323 is an international standard published by the ITU. It is a communications standard for audio, video, and data over the Internet. See also Paul Jones' A Primer on the H.323 Series Standard.

1.2 Copyright

The GNU Gatekeeper is covered by the GNU General Public License version 2 (GNU GPL v2). In addition, we explicitly grant the right to link this code to the OpenH323/H323Plus and OpenSSL library.

Some protocols implemented in the GNU Gatekeeper are covered by patents (especially the firewall / NAT traversal protocols). To the best of our knowledge, the GNU Gatekeeper Project has a valid license for all its releases, but users making derived versions of this code must ensure that they have a valid license before enabling those features.

Generally speaking, the GNU GPL allows you to copy, distribute, resell or modify the software, but it requires that all derived works must also be published under the GNU GPL. This means that you must publish full source for all extensions to the gatekeeper and for all programs where you incorporate code from the GNU Gatekeeper. See the file COPYING for details.

If that's not what you want, you must interface to the gatekeeper through the status port and communicate with it via TCP. This allows you to integrate basic functionality into the gatekeeper (and provide source for that) but keep other parts of your application private.

1.3 Name

The full name of this project is GNU Gatekeeper, but it may also be referred to as GnuGk. The use of "GNU" in the name is to emphasize that this is free software. Early versions were called the OpenH323 Gatekeeper.

1.4 Download

The newest version is available at the download page.

The very latest source code is in the CVS at Sourceforge Web-GUI. Beware - that's the bleeding edge.

You can also download executables for a number of operating systems from the download page.

1.5 Mailing Lists

There are two mailing list for the project, one for developers and one for users.

General user questions should be sent to the users mailing list. You can find the list archive here. To join this mailing list, click here.

To report problems or submit bugs/patches, send email to the developers mailing list. The list archive is here. Please send user questions to the users mailing list and keep this list for development! If you want to contribute to the project, please join the developers mailing list.

1.6 Contributors

The project founder and current maintainer is Jan Willamowius <jan@willamowius.de>

Over the years many people have contributed, most notable Simon Horne, Michal Zygmuntowicz and Chih-Wei Huang.

2. Compiling and Installing

2.1 Pre-requisites for Compiling

To build the gatekeeper you need PTLib and H323Plus. Please see http://www.gnugk.org/compiling-gnugk.html for up-to-date information on required library versions.

To successfully compile the GNU Gatekeeper you must first compile the pre-requisites in this order:

  1. PTLib
  2. H323Plus

On Unix, run configure and make debugnoshared or make optnoshared in the gatekeeper directory to build debug or release version, respectively.

NOTE: You must use either make debugnoshared or make optnoshared throughout the compile process. For example, if a library is compiled with make optnoshared then everything must be compiled the same way.

2.2 Installing on Unix

The first step is to get an executable: You can either download an executable for your flavour of Unix from gnugk.org, use the executable your distribution provides or compile the GNU Gatekeeper yourself. For simple installations or to try the features of the gatekeeper, using pre-built executables shouldn't pose any issues, but for professional installations it is always recommended that you self-compile GnuGk.

Installing a binary of GnuGk

Copy the executable to the directory you like and create a config file. There are several config examples and auto startup scripts in the etc/ subdirectory of the source tree. See section Configuration File for detailed explanations of the parameters.

For example you may copy GnuGk to /usr/sbin/, create a config in /etc/gatekeeper.ini and start it by

/usr/sbin/gnugk -c /etc/gatekeeper.ini -o /var/log/gnugk.log -ttt
See section Command Line Options for details on the command line options.

Compiling the Gatekeeper

NOTE: you must use GCC 3.3.x or later.

You are strongly encouraged to execute make debugdepend or make optdepend in the gatekeeper directory before starting actual compilation - these commands build appropriate dependency lists, so any CVS updates to the source code will force all affected files to get recompiled and will prevent the resulting binary from being compiled with a mix of old and updated headers.

Type

configure --help
to see a detailed list of all compile-time options. You can use them to enable or disable features of the gatekeeper. For example, if you do not need RADIUS just type:
configure --disable-radius

In order to use the gatekeeper under heavy load, enabling the LARGE_FDSET feature (only available on Unix) is recommended (configure --with-large-fdset=4096). Some systems also need to use ulimit in order to allow more than 1024 sockets to be allocated for a single process. Maximum LARGE_FDSET value for voice calls should be calculated based upon predicted maximum sockets usage using the following formula:

MAX_NUMBER_OF_CONCURRENT_CALLS * 10 * 120%

Where:
10 = 2 sockets for Q.931 + 2 sockets for H.245 + 6 sockets for RTP
So for 100 concurrent voice calls you don't need more than 1024 sockets in the LARGE_FDSET.

As a final step, you must either use make debugnoshared or make optnoshared, depending on how you compiled the libraries.

2.3 Installing on Windows

The first step is to obtain the executable program; you can either download it from gnugk.org or compile the GNU Gatekeeper yourself.

There are two versions of the gatekeeper available: A regular program and a service.

Installing as a Program

These are the steps for a manual installation:

Copy gnugk.exe to the folder you like and create a config file. There are several config examples in the etc/ subdirectory of the download archive. See section Configuration File for detailed explanations.

Then start the gatekeeper manually from the command line ('cmd.exe') or create a batch file to start it.

For example you may copy GnuGk to C:\GnuGk\, create a config in C:\GnuGk\gatekeeper.ini and start it as

C:\GnuGk\gnugk.exe -c C:\GnuGk\gatekeeper.ini -o C:\GnuGk\gnugk.log -ttt
See section Command Line Options for details on the command line options.

Remember to add GnuGk as an exception for the Windows Firewall so it can communicate freely with the network.

Installing as a Service

These are the steps for a manual installation; there may be a binary version of the Gatekeeper-as-service which includes a GUI installer program available in the download location.

First, ensure that you have the service version of GnuGk before you proceed.

Copy gnugk.exe to the folder you like and create a config file named gatekeeper.ini in the same folder. See section Configuration File for detailed explanations. When you run GnuGk as a service, no command line options are available.

To register the service, run the following command from the command line ('cmd.exe'):

gnugk.exe install

Your service is now installed and will be started on the next reboot, or you may start it manually using the Windows Control Panel -> Services function. On Windows Vista and Windows 7, you may have to disable UAC during the service installation.

When running GnuGk as a service, it will always look for a config file named gatekeeper.ini in the current directory. Any changes to the trace level and location of the trace file must be made in the config file rather than the command line.

Remember to add GnuGk as an exception for the Windows Firewall so it can communicate freely with the network.

Compiling the Gatekeeper

Once you have compiled the pre-requisites as specified at the beginning of this section and have the appropriate include/library paths configured, open and compile one of the provided solution files (.sln) for your version of Microsoft Visual Studio. If you need database support (MySQL, PostgreSQL, ODBC etc.), install/compile appropriate client libraries before you compile GnuGk.

2.4 The addpasswd utility

Status port authentication and many other authentication modules, like SimplePasswordAuth, require encrypted passwords to be stored in the gatekeeper configuration file. The gatekeeper also supports encryption of all passwords in the config. The addpasswd utility is required to generate and store these encrypted passwords. This utility is included with the gatekeeper and can be compiled using:

$ cd addpasswd
$ make optnoshared

The usage is as follows:

$ addpasswd CONFIG SECTION KEYNAME PASSWORD

Example 1: 'gkadmin' user with 'secret' password has to be added to the [GkStatus::Auth] config section to enable authentication on the status port:

$ addpasswd gatekeeper.ini GkStatus::Auth gkadmin secret

Example 2: 'joe' user with 'secret' password has to be added to the [Password] config section to enable endpoint authentication:

$ addpasswd gatekeeper.ini Password joe secret

Example 3: An encrypted shared secret is added to a RadAuth config section:

$ addpasswd gatekeeper.ini RadAuth SharedSecret VerySecretPassword

IMPORTANT: The KeyFilled variable defines a default initializer for password encryption keys. It can be omitted in the config (and therefore defaults to 0), but if it is specified, each time it changes, encrypted passwords have to be regenerated (encrypted again using the addpasswd utility).

3. Getting Started (Tutorial)

3.1 A simple first call

To confirm that all components are up and running, we will use two Linux workstations, both connected to the same LAN. In the examples, the H.323 client is a softphone called "SimpH323" which comes as a sample application with H323Plus in the samples/simple/ folder. If your Linux distribution doesn't include it, you can download the H323Plus source code and compile it yourself or you can use another H.323 endpoint.

On the first server start the gatekeeper in direct mode:

jan@server1> gnugk -ttt

The "-ttt" option tells the gatekeeper that it should be verbose and print extra debug output to the console. You can direct the output to a file with "-o logfilename.log"

Now, start SimpH323 on another console on the same system:

jan@server1> simph323 -l -a -u jan

SimpH323 is now listening (-l) for calls and will automatically accept them (-a). It has also registered with the gatekeeper as user "jan" thereby allowing the gatekeeper to creating an association between the user "jan" and their IP address.

SimpH323 will attempt to automatically locate the gatekeeper, but if the auto detection fails, use "-g 1.2.3.4" to specify the IP address.

On the second client run simph323 this way:

peter@client2> simph323 -u peter jan

This instance of SimpH323 registers with the auto-detected gatekeeper as user "peter" and tries to call user "jan". The gatekeeper will accept the request from "peter" and will determine if it can locate the IP address of a user name "jan".

Because "jan" has already registered with the gatekeeper, it will send "jan"s IP address to "peter". "peter"s SimpH323 will then use that IP address to setup a direct session to "jan"s SimpH323 running on server1.

The instance of SimpH323 on server1 will automatically accept the call and Peter and Jan can chat.

3.2 Using the Status interface to monitor the gatekeeper

The status interface presents a text-based means of interacting with an already-running gatekeeper.

On a new console we use telnet to connect to the gatekeeper:

jan@server1> telnet localhost 7000

You should receive an "Access forbidden!" message because by default, access to the status port is restricted.

Create a file called gatekeeper.ini in the directory where we start the gatekeeper. gatekeeper.ini will contain the following three lines:

[Gatekeeper::Main]
[GkStatus::Auth]
rule=allow

Stop the gatekeeper with Ctrl-C and restart it, but specify that it should use the gatekeeper.ini we just created:

jan@server1> gnugk -ttt -c ./gatekeeper.ini

Use telnet to connect to port 7000 and you should now be allowed to connect to the gatekeeper:

jan@server1>  telnet localhost 7000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Version:
Gatekeeper(GNU) Version(2.3.5) Ext(pthreads=1,radius=1,mysql=0,pgsql=0,firebird=0,odbc=0,sqlite=0,
large_fdset=0,crypto/ssl=0,h46018=1,h46023=1,ldap=0,ssh=0) H323Plus(1.22.2) PTLib(2.8.5)
Build(Jul 31 2011, 09:03:11) Sys(Linux x86_64 2.6.32-33-generic)
Startup: Sun, 31 Jul 2011 08:07:36 -0600   Running: 102 days 01:08:15
;

Now repeat the first experiment where Peter calls Jan and see which messages are handled by the gatekeeper in non-routed mode.

There are a number of commands that can be issued in the telnet session - type "help" to see them.

To end the telnet session with the gatekeeper type "quit" and hit Enter.

The example configuration file we created is very insecure because it has a default allow rule, so there are no restrictions on who can connect to the status port and which commands they may execute.

Change the configuration file to:

[Gatekeeper::Main]
[GkStatus::Auth]
rule=password
gkadmin=QC7VyAo5jEw=

The fourth line was added by the addpasswd utility, which was used to create a user "gkadmin" with password "secret". This change now enforces authentication to the status port.

Restart the gatekeeper with this new configuration and perform the telnet again. You should now be prompted for a username and password:

jan@server1>  telnet localhost 7000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

GnuGk login: gkadmin
Password: secret
Version:
Gatekeeper(GNU) Version(2.3.5) Ext(pthreads=1,radius=1,mysql=0,pgsql=0,firebird=0,odbc=0,sqlite=0,
large_fdset=0,crypto/ssl=0,h46018=1,h46023=1,ldap=0,ssh=0) H323Plus(1.22.2) PTLib(2.8.5)
Build(Jul 31 2011, 09:03:11) Sys(Linux x86_64 2.6.32-33-generic)
Startup: Sun, 31 Jul 2011 08:07:36 -0600   Running: 102 days 01:10:15
;

The [GkStatus::Auth] section contains additional information on securing the status port.

3.3 Running the gatekeeper in routed mode

Starting the gatekeeper in routed mode means that the gatekeeper uses "gatekeeper routed signaling". All signaling messages go through the gatekeeper, giving it much greater control over the calls.

Start GnuGk like this:

jan@server2> gnugk -r

will put the gatekeeper in routed mode. Telnet to the status port and make a call to see what messages are now handled by the gatekeeper.

Note that all media packets (audio and video) are still sent directly between the endpoints (the 2 instances of SimpH323).

3.4 A virtual PBX: Disconnecting calls

Until now the gatekeeper has acted only as a mechanism to resolve symbolic names to IP addresses. This is a critical function of a gatekeeper, but the gatekeeper is capable of much more.

Because the gatekeeper has a lot of control over the calls, it can also be used to terminate them. While connected to the status port, you can list all active calls with "PrintCurrentCalls". To terminate a call, type "Disconnectip 1.2.3.4" for one of the endpoints.

For example, a simple script could be written to connect to the status port, obtain a list of ongoing calls and terminate them after 5 minutes to prevent users from using too many system resources.

Other functions such as TransferCall are also available.

3.5 Routing calls to a gateway to reach external users

Without using a gateway you can only call other people with an IP phone over the Internet. To reach people with ordinary telephones you must use a gateway.

_________________          ______________
| endpoint "jan"|          |            |
| 192.168.88.35 |--------->| Gatekeeper |
|_______________|          |            |
_________________          |            |
| gateway "gw1" | outgoing |            |
| 192.168.88.37 |<---------|____________|
|_______________|

The gatekeeper must be configured to specify which calls should be routed to the gateway and which numbers can be called directly. Use the [RasSrv::GWPrefixes] section of the config file to tell the gatekeeper the prefix of numbers that should be routed to the gateway.

[RasSrv::GWPrefixes]
gw1=0

This entry tells the gatekeeper to route all calls to E.164 numbers starting with "0" to the gateway that has registered with the H.323 alias "gw1". If there is no registered gateway with that alias the call will fail.

NOTE: You must use the gateway alias - you cannot use the IP address of the gateway.

A prefix can contain digits 0-9, # and *. It can also contain a special character . (a dot) that matches any digit and can be prefixed with ! (an exclamation mark) to disable the prefix. Prefix matching is done according to the longest matching prefix rule, with ! rules having higher priority if lengths are equal. You may also use := syntax to set the priority between several gateways matching the same prefix (see section [RasSrv::GWPrefixes] for details). Some examples:

[RasSrv::GWPrefixes]
; This entry will route numbers starting with 0048 (but not with 004850 and 004860)
; to gw1
gw1=0048,!004850,!004860
; This entry will match only 001 with 10 digits following and route the call to
; gw2
gw2=001..........

3.6 Rewriting E.164 numbers

When using a gateway you often have to use different numbers internally and rewrite them before sending them over a gateway into the telephone network. You can use the [RasSrv::RewriteE164] section to configure that.

Example: You want to call number 12345 with your IP Phone and would like to reach number 08765 behind a gateway called "gw1".

[RasSrv::GWPrefixes]
gw1=0

[RasSrv::RewriteE164]
12345=08765

You can also configure rewriting of E.164 numbers based on which gateway you are receiving a call from or sending a call to using the [RasSrv::GWRewriteE164] section.

Example: You have two different gateways ("gw1" and "gw2") which you are sending calls with prefix 0044 to, but which require a different prefix to be added to the number after the routing has selected the gateway. This might be for identification purposes for example.

[RasSrv::GWPrefixes]
gw1=0044
gw2=0044

[RasSrv::GWRewriteE164]
gw1=out=0044=77770044
gw2=out=0044=88880044

Example: You want to identify calls from a particular gateway "gw1" with a specific prefix before passing these calls to another gateway "gw2".

[RasSrv::GWPrefixes]
gw2=1

[RasSrv::GWRewriteE164]
gw1=in=00=123400

Rewrite expressions accept dot '.' and percent sign '%' wildcard characters to allow building more general rules. The dot character can occur on both the left and right hand sides of expressions. The percent sign can occur only at the left side. Use '.' to match any character and copy it to the rewritten string and '%' to match any character and skip it. A few simple examples:

[RasSrv::RewriteE164]
; Rewrite 0044 + min. 7 digits to 44 + min. 7 digits
0044.......=44.......
; Rewrite numbers starting with 11 + 4 digits + 11  to 22 + 4 digits + 22
; (like 11333311 => 22333322, 110000112345 => 220000222345)
11....11=22....22
; strip the first four digits from all numbers (11114858345 => 4858345)
; this is equivalent of 10 rules %%%%1=1, %%%%2=2, ... 
%%%%.=.
; insert two zeros in the middle of the number (111148581234 => 11110048581234)
....48=....0048
; even this is possible (415161 => 041051061)
4.5.6=04.05.06

3.7 Using IPv6

To use IPv6 with GnuGk, you must enable it in the config file:

[Gatekeeper::Main]
EnableIPv6=1

Calls between IPv4 and IPv6 endpoints are automatically put into proxy-mode to allow GnuGk to perform address translation. If your endpoints can automatically handle mixed IPv4-IPv6 calls the auto-proxying can be disabled using the AutoProxyIPv4ToIPv6Calls switch in the [RoutedMode] section. As of 2011-11-10 there don't appear to be any endpoints which can do this.

To support IPv4 and IPv6 endpoints at the same time, GnuGk relies on the operating system to manage IPv4 mapped IPv6 addresses. With a few exception, most current operating systems support this.

Operating System Overview:

For Windows, you need at least Windows Vista, Windows Server 2008, Windows 7 or newer. On Windows XP GnuGk will run as a IPv6-only gatekeeper if you enable IPv6 support. OpenBSD doesn't support IPv4 mapped addresses at all (latest version tested: OpenBSD 5.0), so it can only run GnuGk as either an IPv4 or IPv6 gatekeeper.

As of December 2011, IPv6 support in endpoints is known to work with the following:

Known to not work:

3.8 Using servers with multiple IPs

By default GnuGk will listen to all IPs on a server and will automatically select the correct sending IP to reach an endpoint. There are a number of config switches to select which IPs to use specifically.

With Home= you can select the interfaces GnuGk should listen on. Usually you would select 1 or 2 interfaces on a machine with multiple IPs. Thats something every user might consider.

With Bind= you can select which IP to use for outgoing messages. This can be useful if your gatekeeper listens to many IPs, but it can also have some non-obvious consequences and this switch should be avoided by most users.

Another related switch is ExternalIP= which can be used to send different IPs inside of your messages than you are actually listening on. This can be usefull if you are doing port forwarding, but should also be avoided and you should use one of the firewall traversal protocols instead.

3.9 Enabling Audio and Video Encryption

You can configure GnuGk as an encryption proxy to ensure that more or all outgoing calls are encrypted, whether your endpoint support encryption themselves or not.

First, enable "half call media" which means GnuGk will add encryption if only one side of the call supports encryption. This will enable encryption for those of your endpoints that might not support encryption by themselves. You can also set if you want 128 or 256 bit AES. (Check "h235media=1" in the startup message to make sure your GnuGk has the encryption features enabled.)

[RoutedMode]
EnableH235HalfCallMedia=1
H235HalfCallMediaStrength=256

To make sure no call goes through without encryption, you can set

[RoutedMode]
RequireH235HalfCallMedia=1

When you have this switch on, calls without encryption will be aborted.

Finally, you can take precautions that its always the "outside" connection that gets encryption added. The GnuGk feature is "half call media" and you have to make sure its not only the internal half of the call that gets encrypted. Thus you can remove the encryption from all endpoint on your internal network and with the above settings GnuGk will add encryption to all outgoing calls.

[RoutedMode]
RemoveH235Call=192.168.1.0/24, 10.0.1.0/32

The next step after media encryption would be to add TLS (transport layer security) encryption to the signalling channel.

4. Basic Gatekeeper Configuration

The behavior of the gatekeeper is determined by the command line options and configuration file. Some command line options may override a setting from the configuration file. For example, the option -l overrides the setting TimeToLive in the configuration file.

4.1 Command Line Options

Almost every option has a short and a long format, e.g., -c is the same as --config.

Basic

-h --help

Show all available options and quit the program.

-c --config filename

Specify the configuration file to use.

--strict

Strict configuration check (don't start with config errors)

-s --section section

Specify which main section to use in the configuration file. The default is [Gatekeeper::Main].

-l --timetolive n

Specify the time-to-live timer (in seconds) for endpoint registration. Overrides the setting TimeToLive in the configuration file. See there for detailed explanations.

-b --bandwidth n

Specify the total bandwidth available for the gatekeeper in units of 100 bits per second. Without this option, bandwidth management is disabled.

--pid filename

Specify the pid file. Only valid for Unix version.

-u --user name

Run the gatekeeper process as this user. Only valid for Unix version.

--core n

Enable writing core dump files when the application crashes. A core dump file will not exceed n bytes in size. A special constant "unlimited" may be used to not enforce any particular limit. Only valid on Linux.

--mlock

Lock GnuGk into memory to prevent it being swaped out. Only valid on Linux.

Gatekeeper Mode

The options in this subsection override the settings in the [RoutedMode] section of the configuration file.

-d --direct

Use direct endpoint call signaling.

-r --routed

Use gatekeeper routed call signaling.

-rr --h245routed

Use gatekeeper routed call signaling and H.245 control channel.

Debug Information

-o --output filename

Write trace log to the specified file.

-t --trace

Set trace verbosity. Each additional -t adds additional verbosity to the output. For example, use -ttttt to set the trace level to 5.

4.2 Configuration File

The GNU Gatekeeper configuration file is a standard text file. The basic format is:

[Section String]
Key Name=Value String

Comments are marked with a hash (#) or a semicolon (;) at the beginning of a line.

The file complete.ini contains all available sections for GnuGk. In most cases it doesn't make sense to use them all at once. The file is just meant as a collection of examples for many settings.

The configuration file can be changed at run time. Once you modify the configuration file, you may issue the reload command via the status port, or send the HUP signal to the gatekeeper process:

kill -HUP `cat /var/run/gnugk.pid`

4.3 Database Configuration

All GnuGk modules that use a database (eg. [SQLAuth], [SQLAcct] etc.) support a common set of configuration parameters that is described here. You have to repeat all settings for each module, even if they are the same. But you are also free to use differend database drivers and options for each module.

Placeholders in queries

Many SQL modules provide a set of placeholders that you can use in your queries, like %{CallId} in SqlAcct.

Placeholders allways start with the percent sign. Beware that you must escape the percent sign if you need it for something else in your queries (eg. in a LIKE). One way to do so is to use CHAR(37), eg. concat(alias,CHAR(37)) instead of concat(alias,'%').

Stored Procedures

Stored procedures work very well when using MySQL.

When using ODBC, you can not call stored procedures which use parameters using the "CALL ProcedureName" syntax, but you can call them with "EXEC ProcedureName".

4.4 Regular Expressions

In a few places in the configuration file, GnuGk allows regular expressions. The syntax for these regular expressions is "extended POSIX 1003.2 regular expressions". On Unix systems you can usually get a manual page explaining the syntax with "man 7 regex" or see it online at http://www.kernel.org/doc/man-pages/online/pages/man7/regex.7.html.

4.5 Section [Gatekeeper::Main]

Most users will never need to change any of the following values. They are mainly used for testing or very sophisticated applications.

4.6 Section [GkStatus::Auth]

Defines a number of rules regarding who is allowed to connect to the status port. Access to the status port provides full control over your gatekeeper. Ensure that this is set correctly. The status port is active on all IPs GnuGk listens to. You should block as many status ports in your firewall as your setup allows. If you rely on password rules to secure the status port, you should add additional IP based rules ('explicit' or 'regex') to limit the IP range where logins are allowed from.

4.7 Section [GkStatus::Filtering]

See Status Port Filtering.

4.8 Section [LogFile]

This section defines log file related parameters. Currently, it allows users to specify log file rotation options.

5. Routed Mode and Proxy Configuration

5.1 Section [RoutedMode]

Call signaling messages may be passed in two ways: The first method is Direct Endpoint Call Signaling, where call signaling messages are passed directly between the endpoints. The second method is Gatekeeper Routed Call Signaling. With this method, the call signaling messages are routed through the gatekeeper.

When Gatekeeper Routed call signaling is used, there are three different options for routing of the H.245 control channel and media channels.

Case I.

The gatekeeper doesn't route them. The H.245 control channel and media channels are established directly between the endpoints.

Case II.

The H.245 control channel is routed through the gatekeeper, while the media channels are established directly between the endpoints.

Case III.

The gatekeeper routes the H.245 control channel, as well as all media channels, including RTP/RTCP for audio and video, and T.120 channel for data. In this case, no traffic is passed directly between the endpoints. This is usually called a H.323 Proxy, and can be treated as a H.323-H.323 gateway.

This section defines the gatekeeper routed mode options (case I & II). The proxy feature is defined in the next section.

The settings in this section may be updated by reloading the configuration while the gatekeeper is running.

5.2 Section [Proxy]

The section defines the H.323 proxy features. It means the gatekeeper will route all the traffic between the calling and called endpoints, so there is no traffic between the two endpoints directly. Thus it is very useful if you have some endpoints using private IP behind an NAT box and some endpoints using public IP outside the box.

The gatekeeper can do proxy for logical channels of RTP/RTCP (audio and video) and T.120 (data). Logical channels opened by fast-connect procedures or H.245 tunneling are also supported.

Note to make proxy work, the gatekeeper must have direct connection to both networks of the caller and callee.

5.3 Section [ModeSelection]

In routed mode or proxy mode, you may use this section to specify the exact routing mode (routed mode, routed mode plus H.245 routing or proxy mode) on a per-IP network basis.

Syntax:

network=mode[,mode]

The network is specified by an IP plus optional CIDR, eg. 192.168.1.0/24. The rule for the network with the longest netmask is used (the most specific).

Possible modes are (the names are case in-sensitive)

The first mode is used for calls into and out of the specified network. The second mode is used for calls that stay inside the network. If only one mode is specified it is used for both cases.

Example:

In this example calls into and out of the 1.2.3.0/24 network are proxied, but calls that remain inside this network are in routed mode. Calls in the 3.4.5.0/24 are always proxied, even when they remain inside the network, unless IP 3.4.5.6 is involved. If 2 networks have a rule for the call, the one with the most proxying is used, eg. a call from 192.168.1.222 to 3.4.5.20 would be proxied.

[ModeSelection]
127.0.0.0/24=ROUTED
192.168.0.0/18=H245ROUTED,ROUTED
1.2.3.0/24=PROXY,ROUTED
3.4.5.0/24=PROXY,PROXY
3.4.5.6=ROUTED
2005:4dd0:ff00:99a::9/64=PROXY

If no rules match the settings then [RoutedMode]GkRouted=, H245Routed= or [Proxy]Enable= are used to determine the routing mode.

There are a few cases where these rules don't apply, because the GNU Gatekeeper knows that the call needs proxying: For example calls involving H.460.18/.19 will always be proxied (because this protocol requires proxying).

p>

5.4 Section [ModeVendorSelection]

In routed mode or proxy mode, you may use this section to specify the exact routing mode (routed mode, routed mode plus H.245 routing or proxy mode) on vendor specific basis. The vendor information is collected from the H225_EndpointType field of the setup and connect message

Syntax:

vendor=mode

The vendor is specified by an string matching value. The rule for the longest string match is used (the most specific).

Possible modes are in accordance with the [ModeSelection] section above.

Example:

[ModeSelection]
VoIP Technologies=PROXY

6. Routing Configuration

The following sections in the config file can be used to configure how calls are routed.

For GnuGk, "routing" means that the gatekeeper must find a destination IP for each new call.

For example GnuGk may need to decide where to send a voice call given a particular E.164 destination; there may be multiple IP-to-ISDN gateways which it may choose from for that E.164 address.

Routing decisions are typically made by examining the called name or number, but GnuGk has flexibility in what it evaluates in order to successfully route the call.

Each call gets passed down a chain of routing policies. Each policy may route the call and terminate the chain or modify it and pass it on. You can use the setting in the following sections to specify which policies to use and modify their behavior.

6.1 Section [RoutingPolicy]

This section explains how GNU Gatekeeper routing policies are configured.

An incoming call request can be routed using the following methods:

Default configuration for routing policies is as follows:

[RoutingPolicy]
default=explicit,internal,parent,neighbor

If one policy does not match, the next policy is tried.

These policies can be applied to a number of routing request types and routing input data. The different types are ARQ, LRQ, Setup and Facility (with the callForwarded reason). There is also the general routing policy, which is a default for the other types.

Example:

[RoutingPolicy]
h323_ID=dns,internal
002=neighbor,internal
Default=internal,neighbor,parent

When a message is received which requires a routing decision, all calls to an alias of the h323_ID type will be resolved using DNS. If DNS fails to resolve the alias, it is matched against the internal registration table. If a call is requested to an alias starting with 002, the neighbors will be checked first, then the internal registration table. If the requested alias is not an h323_ID or an alias starting with 002, the default policy is used by querying the internal registration table, then the neighbors, and if those fail, the parent.

Routing policies are applied to the first message of a call: The ARQ for calls from registered endpoints, the Setup for calls from unregistered endpoints, the LRQ for calls from neighbors and certain Facility messages for calls that are forwarded by GnuGk using the ForwardOnFacility feature. You can specify different routing policies for each type of call by using the [RoutingPolicy::OnARQ], [RoutingPolicy::OnLRQ], [RoutingPolicy::OnSetup] and [RoutingPolicy::OnFacility] sections using the same syntax explained above.

Example:

[RoutingPolicy::OnARQ]
default=numberanalysis,internal,neighbor

A typical ENUM routing setup would look like this:

Example:

[RoutingPolicy]
default=explicit,internal,enum,srv,dns,internal,parent,neighbor

6.2 Section [RasSrv::RewriteE164]

This section defines the rewriting rules for dialedDigits (E.164 number).

Format:

[!]original-prefix=target-prefix

If the number begins with original-prefix, it is rewritten to target-prefix. If the `!' flag precedes the original-prefix, the sense is inverted and the target-prefix is prepended to the dialed number. Special wildcard characters ('.' and '%') are available.

Example:

08=18888

If you dial 08345718, it is rewritten to 18888345718.

Example:

!08=18888

If you dial 09345718, it is rewritten to 1888809345718.

Option:

6.3 Section [RasSrv::RewriteAlias]

This section defines the rewriting rules for aliases. This can be used to map gatekeeper assigned aliases to registered endpoints.

Format:

[!]original-alias=target-alias

If the alias is original-alias, it is rewritten to target-alias.

Example:

bill=033123456

6.4 Section [RasSrv::GWRewriteE164]

This section describes rewriting the dialedDigits E.164 number depending on the gateway a call has come from or is being sent to. This allows for more flexible manipulation of the dialedDigits for routing etc.

Despite the name of the section, you can not only rewrite calls from and to gateways, but also calls from terminals (regular endpoints) and neighbor gatekeepers.

In combination with the RasSrv::RewriteE164 you can have triple stage rewriting:

Call from "gw1", dialedDigits 0867822
                |
                |
                V
Input rules for "gw1", dialedDigits now 550867822
                |
                |
                V
Global rules, dialedDigits now 440867822
                |
                |
                V
Gateway selection, dialedDigits now 440867822, outbound gateway "gw2"
                |
                |
                V
Output rules for "gw2", dialedDigits now 0867822
                |
                |
                V
Call to "gw2", dialedDigits 0867822

Format:

alias=in|out=[!]original-prefix=target-prefix[;in|out...]

If the call matches the alias, the direction and begins with original-prefix it is rewritten to target-prefix. If the `!' flag precedes the original-prefix, the sense is inverted. Special wildcard characters ('.' and '%') are available. '.' matches one character and '%' matches any number of characters. Multiple rules for the same gateway are separated by ';'.

To convert dialed digits into post dial digits that are sent to the remote side after the call connects as UserInputIndications, use 'I' (for Input) on the prefix side and 'P' (for Postdial) on the target side. Please note that H.245 routing through the gatekeeper must be active to send post dial digits.

Calls from and to gateways and terminals are matched by their first alias. Calls from and to neighbors are matched by the neighbor ID in the GnuGk config (the XXX in the [Neighbor::XXX] section name) or the gatekeeper identifier of the neighbor if it is set.

Note that when you have multi-homed neighbors or are accepting non-neighbor LRQs, the source of the call can not always be determined and no IN rule for a neighbor will match. In these cases you should only use OUT and [RasSrv::RewriteE164] rules.

Example:

gw1=in=123=321

If a call is received from "gw1" to 12377897, it is rewritten to 32177897 before further action is taken.

Post Dial Example:

gw1=out=09III=09PPP

If a call is sent out through "gw1" to 09123, it is rewritten to 09 and 123 are sent as post dial digits.

Neighbor Example 1:

In this example the neighbor is identified by its ID and incoming calls from NbGk will have their 01 prefix replaced by a 04 prefix. Outgoing calls will have 04 replaced with 01.

[RasSrv::Neighbors]
NbGk=GnuGk

[Neighbor::NbGk]
GatekeeperIdentifier=GK-PW-Prox
Host=192.168.1.100
SendPrefixes=*
AcceptPrefixes=*

[RasSrv::GWRewriteE164]
NbGk=in=01=04;out=04=01

Neighbor Example 2:

In this example the neighbor is identified by its gatekeeper identifier and incoming calls from GK-PW-Prox that don't have a 0049 prefix get the prefix prepended. A call to "1234" would be rewritten to "00491234", while a call to "00496789" would proceed unchanged because the "If incoming does not start with 0049 and any number of digits after 0049, then prepend 0049" logic would be false (because we already have 0049 at the beginning.)

[RasSrv::Neighbors]
NbGk=GnuGk

[Neighbor::NbGk]
GatekeeperIdentifier=GK-PW-Prox
Host=192.168.1.100
SendPrefixes=*
AcceptPrefixes=*

[RasSrv::GWRewriteE164]
GK-PW-Prox=in=!0049.=0049.

6.5 Section [Endpoint::RewriteE164]

Once you specify prefix(es) for your gatekeeper endpoint, the parent gatekeeper will route calls with dialedDigits beginning with that prefixes. The child gatekeeper can rewrite the destination according to the rules specified in this section. By contrast, when an internal endpoint calls an endpoint registered to the parent gatekeeper, the source will be rewritten reversely.

Format:

external prefix=internal prefix

For example, if you have the following configuration,

                        [Parent GK]
                        ID=MasterGK
                        /         \
                       /           \
                      /             \
                     /               \
                [Child GK]          [EP3]
                ID=ProxyGK          E164=18888200
                Prefix=188886
                /       \
               /         \
              /           \
           [EP1]         [EP2]
           E164=601      E164=602

With this rule:

188886=6

When EP1 calls EP3 by 18888200, the CallingPartyNumber in the Q.931 Setup will be rewritten to 18888601. Conversely, EP3 can reach EP1 and EP2 by calling 18888601 and 18888602, respectively. In consequence, an endpoint registered to the child gatekeeper with prefix '6' will appear as an endpoint with prefix '188886', for endpoints registered to the parent gatekeeper.

The section does not relate to the section RasSrv::RewriteE164, though the latter will take effect first.

6.6 Section [Routing::DNS]

6.7 Section [Routing::ENUM]

Additional ENUM schemas may be configured by the [Routing::ENUM::id]

Format:

<enum schema>=<protocol gateway>

Example:

[Routing::ENUM::2]
E2U+xmpp=mygateway@mydomain.com

6.8 Section [Routing::SRV]

Additional SRV schemas may be configured by the [Routing::SRV::id]

Format:

<SRV schema>=<protocol gateway>[;default schema port]

Example:

[Routing::SRV::2]
_xmpp-server._tcp=mygateway@mydomain.com

6.9 Section [Routing::RDS]

6.10 Section [Routing::Explicit]

You can define a mapping where calls to certain IPs should be routed by the 'explicit' policy. The new destination can either be another IP or an alias destination of any type. If you rewrite the destination to something other than an IP, make sure you have other routing policies in the chain behind the 'explicit' policy that can handle the new destination.

Format:

IP=newIP[:port] | E.164 | alias

Example:

[Routing::Explicit]
192.168.1.100=10.10.1.100
192.168.1.101=10.10.1.101:1720
192.168.1.102=654251
192.168.1.103=peter
192.168.1.104=joe@company.com

6.11 Section [Routing::Sql]

Rewrite the called alias with a SQL query. Supports routing OnARQ, OnLRQ and OnSetup.

If the string returned from the database is 'REJECT' (upper or lower case), the call is rejected. If the string matches a dotted IP address, it is taken as destination IP otherwise it is treated as a new destination alias. If 2 columns are returned, the first is treated as the new destination alias and the second is treated as new destination IP. If the 2nd column contains 'IGNORE', the database result is treated as if it would only contain 1 result column. (This allows simpler SQL queries in some cases.)

If multiple rows of destination IPs are returned they are used as alternative routes for failover and GnuGk will try them in order.

When at least one destination IP is specified or the call is rejected, the SQL policy will end the routing chain. If only the alias is changed, the chain continues with this updated alias.

When rejecting a call, the 2nd column can contain an integer designating the reject reason (H.225 AdmissionRejectReason for registered calls, H.225 LocationRejectReason for neighbor calls, H.225 disconnect reason for unregistered calls).

If the database returns nothing, the call is passed on unchanged.

Use the common database configuration options to define your database connection for this module.

6.12 Section [Routing::NeighborSql]

Select which neighbor to query for a call with a database query.

Use the common database configuration options to define your database connection for this module.

6.13 Section [Routing::NumberAnalysis]

This section defines rules for the numberanalysis routing policy. The policy checks a dialed number for minimum and/or maximum number of digits and sends ARJ, if necessary (number of digits is out of range), to support overlapped digit sending. It also partially supports Setup messages (no overlapped sending - only number length validation).

Format:

prefix=MIN_DIGITS[:MAX_DIGITS]

If the number matches the prefix, it is verified to consist of at least MIN_DIGITS digits and (if MAX_DIGITS is present) at most MAX_DIGITS digits. Special wildcard characters (!, '.' and '%') are available. If the number is too short, an ARJ is send with rejectReason set to incompleteAddress. If the number is too long, an ARJ is send with rejectReason set to undefinedReason. Prefix list is searched from the longest to the shortest prefix for a match. For Setup messages, a Release Complete with "badFormatAddress" is sent when the number has an incorrect length.

Example:

[RoutingPolicy::OnARQ]
default=numberanalysis,internal

[Routing::NumberAnalysis]
0048=12
48=10
.=6:20

Calls to destinations starting with 0048 require at least 12 digits, to 48 we require 10 digits and to all other destinations at least 6 and at most 20 digits.

6.14 Section [Routing::Forwarding]

This routing policy performs a database lookup if calls to an endpoint should be forwarded to another endpoint. It supports routing OnARQ, OnSetup and OnLRQ.

There are different types of forwards:

The destination where calls are forwarded to should either be aliases of local endpoints (incl. permanent endpoints) or IP numbers. For local aliases, GnuGk will check if the destination also has forwarding configured and take it into account.

Use the common database configuration options to define your database connection for this module.

Specifically for this module, you can specify a query to read the forwarding rules:

Example:

[RoutedMode]
GKRouted=1
AcceptUnregisteredCalls=1
; failover must be on for forward on timeout
ActivateFailover=1
FailoverCauses=1-15,17-127
DisableRetryChecks=1
; 10 sec alerting timeout (for forward on no answer)
AlertingTimeout=10000

[RoutingPolicy]
default=explicit,forwarding,internal,neighbor,explicit

[Routing::Forwarding]
Driver=MySQL
Host=localhost
Database=gnugk
Username=gnugk
Password=secret
Query=SELECT forwardtype, destination FROM forwards WHERE called = '%c' order by forwardtype asc
MinPoolSize=1

Sample MySQL Schema:

create table gnugk.forwards (
    called varchar(30) not null,
    forwardtype smallint not null,
    destination varchar(30) not null default "",
    PRIMARY KEY (called, forwardtype)
);

Sample Forwarding Rules:

"1234", 1, "2000"
"5678", 2, "4000"
"5678", 3, "4000"
"9876", 4, "5000"

6.15 Section [Routing::CatchAll]

6.16 Section [Routing::Lua]

NOTE: This policy is still experimental and may change in the next release. Please contact the GNU Gatekeeper authors if you want to use it in production.

The LUA script has the following input variables available:

The LUA script can set these output variables to specify a routing destination:

To access external resources, LUA scripts can use LUA libraries, eg. LuaSocket.

6.17 Section [Routing::URIService]

URI Service specific routing policy.

Format:

<schema>=<protocol gateway>

Example:

[Routing::URIService]
xmpp=mygateway.mydomain.com

This switch sets the service type and default gateway for a given URI schema. This can be used in a chain with [Routing::ENUM::<schema>] and [Routing::SRV::<schema>] to provide a service specific routing policy.

6.18 Section [RewriteCLI]

This section contains a set of rewrite rules for ANI/CLI/H.323_ID numbers (Caller ID). The rewrite process is done in two stages - inbound rewrite and outbound rewrite. The inbound rewrite is done before any other Q.931 Setup message processing (such as inbound GWRewrite, authentication, accounting, ...), and because it alters the Calling-Station-Id it will have an effect in the authorization and accounting modules. The outbound rewrite takes place just before the Setup message is to be forwarded and its effect is visible only to the callee.

An inbound rewrite rule can be matched by a caller's IP and a dialed number or an original CLI/ANI. An outbound rewrite rule can be matched by a caller's IP, callee's IP and a dialed number or a destination number (the dialed number after rewrite) or a CLI/ANI (after inbound rewrite).

This module also provides CLIR (Calling Line Identification Restriction) feature that can be configured for each endpoint (rule).

Format for an inbound rule:

in:CALLER_IP=[pi=[allow|restrict][,forward|apply|applyforterminals]] [cli:|dno:]number_prefix(=|*=|~=|^=|/=)NEW_CLI[,NEW_CLI]...

The in: prefix specifies that this is an inbound rule and the CALLER_IP will be used to match the rule (it can be a single IP or an entire subnet). You can use IPv4 or IPv6 addresses for the CALLER_IP.

The optional pi= parameter controls CLIR (Calling Line Identification Restriction) features. Specifying either allow or restrict forces presentation indicator to be set to "presentation allowed" or "presentation restricted". forward, apply and applyforterminals controls how the received (if any) presentation indicator is processed by the gatekeeper. forward means forward it to the callee as-is, apply is used to hide the CLI if the PI is set to "presentation restricted", applyforterminals is similar to apply, except that CLI is hidden only when sending the call to a terminal, not a gateway.

The prefix cli: or dno: (the default) selects what number will be used to match the number_prefix - a caller id (CLI/ANI) or a dialed number. Number matching/rewriting can be done in five ways:

After the equality (=/ =/*=/^=//=) sign, there follows a list of new CLI values to be used. If more than one value is specified, one will be chosen on a random basis. It's possible to specify whole number ranges, like 49173600000-49173699999 (for number ranges CLIs should have a fixed length). There is a special string constant "any" which may be used in place of the CALLER_IP or the number_prefix. To enable CLIR for this rule, use the special string constant "hide" instead of the list of new CLI values. Note that CLIR is far more useful for outbound rules.

Example 1:

[RewriteCLI]
in:192.168.1.1=dno:5551=3003
in:192.168.1.1=cli:1001=2222
in:192.168.1.1=any=1111

These rules state that for calls from the IP 192.168.1.1: 1) if the user dialed a number beginning with 5551, set CLI to 3003, 2) if the call is from user with CLI beginning with 1001, set CLI to 2222, 3) for other calls from this IP, set CLI to 1111.

Example 2:

[RewriteCLI]
in:192.168.1.0/24=any=18001111
in:192.168.2.0/24=any=18002222
in:2002:4ad0:ff00:79a::2/64=any=18003333
in:any=any=0

These rules state that: 1) for calls from the network 192.168.1.0/24, set CLI to 18001111, 2) for calls from the network 192.168.2.0/24, set CLI to 18002222, 3) for calls from the network 2002:4ad0:ff00:79a::2/64, set CLI to 18003333, 4) for other calls, set CLI to 0.

Example 3:

[RewriteCLI]
in:192.168.1.0/24=0048*=48
in:192.168.1.0/24=0*=48
in:any=100.~=48900900900

These rules state that: 1) for calls from the network 192.168.1.0/24, rewrite 0048 to 48 (example - 0048900900900 => 48900900900), 2) for other calls from the network 192.168.1.0/24, rewrite 0 to 48 (example - 0900900900 => 48900900900), 3) for other calls, if CLI is 4 digits and starts with 100, set it to 48900900900.

Example 4 (CLIR):

[RewriteCLI]
in:192.168.1.0/24=any=hide

This example causes caller's number to be removed from Setup messages originating from the 192.168.1.0/24 network. It also causes proper presentation and screening indicators to be set in Setup messages.

Format for an outbound rule:

out:CALLER_IP=CALLEE_IP [pi=[allow|restrict][,forward|apply|applyforterminals]] [cli:|dno:|cno:]number_prefix(=|~=|*=)NEW_CLI[,NEW_CLI]...

The out: prefix tells that this is an outbound rule, the CALLER_IP and the CALLEE_IP will be used to match the rule and can be a single IP or a subnet address.

The optional pi= parameter controls CLIR (Calling Line Identification Restriction) features. Specifying either allow or restrict forces the presentation indicator to be set to "presentation allowed" or "presentation restricted". forward, apply and applyforterminals controls how the received (if any) presentation indicator is processed by the gatekeeper. forward means just to forward it to the callee as-is, apply means hiding CLI if the PI is set to "presentation restricted", applyforterminals is similar to apply, except that the CLI is hidden only when sending the call to a terminal, not a gateway.

The prefix cli:, dno: (the default) or cno: selects what number will be used to match the number_prefix - a caller id (CLI/ANI), a dialed number or a destination/called number (the dialed number after rewrite). Number matching/rewriting can be done in three ways:

After the equality sign (=/ =/*=), a list of new CLI values to be used is specified. If more than one value is configured, one will be chosen on a random basis. It's possible to specify entire number ranges, like 49173600000-49173699999. There is a special string constant "any" which can be used in place of the CALLER_IP, the CALLEE_IP or the number_prefix. To enable CLIR for this rule, use a special string constant "hide" or "hidefromterminals" instead of the list of new CLI values.

Example 1:

[RewriteCLI]
out:any=192.168.1.1 any=1001
out:any=192.168.1.2 any=1002
out:any=any cno:123=1003

These rules set a fixed ANI/CLI for each terminating IP: 1) present myself with ANI 1001, when sending calls to IP 192.168.1.1, 2) present myself with ANI 1002, when sending calls to IP 192.168.1.2. 3) present myself with ANI 1003, when calling 123

Example 2:

[RewriteCLI]
out:any=192.168.1.1 any=1001-1999,3001-3999

This rule randomly selects ANI/CLI from range 1001-1999, 3001-3999 for calls sent to 192.168.1.1.

Example 3 (CLIR):

[RewriteCLI]
out:any=any any=hidefromterminals
out:192.168.1.1=any any=hide

In this example each subscriber has enabled CLIR, so all calls to terminals will have a caller's number removed and presentation/screening indicators set. Calls to gateways will have the presentation indicator set to "presentation restricted" and the caller's number will not be removed to allow proper call routing and number removal at the destination equipment.
One exception to these rules are calls from 192.168.1.1 which will have a caller's number always removed, no matter whether calling a terminal or a gateway.

Example 4 (CLIP):

[RewriteCLI]
out:any=192.168.1.1 any=hide

In this example CLIP (Calling Line Identification Presentation) feature is disabled for the user 192.168.1.1.

Example 5 (CLIR):

[RewriteCLI]
out:192.168.1.1=any pi=restrict,apply cli:.*=.
out:any=any pi=allow cli:.*=.

These rules do not change CLI (.*=.) and: 1) enable CLIR for an endpoint 192.168.1.1. apply tells the gatekeeper to not only set the PI, but also to hide the number. 2) force CLI presentation for other endpoints.

The rule matching process has a strictly defined order:

  1. the closest caller's IP match is determined (closest means with the longest network mask - single IPs have the highest priority, "any" has the lowest priority),
  2. (outbound rules) the closest callee's IP match is determined,
  3. the longest matching prefix/number is searched for the given IP/IP pair in the following order:
    1. dno: type (dialed number) rules are searched,
    2. cno: type (destination/called number) rules are searched,
    3. cli: type (caller id) rules are searched.
After a match for caller's/caller's IP is found, no more rules are checked, even if no prefix/number is matched inside the set of rules for these IPs.

On the Windows platform, there is a problem with duplicated config keys in INI files, so GnuGk provides a workaround for this restriction. This example will not work because of the same key (in:192.168.1.1):

[RewriteCLI]
in:192.168.1.1=1001=2001
in:192.168.1.1=any=2000
As a workaround, you can use a string with percent signs (%) at the beginning and at the end before the key. This prefix will be automatically stripped from the key name before loading rules:
[RewriteCLI]
%r1% in:192.168.1.1=1001=2001
%r2% in:192.168.1.1=any=2000

6.19 Section [RewriteCLI::SQL]

Use the common database configuration options to define your database connection for this module.

Please note that the switches (not the rules) from the RewriteCLI section, like ProcessSourceAddress=, RemoveH323Id= and CLIRPolicy= also apply to the rewrite rules from this section.

The first field returned by the query is used as the new CLI. If the query returns no rows, the CLI is left unchanged. The queries can be parameterized - that means parameter replacement is made before each query is executed. The following parameters are defined:

In most cases you will probably only use the %{cli} parameter.

6.20 Section [RewriteSourceAddress]

With the switches in this section you can filter the sourceAddress elements that are transported in a Setup message. (Please note that the RewriteCLI and RewriteCLI::SQL rules also influence the sourceAddress.)

7. RAS Configuration

7.1 Section [ReplyToRasAddress]

Some messages from endpoints to the gatekeeper (GatekeeperRequest, RegistrationRequest and InfoRequestResponse) contain an element rasAddress where the endpoint tells the gatekeeper where to send the response to these messages. By default GnuGk will ignore this address and respond to the IP and port where it has received the request from. It does so, because some endpoints rely on this behavior and in case where eg. a NAT is used, the response may not reach the sender if it is sent to another IP and port. Usually endpoints will send the RAS messages from their RAS port anyway, so it doesn't make a difference.

This section allows you to define when GnuGk should use the rasAddress inside the message it has received instead of the address where it has received the message from.

Syntax:

network=True|False

The network is specified by an IP plus optional CIDR, eg. 192.168.1.0/24. The network specifies the IP where the RAS message is received from, the setting specifies whether to use the rasAddress. The default is not to use it. The rule for the network with the longest netmask is used (the most specific).

Example:

In this example messages from the 192.168.0.0/18 will use the rasAddress, except for messages coming from the 192.168.4.0/24 network.

[ReplyToRasAddress]
192.168.0.0/18=True
192.168.4.0/24=False

7.2 Section [RasSrv::GWPrefixes]

This section configures how dialed E.164 numbers are routed to a specific gateway.

Format:

gw-alias=prefix[:=priority][,prefix[:=priority],...]

Note that you must specify the alias of the gateway. If a gateway has registered with the specified alias, all numbers beginning with the prefixes are routed to that gateway. Special characters . and ! can be used here to match any digit or to disable the prefix. A priority can be given to each prefix for each gateway (using := syntax), so that if several gateways match the dialed number, the one with the highest prefix priority will be selected to route the call (when the ActivateFailover switch is ON, the call will be routed to all selected gateways in order of the prefix priority). A smaller value corresponds to a higher priority. Default value is 1. If the prefix priority and overlaps the GatewayPriority (see section [EP::...]), the prefix priority will be preferred.

In the following example, the gateway "test-gw" will be responsible for prefixes "02" and "03" with a priority of 3, and for "04" with a priority of 1.

Example:

test-gw=02,03:=3,04:=1

7.3 Section [RasSrv::PermanentEndpoints]

In this section you may configure endpoints that don't have RAS support or that you don't want to be expired. Their records will always remain in the registration table of the gatekeeper. However, you can still unregister it via the status port. Special characters . and ! can be used with prefixes here to match any digit and disable the prefix. You may use := syntax to set a prefix priority in the same manner as in [RasSrv::GWPrefixes] section.

Make sure you add at least one prefix for all gateways, even if you assign the prefixes elsewhere (eg. in the [EP::...] section), otherwise the endpoint won't be considered a gateway and those settings won't apply!

Gateway entries may also optionally include vendor information which is stored with the gateway record

Format:

IP[:port]=alias[,alias,...;prefix[:=priority][,prefix[:=priority]]...;[vendor,product]

Example:

For gateway,

10.0.1.5=MyGW;009,008:=2,0.7:=3
10.0.1.5=MyGW;009,008:=2,0.7:=3;yate,4.1.0
For terminal,
10.0.1.10:1720=700

7.4 Section [RasSrv::RRQFeatures]

7.5 Section [RasSrv::ARQFeatures]

7.6 Section [RasSrv::AssignedAlias]

This allows the assigning of aliases to endpoints as they register, allowing them to set their fully qualified E.164 or URI addresses.

Example:

[RasSrv::AssignedAlias]
1234=3323465777,me@mysite.com 

7.7 Section [AssignedAliases::SQL]

This section configures GnuGk to read the assigned aliases from a database. You can use the same database parameters as defined in [SQLPasswordAuth].

7.8 Section [RasSrv::AlternateGatekeeper]

This section allows you to override the global definition of AlternateGKs from the [Gatekeeper::Main] section for certain IPs or IP ranges. See there for a detailed definition of the config options.

The network is specified by an IP plus optional CIDR, eg. 192.168.1.0/24. The rule for the network with the longest netmask is used (the most specific).

Example:

In this example, 192.168.1.10 gets assigned GnuGk10 as alternate gatekeeper, while the rest of the 192.168.0.0/18 network will use GnuGk4. Endpoints in all other networks will use the globally defined alternate gatekeeper.

[RasSrv::AlternateGatekeeper]
192.168.0.0/18=1.2.3.4;1719;true;120;GnuGk4
192.168.1.10=1.2.3.10;1719;true;120;GnuGk10

7.9 Section [RasSrv::AssignedGatekeeper]

This allows the assigning of a gatekeeper based upon the H323ID or the apparent source IP address of the registering endpoint. The received H323ID in the GRQ is checked to see if it has a prefix for an assigned gatekeeper or the IP is in a range of an assigned gatekeeper. The endpoint is then advised in the GCF to register with that gatekeeper. You may have multiple gatekeepers for a specific prefix. The first is assigned as the primary and others are then the alternates. (requires H.323v6)

Examples:

[RasSrv::AssignedGatekeeper]
;; for endpoint with alias starting with 01234
01234=192.168.1.100:1719
;; for endpoint with alias starting with 999
999=[2a01:4f8:61:2243::99]:1719
;; for endpoints in the range of 195.71.129.0/24 or 195.71.131.0/24
^195\.71\.(129|131)\.[0-9]+$=10.10.0.5:1719
;; for endpoints tarting with ^2a01:
^2a01:=[2a01:4f8:61:2243::199]:1719

7.10 Section [AssignedGatekeepers::SQL]

This section allows GnuGk to read the assigned gatekeepers from a database. You can use the same database parameters as defined in [SQLPasswordAuth].

7.11 Section [AlternateGatekeepers::SQL]

This section allows GnuGk to read the alternate gatekeepers from a database. You can use the same database parameters as defined in [SQLPasswordAuth].

7.12 Section [AssignedLanguage::SQL]

This section configures GnuGk to read the assigned Languages from a database. You can use the same database parameters as defined in [SQLPasswordAuth].

7.13 Section [NATedEndpoints]

The gatekeeper can automatically detect whether an endpoint is behind NAT. However, if the detection fails, you can specify it manually in this section.

Format:

alias=true | yes | 1

Example:

Specify that the endpoint with alias 601 is behind NAT.

601=true

7.14 Section [GkPresence::SQL]

H323 SQL Presence system : Highly Experimental Use the common database configuration options to define your database connection for this module.

8. Authentication Configuration

The following sections in the config file can be used to configure authentication.

8.1 Section [Gatekeeper::Auth]

The section defines the authentication mechanism / modules for the GNU Gatekeeper. After defining which modules to use, you have to add the corresponding config sections for each modulke that you want to use.

Syntax:

authrule=actions

 <authrule> := SimplePasswordAuth | AliasAuth | FileIPAuth | PrefixAuth | RadAuth | RadAliasAuth | SQLAuth | SQLAliasAuth | SQLPasswordAuth | H350PasswordAuth | LDAPPasswordAuth | LDAPAliasAuth | CapacityControl | ...
 <actions>  := <control>[;<ras>|<q931>,<ras>|<q931>,...]
 <control>  := optional | required | sufficient | alternative
 <ras>      := GRQ | RRQ | URQ | ARQ | BRQ | DRQ | LRQ | IRQ
 <q931>     := Setup | SetupUnreg

A rule may results in one of these three codes: ok, fail, next.

There are also three ways to control a rule:

Currently supported modules: (most only support a subset of the ras or q931 actions)

You can also configure a rule to check only for specific RAS messages. The following example configures SimplePasswordAuth as an optional rule to check RRQ and ARQ. If a RRQ is not checked (does not contain tokens or cryptoTokens fields), it is checked by AliasAuth. The default is to check all supported requests.

Example 1:

SimplePasswordAuth=alternative;RRQ,ARQ
AliasAuth=sufficient;RRQ

The example below authenticates all calls, checking signaling Setup message details, using the RadAliasAuth module.

Example 2:

RadAliasAuth=required;Setup
default=allow

This example checks endpoint registrations (RRQ) and call admissions (ARQ) either by means of username/password (RadAuth) or alias/IP (RadAliasAuth). Additionally, if the call is from an unregistered endpoint (and therefore no RRQ or ARQ authentication has been performed), Setup message authentication using RadAliasAuth takes place (SetupUnreg).

Example 3:

RadAuth=alternative;RRQ,ARQ
RadAliasAuth=alternative;RRQ,ARQ,SetupUnreg
default=reject

8.2 Section [FileIPAuth]

This section defines a list of IP addresses/networks which are allowed to access gatekeeper resources. A list of allowed prefixes can be specified together with an IP address. Supported Gatekeeper::Auth events are: GRQ, RRQ, LRQ, Setup and SetupUnreg. Format of a single entry is:

IP=[allow | reject | onlyTLS][;prefix[,prefix...]]

where IP is a single IP address, a network address (in A.B.C.D/M.M.M.M or A.B.C.D/LENGTH format or IPv6 format) or a string 'any' or '*' to match any address. The access list can also be loaded from an external file using include directive. During authentication, network mask length defines a priority for each entry, so rule 192.168.1.1=allow takes precedence over 192.168.1.0/24=reject.

'onlyTLS' is equivalent to 'allow' if the call comes in via a TLS secured connection and means 'reject' for unencrypted calls.

In addition the to endpoint's IP, you can specify a list of prefixes that the endpoint may call. The destination prefixes are only checked on Setup messages.

Example #1:

[Gatekeeper::Auth]
FileIPAuth=required;RRQ,LRQ,Setup

[FileIPAuth]
192.168.1.240=reject
192.168.1.0/24=allow
192.168.2.0/255.255.255.0=allow;48,49,44
2a01:4f8:61:2243::2=allow
2a01:4f8:61:2243::10/128=allow
2a01:4f8:61:2243::/64=allow
any=reject

Example #2:

Placing the list of IP rules into another file.

[Gatekeeper::Auth]
FileIPAuth=required;Setup

[FileIPAuth]
include=/etc/gnugk/accesslist.ini

(EOF)

Contents of /etc/gnugk/accesslist.ini:

[FileIPAuth]
192.168.1.1=allow
192.168.1.100=allow
any=reject

Example #3:

Allow all connects from the local network, but require TLS encryption and authentification for everything else.

[Gatekeeper::Auth]
FileIPAuth=required;Setup

[FileIPAuth]
192.168.1.0/24=allow
any=onlyTLS

8.3 Section [SimplePasswordAuth]

This section defines the userid and password pairs used by SimplePasswordAuth module. All passwords are encrypted using the addpasswd utility.

Usage:

addpasswd config section userid password

Example:

addpasswd config.ini SimplePasswordAuth frank secret

Options:

8.4 Section [SQLPasswordAuth]

Authenticate H.235 enabled endpoints using passwords stored in the SQL database. This section defines the SQL driver to use, SQL database connection parameters and the query to use to retrieve passwords.

Use the common database configuration options to define your database connection for this module.

8.5 Section [H350PasswordAuth]

8.6 Section [RasSrv::RRQAuth]

Specify the action on RRQ reception (confirm or deny) for AliasAuth module. The first alias (this will mostly be an H323ID) of the endpoint to register is looked up in this section. If a parameter is found the value will apply as a rule. A rule consists of conditions separated by "&". A registration is accepted when all conditions apply.

Syntax:

<authrules> :=  empty  |  <authrule> "&" <authrules>

  <authrule>  := <authtype> ":" <authparams>
  <authtype>  := "sigaddr" | "sigip"
  <autparams> := [!&]*

The notation and meaning of <authparams> depends on <authtype>:

Example:

[RasSrv::RRQAuth]
; The endpoint with alias 'cwhuang' must register from 10.0.1.10:1720
cwhuang=sigip:10.0.1.10:1720
; The endpoint with alias 'gw1' must register from 10.0.1.0/24
gw1=sigaddr:.*ipAddress .* ip = .* 0a 00 01 .*port = 1720.*
; The endpoint with alias 'gw2' must register from [2a01:4f8:61:2243::2]:1720
gw2=sigip:[2a01:4f8:61:2243::2]:1720

8.7 Section [SQLAliasAuth]

Authenticate endpoints using rules stored in the SQL database (the rules conform to the format defined in the [RasSrv::RRQAuth] section). This section defines which SQL driver to use, SQL database connection parameters and the query to use to retrieve the patterns.

Use the common database configuration options to define your database connection for this module.

8.8 Section [SQLAuth]

Authenticate and authorize endpoints/calls using a SQL database. Support for RRQ, ARQ, LRQ and Setup events is provided.

Use the common database configuration options to define your database connection for this module.

8.9 Section [PrefixAuth]

The section defines the authentication rule for the PrefixAuth module. Currently, only ARQs and LRQs can be authorized by this module.

First, the most specific prefix is selected according to the destinationInfo field of the received request. Then the request is accepted or rejected according to the matched rules with the most specific netmask. If no matched prefix is found, and the default option is specified, the request is accepted or rejected according to that. Otherwise it is rejected or passed to the next authentication module according to the module requirement.

Format:

prefix=authrule[|authrule|...]

Syntax:

<authrule> :=  <result> <authrule>

  <result>    := deny | allow
  <authrule>  := [!]ip:<iprule> | [!]ipv4:<iprule> | [!]ipv6:<iprule> | [!]alias:<aliasrule>
Where <iprule> can be specified in decimal dot notation or CIDR notation or IPv6 notation, <aliasrule> is expressed in regular expression. If the `!' flag precedes the rule, the sense is inverted. Rules for IP numbers with ip:, ipv4:, ipv6: all behave the same. The different prefixes are just for documentation and compatibility with older versions of GnuGk.

Example:

555=deny ipv4:10.0.0.0/27|allow ipv4:0/0
5555=allow ipv4:192.168.1.1|deny ipv4:192.168.1.0/255.255.255.0
86=deny !ipv4:172.16.0.0/24
09=deny alias:^188884.*
99=deny ipv6:2021:4ad0:ff00:99a::/64
ALL=allow ipv4:0/0|allow ipv6:::/0

In this configuration, all endpoints except those from network 10.0.0.0/27 are allowed to call prefix 555 (except 5555). Endpoints from 192.168.1.0/24 are not allowed to call prefix 5555, except 192.168.1.1. Endpoints not from 172.16.0.0/24 are denied to call prefix 86. Endpoints having an alias beginning with 188884 are not allowed to call prefix 09. IPv6 endpoints from 2021:4ad0:ff00:99a::/64 are not allowed to call prefix 99. All other situations are allowed.

8.10 Section [RadAuth]

This section defines configuration settings that enable RADIUS authentication based on H.235 CATs (Cisco Access Tokens) present in RRQ, ARQ RAS requests and Q.931 Setup messages.

[RadAuth] Access-Request Radius Attributes

For RRQs, the following RADIUS attributes are included within Access-Request packets:

For ARQ and Setup messages, the following RADIUS attributes are included inside Access-Request packets:

[RadAuth] Access-Accept Radius Attributes

For RRQs, the following RADIUS attributes are recognized inside Access-Accept packets:

For ARQs, the following RADIUS attributes are recognized within Access-Accept packets:

NOTE: If both Session-Timeout and h323-credit-time are present, the smaller value is used.

NOTE: If multiple failover mechanisms are specified, eg. multiple numbers in h323-redirect-number and multiple IPs in h323-redirect-ip-address, there is no guarantee that the the first number is used for the first IP and the 2nd number for the 2nd IP. This will usually the case, but for example when a capacity limit disables one IP, the association will change.

8.11 Section [RadAliasAuth]

This section defines configuration settings that enable RADIUS authentication based on endpoint aliases and/or IP addresses present in a RRQ RAS, ARQ RAS or Q.931 Setup request. This authentication scheme is useful both for endpoints registered at the gatekeeper (ARQ, RRQ) and calls from unregistered endpoints (Setup).

[RadAliasAuth] Access-Request Radius Attributes

For RRQs, the same attributes as with RadAuth are sent, with an exception of username/password attributes (CHAP-Password, CHAP-Challenge, User-Name):

For ARQ and Setup messages, the same attributes as with RadAuth are sent, with an exception of username/password attributes (CHAP-Password, CHAP-Challenge, User-Name):

[RadAliasAuth] Access-Accept Radius Attributes

Exactly the same attributes are recognized as with RadAuth module.

8.12 Section [CapacityControl]

This section contains a set of rules for controlling inbound call volume depending on various conditions. In order for this module to work, CapacityControl authentication and accounting modules have to be enabled like this:

[Gatekeeper::Auth]
CapacityControl=required;Setup
 
[Gatekeeper::Acct]
CapacityControl=required;start,stop

A capacity rule can be matched by a caller's IP, caller's H.323 ID and/or caller's number (CLI) - in the order specified. In addition, the match can be narrowed by specifying a called number pattern. This module works by keeping lists of current call volume for each inbound route (rule) - this is done by having CapacityControl accounting module configured to add/remove active calls from matching routes. The CapacityControl authentication module checks rules and accepts/rejects a call based on current/max call volume for a matching inbound route.

Format for an inbound route rule:

[ip:CALLER_IP|h323id:CALLER_H323ID|cli:CALLER_NUMBER]=[CALLED NUMBER REGEX PATTERN] MAX_CAPACITY

ip:, h323id: and cli: prefixes define rule type. An inbound call will be matched either by caller's IP, H.323ID or CLI. The optional CALLED NUMBER REGEX PATTERN is a regular expression that the called number should match to apply this rule to. MAX_CAPACITY is maximum number of active calls for this route.

The rules are match in the following order:

The longest match in the first matching category is used.

Example 1:

[CapacityControl]
ip:192.168.1.0/24=30
ip:any=120

These rules tell that the 192.168.1.0/24 subnet can send up to 30 concurrent calls, while all other IPs can send up to 120 concurrent calls.

Example 2:

[CapacityControl]
%r1% cli:1001=30
%r2% cli:1001=^48(50|51) 5

These rules limit caller with CLI 1001 to send up to 5 calls to 4850/4851 destinations and up to 30 calls to other destinations. %r1% and %r2% are special constructs to allow having the same cli:1001 config key more than once.

8.13 Section [GkH350::Settings]

This section defines the LDAP server and standard H.350 directory operating parameters to be used.

8.14 Section [GkLDAP::Settings]

This section defines the LDAP server and connection parameters for the LDAP authentication modules (LDAPAliasAuth and LDAPPasswordAuth) and the LDAP routing policy ('ldap').

Example:

[GkLDAP::Settings]
ServerName=192.168.1.1
BindAuthMode=simple
SearchBaseDN=dc=gnugk,dc=org
BindUserDN=cn=admin,dc=gnugk,dc=org
BindUserPW=secret

8.15 Section [GkLDAP::LDAPAttributes]

With this section you can map the LDAP attributes GnuGk queries to your LDAP schema.

Example:

[GkLDAP::LDAPAttributeNames]
IPAddress=voIPIpAddress
H235PassWord=plaintextPassword
H323ID=sn
TelephonNo=telephoneNumber
CallDestination=roomNumber

9. Accounting Configuration

The following sections in the config file can be used to configure accounting.

9.1 Section [Gatekeeper::Acct]

This section defines a list of modules which may be used to perform accounting. The accounting function can be used for logging gatekeeper on/off events and call start/stop/update events. Each accounting module logs received events to module-specific storage. The various storage options include plain text file, RADIUS server and many more. The configuration is very similar to the one for gatekeeper authentication (see [Gatekeeper::Auth]).

All CDRs are also sent to the status port and can be used by external applications.

Syntax:

acctmod=actions

 <acctmod> := FileAcct | RadAcct | SQLAcct | StatusAcct | SyslogAcct | CapacityControl | ...
 <actions> := <control>[;<event>,<event>,...]
 <control> := optional | required | sufficient | alternative
 <event>   := start | stop | alert | connect | update | register | unregister | on | off
The event list tells the gatekeeper which events should trigger logging with the given accounting module (if an event type is supported by the module): An event logged by a module may results in one of three result codes: ok, fail, next. Accounting modules can be stacked to log events by multiple modules or to create failover setups. The control flag for each module, along with result codes, define what is the final status of the event processing by the entire module stack. If the final result is failure, some special actions may take place. Currently, if a call start event logging fails, the call is disconnected immediately. The following control flags are recognized:

Currently supported accounting modules:

Sample configuration #1 (try to log call start/stop with RADIUS server, and always write a CDR to a text file):

Example:

RadAcct=optional;start,stop
FileAcct=required

Sample configuration #2 (try to log call start/stop with RADIUS server, if it fails use a CDR log file):

Example:

RadAcct=alternative;start,stop
FileAcct=sufficient;stop
default=accept

The default rule is required here to prevent calls from being rejected because of RadAcct start event logging failure. If RadAcct responds with a fail return code, it is passed down to the FileAcct module. The FileAcct module does not support start events, so it returns a next code. If there were no default rule, the final status would be failure, because no module has been able to log the event.

Sample configuration #3 (always log call start and stop events with RADIUS server, if it fails for call stop event, use a CDR file to store call info):

Example:

RadAcct=alternative;start,stop
FileAcct=sufficient;stop
default=fail;start

The default rule is optional here. If RadAcct returns a fail code for the start event, the code is passed to the FileAcct module. The FileAcct module does not support start events, so it returns next return code. The default rule ensures that the call is disconnected if the call start event could not be logged with RadAcct. However, we still want to store a CDR in a text file in case the RADIUS server is down when the call disconnects, so we can fetch call duration into a billing system later.

9.2 Customizing CDR strings

Most accounting modules let you customize the CDR data they store. They use a common set of parameters to define the CDR string.

Parameters are specified using % character and can be one letter (like %n) or longer (like %{CallId}). Any remaining characters that are not parameter names are simply copied to the final CDR string. The following parameters are recognized:


9.3 Section [FileAcct]

This accounting module writes CDR lines to a specified text file. The CDR format can be a standard one (the same as displayed by the status interface) or a customized one (using parametrized query string).

9.4 Section [RadAcct]

This accounting module sends accounting data to a RADIUS server. Module configuration is almost the same as for RADIUS authenticators (see [RadAuth] and [RadAliasAuth] for more details on the parameters).

[RadAcct] Accounting-Request RADIUS Attributes

For an Accounting-Request, the following RADIUS attributes are included within Accounting-Request packets. Each attribute is followed by a list of accounting event types.

[RadAcct] Accounting-Response Radius Attributes

The gatekeeper ignores all attributes present in Accounting-Response Radius packets.

9.5 Section [SQLAcct]

This accounting module stores accounting information directly to a SQL database. Many configuration settings are common with other SQL modules.

Use the common database configuration options to define your database connection for this module.

A Sample MySQL Schema

The SQLAcct module is designed to adapt to whatever database structure you already have. You can define all queries so they fit your existing tables. Here is an example of what those tables might look like in MySQL and which you can use as a starting point.

Create a new database; here we use the name 'GNUGK':

create database GNUGK;

Then create a table in this database to store you accounting data; we call the table 'CDR'.

create table GNUGK.CDR (
        gatekeeper_name varchar(255),
        call_number int zerofill,
        call_duration mediumint unsigned zerofill,
                index duration_idx (call_duration),
        disconnect_cause smallint unsigned zerofill,
                index dcc_idx (disconnect_cause),
        acct_session_id varchar(255),
        h323_id varchar(255),
        gkip varchar(15),
        CallId varchar(255),
        ConfID varchar(255),
        setup_time datetime,
        connect_time datetime,
        disconnect_time datetime,
        caller_ip varchar(15),
                index srcip_idx (caller_ip),
        caller_port smallint unsigned zerofill,
        callee_ip varchar(15),
                index destip_idx (callee_ip),
        callee_port smallint unsigned zerofill,
        src_info varchar(255),
        dest_info varchar(255),
        Calling_Station_Id varchar(255),
        Called_Station_Id varchar(255),
                index dialednumber_idx (Called_Station_Id (20)),
        Dialed_Number varchar(255)
);

Then you need to create a username for accessing the data.

mysql> GRANT delete,insert,select,update ON GNUGK.* TO 'YourDesiredUsername'@'localhost' IDENTIFIED BY 'APassword';
mysql> flush privileges;

With this command you will permit access to the data only from the local server. If you need to access the data from any other computer then you have to set the proper security options.

For example, to permit access from the 192.168.1.0/24 network:

mysql> GRANT delete,insert,select,update ON GNUGK.* TO 'YourDesiredUsername'@'192.168.1.%' IDENTIFIED BY 'APassword';
mysql> flush privileges;

Then you can add the following settings into your gnugk.ini file to insert and update the history of the calls into your database.

[Gatekeeper::Acct]
SQLAcct=optional;start,stop,update
FileAcct=sufficient;stop

[FileAcct]
DetailFile=Add your desire path here something like /var/log/cdr.log
StandardCDRFormat=0
CDRString=%g|%n|%d|%c|%s|%u|%{gkip}|%{CallId}|%{ConfId}|%{setup-time}|%{connect-time}|%{disconnect-time}|%{caller-ip}|%{caller-port}|%{callee-ip}|%{callee-port}|%{src-info}|%{dest-info}|%{Calling-Station-Id}|%{Called-Station-Id}|%{Dialed-Number}
Rotate=daily
RotateTime=23:59

[SQLAcct]
Driver=MySQL
Database=GNUGK
Username=YourDesiredUsername
Password=APassword
StartQuery= insert into CDR (gatekeeper_name, call_number, call_duration, disconnect_cause, acct_session_id, h323_id, gkip, CallId, ConfId, setup_time, connect_time, disconnect_time, caller_ip, caller_port, callee_ip, callee_port, src_info, dest_info, Calling_Station_Id, Called_Station_Id, Dialed_Number) values ('%g', '%n', %d, %c, '%s', '%u', '%{gkip}', '%{CallId}', '%{ConfId}', '%{setup-time}', '%{connect-time}', '%{disconnect-time}', '%{caller-ip}', '%{caller-port}', '%{callee-ip}', '%{callee-port}', '%{src-info}', '%{dest-info}', '%{Calling-Station-Id}', '%{Called-Station-Id}', '%{Dialed-Number}')

StartQueryAlt= insert into CDR (gatekeeper_name, call_number, call_duration, disconnect_cause, acct_session_id, h323_id, gkip, CallId, ConfID, setup_time, connect_time, disconnect_time, caller_ip, caller_port, callee_ip, callee_port, src_info, dest_info, Calling_Station_Id, Called_Station_Id, Dialed_Number) values ('%g', '%n', %d, %c, '%s', '%u', '%{gkip}', '%{CallId}', '%{ConfID}', '%{setup-time}', '%{connect-time}', '%{disconnect-time}', '%{caller-ip}', '%{caller-port}', '%{callee-ip}', '%{callee-port}', '%{src-info}', '%{dest-info}', '%{Calling-Station-Id}', '%{Called-Station-Id}', '%{Dialed-Number}')

UpdateQuery= update CDR set call_duration=%d where gatekeeper_name='%g' and acct_session_id='%s'

StopQuery= update CDR set call_duration=%d, disconnect_cause=%c, disconnect_time='%{disconnect-time}' where gatekeeper_name='%g' and acct_session_id='%s'

StopQueryAlt= insert into CDR (gatekeeper_name, call_number, call_duration, disconnect_cause, acct_session_id, h323_id, gkip, CallId, ConfID, setup_time, connect_time, disconnect_time, caller_ip, caller_port, callee_ip, callee_port, src_info, dest_info, Calling_Station_Id, Called_Station_Id, Dialed_Number) values ('%g STOP Alt', '%n', %d, %c, '%s', '%u', '%{gkip}', '%{CallId}', '%{ConfID}', '%{setup-time}', '%{connect-time}', '%{disconnect-time}', '%{caller-ip}', '%{caller-port}', '%{callee-ip}', '%{callee-port}', '%{src-info}', '%{dest-info}', '%{Calling-Station-Id}', '%{Called-Station-Id}', '%{Dialed-Number}')

TimestampFormat=MySQL

9.6 Section [StatusAcct]

This accounting module sends all accounting information to the status port where it can be used to interface to external systems in real time.

You can use the common CDR parameters to define what to include into your event strings.

In addition to the CDR parameters, Register and Unregister events can use the following parameters:

9.7 Section [SyslogAcct]

This accounting module sends accounting information to the Unix syslog and is not available on Windows. The local syslog daemon will then route the messages according to its configuration, generally specified in /etc/syslog.conf.

You can use the common CDR parameters to define what to include into your event strings.

10. Neighbor Configuration

10.1 Section [RasSrv::Neighbors]

If the destination of an ARQ is unknown, the gatekeeper sends LRQs to its neighbors to ask if they have the destination endpoint. A neighbor is selected if one of its prefixes matches the destination or it has the ``*'' prefix. More than one prefix may be specified. You can use special characters ``.'' to do wildcard matching and ``!'' to disable a specific prefix.

The gatekeeper will only reply to LRQs sent from neighbors defined in this section. If you specify an empty SendPrefixes entry, no LRQ will be sent to that neighbor, but the gatekeeper will accept LRQs from it.

The password field is used to authenticate LRQs from that neighbor. See section [Gatekeeper::Auth] for details.

Whether a call is accepted from a neighbor also depends on the AcceptNeighborsCalls switch in the [RoutedMode] section.

GKID="GnuGk" | "CiscoGk" | "ClarentGk" | "GlonetGk"

The gatekeeper types have the following characteristics:

Example:

[RasSrv::Neighbors]
GK1=CiscoGk
GK2=GnuGk

[Neighbor::GK1]
GatekeeperIdentifier=GK1
Host=192.168.1.1
SendPrefixes=02
AcceptPrefixes=*
ForwardLRQ=always

[Neighbor::GK2]
GatekeeperIdentifier=GK2
Host=192.168.1.2
SendPrefixes=03,0048
AcceptPrefixes=0049,001
ForwardHopCount=2
ForwardLRQ=depends

The [RasSrv::Neighbors] section is only used to specify the gatekeeper type. The configuration for each neighbor is placed in a separate section.

10.2 Section [RasSrv::LRQFeatures]

Defines some features of LRQ and LCF.

10.3 Section [Neighbor::...]

Sections starting with [Neighbor:: are specific for one neighbor. If you define a [Neighbor::...] section, the default values of all settings in [RasSrv::LRQFeatures] will be applied to this neighbor. You may override the global defaults through configuration options in each neighbor-specific section.

10.4 Configuring a Traversal Zone with GnuGk as Traversal Server

To configure a traversal zone with a Tandberg VCS, add a Zone of type "Traversal client" in the VCS.

The user name and password configured in the VCS should be set as AuthUser= and Password= in the [Neighbor::..] section. The password must be encoded with the addpasswd tool if the Keyfilled= switch is used, otherwise it is entered as plain text in the config. Please note that for any password authentication to work, both systems must have accurate and synchronized time, so it is strongly recommended that you configure NTP.

Enable H.323 in the VCS settings, set the Protocol to H.460.18 (not Assent) and the port to 1719.

Add the IP of your GnuGk server as the Peer 1 address in the VCS.

Enable H.460.18 in your GnuGk config with EnableH46018=1 in the [RoutedMode] section. Set H46018Client=0 and H46018Server=1 in the [Neighbor::..] section. If H.460.18 is globally enabled, GnuGk will automatically detect that a neighbor is acting like a H.460.18 traversal zone client and it needs to act as a traversal server. But since traversal clients may come from unknown or changing IPs, setting the H46018Server flag explicitly allows GnuGk to update the client's IP on the first keepAlive SCI message.

Example:

[RoutedMode]
EnableH46018=1

[RasSrv::Neighbors]
VCSClient=Generic

[Neighbor::VCSClient]
GatekeeperIdentifier=FooVCS
Host=192.168.1.1
SendPrefixes=02
AcceptPrefixes=*
H46018Client=0
H46018Server=1
AuthUser=clientuser
Password=clientpw

10.5 Configuring a Traversal Zone with GnuGk as Traversal Client

To configure a traversal zone with a Tandberg VCS, add a Zone of type "Traversal server" in the VCS. When functioning as a traversal server, the VCS usually uses a different port, so make sure you add the port to the Host switch.

Enable H.323 in the VCS settings, set the Protocol to H.460.18 (not Assent) and select a port (you can't use 1719!). You must specify this port in your GnuGk config for this neighbor. Set a username and password in the VCS and put them into SendAuthUser= and SendPaswword= in your GnuGk config.

In the GnuGk config, set EnableH46018=1 in [RoutedMode] and set H46018Client=1 in the [Neighbor::..] section.

Please note that for any password authentication to work, both systems must have accurate and synchronized time, so it is strongly recommended that you configure NTP.

Example:

[RoutedMode]
EnableH46018=1

[RasSrv::Neighbors]
VCSServer=Generic

[Neighbor::VCSServer]
;from unknown IP
Host=211.211.10.10:9004
SendPrefixes=*
AcceptPrefixes=*
H46018Client=1
H46018Server=0
SendAuthUser=serveruser
SendPassword=serverpw

11. Per-Endpoint Configuration

In addition to the standard configuration file options, per-endpoint configuration settings can be specified in the GnuGk config file. The syntax is as follows:

11.1 Section [EP::...]

[EP::ALIAS]
Key Name=Value String

ALIAS should be replaced with the actual alias for the endpoint the settings should apply to. If your endpoint has multiple aliases, you can pick one of them. GnuGk will look through all aliases and use the first [EP:..] section it finds.

Currently, the following options are recognized:

Example how to attach an [EP::..] section to an endpoint:

[RasSrv::PermanentEndpoints]
192.168.1.1=gw1;48
192.168.1.2=gw2;48,!4850,!4860,!4869,!4888

[EP::gw1]
Capacity=60
GatewayPriority=1

[EP::gw2]
Capacity=30
GatewayPriority=2

In this example, calls will be sent to the gateway gw1 until its capacity is fully utilized (60 concurrent calls) and then to the gateway gw2.

12. Advanced Configuration

12.1 Section [CallTable]

12.2 Section [H225toQ931]

When converting between H.225 reasons and Q.931 cause codes, GnuGk uses a conversion table. Using this section you can change this mapping.

[H225toQ931]
;0=34 # noBandwidth
;1=47 # gatekeeperResources
2=34 # unreachableDestination => NoCircuitChannelAvailable (default 3)
;3=16 # destinationRejection
;4=88 # invalidRevision
;5=111 # noPermission
;6=38 # unreachableGatekeeper
;7=42 # gatewayResources
;8=28 # badFormatAddress
;9=41 # adaptiveBusy
;10=17 # inConf
;11=31 # undefinedReason
;12=16 # facilityCallDeflection
;13=31 # securityDenied
14=34 # calledPartyNotRegistered => NoCircuitChannelAvailable (default 20)
;15=31 # callerNotRegistered
;16=47 # newConnectionNeeded
;17=127 # nonStandardReason
;18=31 # replaceWithConferenceInvite
;19=31 # genericDataReason
;20=31 # neededFeatureNotSupported
;21=127 # tunnelledSignallingRejected

12.3 Section [GkQoSMonitor]

Use H.460.9 to collect Quality of Service information from endpoints. Endpoints must support H.460.9 for this service to function.

12.4 Section [GkQoSMonitor::SQL]

This section allows you to store QoS information in a database. You can use the same database parameters as defined in [SQLPasswordAuth].

12.5 Section [Endpoint]

The gatekeeper can function as an endpoint by registering with another gatekeeper, allowing you to build gatekeeper hierarchies. This section defines the endpoint features for the gatekeeper.

12.6 Section [CTI::Agents]

This section allows the configuration of a so-called virtual queue to allow inbound call distribution by an external application via the status port. A virtual queue has a H.323 alias that can be called like an endpoint or it can answer to a set of aliases.

Once a call arrives on the virtual queue, the gatekeeper signals a RouteRequest on the status port and waits for an external application to respond with either a RouteReject (which will cause the call to be rejected) or with RouteToAlias/RouteToGateway which leads to the destination being rewritten so the call will be routed to the alias (eg. call center agent) specified by the external application.

If no answer is received after a timeout period, the call is terminated.

You can specify virtual queues in three ways:

To apply the virtual queue to all calls, specify a regular expression that matches everything, see the example below.

See the monitoring section for details on the messages and responses.

12.7 Section [CTI::MakeCall]

This section contains the settings for the status port command MakeCall.

12.8 Section [SQLConfig]

Load gatekeeper settings from a SQL database (in addition to settings read from the config file). A generic ConfigQuery can be used to read almost all setting from the database and/or one of [RasSrv::RewriteE164], [RasSrv::PermanentEndpoints], [RasSrv::Neighbors], [RasSrv::GWPrefixes] queries can be used to load particular settings. Entries read from the SQL database take precedence over settings found in the config file.

Use the common database configuration options to define your database connection for this module.

12.9 Section [PortNotifications]

GnuGk can execute a system command whenever it opens a new port for listening. For example, this can be used to automatically update the firewall configuration.

The following placeholder are available:

By configuring a command to run for some types of ports, but not for others, you can easily choose which ports to handle and which to ignore.

Example:

[PortNotifications]
Q931PortOpen=/usr/local/bin/ports.sh %p %n %i
Q931PortClose=/usr/local/bin/ports.sh %p %n %i
H245PortOpen=/usr/local/bin/ports.sh %p %n %i
H245PortClose=/usr/local/bin/ports.sh %p %n %i
RTPPortOpen=/usr/local/bin/ports.sh %p %n %i
RTPPortClose=/usr/local/bin/ports.sh %p %n %i
RASPortOpen=/usr/local/bin/ports.sh %p %n %i
RASPortClose=/usr/local/bin/ports.sh %p %n %i
T120PortOpen=/usr/local/bin/ports.sh %p %n %i
T120PortClose=/usr/local/bin/ports.sh %p %n %i

12.10 Section [SNMP]

The Simple Network Management Protocol (SNMP) lets you monitor the GNU Gatekeeper during operation and allows you to configure a destination system for notifications ("traps") when an error occurs.

If the GnuGk configuration file enables SNMP, and the Net-SNMP implementation is selected, then GnuGk will register as an AgentX sub-agent with the Net-SNMP daemon. By default GnuGk will connect to the localhost IP address (127.0.0.1) and TCP port 705. Registering as a sub-agent allows you to continue querying Net-SNMP about the general health of the server and adds a GnuGk specific object.

All GET / SET requests and SNMP traps are performed by the Net-SNMP daemon, so configuration of access control, trap destination and SNMP version information must be done in the Net-SNMP .conf file.

If PTLib's SNMP implementation is selected, GnuGk starts a standalone SNMP agent. NOTE: Only one SNMP agent can bind to UDP/161, so you might have to use a non-standard port if you are using another SNMP agent on your server.

NOTE: By default, PTLib enables SNMP during the configuration process, so if SNMP doesn't work ensure that your PTLib wasn't compiled with --disable-snmp

Using PTLib rather than the fully-featured Net-SNMP means that only traps and GET requests are supported. See below for the additional switches which are required when using PTLib for SNMP.

The Windows implementation integrates as a sub-agent into Windows' SNMP service. This implementation is incomplete. You can use the PTLib implementation on Windows, for the sam elimited SNMP support as on Unix. Please contact the authors if you need full SNMP support on Windows.

GNU Gatekeeper Enterprise MIB

The GNU Gatekeeper Project was assigned the enterprise number 27938 by IANA (Internet Assigned Number Authority), so all of GnuGk's OIDs are under 1.3.6.1.4.1.27938.

The formal MIB specification (SMIv2) can be found in the file 'gnugk.mib' that is distributed with GnuGk. You might want to import it into your SNMP management software to see symbolic names for GnuGk's OIDs.

The following OIDs are available:

All of these OIDs are scalars, so please remember to append '.0' when querying them eg. with 'snmpget'.

Note: Setting the CatchAll destination via SNMP will update the config file to make the change permanent. Setting the trace level is a temporary setting.

The following traps are defined:

Traps may have 3 optional data elements:

Configuring Net-SNMP

Net-SNMP configuration is usually found in /etc/snmp/snmpd.conf. This configuration file defines access control rules for the SNMP manager and where settings such as readonly and read-write community names are defined, where to send traps, etc.

Depending on which trap host definition you use, Net-SNMP will convert the traps to the appropriate version. Use 'trapsink' if you want to send version 1 traps, 'trap2sink' if you want to send version 2 traps and 'informsink' for SNMP v3 inform messages.

Please make sure AgentX support is enabled in the Net-SNMP daemon.

Simple example of a snmpd.conf for SNMP version 2c:

# server location and contact
syslocation Server Room
syscontact Sysadmin (root@example.com)

# read-only access only from this network, access to all MIBs
rocommunity public 192.168.1.0/24
# read-write access only from this network, restricted to the GnuGk MIB
rwcommunity mysecret 192.168.1.0/24     1.3.6.1.4.1.27938

# send traps as version 2 to this host with community string 'public'
trap2sink   192.168.1.64    public

# enable AgentX support
master agentx
agentxsocket tcp:localhost:705

For SNMP version 3 the config file could look like this:

# server location and contact
syslocation Server Room
syscontact Sysadmin (root@example.com)

# read-only access for user 'peter'
rouser peter
# full read-write access for user 'paul'
rwuser paul
# read-write access only for the GnuGk MIB for user 'mary'
rwuser mary auth 1.3.6.1.4.1.27938

# create the user accounts and set passwords
createUser peter MD5 peterpeter DES
createUser paul MD5 paulpaul DES
createUser mary MD5 marymary DES

# send traps as version 3 Inform messages with community string 'public'
informsink   192.168.1.64    public

# enable AgentX support
master agentx
agentxsocket tcp:localhost:705

You can also configure the Net-SNMP based agent to run standalone without the Net-SNMP daemon, but this is not suggested.

Using PTLib's SNMP implementation

PTlib supports SNMP version 1 and 2 GET requests and will always send version 1 traps in a version 2c message. GETNEXT (for 'walk') and SET requests are not supported.

When using PTLib, you can use these additional switches:

12.11 Section [TLS]

Using TLS (transport layer security), you can encrypt the Q.931 signalling channel (and eg. H.245 when it is tunneled). When TLS is enabled, GnuGk will listen on port 1300 for TLS connections.

Each leg of the call can use not not use TLS individually. For example one endpoint might encrypt its signalling to the GNU Gatekeeper and the 2nd half of the call going out to another endpoint may be unencrypted.

You have to define manually which endpoints use TLS when we call them, by setting a switch in their [EP::...] section. Similar you can enable TLS for neighbor and parent gatekeeper. Since not many endpoints support TLS encryption, so this feature can be very usefull to secure "trunk" connections or traversal zones to branch offices etc.

Using TLS is also important to avoid man-in-the-middle attacks on H.235.6 media encryption.

Note: Currently you must use H.245 tunneling when using TLS, consider H245TunnelingTranslation=1 to tunnel H.245 between gatekeepers when not all of your endpoints enable tunneling natively.

Generating keys and certificates with OpenSSL

You don't have to trust the same CAs (certification authorities) that you are using for web browsing etc. By default GnuGk ignores the root certificates installed with OpenSSL on your server, but you can enable them by setting CADir=.

To have tight control over who you trust, you can generate your own CA using OpenSSL and only allow connections with certificates signed by your CA. Set you own CA with the CAFile= switch and leave CADir= unset.

To follow the step-by-step instructions, you need a definition file for your CA, called root.cnf and one for the server called server.cnf (see below). While following these steps, you will be asked a few times for the passphrase for the generated files. You should use the same for all of them and add it to your GnbuGk config with the Passphrase= switch.

First, generate your CA and self-sign it:

openssl req -newkey rsa:2048 -sha256 -keyout root_key.pem -out root_req.pem -config root.cnf
openssl x509 -req -in root_req.pem -sha256 -extfile root.cnf -days 365 -extensions certificate_extensions -signkey root_key.pem -out root_cert.pem

Then generate one key for each server or endpoint and sign them with the CA certificate:

openssl req -newkey rsa:2048 -sha256 -keyout server_key.pem -out server_req.pem -config server.cnf -reqexts req_extensions
openssl x509 -req -in server_req.pem -sha256 -extfile root.cnf -days 365 -extensions certificate_extensions -CA root_cert.pem -CAkey root_key.pem -CAcreateserial -out server_cert.pem
And then repeat to generate as many certificates as necessary.

The certificates generated above are valid for 365 days. Make sure you replace them before they expire, otherwise you won't be able to make calls!

To check then content of a generated certificate (eg. to see if it has expired or if the DNS name is OK), you can use

openssl x509 -text -in server_cert.pem

Here is a sample root.cnf file that you can adapt:

[ ca ]
default_ca       = gnugk_ca

[ gnugk_ca ]
dir              = /opt/gnugk-ca
certificate      = $dir/cacert.pem
database         = $dir/index.txt
new_certs_dir    = $dir/certs
private_key      = $dir/private/cakey.pem
serial           = $dir/serial
 
default_crl_days = 7
default_days     = 365
default_md       = sha256
 
policy           = gnugk_ca_policy
x509_extensions  = certificate_extensions
 
[ gnugk_ca_policy ]
commonName             = supplied
stateOrProvinceName    = supplied
countryName            = supplied
emailAddress           = supplied
organizationName       = supplied
organizationalUnitName = optional
 
[ req ]
default_bits        = 2048
default_keyfile     = privkey.pem
default_md          = sha256

prompt              = no
distinguished_name  = req_distinguished_name
x509_extensions     = req_extensions

# the following sections are specific to the request we're building

[ certificate_extensions ]
basicConstraints = CA:true
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always

[ req_distinguished_name ]
countryName         = US
stateOrProvinceName = Virginia
localityName        = Fairfax
organizationName    = Zork.org
commonName          = GnuGk Root CA

[ req_extensions ]
basicConstraints = CA:true

Here is a sample server.cnf file that you can adapt:

[ ca ]
default_ca       = gnugk_ca

[ gnugk_ca ]
dir              = /opt/gnugk-ca
certificate      = $dir/cacert.pem
database         = $dir/index.txt
new_certs_dir    = $dir/certs
private_key      = $dir/private/cakey.pem
serial           = $dir/serial
 
default_crl_days = 7
default_days     = 365
default_md       = sha256
 
policy           = gnugk_ca_policy
x509_extensions  = certificate_extensions
 
[ gnugk_ca_policy ]
countryName            = supplied
stateOrProvinceName    = supplied
localityName           = supplied
organizationName       = supplied
organizationalUnitName = optional
commonName             = supplied
emailAddress           = optional
 
[ req ]
default_bits        = 2048
default_keyfile     = privkey.pem
default_md          = sha256

prompt              = no
distinguished_name  = req_distinguished_name
x509_extensions     = req_extensions

# the following sections are specific to the request we're building       

[ certificate_extensions ]
basicConstraints = CA:false
subjectAltName = DNS:gk1.zork.org

[ req_distinguished_name ]
countryName            = US
stateOrProvinceName    = Virginia
localityName           = Fairfax
organizationName       = Zork.org
commonName             = gatekeeper.zork.org

[ req_extensions ]
basicConstraints = CA:true
subjectAltName = DNS:gk1.zork.org

13. Monitoring the Gatekeeper

13.1 Status Port

The status port is the external interface for monitoring and controlling the gatekeeper. The gatekeeper will send out messages about ongoing calls to all connected clients and it can receive commands via this interface.

Access to the status port is restricted by the rules in GkStatus::Auth. For security reasons, the default is not to allow any access until you have configured GkStatus::Auth.

The messages sent by the gatekeeper to the status port are grouped into three output trace levels: (These trace levels only apply to what is shown on the status port. Don't confuse them with the trace level for GnuGk's trace file.)

The client connected to the status port can choose the output level it is interested in.

The interface is a simple TCP port (default: 7000) which you can connect to with telnet or another client. One example of a different client is the Java GUI, aka GkGUI. Another example is the Automatic Call Distribution application, aka GnuGk ACD.

Application Areas

What you do with the powers of the Status Interface is up to you, but here are a few ideas:

Examples

Suppose you are just interested in the CDRs (call detail records) and want to process them as a batch at regular intervals.

Here is a simple Perl script (gnugk_cdr.pl) that starts the gatekeeper and also forks a very simple client for the Status Interface and writes just the CDRs into a logfile. You'll have to modify it a little to fit your needs.

#!/usr/bin/perl
# sample program that demonstrates how to write the CDRs to a log file
use strict;
use IO::Socket;
use IO::Handle;

my $logfile = "/home/jan/cdr.log";      # CHANGE THIS
my $gk_host = "localhost";
my $gk_port = 7000;
my $gk_pid;

if ($gk_pid = fork()) {
        # parent will listen to gatekeeper status
        sleep(1);       # wait for gk to start
        my $sock = IO::Socket::INET->new(PeerAddr => $gk_host, PeerPort => $gk_port, Proto => 'tcp');
        if (!defined $sock) {
                die "Can't connect to gatekeeper at $gk_host:$gk_port";
        }
        $SIG{HUP} = sub { kill 1, $gk_pid; };   # pass HUP to gatekeeper
        $SIG{INT} = sub { close (CDRFILE); kill 2, $gk_pid; };  # close file when terminated

        open (CDRFILE, ">>$logfile");
        CDRFILE->autoflush(1);  # don't buffer output
        while (!$sock->eof()) {
                my $msg = $sock->getline();
                $msg = (split(/;/, $msg))[0];   # remove junk at end of line
                my $msgtype = (split(/\|/, $msg))[0];
                if ($msgtype eq "CDR") {
                        print CDRFILE "$msg\n";
                }
        }
        close (CDRFILE);
} else {
        # child starts gatekeeper
        exec("gnugk");
}

Keep in mind that this is just an example to show the usage of the status port. You can use the FileAcct module to log CDRs in a production system.

Java GUI for the Gatekeeper

Developed by Jan Willamowius.

You can monitor the registrations and calls that go through the gatekeeper. A right-click on a button gives you a pop up menu for that endpoint.

This GUI works with Java 1.0 built into most web browsers. For security reasons the GUI must be run as a standalone application or served by a web server on the same IP number as the gatekeeper (you cannot run it as an applet via a local file).

The program is available at GnuGk.org

13.2 Commands (Reference)

This section lists all commands that you can issue to the status port (manually or with an external application). Commands are not case-insensitive, but parameters may be.

Entering help or h will display a list of all available commands.

13.3 Messages (Reference)

The section describes the messages output to the status interface.

13.4 Status Port Filtering

Status port filtering facilitates control of the amount and type of output messages shown to the end user. Filtering is done using regular expressions which are used to decide whether to include (show) or exclude (ignore) an output message. Filtering control is performed using the following set of commands:

In order to enable usage of predefined filters, a new section named [GkStatus::Filtering] has been introduced. You may specify predefined filters to be loaded when the status port starts.

Example:

[GkStatus::Filtering]
IncludeFilter=.+
ExcludeFilter=.RQ
Enable=1

When filtering is enabled using the the filter 1 command, all messages will be shown other than lines with ARQ, LRQ etc. You may also type the following into the status port:

addincludefilter .+
addexcludefilter .RQ
filter 1

Note that if you enable filtering when there are no include filters defined this will automatically exclude all message output!

Example to hide Tandberg's neighbor check and traversal zone keepalive messages:

[GkStatus::Filtering]
Enable=1
IncludeFilter=.+
ExcludeFilter=gatekeeper-monitoring-check
ExcludeFilter=SCR

There is an additional switch to only print RCF events for previously unregistered endpoints and supress the refereh RCFs:

[GkStatus::Filtering]
NewRCFOnly=1

13.5 Status Port Message Format

The format of status port event messages may be altered to reorder or include options not included in the standard output format. NOTE: This section has no effect on the format of the response of status port commans, like eg. PrintAllRegistrationsVerbose.

The settings in this section may be updated by reloading the configuration while the gatekeeper is running.

Example:

[GkStatus::Message]
Compact=0
RCF=%{IP:Port}|%{Aliases}|%{Endpoint_Type}|%{EndpointID}|%{NATType}|%{Vendor}
URQ=%{IP:Port}|%{Aliases}|%{Endpoint_Type}|%{EndpointID}|%{NATType}|%{Vendor}|%{EndpointRASAddr}|%{URQReason}

14. Advanced Topics

This portion of the manual will cover advanced topics, such as compiling and debugging the GNU Gatekeeper.

14.1 Compiling GnuGk from CVS

The following instructions are an example of how to compile GnuGk from source on an Ubuntu platform.

First make sure your system is up-to-date and install the tools needed for the compile

$ sudo apt-get update
$ sudo apt-get install flex bison build-essential subversion cvs pkg-config automake
Also make sure the "...-devel" packages for all databases you want to use are installed.

NOTE: As of 2013-12-30, it's recommended that you do not use PTLib SVN; it is undergoing many changes that are incompatible with GnuGK.

Get and compile PTLib from SourceForge:

$ cd ~
$ svn co http://svn.code.sf.net/p/opalvoip/code/ptlib/tags/v2_10_9 ptlib-v2.10.9/
$ cd ptlib-v2.10.9
$ export PTLIBDIR=~/ptlib-v2.10.9
$ ./configure
$ make optnoshared

Get and compile H323Plus:

$ cd ~
$ cvs -d:pserver:anonymous@h323plus.cvs.sourceforge.net:/cvsroot/h323plus login

(just press enter when prompted for password)

$ cvs -z3 -d:pserver:anonymous@h323plus.cvs.sourceforge.net:/cvsroot/h323plus co -P h323plus

$ cd h323plus
$ export OPENH323DIR=~/h323plus
$ ./configure
$ make optnoshared

Get and compile GnuGk:

$ cd ~
$ cvs -d:pserver:anonymous@openh323gk.cvs.sourceforge.net:/cvsroot/openh323gk login

(just press enter when prompted for password)

$ cvs -z3 -d:pserver:anonymous@openh323gk.cvs.sourceforge.net:/cvsroot/openh323gk co -P openh323gk

$ cd openh323gk
$ ./configure --enable-h46018
$ make optnoshared

Once the compile is finished, the binary can be found in the obj_linux_x86_s subdirectory.

At this time, because all libraries and GnuGk are running CVS and SVN versions of the software, in order to stay up-to-date, run the following:

$ cd ~/ptlib
$ svn update
$ cd ~/h323plus
$ cvs update
$ cd ~/openh323gk
$ cvs update
If any of the source files are changed, you have to recompile.

14.2 Tracing GnuGk

If GnuGk doesn't handle calls like you expect, you can enable tracing to see what GnuGk does internally. Don't confuse this with connection to the status port and looking at the events ("telnet 127.0.0.1 7000"). Creating a trace file will reveal a lot more of the internal workings.

On the command line, start GnuGk with -ttttt and -o to write the trace to a file:

gnugk -c gnugk.ini -ttttt -o trace.log

If you have a lot of calls, trace.log can grow quite large, so make sure you disable it after you are done with testing, or at least reduce the trace level to 2 or 3 for production.

You can also enable tracing in your config file:

[Gatekeeper::Main]
TraceLevel=5

[LogFile]
Filename=trace.log

Or you can enable tracing through the status port:

setlog trace.log
debug trc 5

Doing it through the status port has the advantage that you won't interrupt ongoing calls and you can quickly turn it on or off.

The trace file will contain information al everything GnuGk does. To reduce it to a single call, you can eg. search for the callID or write a small Perl script to extract only those messages you are interested in.

14.3 Debugging GnuGk (on Linux)

In order to use gdb with GnuGk, the software and libraries must be compiled with debug support.

You may follow the instructions above in obtaining the software, but the compile in each subdirectory must be:

$ make debugnoshared

Allow unlimited core dumps:

ulimit -c unlimited

Run GnuGk:

~/openh323/obj_linux_x86_64_d_s/gnugk -c your.ini
# wait for crash
gdb obj_linux_x86_64_d_s/gnugk core
bt

Once you've obtained a backtrace, post it to the mailing list.

Note: On some systems, the core dump is named "core.xxx" where xxx is the process number of the program that crashed.