How to block a single extension’s ability to make outgoing toll calls in FreePBX


This is an edited version of a post that originally appeared on a blog called The Michigan Telephone Blog, which was written by a friend before he decided to stop blogging. It is reposted with his permission.
Courtesy Phone
Image by zacklur via Flickr

EDIT (May, 2018): FreePBX and Asterisk users that wish to continue using Google Voice after Google drops XMPP support should go here: How to use Google Voice with FreePBX and Asterisk without using XMPP or buying new hardware.

This question comes up a lot and rather than having to re-type the answer each time I see it posted in some forum, I decided to put it here, where I can just link to it.  If you want to know why this works, read my previous article, Asterisk hiding a useful feature in plain sight by giving it a “cute” name.

Many organizations have a single extension that is a “house phone” for visitors, and they don’t want anyone to be able to use that phone to make “off-site” calls.  The thing you must decide is, do you want your users to only be able to make in-house calls, or do you want to in addition allow calls to local and toll-free numbers? It makes a bit of difference in how you do this.  And remember, in most places, by law you MUST allow calls to 911 or whatever your local emergency number might be — if you block emergency calls and someone tries to use that phone to summon an ambulance or get other necessary emergency help and is unsuccessful in doing so, then prepare to have your butt sued off (and possibly even serve some time in prison), and I don’t have a bit of sympathy for you.  I don’t care what reasons you may think you have for wanting to block emergency calls, just DON’T DO IT.

Anyway, here’s the basic technique:

1.  Create a Trunk: (EDIT: This step is unnecessary in the most recent versions of FreePBX). If you want to allow “free” off-premises calls, then the easiest thing to do is create an ENUM trunk, if you haven’t done so already.  If you DON’T want to allow free calls, then create a “dummy” trunk for the purpose.  Create a CUSTOM trunk (not SIP or IAX2, etc.), name it Blocked, and make the Custom Dial String Local/congestion@app-blackhole — that’s all you have to do. For extra safety, you can also check the “Disable Trunk” checkbox (this should play a recording saying that all circuits are busy, or something to that effect, whereas leaving the trunk enabled would play “fast busy” tones). Then submit the changes.

2.  Create an Outbound Route: Give the Outbound Route any name you like. In the “Dial Patterns that will use this Route” section, enter the patterns you do NOT want the extension to be able to dial (in the third field of a pattern if using FreePBX 2.8 or higher) followed by the extension number that you want to restrict (in the fourth field in FreePBX 2.8 or higher, or after a forward slash character if using a lower version).  I’m going to show the following examples in the syntax used in FreePBX 2.7 (EDIT: you would also use this syntax in FreePBX 12 or later, if under Settings | Advanced Settings, in the “GUI Behavior” section you have set Enable The Old Style FreePBX Dial Patterns Textarea to True).  Let’s say you want to block calls from extension 234:

To block all calls of 11 digits or more (in case you have “local” 10 digit dialing):

To block all calls of 8 digits or more (allowing 7 digit local calls):

To block all calls of 4 digits or more (in case you have three-digit extensions and want to allow in-house and 911 calls only):

In the Outbound Route trunk selection, (EDIT: if you have a recent version of FreePBX, simply do not select any trunks at all in the “Trunk Sequence for Matched Routes” section of the Outbound Route, and then optionally select a failure announcement or whatever treatment you want to give the call in the “Optional Destination on Congestion” section. Otherwise, if you are still running an older version of FreePBX) select whichever trunk you created in Step 1 (ENUM or Blocked).  Select only that one trunk.  Note that if you “disabled” the Blocked trunk it may be grayed out, but you still should be able to select it as a trunk choice, and that should be sufficient to keep FreePBX from complaining that you haven’t made a trunk selection.

Priority is important! Make sure this Outbound Route appears in your list of Outbound Routes BELOW any routes that handle calls you want to allow (your emergency route(s) for sure, and possibly routes that handle Toll-Free calls if you want to allow those), but ABOVE any routes that would normally be used for the type of calls you want to restrict.  Remember that this route will only restrict calls that match the patterns, so if you only restrict calls that are 8 digits or more and you have a lower-priority route that handles 7-digit local calls, those calls should still go out.

Just a note about use of an ENUM trunk (EDIT: Optional and not necessary in newer versions of FreePBX).  If someone calls a number that is registered as an ENUM number, it will go out as a direct SIP call, bypassing your normal SIP or IAX providers, so it won’t cost you a dime.  The vast majority of numbers are NOT reachable via ENUM so if you use an ENUM trunk as your “blocker” trunk, it will be a very rare thing if a call actually connects that way, but if it does you won’t be paying for it.  Sometimes U.S. or Canada Toll-Free numbers are reachable via ENUM and sometimes they are not — it’s actually pretty much a crap shoot whether it will even work at all.  So if you want to specifically allow toll-free calls, don’t count on ENUM to handle them, but be aware that in some cases they might go through via ENUM, at no cost to you (other than whatever you may pay for your Internet connection, of course).

Be sure to make some test calls from the extension to make sure everything works as you expect.  And double-check to make sure you have not blocked emergency (911, or whatever your local number is) calls!

If you need to do blocking for more than one extension, you can either use patterns (rather than single extension numbers) after the forward slash, or simply add new blocking rules.  For example, you could do this:

Block all calls of 4 digits or more from extension 234 or 235:

Block all calls of 4 digits or more from extension 230 through 239:

Block all calls of 4 digits or more from extension 234, and block all calls to 1-900 numbers from extension 288:


16 thoughts on “How to block a single extension’s ability to make outgoing toll calls in FreePBX

  1. Hi,

    Thanks for something that I have been seeking for a while. I tried to insert “XXXX!/23X” with Swiss Army Knife enabled, but it only shows up ” “XXXX/23X” without the exclamation mark (!) when configurations saved.

    Is there any workout to include the ! mark ? And thanks for the nice tutorial again.

    1. It’s not Swiss Army Knife per se — try turning it off and change a pattern and you’ll see the problem persists. It’s probably the f—ing F—PBX error checking again. Why they insist on messing with the characters you put in I’ll never know, because it’s always screwing up somebody’s attempts to configure their dialplan with perfectly valid syntax. At least they should give you the option to turn the error checking off. I hate F—PBX for this (if you ever wonder why I usually write it as F—PBX, it’s partly because they are becoming a bit less “free” with each new version, but mostly because I usually privately refer to it by another four letter word starting with “F”, which seems especially appropriate when you run into crap like this! They certainly don’t seem to think you should be “free” to enter the characters you need to enter in your PBX).

      You could try filing a bug report with their stupid black hole of a bug tracker, and maybe in a year or two it might get fixed (maybe sooner if you are truly fortunate). The only other workarounds I can think of are:

      Try using XXX. rather than XXXX! (exclamation point means “zero or more” vs. the period’s “one or more” of the character that comes before).

      Try using phpMyAdmin or Webmin’s MySQL Database Server module (under “Servers”) to directly change the string in the database (I’d back up your system before doing this, in case you mess something up). If that works, make sure you never edit that outbound route in F—PBX’s GUI, or you’ll probably have to do it again.

      Or, try finding the generated context in extensions_additional.conf. It should start with a couple of lines that look like this:
      [outrt-x] ; Context_Name
      include => outrt-x-custom
      Where x is replaced by some number (may be more than one character). Copy that entire context to extensions_custom.conf, but change the context name to the name shown in the “include” line, and then remove the “include” line. In theory, that context will then be called first, and you can make the changes you need in that context. The problem with this is that as you make changes in the GUI, and especially if you add or remove Outbound Routes, the number of this route might change, and you’ll have to change the number in the copied context.

      And/or, dump F—PBX as soon as any reasonably usable replacement appears, as I plan to do. Words can’t express how much I hate F—PBX and especially their entire philosophy of taking control away from the user. I really wish there were a viable competing product.

  2. for me it does exactly the opposite that you described.

    900XXXXXXX/288 blocks all extension and let only the 288 extension to go trough.

    Any idea why it is working in this way?

    1. Zsolt Molnar: Right, that’s how it works. The trick is to let it “go through” on a route that only has an ENUM trunk (and not any other trunk) as a destination. The ENUM trunk won’t accept the 1-900 call and therefore the call will be blocked. And, the route that allows this must be higher in priority than any other route.

      If calls are going through then either you have specified something other than an ENUM trunk as the one and only trunk to use on that outbound route, or you have another outbound route that’s higher in priority that’s passing the calls. Or maybe ENUM trunks have started passing 1-900 calls, but if they are then somebody somewhere is eating the charges for those calls (really this should never happen, so if the calls are going through, assume something is misconfigured somewhere and you are paying the bill).

      By the way, you don’t necessarily have to use an ENUM trunk — you could instead create a CUSTOM trunk that plays a recording. If your CUSTOM Trunk had a “Custom Dial String” of Local/12345@from-internal and you had extension 12345 set up to play an announcement and then hang up, you could use that to block the call. I just find that it’s easiest to use the ENUM trunk if you don’t really care if the call goes out, so long as you don’t have to pay for it.

      Oh, and just so you know, I still have a burning hatred of FreePBX (and I don’t care for Asterisk much either), and would strongly recommend that you look at software based on FreeSWITCH and/or YATE the next time you are thinking about upgrading your PBX.

      1. Sir i would like to know how i can make only 1 telephone to call sip (4 digit),long distance (area code + 7 digit) and local (7 digit) and the rest of the telephones can call only sip (4 digit) and local (7-digit). im using elastix as voice server, openvox iag804 as my voice router to telecom.
        and voxtack 4g to call mobile.

        1. See Asterisk hiding a useful feature in plain sight by giving it a “cute” name – since that was written this feature has become supported in FreePBX. Also see How to give a particular extension or group of extensions access to a specific trunk or group of trunks for outgoing calls in FreePBX. Basically, in your outbound route you include the patterns to “call sip (4 digit),long distance (area code + 7 digit) and local (7 digit)”, BUT at the end of the one for long distance (area code + 7 digit) you add / and the extension number of the extension that is allowed to make long distance calls. For example, if that extension is number 123, then:
          For the other patterns (sip and local) you don’t use the /123 (note that if by “sip (4 digit)” you mean other local extensions on your PBX, then those do NOT go in your outbound routes at all – outbound routes are only for calls that leave your system). Note that newer versions of FreePBX have separate boxes for each part of the pattern, so make sure you put the extension number in the box following the / character. You say you are using Elastix and it has been many years since I’ve looked at it, so I think it still uses textboxes where you can enter a list of patterns, and if that’s the case then what I showed above is probably correct.

          However I think now there are two or three different versions of Elastix, so I have no idea what the interface looks like in your version. But hopefully this answers your question, or at least gives you some idea what you need to do.

  3. Is it possible to use this method to prevent extensions from calling each other?

    I created the Blackhole/Blocked trunk as a custom trunk then created the route but it isn’t matching. Am I missing something?

    Asterisk 1.8 on AsteriskNow with FPBX (I know, I know, you hate it)

    1. MBH, I’m going to reply by lifting some text from an otherwise outdated page at

      … the question came up about how to make a particular extension or group of extensions unreachable from certain other extensions. While I have no idea why anyone would want to do this, it can be done using similar techniques to those used for restricting calls to certain trunks, but it potentially might involve a fair bit of effort. Let’s say you wanted to restrict calls to extension 299 and all extensions in the 440-449 range (this is just an example) – you might add something like this to /etc/asterisk/extensions_custom.conf:

      exten => 299,1,Goto(app-blackhole,congestion,1)
      exten => _44X,1,Goto(app-blackhole,congestion,1)
      exten => _[*0-9]!,1,Goto(from-internal,${EXTEN},1)
      exten => h,1,Hangup()

      The first line of the context would send all calls specifically made to extension 299 to congestion – you can use as many lines as you need if you need to restrict calls to more than one extension. The second line is an example of a pattern match, restricting all calls to extensions matching the 44X pattern – note the underscore at the start of the pattern; this indicates to Asterisk that you are matching a pattern and not an individual extension named “44X”. The third line catches any other number containing the digits 0-9 and/or the * character in any position, and passes it on to the from-internal context.

      After setting up the context as you need it in extensions_custom.conf, you’d then go to the configuration page for each of the extensions you want to restrict (yes, every single one of them, one by one) and change the context from from-internal to custom-restricted-internal, or whatever you called your context.

      Hopefully that will work for you, though why anyone would want to do this escapes me, since it potentially ties up two of your trunk channels for what could be an internal call.

      By the way, for anyone that followed the link in the first paragraph, more up-to-date information is here: (but it does not include anything on the section I quoted above).

  4. I’m building an information-system service where subscribers are called, but aren’t expected to call back nor should be calling each other.

    I did see your post about the custom contexts, but I was trying to avoid the hassle of changing the context for every extension.

    I tried a pattern of 60XX to prevent 60XX extensions from dialing each other, but Asterisk happily sends the call. It only blocks it with congestion signal if I define an exact extension.

    Seeing your hatred for Asterisk/FPBX, I started looking FreeSwitch to see if any of this can be done without this much effort.

    1. Oh, now I see what you’re doing. I hope you are successful with FreeSWITCH (and if not, you may also want to look at YATE, though I’m not saying that either is better than the other, just that either might be better than Asterisk for what you want to do). In fact, if you plan to have a large number of users you probably would be better off with one of the newer programs, since I have read that Asterisk doesn’t scale well (though that’s probably open to debate). Even with the very small legacy Asterisk system I have, I’ve hit the issue where if you have too many contexts Asterisk apparently just silently pretends some of them don’t exist (and worse, if a call happens to go into one, it’s like it falls into a black hole – the Asterisk CLI shows nothing, there is no Call Detail Record made, etc.). I don’t actually know enough about why this happens or where the fault lies (could be F—PBX or could be a native Asterisk issue) to file an intelligent bug report, but when I made an adjustment to get rid of some of the contexts the problem disappeared. And if I hit this problem on a small system with just a few extensions, I can only imagine what a nightmare something like that might be on a huge system with many users.

      I am aware that one of the major commercial VoIP providers (probably shouldn’t say which one) started out with Asterisk but then switched to FreeSWITCH many months ago. Of course, I have no idea if the Asterisk folks might have ever done anything to try and fix any of these types of issues, but at this point I really just don’t care anymore.

  5. NOTICE: All comments above this one were imported from the original Michigan Telephone Blog and may or may not be relevant to the edited article above.

  6. I am using F_PBX and trying to specify an extension in the dial plan as follows
    xxx./3299 where 3299 is the extension I wan to prevent from making external calls

    F_Pbx does not allow that and gives an “dial plan is invalid”

    Any ideas

    1. If you are using a newer version of FreePBX then in your Outbound Route setup the xxx. goes into the “match pattern” text field and the 3299 goes into the adjacent “CallerID” text field. You do not type the / character. Or alternately, in FreePBX 12 or later, under Settings | Advanced Settings, in the “GUI Behavior” section set Enable The Old Style FreePBX Dial Patterns Textarea to True and then you can enter the patterns as shown.

  7. Thank you sir i think i get it… after ive put the long distance dial pattern in my outbound route with specific sip (/1234) means this sip is the only can call long distance while others dont unless it matches the sip in the dial pattern.

    1. You probably meant to say, “after I’ve put the long distance dial pattern in my outbound route with a specific extension (/1234), that means this extension is the only one that can call long distance while others can’t, unless the called number matches a different dial pattern that isn’t restricted to a specific extension.”

      SIP is a communications protocol, so not really relevant to this discussion.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent Posts

Recent Comments




GiottoPress by Enrique Chavez