Expected response if IAX2 encryption fails

In my iax.conf, I have encryption=yes (because why not?), but I wanted to look into some more IAX2 security options, like those detailed here: https://wiki.asterisk.org/wiki/display/AST/Secure+Calling+Specifics

The page says IAX2 is supported and that “If a peer is defined as requiring encryption but the endpoint does not support it, the call will fail with a HANGUPCAUSE of 58 (bearer capability does not exist).”

To test this, I added the following before an outgoing IAX2 call:

The call fails, and in the console I get:

[2021-01-24 20:12:45] WARNING[30643][C-000002c6]: chan_iax2.c:5147 iax2_call: Call terminated. No secret given and force encrypt enabled
[Jan 24 20:12:45]     -- Couldn't call IAX2/redacted
[Jan 24 20:12:45]     -- Hungup 'IAX2/redacted
[Jan 24 20:12:45]   == Everyone is busy/congested at this time (0:0/0/0)
[Jan 24 20:12:45]     -- NoOp("", "DIALSTATUS: CHANUNAVAIL / HANGUPCAUSE: 0") in new stack

This seems to conflict with the Asterisk wiki page about the HANGUPCAUSE being 58 if forcing a secure call fails. Are these two different scenarios, or is it supposed to be one or the other? I just would like to be able to detect the situation, but I’m unsure which hang up cause code I should be looking for in this scenario.

As an aside, the Asterisk switch I was calling also has encryption=yes in iax.conf, so it’s interesting that forcing a secure call fails there…

This reads as if it is a different scenario. What is the actual IAX2 configuration for the peer?

The peer has:


My switch has:

relaxdtmf=yes ; If your server has issues with DTMF this option may help
delayreject=yes ; for increased security against brute force attacks

IAX2 encryption requires a secret on a peer to operate.

Well, dummy me, then, I always assumed that was some kind of automatic encryption.
By secret, you mean this kind of thing?


I (and other peers) define secrets mainly for stuff that is not supposed to be semi-public. Is it OK if the secrets are “semi-public” like defined in a public lookup or would that defeat the encryption?

e.g. suppose I advertise to “everyone” they can use:

IAX2/mycontext:mysecret@myhost/extension to call into my switch - is the encryption secure even if other parties are privy to the secret?

Yes, that is what it requires. I can’t comment on IAX2 encryption specifics any further, I am unfamiliar with the implementation or how it works.

So, I might be missing something, but providing a secret seems not to do the trick:

Dial("Local/redacted", "IAX2/user:testing@redacted,,gF(autovonpreempted-callee,161159151912996,1)") in new stack
[2021-01-25 11:18:39] WARNING[27097][C-00000bfd]: chan_iax2.c:5147 iax2_call: Call terminated. No secret given and force encrypt enabled
[Jan 25 11:18:39]     -- Couldn't call IAX2/redacted:testing@redacted
[Jan 25 11:18:39]     -- Hungup 'IAX2/redacted

I have no idea what this means. I am providing a secret (literally testing). In fact, if I call without the secret, the call fails because it says “I don’t know how to authenticate user…” etc… since I haven’t provided the secret. So the secret is mandatory in the first place for the call to work, yet as soon as I explicitly say “secure the call”, it fails.

On the remote end’s context, I have defined in the appropriate user:


When I call normally, the call goes through, no problems at all. However, if I force encryption using those two channel settings, the call fails, saying “No secret given and force encrypt enabled.”

Is this secret not the password “testing” in this case? What other secret could it be referring to?

I don’t know anything further. I haven’t used chan_iax2 in 8+ years at this point, and just remembered from the original implementation that it required a secret defined in a peer.

Looking at the code it may require a peer/friend to be configured on both sides. Not just on one, and not put into the Dial line.

It was defined as a friend on the remote end. I tried adding the same entry to my iax.conf verbatim and trying the call again, still providing it in the dial string though Asterisk usually seems to detect if that corresponds to something in iax.conf or sip.conf, even if I don’t want it too.

[Jan 25 11:43:43]     -- Called IAX2/redacted
[Jan 25 11:43:47]     -- IAX2/redacted-2007 is circuit-busy
[Jan 25 11:43:47]     -- Hungup 'IAX2/redacted-2007'

It doesn’t work even with the entry locally defined if I dial it normally, but when I try it with just the local IAX2 section/user name for it, which has the remote host defined as well, it works, although on the remote end’s CLI, it still says Accepting UNAUTHENTICATED call. Not sure if it’s supposed to say “Accepting authenticated call” or something of that sort, but I do set those encryption settings on the channel and the call goes through, so it does work.

Unfortunately, there are 130 remote peers and defining them all in iax.conf and updating constantly would be utterly impractical, not to say anything of the other 130 nodes, so I guess I will have to give up on it for now, unless there is a way to do this dynamically in the dialplan without modifying iax.conf on the calling side (obviously, it would be expected that the secret is defined on the remote side). I can get the secret through a lookup, and I’m not really sure what difference it makes if it’s defined locally or not, so this seems like an oversight to me. If it’s not by design, maybe a possible feature request I guess.

Maybe off topic, but is IAX2 no longer “the thing” like it used to be? I’m a huge fan of IAX2 for several reasons but it seems like outside of a few niche communities, the protocol isn’t very well liked/used for whatever reason. Just curious. As long as it doesn’t get removed in a later release though I guess it shouldn’t matter much.

The chan_iax2 module and protocol don’t receive any attention by anyone, and isn’t used much anymore. There’s no plans currently to remove it but someone could certainly propose it and it could be evaluated in the future.

I assume, the encryption is symmetric encryption, not public key with a random key, so both sides need to know the key. The secrets are totally unsuitable for public key with a published key.

Hi, David,
My problem is not with both sides knowing the key. I understand that. Say I have my switch (A) and another (B). The secret is defined on switch B in iax.conf, as one would expect.

What I would like to do on switch A is dial that IAX2 connection directly using IAX2/user:secret@host/extension, without having my own iax.conf entry corresponding to the dialed destination. That is, be able to do it all in the dialplan with an explicit IAX2 call. We have a custom lookup that returns the IAX2 endpoint based on the # dialed. At this point, nobody is using secrets but I am trying to toy with integrating them in in a clean way. The lookup can and currently does return the secret for the dial string if there is one, though. No issues here.

In theory, I could use System() and write a new section out to iax.conf on the spot, call “iax2 reload”, and then proceed with the call using the new temporary IAX2 (local) user for the call, and then have some job automatically clean up these garbage entries periodically, but it seems like there has to be a better way of doing this.

Right now, I am trying to get even plaintext encryption working so we can get the media stream encrypted, and if I can figure out how to get MD5 encryption working without needing something in iax.conf on switch A, that would be nice, but I figured that might not be possible. However, the plain text secret can be provided directly in the dial string, so I’m wondering why encryption does not work with that. The call itself works, but if I force encryption the call fails unless I call my own IAX2 user defined corresponding to switch B. I don’t want to have to define anything on switch A for any switches I might call.

As to why I saw “Accepting Unauthenticated Call”, I wonder if that has anything to do with this:

The “(E)” indicates our encryption feature. Unfortunately the “(E)” also appears when using other authentication methods than MD5, however the actual encryption is NOT operational in this case.

Perhaps plain text does not support encryption?

I’ve been playing around all day and I’ve finally gotten encryption working.

The catch is plaintext auth is not supported. It works only with MD5 or better.

I did some packet captures and I confirmed by checking the hexdumps that it’s encrypted as it appears to be random rather than just a bunch of hex 7Es, 7Fs, FFs, etc.

One interesting thing I see in some packets is Wireshark says “G723.1 compression”.

I’m a bit puzzled how that even got negotiated, as both my switch and the other one forbid everything except ulaw, alaw, and G722.

Does encryption use G723 instead of G711?

When the call negotiates, it says “ulaw” so I’m just curious what’s going on:

FORMAT2         : ulaw

    -- Accepting AUTHENTICATED call from redacted:4569:
    --        > requested format = ulaw,
    --        > requested prefs = (ulaw|alaw|g722),
    --        > actual format = ulaw,

Encryption wouldn’t use another codec, but the fact that the contents are encrypted may mean that Wireshark can not correctly decode and presents incorrect information.

1 Like

Here’s something interesting I’ve noticed over the past day.

It seems like every now and then, a little bit after an encrypted call ends, IAX2 will be trying to do stuff and then errors out like so:

[2021-01-26 17:44:06] WARNING[16583]: chan_iax2.c:6725 iax2_send: Supposed to send packet encrypted, but no key?
na01*CLI> core show channels
Channel              Location             State   Application(Data)
0 active channels
0 active calls
139 calls processed
[2021-01-26 17:44:16] WARNING[16584]: chan_iax2.c:6725 iax2_send: Supposed to send packet encrypted, but no key?
[2021-01-26 17:44:17] WARNING[16586]: chan_iax2.c:6725 iax2_send: Supposed to send packet encrypted, but no key?
[2021-01-26 17:44:26] WARNING[16588]: chan_iax2.c:6725 iax2_send: Supposed to send packet encrypted, but no key?

I’m inclined to think this may be one of those things that’s actually nothing to worry about, but is there a reason I’d this? As can be seen above, it thinks it’s supposed to be sending packets, and there are actually 0 ongoing calls, so that makes no sense at all to me.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.