E.164, ENUM & NATPR
First of all, the acronym ENUM stands for E.164 NUmber Mapping. ENUM is an specification on how to use the DNS system to map telephone numbers (in E.164 format) to an URI, email address or internet protocol address. E.164 is the number format for national and international telephone numbers, normal telephone numbers. The E.164 notation is documented in the ITU E.123 standard.
The resulting fields of an ENUM query are a DNS record type called NAPTR, DNS NAPTR, or less commonly; DNS Name Authority Pointer. Not all DNS servers support this record type. BIND/Named and PowerDNS support it natively, djbdns requires to be patched, Windows DNS Server doesn't support NAPTR at all.
ENUM is ideal for many telecommunications and operation environments, in which given destinations are to be found only under specific hosts or providers. It can be used not only for E.164 format numbers, but also for finding user extensions inside internal numbering and dialing plans in large corporate infrastructures as well as a basic mechanism for clustering and distributed call processing systems.
Setting up an ENUM server:
I will use PowerDNS to give an example of a DNS server which will respond to ENUM queries. PowerDNS offers several backend drivers, such as LDAP and PostgreSQL and SQLite3. I will to use the MySQL backend in this article:
# apt-get install pdns-backend-mysql pdns-server
Then you need to create the database and the tables tables in which domains and records will be stored. You will also need to create a MySQL user for PowerDNS:
# mysqladmin create pdns # mysql pdns << EOF create table domains ( id INT auto_increment, name VARCHAR(255) NOT NULL, master VARCHAR(128) DEFAULT NULL, last_check INT DEFAULT NULL, type VARCHAR(6) NOT NULL, notified_serial INT DEFAULT NULL, account VARCHAR(40) DEFAULT NULL, primary key (id) )type=InnoDB; CREATE UNIQUE INDEX name_index ON domains(name); CREATE TABLE records ( id INT auto_increment, domain_id INT DEFAULT NULL, name VARCHAR(255) DEFAULT NULL, type VARCHAR(6) DEFAULT NULL, content VARCHAR(255) DEFAULT NULL, ttl INT DEFAULT NULL, prio INT DEFAULT NULL, change_date INT DEFAULT NULL, primary key(id) )type=InnoDB; CREATE INDEX rec_name_index ON records(name); CREATE INDEX nametype_index ON records(name,type); CREATE INDEX domain_id ON records(domain_id); create table supermasters ( ip VARCHAR(25) NOT NULL, nameserver VARCHAR(255) NOT NULL, account VARCHAR(40) DEFAULT NULL ); GRANT SELECT ON supermasters TO 'pdns'@'localhost' IDENTIFIED BY 'yourpassword'; GRANT ALL ON domains TO 'pdns'@'localhost' IDENTIFIED BY 'yourpassword'; GRANT ALL ON records TO 'pdns'@'localhost' IDENTIFIED BY 'yourpassword'; FLUSH PRIVILEGES; EOF
Edit /etc/powerdns/pdns.d/pdns.local, and add the following lines to enable MySQL support and specify database connection parameters (replace parameters with your connection parameters):
launch=gmysql gmysql-host=localhost gmysql-user=pdns gmysql-password=yourpassword gmysql-dbname=pdns
Re-start the pdns daemon, use /etc/init.d/pdns monitor to debug its initialization.
Tip: You can add log = /var/log/mysql/mysql.log to /etc/mysql/my.conf to enable query logging in MySQL.
ENUM Domain Names:
In order to provision the database with NAPTR records, we first need to generate a valid ENUM "domain name". If you want to convert for example the number: "+44-116-496-0348", you'll need to (excerpt from RFC 3761):
1. Remove all characters with the exception of the digits.
2. Put dots (".") between each digit. Example: 4.4.2.0.7.9.4.6.0.1.4.8
3. Reverse the order of the digits. Example: 8.4.1.0.6.4.9.7.0.2.4.4
4. Append the string ".e164.arpa" to the end. Example: 8.4.1.0.6.4.9.7.0.2.4.4.e164.arpa
This way "+442079460148" becomes "8.4.1.0.6.4.9.7.0.2.4.4.e164.arpa".
NAPTR records:
Suppose you have several proxies across a corporate network and you'd like to use ENUM as a call routing mechanism, so you'd like to create a NAPTR record for the extension number 12345678 under the example.tld domain name and point it to sip:12345678@10.0.0.10, so you create the domain name and the record separately in the database:
INSERT INTO `domains` (name, TYPE)
VALUES ('enum.example.tld',
'MASTER');
INSERT INTO `records` (domain_id, name, TYPE, content, ttl, prio)
VALUES (1,
'8.7.6.5.4.3.2.1.enum.example.tld',
'NAPTR',
"100 10 \"u\" \"E2U+sip\" \"!^.*$!sip:12345678@10.0.0.10!\" .",
120,
0);
Make sure that records.domain_id corresponds to domains.id, or your queries will not work. Since most of the fields are self-descriptive the only one I think it's worth to explain is content. Note that this is a string holding several space-separated fields. These fields are: order, preference, flags, service, regex and replacement. This is the standard format for NAPTR records defined in RFC 2915.
Testing your setup:
In order to query the DNS for a NAPTR you can simply do (supposing your DNS server is running in localhost):
host -t naptr 8.7.6.5.4.3.2.1.enum.example.tld 127.0.0.1
Or using dig...
dig @127.0.0.1 8.7.6.5.4.3.2.1.enum.example.tld NAPTR
Asterisk's CMD ENUMLookup:
Make sure /etc/asterisk/enum.conf contains the domains you want to use:
[general] search => e164.arpa search => e164.org search => example.tld
Then call the ENUMLOOKUP function in the dialplan (note: the function sets only a string variable you will have to include in your dial-string separatedly). A very minimalistic example:
exten => _X.,1,Set(res=${ENUMLOOKUP(12345678,sip,1,enum.example.tld)})
exten => _X.,n,Dial(SIP/${res})
This module has several configuration parameters you might want to take a look at.
Posted by Administrator on Mon, 27 Dec 2010