Client Firewall Mangling SIP Headers

I have an Asterisk server behind a NAT, and multiple internal (on the same network as the Asterisk server) and external (on different networks NAT’d) SIP phones all working fine, except one.

When the one non-working phone tries to make a call, the IP address that ends up in the SIP header is a mangled version of the external IP. The phone doesn’t know the external IP, so I know the firewall on the client’s side is mangling the IP address. It comes through as something like “184.0.23.25206”, which obviously is not a valid IP address. So errors such as “netsock2.c:263 ast_sockaddr_resolve: getaddrinfo(“184.0.23.25206”, “(null)”, …): Name or service not known” show up in the log. A SIP trace shows that this is the IP address that Asterisk is receiving from the client, so I don’t think Asterisk is to blame. On the phone (GXP2100), it displays “488 Not Acceptable Here”.

In searching for this, I found other people who had the same issue, and the solution was generally to disable the SIP Helper (or similar) functionality in the firewall. An example is here (the symptoms described are the same as mine):
tomatousb.org/forum/t-303479/tra … rs-problem

This particular client has an Airlink101 Super G AR430W. I’ve sifted through its configuration, but can’t find anything SIP related. While I’m fairly certain that replacing this device will solve the issue, I’d like to find a better solution so that when/if I encounter this again, I won’t need to keep buying new firewalls.

Is there a setting in either Asterisk or the phone itself that could send the data in such a way as to prevent the firewall from thinking it’s a good idea to try and “help” with the connection by modifying the packets?

Try using a domain name instead of an IP address.

This is not normal router brain damage, so I would not expect Asterisk to have a work around option.

I’m not really following what you mean here. Where should I be using a hostname instead of an IP address?

The phone connects to the Asterisk server by hostname, not IP address. The IP address “184.0.23.25206” is what Asterisk is receiving from the client in the SIP headers.

It wasn’t clear that this was inbound.

How does Asterisk reject the call? I’m not sure that it should look up addresses for all except Contact headers, and if that is wrong, you are in trouble.

You could experiment with putting in /etc/hosts entries to see if they can translate back to sensible addresses.

When the call is made on the non-working handset, this is what shows in Asterisk’s logs:

[2013-01-21 17:23:45] ERROR[20860]: netsock2.c:263 ast_sockaddr_resolve: getaddrinfo("184.0.23.25206", "(null)", ...): Name or service not known [2013-01-21 17:23:45] WARNING[20860]: chan_sip.c:9569 process_sdp_c: Unable to lookup RTP Audio host in c= line, 'IN IP4 184.0.23.25206' [2013-01-21 17:23:45] WARNING[20860]: chan_sip.c:9198 process_sdp: Insufficient information in SDP (c=)...

This phone worked when it was at my location (also on a NAT separate from the Asterisk server), but it doesn’t work at the end-user’s home office. This is why I suspect that the client firewall is mangling the content of the SIP packets.

What is it you’re suggesting that I would place into /etc/hosts?

The correct IP address, followed by the mangled one.

Is using VPN tunnels an option?

Let’s say it worked, where would that leave me? The client’s IP address (the one being mangled) is dynamic, so it would break again as soon as their address changed.

In this particular case it would be, but it would mean replacing the firewall (which would then solve the issue without a VPN tunnel). I can certainly do that, but I’m looking for a more generic solution that will work in other cases without having to setup tunnels or replace the client’s firewall. If it’s not possible because they just have a bogus firewall, then that’s what it is. I’m just not ready to give up on it yet.

If the address is dynamic, you will need to find an algorithm to invert the damage and then either implement it in the source code of Asterisk, or add a proxy that does hte repair.

You may find that some nat= settings might work round it. but you might still have to modify the source to prevent the call being dropped. Don’t use nat=yes, as it is deprecated.