Can I connect two FreePBX/Asterisk Systems Together Over the Internet?
Yes. You can connect as many systems as you want together over the internet, even if all of them are behind a NAT Firewall. For the purpose of this Configuration Guide, we're going to assume that you have two systems, configured as listed below:
System 1: Los Angeles Extensions Numbered: 40 to 49 |
---|
System 2: New York Extensions Numbered: 50 to 59 |
---|
There are four simple steps:
- Configure an IAX2 Trunk on System1, The Trunk will establish a connection with System2.
- Configure an Outbound Route on System1. The Route will tell System1 which calls to send out to System2.
- Configure an IAX2 Trunk on System2. The Trunk will establish a connection with System1.
- Configure an Outbound Route on System2. The Route will tell System2 which calls to send out to System1.
1. Configure an IAX2 Trunk on System1
Access the Trunks Module on System1.
Click on the "Add Trunk" link at the top, right hand side of the screen in the Trunks Module.
Choose to create an IAX2 Trunk.
Use these parameters in the Trunk Settings:
Trunk Name: System2
Outbound Caller ID: CallerID
Dialed Number Manipulation Rules: Usually Blank
Trunk Name: System2
PEER Details:
username=System2 secret=password host=system2ipaddress type=friend context=from-internal qualify=yes qualifyfreqok=25000 transfer=no trunk=yes forceencryption=yes encryption=yes auth=md5 |
---|
Registration String: Blank.
Notes:
- Replace System1, System2, CallerID and password with whatever you want. However, be consistent! If you change System1, System2, or password in one spot, you must change it to the same thing in all of the other spots (on both systems).
- Capitalization Matters: System1 is not the same as system1 or SYSTEM1.
- If you have trouble making calls, your version of Asterisk may not have the encryption routines installed. Try deleting the last three lines in the PEER details on both systems.
- If you only want to be able to place calls to the remote system, but do not want the remote system to be able to call you directly, change "context=from-internal" to "context=from-trunk".
- If one of your systems has a dynamic IP address, you should register that system with a dynamic DNS service like DYNDNS and use domain names (i.e., xxxxxx.dyndns.com) instead of IP addresses in the host= field.
2. Configure an Outbound Route on System1
Access the Outbound Routes Module on System1.
Click on the "Add Route" link at the top, right hand side of the screen in the Trunks Module.
Use these parameters in the Route Settings:
Route Name: InterOfficetoSystem2
Route CID: YOURNUMBER
Route Type: CHECK Intra-Company.
Dial Patterns that will use this Route:
Patterns: () + | 5X () + | *805X () + *81 | .
| What it does: If a user dials extensions 50 through 59, the call will be sent to System2. If a user dials *80 (or presses an intercom button) and then extensions 50 through 59, the call be sent to System2. If a user dials *81 and then dials anything, the *81 will be removed and the rest of the numbers will be sent to System2. |
---|
Trunk Sequence: System2
Note:
- If your System2 does not use extensions 50 to 59, you'll want to change 5X to match whatever pattern you use. For example, if your System2 uses extensions in the 500 range, you might change 5X to 5XX. See the Dial Patterns tooltip for more examples.
- If your System2 has extension numbers that are the same as the extension numbers of your System1, then you should delete the first two dial patterns.
- If you do not want users on System1 to be able to dial *81 and then any feature code on System2, delete the third Dial Pattern.
- If your System2 has extension numbers that are the same as the extension numbers System1 and you do not want your System1 users to be able to dial *81 and then any feature code on System2, then you should delete all of the dial patterns and replace them with these:
- It appears that the username has to be the actual trunk name from the opposite end
() + *81 | 5X () + *81 | *805X | If a user dials *81 and then extension 50 to 59, the *81 will be removed and the rest will be sent to System1 If a user dials *81 and then *80 and then extension 50 to 59, the *81 will be removed and the rest will be sent to System1 This is used for intercom calls. |
---|
3. Configure an IAX2 Trunk on System2
Access the Trunks Module on System2.
Click on the "Add Trunk" link at the top, right hand side of the screen in the Trunks Module.
Choose to create an IAX2 Trunk.
Use these parameters in the Trunk Settings:
Trunk Name: System1
Outbound Caller ID: CallerID
Dialed Number Manipulation Rules: Usually Blank
Trunk Name: System1
PEER Details:
username=System1 secret=password host=system1ipaddress type=friend context=from-internal qualify=yes qualifyfreqok=25000 transfer=no trunk=yes forceencryption=yes encryption=yes auth=md5 |
---|
Registration String: Blank.
Notes: See the notes above, with respect to "Configure an IAX2 Trunk on System 1."
4. Configure an Outbound Route on System2
Access the Outbound Routes Module on System2.
Click on the "Add Route" link at the top, right hand side of the screen in the Trunks Module.
Use these parameters in the Route Settings:
Route Name: InterOfficetoSystem1
Route CID: YOURNUMBER
Route Type: CHECK Intra-Company.
Dial Patterns that will use this Route:
Patterns: () + | 4X () + | *804X () + *81 | .
| What it does: If a user dials extensions 40 through 49, the call will be sent to System1. If a user dials *80 (or presses an intercom button) and then extensions 40 through 49, the call be sent to System1. If a user dials *81 and then dials anything, the *81 will be removed and the rest of the numbers will be sent to System1. |
---|
Trunk Sequence: System1
Note:
- If your System1 does not use extensions 40 to 49, you'll want to change 5X to match whatever pattern you use. For example, if your System1 uses extensions in the 400 range, you might change 4X to 4XX. See the Dial Patterns tooltip for more examples.
- If your System1 has extension numbers that are the same as the extension numbers of your System2, then you should delete the first two dial patterns.
- If you do not want users on System2 to be able to dial *81 and then any feature code on System1, delete the third Dial Pattern.
- If your System1 has extension numbers that are the same as the extension numbers System2 and you do not want your System2 users to be able to dial *81 and then any feature code on System1, then you should delete all of the dial patterns and replace them with these:
() + *81 | 4X () + *81 | *804X | If a user dials *81 and then extension 40 to 49, the *81 will be removed and the rest will be sent to System1 If a user dials *81 and then *80 and then extension 40 to 49, the *81 will be removed and the rest will be sent to System1. This is used for intercom calls. |
---|
What Ports do I need to Forward?
None.
If you use IAX2 Trunks and configure them as indicated above, the IAX2 protocol will keep the ports open for the other system.
What If I Want to Connect More Than Two Systems?
There are two ways to do this.
1. You can connect each system to the other independently following the instructions above, i.e.
System 1 to System 2
System 1 to System 3
System 2 to System 1
System 2 to System 3
System 3 to System 1
System 3 to System 2
2. You can
- Connect System 1 to System 2
- Connect System 2 to System 3
- Configure the Outbound Route on System 1 to send calls intended for System 3 to System 2, which will then forward those calls to System 3.
- Configure the Outbound Route on System 3 to send calls intended for System 1 to System 2, which will then forward those calls to System 1.
The first option is far more reliable, as it permits each system to connect directly to each other system.
What if I want to use SIP Trunks?
If you want to use SIP Trunks, then at least one of your two systems must have external ports forwarded or be exposed directly to the internet. Setup is much more complicated, and you should also carefully set-up your firewall to keep out unauthorized users.
39 Comments
varnav
Martin Anderson
I can't say whether there is or is not a need for encryption=yes. However, it definitely doesn't hurt to have it on.
However, you are completely wrong about port forwarding. It is definitely NOT required. IAX was, in fact, designed to open ports only for the remote system and it does so perfectly. Opening the ports generally (for everyone) exposes your system to unnecessary security risks, and is definitely not necessary so long as both trunks point to one another. If you use host=dynamic on either end, then that device would require an open port.
varnav
iax2.conf.sample says that forceencryption=yes turns on encryption as well. There is simply no need to set encyption=yes in this case.
Talking about the port forwarding, it is best to look into RFC 5456 (IAX: Inter-Asterisk eXchange Version 2):
Deploying a single IAX server behind a NAT gateway requires little effort. If the server acts as a registrar, the IAX UDP port on the NAT gateway must be forwarded to the server. If the server acts as a registrant, the default, 60 second, REGREQ refresh timer should be sufficient to maintain a port association in the NAT gateway; however, a static port mapping is preferred.
But, in your example, registration mechanism is not used. If call is placed, calling server attempts to connect to port UDP 4569 on called server. If this port is not open or forwarded, no connection will be estabilished. There is no mechanism like UPnP in IAX2 protocol that allows reconfiguring NAT router automatically. So ports should be open/forwarded on both ends.
Martin Anderson
The qualify packets open the ports and keep them open. That's why we have qualify=yes and qualifyfreqok=25000. If you wanted to delete the qualify packets, you could also use registration to accomplish the same thing. You could even have each machine register to one another, I suppose.
It's all well and good to read the manual and make assumptions. But, I've used this configuration for years and it works just fine without forwarding any ports.
varnav
What transfer=no option is needed for?
Martin Anderson
transfer=no is the equivalent of canreinvite=no for SIP trunks.
varnav
Why do we need to set this for trunks?
Martin Anderson
Who said that we "needed" to set this? Much of what's in this configuration is based upon what's desirable.
The trunk would work just fine without the transfer, trunk, encryption, forceencryption, auth, and secret lines. However, that operation would not be very desirable.
If you chose to forward ports, you could also delete qualify and qualifyfreqok...
varnav
I know what transfer, trunk, encryption, forceencryption, auth, and secret lines do and what they are needed for.
But it's not clear for me what transfer=no does in trunk configuration. Can you please clarify?
Larry McPhillips
I tried these settings and at first it didn't work. Calls that were sent through the trunk were getting immediately disconnected. I turned on IAX2 debugging with "iax2 set debug on" and I saw the calls were getting rejected with Error 50: "No authority found".
In order to get the trunk to work, I had to fill in the "Incoming Settings" section of the Trunk screen in FreePBX. I filled it in as follows:
USER Context: <the user name from the opposite system's PEER Details section>
USER Details:
And then everything was fine and calls through the trunk were successful.
I wonder what's different about my setup which caused me to have to fill in the "Incoming Settings", when the original author apparently didn't have to.
varnav
In "Outbound route" - is "Intra company" checked?
Larry McPhillips
Ok, yep I've got the "Intra-Company" checked in the Outbound routes on both systems.
So I take it this is unusual, and most people don't see this issue? Hopefully my comment above will be useful to anyone else who experiences this.
Martin Anderson
When I wrote this article, I was using Asterisk 1.8. I'm now using Asterisk 11 and it still works just fine.
If it isn't working for you, I'd suspect that you're using a newer version of Asterisk. Digium makes changes in every version of Asterisk and there may well be something different in your version of Asterisk that requires additional settings.
Alternatively, you may not have followed the directions about how important it is that the username in the PEER details must match the trunk name right above the PEER details on the other system. Given what you're written as the solution, I'd bet that this is the issue.
Larry McPhillips
Ah- bingo, that's it! I had used a different name for the user than I did for the trunk.
Now I'm scratching my head as to why I didn't "follow the directions..."
Martin Anderson
From the directions...
"Notes:
Johann Zurner
But I can't imagine how this could work without forwarding port 4569 at least on one firewall. Cause if both of the servers are behind a different NAT firewall, then how would packets sent from one server (let's say on first time registration etc) ever be able to get through to the other server if the traffic coming from that server's IP address is not allowed through 4569 port on the other firewall?
Martin Anderson
It sounds as if you don't understand how iptables and similar firewalls operate, then.
You're right the very first packet that goes out won't make it. But, that's the only one that won't make it. Here's a summary of how it works.
These qualify packets continue to get sent, received, and replied to, keeping port 4569 open for the other system, in the event that an actual call needs to be set-up.
Larry McPhillips
This is interesting and instructive. One question that occurs to me: our routers frequently change the "from" port number on outbound traffic. So if the NAT does that, I believe that would prevent this solution from working?
For example, traffic coming from System A's port 4569 might be represented to the outside world as port 49162. And that would mean that 49162 is the external port number that the firewall leaves open.
Martin Anderson
Larry,
IAX2 uses IP headers to route return messages. So, if the router sends out a message from port 49162, the remote system will see that in the IP header and reply to that port.
Also, my experience is that most routers will use the desired port unless it is already in use. So, if you had two systems both using IAX2 behind the same router, one of them would likely get an alternative port. But, it wouldn't matter for the reason I stated above.
Johann Zurner
Thanks for the valuable info.
Does that still apply when one of the servers sits behind a firewall with a dynamic external IP address?
In the wiki you are saying that in that case, that system should be registered with a Dynamic DNS service.
Is there a way to make the setup work without DDNS, cause I don't find that that's particularly reliable?
Martin Anderson
Yes, this was written for use in systems where BOTH are behind a firewall with a dynamic IP address using DDNS.
If you have a static IP address, then you can just open a port and create a firewall rule that only allows packets in from the static IP of the remote system. Then you don't need the qualify settings at all, though they're still helpful to show that the connection is up.
Martin Anderson
Oh, and the DDNS setup works just fine for me. I also have VPN set-up between the two locations and a separate trunk that routes over the VPN.
William Wiley
Thank you for writing this guide. It worked perfectly for me. I'm running Asterisk 13.11.2; FreePBX 13.0.188.8 on two servers.
However, to make it work and stay working, I had to use the specific IP address in the host= field under peer details for each machine. Though they rarely change, they are both dynamic. (This also sounds like the issue Johann Zurner was experiencing.)
Using the DDNS (preferable) allowed it to work for a few minutes, but would stop working.
The asterisk terminal would spit out the following when this occurred:
netsock2.c:524 ast_sockaddr_hash: Unknown address family
I'm trying to figure out a solution at the moment so that pointing to the DDNS works reliably.
It appears to be related to the issue explained here and here.
I already have the dnsmgr.conf referenced in the first link with the installation. Anyone know of a solution?
Johann Zurner
For me this setup is not working at all, using hostnames or static IP addresses. Sangoma says this setup does work for some people depending on what firewall they have. Some can be tricked, some not. https://community.freepbx.org/t/iax-trunk-between-two-servers-behind-nat-not-working/39349
Apparently for mine, Sonicwall and OpenBSD, it doesn't work.
That wiki should be updated to reflect that it's only working for some.
Still, it's a very useful guide.
Martin Anderson
Please try forwarding Port 4569 from each router to your PBX and see if it does or does not work.
If it DOES NOT work, then you're likely seeing the recent Asterisk bug, and it has nothing to do with your router.
If it DOES work, then the issue is your router.
Please let me know.
ALSO- you should try rebooting your router or disable both trunks for 15 minutes or so and try again. Sometimes routers just get their NAT tables messed up. Likewise, if you have any other device on your network that uses IAX or uses Port 4569, that can prevent this method from working as well.
FreerPBXer
Running Asterisk 13.14.0 and FreePBX 10.13.66-19. There are incoming and outgoing tabs for an IAX trunk; does the username, etc. from the outgoing section need to be entered in the incoming section of the other system (this would be how it's done with SIP registrations).
Also, for test, I just want to make calls from System1 to System2 over the IAX trunk. Will it work if I create an outbound route on System1 for the IAX trunk, but not an outbound route on System2?
I think I have it setup per the instructions (including the intra-company setting and the dial pattern), but am getting the "Your call cannot be completed as dialed..." message on calls from System1 to System2 extensions.
FreerPBXer
More info: It looks like the IAX tunnel isn't getting build.
IAX2 show registry on the receiving system shows :
seaphones*CLI> iax2 show registry Host dnsmgr Username Perceived Refresh State 0 IAX2 registrations.
IAX set debug on shows this repeating:
Tx-Frame Retry[ No] -- OSeqno: 000 ISeqno: 001 Type: IAX Subclass: PONG Timestamp: 00019ms SCall: 00001 DCall: 14738 10.90.1.240:4569 Rx-Frame Retry[ No] -- OSeqno: 001 ISeqno: 001 Type: IAX Subclass: ACK Timestamp: 00019ms SCall: 14738 DCall: 00001 10.90.1.240:4569 Tx-Frame Retry[000] -- OSeqno: 000 ISeqno: 000 Type: IAX Subclass: POKE Timestamp: 00013ms SCall: 08766 DCall: 00000 10.90.1.240:4569
Sorry, I don't know enough to determine what's happening here.
FreerPBXer
I got it working using the instructions here: http://www.telecomworld101.com/Asterisk/pbx101trunk.html
This article could really use a rewrite; it's not complete/accurate for current versions of FreePBX.
Erik Hopfensperger
This is an extremely useful page. It would be helpful to update the OP to have the Incoming / USER Context examples as well. The link just above from FreerPBXer was great!
Martin Anderson
The configuration on Telecomworld101 is functionally exactly the same as the configuration posted here, if you follow all of the notes and delete certain lines that won't work if your system doesn't have the encryption routines installed.
The Incoming/USER settings are not necessary when you use type=friend (as indicated in these instructions). Type=friend generates the Incoming/USER settings automatically.
If you use type=peer (as is the case with the Telecomworld101 instructions), then you must repeat some settings in the Incoming/USER settings.
As to why these instructions weren't working for you, I cannot say for certain – especially since you haven't posted ANYTHING about your configuration.
I have installed new versions of FreePBX in the last 6 months and I've used these instructions without any issues. However, strict adherence to the "Notes," is very important. As noted above, several people who had trouble failed to ensure that System1, and System2, etc., were consistent across both systems and were present everywhere they needed to be. It is vitally important that the Trunk Name in the Outgoing Settings on SystemA match the username= in the Outgoing Settings on SystemB, for example.
Also, in at least one recent version of Asterisk there was a bug that prevented this from working.
Erik Hopfensperger
Martin Anderson sorry for potentially misleading you with my statement. I currently have (1) FreePBX box up and running and will deploy a second box within the next week. I was just pre-planning for the connection over the Internet between the boxes and going through the setup on paper.
I was just confused when I didn't see any credentials (username or secret) used to make the connection back to the opposite server. From this note in the OP: "If you change System1, System2, or password in one spot, you must change it to the same thing in all of the other spots (on both systems)." is where I was a little confused. I didn't see anywhere you used System1 or System2 more than in the Outgoing iax Settings tab. I would expect to see at least User Context showing the opposite username and that wasn't in the OP. I will test out the setup per the OP and your notes above and see how it goes! Thanks for all of the information on this site, it is extremely helpful.
Martin Anderson
If you use type=friend (as recommended in these instructions) then the user context is automatically generated by Asterisk using the same parameters, and you don't need to (and shouldn't) put anything at all in the Incoming/User area.
For more details, see:
https://github.com/mojolingo/asterisk/blob/master/configs/iax.conf.sample
which says, among other things:
"
Erik Hopfensperger
Martin Anderson Thank you for the link. Still learning how all of these features work together. Plus I read the settings above again and the the light bulb came on. In my head, even though I didn't directly read it, I had a secret for System1 and a secret for System2 which were different. I was treating it as separate secrets like a standard user and password and not a shared secret (ie, shared key for a Wi-Fi connection). Can't wait to get my second system up and running and test out the setup.
Martin Anderson
Hi Erik,
Once you get it set-up, please let me know how it works.
Erik Hopfensperger
It was taking me too long to get my second server up and running so I just dusted off my RasPBX box and used it at my second location. Intraoffice calls worked flawlessly! Used the setup documented on this page with one common password. Now I've proven out the concept using DDNS too. Thanks for all the assistance.
Martin Anderson
Hi Erik,
Thanks for the update. I'm glad to hear it still works
Martin Anderson
Also, since the Telecommworld101 instructions do not change QualifyFreqOK to 25000, there is a risk that your router will close the port intermittently and you may have calls that don't get through at times, depending upon your router..
munozj
This is working perfectly for me to dial stations on both systems. I'm having trouble however setting this up so that calls that come into a DAHDI trunk on system2 get forwarded to the IVR and Queues on System1.
Right now if i set the destination of the DID's (10 digit) on System2 to the IAX Trunk, System1 then dials the DID over it's PSTN trunks, and System2 answers and sends to System1 and System1 dials.... i'm caught in a loop. how do i get system1 to take and handle the call?
Chris Dolese
add an inbound route for the DID on System 1 ?
anyway id take this to the forums or IRC - its been a while since we've chatted , give me a shout sometime l