[Home]

Summary:ASTERISK-12792: [feature request] Reporter would like an option to ignore src ports in iax2
Reporter:Farid (ffadaie)Labels:
Date Opened:2008-09-28 12:56:08Date Closed:2011-06-07 14:02:36
Priority:MajorRegression?No
Status:Closed/CompleteComponents:Channels/chan_iax2
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:
Description:There are two Asterisk servers. One of them is behind a firewall/NAT and the other one has a public routable IP address. They both have static public IP addresses.
Here is what I have on Asterisk one(Asterisk-1) in iax.conf:
[GW2]
type=friend
host=public_ip_address_of_GW2
qualify=yes
context=something

and on the second one [behind the firewall] (Asterisk-2):
[GW1]
type=friend
host=ip_address_of_GW1
qualify=yes
context=something_else

External IAX2 port, 4569, is forwarded to the internal 4569 on the firewall. They however use dynamic source port overwriting which means if Asterisk-2 tries to contact Asterisk-1 from 4569 on Asterisk-2 to 4569 on Asterisk-1, then the firewall on Asterisk-2's side will overwrite 4569 to some random port number.
Using this set up, both peers will be unreachable on the other one (using a iax2 show peers command).
Now, if you can find out what is the port that is being overwritten to, you can fix the problem this way:

on Asterisk-1 you can have:
[GW2]
type=friend
host=public_ip_address_of_GW2
qualify=yes
context=something
port=_public_port_of_GW2

Interestingly, you don't even have to port forward this second port on the firewall. Just do a reload and everything will work!
Now, after it worked, you can come and remove than line and reload iax. It will still work!
It looks like it does some sort of source port authentication. It expects to "RECEIVE" packet on the specific port defined in IAX peer definition section. Technically, this should be just for "SENDING" packets not receiving.
Comments:By: Russell Bryant (russell) 2008-10-05 16:30:38

Can you get a packet capture on each server that shows the failed qualify attempts?  A pcap file that I can open in wireshark would be preferable ...

By: Russell Bryant (russell) 2008-10-05 16:34:05

Another useful thing that you could do is go back to an older version, 1.4.20 or something, and see if the error still occurs.  Qualify handling has changed very recently, and could be the cause of this ...

By: Tilghman Lesher (tilghman) 2008-11-13 15:10:09.000-0600

Part of your summary is incorrect.  When you remove a port line from a config and reload, the port number will not change in the loaded configuration.

By: Tilghman Lesher (tilghman) 2008-11-13 15:11:57.000-0600

and yes, when you define a port in an IAX peer/friend, it expects that both outgoing packets to that remote host and well as incoming packets should come through on that same remote port number.

By: Tilghman Lesher (tilghman) 2008-11-13 15:13:35.000-0600

For the above reasons, I am closing this issue, as I think the report resulted from a misunderstanding of how IAX2 works.

By: Farid (ffadaie) 2008-11-13 15:23:02.000-0600

But why would Asterisk care about the incoming port? This will cause NATting problems as most non-enterprise natting solutions overwrite the incoming port to a random number. This is true for most of the firwalls even if you set port forwarding (as the port forwarding will just affect the destination port for incoming packets and not the source port for outgoing ones).
Is there any specific reason as why IAX2 should care about the source port?

By: Tilghman Lesher (tilghman) 2008-11-13 16:49:10.000-0600

That is completely not true.  On most firewalls, the port number MUST be equal for incoming and outgoing packets.  If this were not true, then connections would NEVER be able to be attained.

By: Farid (ffadaie) 2008-11-13 16:54:59.000-0600

Here is the situation (and you can verify it on most Dlink, LinkSys firwalls):

Host A behind Firewall X
Host B : Public IP

A -> B (Source port n, destination port k)
X receives it. Overwrite the source port with m and stores the UDP state. (basically it stores what port is mapped to what n -> m)
B receives it and replies to A:m
X recives it and rewrites the destination port from m -> n
A receives it on port n

By: Tilghman Lesher (tilghman) 2008-11-13 22:15:28.000-0600

Correct.  That is why registration is important.  The only way for a public host to reach a host behind a NAT is for the host behind the NAT to register to the public host and re-register on a regular basis, to keep the NAT mapping active.

The way you've configured it in your example is very atypical and requires quite a lot of setup (which is easily broken).  This is why host=dynamic (on the public host) and the registration lines in iax.conf (on the host behind the NAT) are the normal way to configure connections in this situation.

By: Farid (ffadaie) 2008-11-13 22:37:05.000-0600

but why do we need to have this source port authentication in IAX2? I know it is possible to set it up the way you said (host=dynamic) but if we just remove source port check (kinda authentication) and use the port in iax.conf just for the destination port (and not the source port), the life would be much easier and IAX2 would be way more NAT friendly. It will also be backward compatible to the current implementation.
Is there any benefit in checking the source port?

By: Tilghman Lesher (tilghman) 2008-11-13 23:49:33.000-0600

Yes, it allows multiple hosts to register from behind the same NAT.

By: Farid (ffadaie) 2008-11-14 01:43:14.000-0600

Hmmm, I'd use host=dynamic and unique usernames for each host. However, if this (letting multiple hosts to register from behind the same NAT by doing source port authentication) has been intentional I understand even though it has created a huge problem in our development environment where we don't use production firewalls (Cisco or even Linux).
Why not giving it an option in iax.conf? something like portauth = yes/no?

By: Farid (ffadaie) 2008-11-14 12:29:47.000-0600

Just a brief comment:
If even I deploy username/secret and host=dynamic in my case (where source ports are being dynamically mapped on the firewall) I'd have this:

On host A, iax2 show peers:
xxxx/yyyy  B's IP    (D)  255.255.255.255  4569 (T)      OK (361 ms)

On host B, iax2 show peers:
cccc/dddd  A's public IP (WAN IP of the firewall)    (D)  255.255.255.255  60001         OK (378 ms)

As you can see, 60001 is dynamically mapped on the firewall. Now when B wants to contact A, it uses 60001 that is not necessarily true. Port 4569 is forwarded on the firewall and should be used. It means if I should add port=4569 in iax.conf on host B (where I defined peer A).
However, if host=dynamic, it seems that port=4569 is being ignored and Asterisk responds to 60001 anyways.
The solution to this is to make sure that A registers into B so often so that the timeout for mapping on the firewall does not expire.
Having the option of not doing source port authentication can solve this issue (It is somehow documented on the wiki page too).

By: Tilghman Lesher (tilghman) 2008-11-14 14:29:44.000-0600

Correct.  And it should use port 60001.  That is the correct address for mapping from the outside address to the IAX2 port on the inside address.

The only reason for using port 4569 on the outside would be if you're expecting users to call you over IAX2.  And even then, the firewall will (or SHOULD) map back outgoing packets back to appear as if they originated from the firewall, port 4569.  If it wasn't this way, many connections would not work correctly.

By: Farid (ffadaie) 2008-11-14 15:21:55.000-0600

I know but in many home user case (and development environments) there is no way out. port=... in the iax.conf should not be ignored when host=dynamic [This is another issue though not the same as having source port authentication] for the people (many home users [and development groups] that can port forward but do not have any control over how their firewall does the port mapping).
Having that option will make IAX2 more NAT friendly.

I would summarize all the above in:

1- Having an option for disregarding source port authentication when host != dynamic
2- Having the option of not ignoring port=... when host = dynamic. In this case it just should be used as the destination port. [just to send IAX2 packets to this port even if it was received on another port]

Backward compatibility can also be guaranteed in both cases.
BTW, I'd make this a feature request at the beginning if I knew it is not a bug :). I could not find any formal IAX2 RFC (I know there is no RFC in the true meaning of the word but something similar) to check if this is a bug or not.



By: Tilghman Lesher (tilghman) 2008-11-14 17:33:19.000-0600

You might want to look a little closer for an RFC track recommendation:

http://tools.ietf.org/id/draft-guy-iax

By: Jason Parker (jparker) 2008-11-18 13:40:48.000-0600

Closing.

Feature requests without patches are not appropriate for this bug tracker.  If you can come up with a patch, we can review this further.