Notes on making DUNDi work on Asterisk.

Loren Moore 346d832876 Additional tweak 1 month ago
README.md 346d832876 Additional tweak 1 month ago

README.md

Asterisk & DUNDi For A Private Experimental Network

DUNDi is a distributed/peer-to-peer system for locating endpoints. Peers ask known and trusted peers the location of a number, who will reply or ask their peers. Once a destination is found; information is exchanged so the call can be completed. Each server is responsible for announcing which numbers it serves. Pattern matching is also possible; which is how our organization will use it.

The Super-Simple Explanation

You're on server number 34 and you want to call your friend on server 555. So you punch his number, 555-555-123, in to your phone and hit the send command. Your server looks at the number:

Peer A: "Okay...it's a nine digit number. That's a network number. I don't know where 555 is. HEY! ANYONE KNOW WHERE 555-555-123 IS?"

Peer B: "Hold on."

Peer C: "I'm on it."

Peer C: "Where's 555-555-123?"

Peer D: "I heard 10.1.1.123 is handling 555-555-123"

Peer C: "Okay. HEY PEER A! TRY 10.1.1.123!"

Peer A: "Hi 10.1.1.123. I'm from the network. I got a call for 555-555-123"

555: "You came in the right door with the right key. Here you go."

It's very clearly a case of you don't have the entire phone book, but you know where to find who might. Peer A and Peer D don't even have to know each other; but as long as each one is trusted by a server in the chain. This sounds over-complicated; but it allows for a decentralized system where the outage of a server only affects the users of that server.

Of course this is just a draft and I need to probably clear up some technical documents. I'm just writing this as a quick-n-dirty for network devs to get started.

Just Get To The Configs

There are three files we need to mess with:

  • iax.conf
  • dundi.conf
  • extensions.conf

These are the basic steps it takes to get this going...I'll cover in detail:

  • configure dundi and peers
  • generate and exchange keys for dundi peers
  • configure the iax2 bridge we'll use for calls
  • specify the calls we'll serve using DUNDi
  • the dialplan to make it all work (incoming and outgoing)

You will need these modules loaded:

  • res_crypto
  • pbx_dundi

dundi.conf

[general]
;
department=VOIP
organization=org international
locality=New York
stateprov=NY
country=US
email=dude@mail.c
phone=+4204206969
;
; Specify bind address and port number.  Default is port 4520.
;bindaddr=0.0.0.0
;port=4520
entityid=FF:FE:FF:FE:FF:FE
ttl=32
autokill=yes
;secretpath=dundi

[00:00:00:00:00:00] ; Home PBX
model = symmetric
host = host.name
inkey = keyofpeer
outkey = yourkey
include = mapping
permit = mapping
qualify = yes
dynamic=yes

[mappings]
network1 => local-context,0,IAX2,name:${SECRET}@host.name/${NUMBER}

The basic configuration is similar on each side. The General section contains information about your organization. This is required for linking with the public DUNDi network. We're running a lulzwerk, this doesn't need to be real. (Although we may ask server ops to be somewhat serious in the fugure)

  • entityid= defaults to your MAC address. We will make-up/assign ones for our private use.
  • ttl= I'll get back to you when I see a reason to change this from 32
  • autokill= prevents issues if a peer doesn't respond

Peers are in a context containing their mac address. Each peer you trust is put here. I'll only cover the values you're interested in:

  • host= ovbiously the hostname of the peer. use a hostname to keep dynamic IPs from breaking things
  • inkey= the public .key file of the peer. stored in /var/lib/asterisk/keys
  • outkey= your private key stored in /var/lib/asterisk/keys
  • include= the mapping context to include in this peer's search
  • permit= the mapping context you permit matching to (??? - just make it match)

The [mappings] section defines a network_to_map => context_of_numbers. The context must exist in your dialplan somewhere, we'll cover how you make extensions. The network name must be the same across all peers.

network1  => network1-context,0,IAX2,name:${SECRET}@host.name/${NUMBER}
network2  => network2-context,0,IAX2,name:${SECRET}@host.name/${NUMBER}

Generating Keys

cd /var/lib/asterisk/keys
/usr/sbin/astgenkey -n name

astgenkey may be under /contrib/scripts in your asterisk source directory

You get two files; the .key is the public key. This is the one you share with all your peers; unless you all run the exact same key.

In theory any peer can be an idiot and stick another peer on the network by adding them to their configuration and exchanging keys. Then that new rogue peer just has to advertise some numbers.

iax.conf

I'm going to give you a stupid simple conf:

[iaxname]
type=friend
dbsecret=dundi/secret
context=incomigcontext

This enables iax2 connectivity between servers after talking via DUNDi. Give the connection a name (I was wrong..this doesn't have to match the DUNDi mapping name), set the context in the dialplan that handles incoming calls. Calls on the trunk from DUNDi go to that context. Authentication is handled by black magic DUNDi key rolling and such. This avoids us haivng to pass any passwords around for SIP.

extensions.conf

The dialplan itself is almost as simple:

[lookupdundi]
switch => DUNDi/network1

[network1-context]
exten => _420XXXXXX,1,NoOp

[incomingcontext]
exten => _420XXXXXX,1,Goto(internal,${EXTEN:-4},1)

[somecontextforoutgoingcalls]
exten = _XXXXXXXXX,1,Goto(lookupdundi,${EXTEN},1)
  • [lookupdundi] is what we call when we need to do a call with DUNDI. The context itself just switches channels.
  • [network1-context] are the numbers we advertise via DUNDi. In this case...we handle everything going to (420)XXX-XXX.
  • [incomingcontext] is how we handle incoming calls. This example just pulls the last four and sends to internal. This can get as easy or complex as you want.
  • [somecontextforoutgoingcalls] matches anything that's exactly six digits and looks it up via DUNDi. This requires I not use 6 digit extensions internally or elsewhere.

Firewall Ports

DUNDi uses port 4520/UDP. This needs to be open both ends.

Finishing Up & Testing

Reboot your server...or reload res_crypto, pbx_dundi, and chan_iax2 so all the new stuff takes effect. With luck you should see something like this on your asterisk console:

[Aug 15 23:07:14] NOTICE[98773]: pbx_dundi.c:3225 destroy_trans: Peer 'b0:0b:1e:54:20:69' has become REACHABLE!

This is good. You can verify by running dundi show peers

dundi show peers
EID                  Host                                          Port   Model      AvgTime  Status
b0:0b:1e:54:20:69    144.172.124.240                           (S) 4520   Symmetric  Unavail  OK (12 ms)
1 dundi peers [1 online, 0 offline, 0 unmonitored]

The real test is doing a query for a number:

pickmy*CLI> dundi lookup 4205555555@gonk
  1.     0 IAX2/gonko:J4wqBRGZYwQVGLImkPS5Lg==@dewdude.ath.cx/4205555555 (EXISTS|CANMATCH)
     from d0:0b:1e:04:20:69, expires in 3600 s
DUNDi lookup completed in 14 ms

You're Done

DUNDi is working. If calls fail then it's a problem with dialplan.