Contact URI switching between internal and external IP

bug
pjsip
siptrunk
configuration
asterisk
Tags: #<Tag:0x00007f91cf69bd48> #<Tag:0x00007f91cf69baa0> #<Tag:0x00007f91cf69b870> #<Tag:0x00007f91cf69b708> #<Tag:0x00007f91cf69b5a0>

(Henri) #1

Does anyone know what could cause the behaviour in the title?
I have a server where it connects to the internet out of an 1 interface on a router, while the (PJSIP) trunk traffic goes through another interface (using a static route in the router), directly to the VoIP provider. The server only has 1 interface.
By Settings - Asterisk SIP Settings, General Settings tab, the external address is set to the external IP of the 2nd router interface. By local address, I have a couple of subnets, including the one the server is in. PJSIP tab, external address matches the one on the general tab, by local address there is only the subnet the server is in, with slash notation.

I had the CHAN_SIP tab set with: NAT-yes, static IP, and the same IP as by the general and PJSIP tabs, but as this behaviour continued, I came to believe it might be some sort of conflict between the PJSIP and CHAN_SIP, so I set the SIP channel driver, by Advanced Settings, to PJSIP, rebooted, then all the CHAN_SIP things disappeared, including the tab by Asterisk SIP Settings.

I thought I was home free, when after the reboot, inspecting the packets across the interface to the provider revealed that it was finally just sending the external IP in the contact-URI… then it spontaneously went back to the internal server IP after working perfectly for a day. I honestly don’t know what to do anymore. Is this a bug or am I missing something?

pjsip.transports.conf looks like this:
[0.0.0.0-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060
external_media_address=10.20.30.40
external_signaling_address=10.20.30.40
allow_reload=no
tos=cs3
cos=3
local_net=192.168.1.0/24
local_net=192.168.2.0/24
local_net=192.168.3.0/24
local_net=192.168.1.0/24

The first and last local_net are from the local network on the general tab and PJSIP tab respectively, on the Asterisk SIP Settings page, and are the one that the server itself is in. I tried removing from each page so that it is only listed once in the config file, restarting and trying, but no help.
I want it to stick with saying …@10.20.30.40:5060, but it keeps going back to …@192.168.1.1:5060 in the contact URI… help me, please. :frowning:

(the IPs are dummies, by the way)


Incorrect IP in contact header
#2

Please provide details. If your VoIP provider has an SBC on your site, why is it going through the router at all, instead of being connected directly to the PBX (using a VLAN, if it’s not feasible to have a second NIC)? Or, if it must be routed, why is it NATted?

Assuming that Asterisk only needs to present its LAN address (when talking to local extensions) or 10.20.30.40 (when talking on the trunk), I would try on the general tab:
External Address: 10.20.30.40
Local Networks: 192.168.0.0 / 16
and on the pjsip tab leave External IP Address and Local network blank. Submit, Apply Config, restart Asterisk, test. If no luck, post details including the contents of pjsip.transports.conf
Otherwise, please explain the setup. For example, do you need to present your public IP for remote extensions or other trunks?


(Henri) #3

Thanks for coming in on this, Stewart.

  • No SBC is present, just FPBX - switch (VLAN) - firewall/router - PSTN Provider.
  • The FreePBX is a VM sitting on an ESXi hypervisor, thus it is using a virtual interface that is in a DMZ VLAN. From this VLAN, it connects to local and SSL-VPN clients, in their own respective VLANs, and to the trunk, on the 2nd WAN interface of the firewall, which is the sole routing device.
  • When testing FPBX earlier, I tried to add a 2nd NIC to the VM, so that 1 can connect to the LAN and the other to the trunk, but upon adding the NIC (not spontaneously, but shutting down, adding, booting, etc), FPBX stopped working properly and I couldn’t find much info to pursue fixing it all, nor much time to figure it out. Thus I just stuck with the single NIC, which seemed to be the common configuration.
  • I actually did set it as you say for the external and local networks, but the behaviour continues.
  • All extensions only connect from the Voice and SSL-VPN VLANS, so they only access FPBX using the local IP. Only the trunk needs to use the public/external IP that is on the router’s 2nd WAN interface.

This affects incoming calls, as the 200 OK from FPBX is the one with the wrong IP, thus the ACK from the provider fails to get back to FPBX, then FPBX retries the 200 OK several times, then cuts the call precisely 30-32 seconds after the call is answered.
Reviewing my packet capture at the WAN interface for the trunk, shows, 1 call where this error happened, 12 calls are handled correctly without the error, then another call with the error; with no obvious pattern or reason.

Is it possible that FPBX is somehow overriding what is regarded as external, regarding it the router’s IP on the Internet facing interface, that it detects from Internet traffic, instead of the IP of the trunk interface, that I explicitly set as external? I could imagine that if this is the case, it would try to only NAT the traffic going to the Internet, and treat the rest as local, including the traffic going to the trunk.


(Henri) #4

After clearing the PJSIP tab, applying and running the fwconsole restart command, the problem continues and the pjsip.transports.conf looks like this

[0.0.0.0-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060
external_media_address=10.20.30.40
external_signaling_address=10.20.30.40
allow_reload=no
tos=cs3
cos=3
local_net=192.168.0.0/16


#5

I have not seen this problem before. Possibly, the router/firewall or hypervisor is altering the packets. To rule that out, at the Asterisk command prompt, type
pjsip set logger on
which causes the SIP traffic to appear in the Asterisk log, along with the regular entries. Make test calls in until you get a failure, then check the Contact header in the 200 OK.

If it has the correct external address, you can check intermediate points (ESXi NIC, router LAN port, etc.) to see where it is getting corrupted.

If it’s wrong (pjsip sending Asterisk’s private address), there may be a clue in the Asterisk log, or you may see a difference between incoming INVITEs that result in the proper response and those the give the incorrect Contact header. It would also be interesting to see whether the INVITE sent on an outgoing call has a bad Contact header (this may be easier to debug).

What version of FreePBX and Asterisk are you running? Was this system installed from the Distro (.iso file)? If not, how did you build it? Is the VM using ‘bridged’ networking (the PBX has an address in the same subnet as the ESXi host)? The redacted address on your side of the trunk (10.20.30.40) is a private address (not routable on the public internet). If that is true of the actual address, please explain (ISP does not provide a public IP, this is a dedicated link to the carrier etc,).


(Henri) #6

The firewall (Fortigate on F/W 7.0.1) ALG was altering the IP to the WAN IP and the ports to random ports from 5060, but not properly mapping it back to FBPX’s port 5060, so the ALG was disabled from altering the contact header altogether. That time, the the ALG always made sure the IP was right (the WAN IP), but it was just the ports where it was messing it up.
I’ve enabled the pjsip logger and am watching for failures.

In the packet capture on the WAN interface, I saw that the INVITE on outgoing calls next to the bad incoming calls, also have the internal IP, but the rest of the flow sequence does not break down, as it does for incoming.
The FPBX is completely updated:

  • Current PBX Version: 15.0.17.55

  • Current System Version: 12.7.8-2107-3.sng7

  • Packets show: FPBX-15.0.17.55(16.19.0)

  • Yes, it was installed from distro.

  • FPBX is connected to an isolated DMZ VLAN on a vSwitch, so it is not in the same subnet as the host.

  • Yes, although the IP is redacted and not the true address, the ISP did indeed allocate a point-to-point subnet from the class A private IPv4 range for the SIP traffic, as a security measure. The Internet facing WAN interface is the one with a public IP.

For the time being, it seems like the bug is lying low and I’m not observing the error, but I’ll keep watching, because it just randomly seems to pop up.


(Henri) #7

The issue has spontaneously resumed.
I tried looking at the logs after enabling the pjsip logging, but the only useful thing I am seeing is that it is sending the internal IP as the contact for both outgoing and incoming calls.
No event (known to me) occurred between it sending the correct contact with the external IP, to suddenly sending the internal IP.
All calls now have the issue and none are with the external IP anymore, so the NAT is effectively off.


#8

pjsip doesn’t have a NAT setting. It should send the external address (in both Contact and SDP) whenever the address with which it’s communicating does not match Local Networks.

This could be a bug, or possibly the remote address is now appearing to be local. You can confirm or refute the latter by the destination address logged by pjsip. If a bug, the pjsip config files (primarily pjsip.transports.conf) should show whether this is an Asterisk or a FreePBX issue.

Of further interest is whether this problem is (temporarily) fixed by restarting Asterisk and if not, by fwconsole restart.


(Simon Telephonics) #9

Please post sip traces & logs so that we can help analyze.

That’s why you need a second set of eyes. :wink:

Also from the asterisk console, post the result of pjsip show transport 0.0.0.0-udp please.


(Henri) #10

@Stewart1 I tried the fwconsole restart and it did not help.

@billsimon I need all the eyes I can get!
I cannot attach (or link) here, as a new user, however, I did open a issue (https://issues.freepbx.org/browse/FREEPBX-22916) and have attached the trace (anon’d) there. I will try to attach a log too.


#11

I’m puzzled. The correct external address is presented in the SDP, though not in Contact (and also not in Via on outgoing). There are some quirks in the SIP, e.g. the Via header received from the trunk on the outgoing call has an rport tag without the port number. However, this occurs after the bad INVITE has already been sent, so it is likely irrelevant.

Although you have confirmed that incorrect headers are present at the Asterisk (virtual) NIC, please provide a pcap from there (running tcpdump on the PBX). There may be some clue if the payload is different (other than the required NAT translation). Also, since your basic complaint is “Asterisk is sending the wrong stuff”, it makes sense to show a capture from Asterisk, rather than one possibly modified by ESXi and/or Fortigate.

I’m curious if some unusual setting in the Zamtel trunk may be triggering a pjsip bug. Please post the [Zamtel] section of pjsip.endpoint.conf, as well as any customization to the pjsip config files.

Just guessing here, pjsip may be detecting some exception that causes it to not substitute the WAN address in Via and Contact; turning on Enable Debug in SIP Settings for chan_pjsip may log something useful.

Somewhat off topic: The incoming call has alaw as the first priority codec (and AFAIK Zambia uses G.711A on their PSTN), so you could get somewhat better voice quality by prioritizing alaw over ulaw in Asterisk and on your endpoints; this will avoid transcoding on domestic calls.


#12

Oops, I forgot something. At the Asterisk command prompt, type
pjsip show transports
pjsip show transport 0.0.0.0-udp
pjsip show endpoint Zamtel
and post the output.


(Henri) #13

Hi Stewart,

Sorry, I know I have been quiet, but it returned to a working state until yesterday evening, when it went back to nonsense again.
I observe in the packet capture before 6pm, it was fine, then after, it wasn’t.
So it seems that some kind of cron or something at 6pm may be the trigger.

Also in an earlier capture, it was not working up until 1pm, then it was working.
So something triggered it to work at 1pm, and now something to stop again at 6pm.


#14

Leave pjsip Enable Debug on, also pjsip logger. Then, when a call fails, the Asterisk log should have useful info. Please post the results of the requested pjsip show commands as well.


(Henri) #16

Here is the output of the commands:

freepbx*CLI> pjsip show transports

Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress....................>
==========================================================================================

Transport:  0.0.0.0-udp               udp      3     96  0.0.0.0:5060
Transport:  ipv6-udp                  udp      3     96  [::]:5060

Objects found: 2

freepbx*CLI> pjsip show transport 0.0.0.0-udp

Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress....................>
==========================================================================================

Transport:  0.0.0.0-udp               udp      3     96  0.0.0.0:5060

 ParameterName              : ParameterValue
 ====================================================
 allow_reload               : false
 async_operations           : 1
 bind                       : 0.0.0.0:5060
 ca_list_file               : 
 ca_list_path               : 
 cert_file                  : 
 cipher                     : 
 cos                        : 3
 domain                     : 
 external_media_address     : 10.20.30.100
 external_signaling_address : 10.20.30.100
 external_signaling_port    : 0
 local_net                  : 192.168.0.0/255.255.0.0
 method                     : unspecified
 password                   : 
 priv_key_file              : 
 protocol                   : udp
 require_client_cert        : No
 symmetric_transport        : false
 tos                        : 96
 verify_client              : No
 verify_server              : No
 websocket_write_timeout    : 100

freepbx*CLI> pjsip show endpoint Zamtel

 Endpoint:  <Endpoint/CID.....................................>  <State.....>  <Channels.>
    I/OAuth:  <AuthId/UserName...........................................................>
        Aor:  <Aor............................................>  <MaxContact>
      Contact:  <Aor/ContactUri..........................> <Hash....> <Status> <RTT(ms)..>
  Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress..................>
   Identify:  <Identify/Endpoint.........................................................>
        Match:  <criteria.........................>
    Channel:  <ChannelId......................................>  <State.....>  <Time.....>
        Exten: <DialedExten...........>  CLCID: <ConnectedLineCID.......>
==========================================================================================

 Endpoint:  Zamtel                                               Not in use    0 of inf
        Aor:  Zamtel                                             0
      Contact:  Zamtel/sip:10.20.40.5:5060                 583345d05d Avail         2.201
  Transport:  0.0.0.0-udp               udp      3     96  0.0.0.0:5060
   Identify:  Zamtel/Zamtel
        Match: 10.20.40.5/32


 ParameterName                      : ParameterValue
 ==========================================================
 100rel                             : yes
 accept_multiple_sdp_answers        : false
 accountcode                        : 
 acl                                : 
 aggregate_mwi                      : true
 allow                              : (alaw|ulaw|g723|g729)
 allow_overlap                      : true
 allow_subscribe                    : true
 allow_transfer                     : true
 allow_unauthenticated_options      : false
 aors                               : Zamtel
 asymmetric_rtp_codec               : false
 auth                               : 
 bind_rtp_to_media_address          : false
 bundle                             : false
 call_group                         : 
 callerid                           : <unknown>
 callerid_privacy                   : allowed_not_screened
 callerid_tag                       : 
 connected_line_method              : invite
 contact_acl                        : 
 context                            : from-pstn
 cos_audio                          : 0
 cos_video                          : 0
 device_state_busy_at               : 0
 direct_media                       : false
 direct_media_glare_mitigation      : none
 direct_media_method                : invite
 disable_direct_media_on_nat        : false
 dtls_auto_generate_cert            : No
 dtls_ca_file                       : 
 dtls_ca_path                       : 
 dtls_cert_file                     : 
 dtls_cipher                        : 
 dtls_fingerprint                   : SHA-256
 dtls_private_key                   : 
 dtls_rekey                         : 0
 dtls_setup                         : active
 dtls_verify                        : No
 dtmf_mode                          : auto
 fax_detect                         : false
 fax_detect_timeout                 : 0
 follow_early_media_fork            : true
 force_avp                          : false
 force_rport                        : false
 from_domain                        : 
 from_user                          : 
 g726_non_standard                  : false
 ice_support                        : false
 identify_by                        : username,ip
 ignore_183_without_sdp             : false
 inband_progress                    : false
 incoming_mwi_mailbox               : 
 language                           : en
 mailboxes                          : 
 max_audio_streams                  : 1
 max_video_streams                  : 1
 media_address                      : 
 media_encryption                   : no
 media_encryption_optimistic        : false
 media_use_received_transport       : false
 message_context                    : 
 moh_passthrough                    : false
 moh_suggest                        : default
 mwi_from_user                      : 
 mwi_subscribe_replaces_unsolicited : no
 named_call_group                   : 
 named_pickup_group                 : 
 notify_early_inuse_ringing         : false
 one_touch_recording                : false
 outbound_auth                      : 
 outbound_proxy                     : 
 pickup_group                       : 
 preferred_codec_only               : false
 record_off_feature                 : automixmon
 record_on_feature                  : automixmon
 refer_blind_progress               : true
 rewrite_contact                    : false
 rpid_immediate                     : false
 rtcp_mux                           : false
 rtp_engine                         : asterisk
 rtp_ipv6                           : false
 rtp_keepalive                      : 0
 rtp_symmetric                      : true
 rtp_timeout                        : 0
 rtp_timeout_hold                   : 0
 sdp_owner                          : -
 sdp_session                        : Asterisk
 send_connected_line                : no
 send_diversion                     : true
 send_history_info                  : false
 send_pai                           : false
 send_rpid                          : false
 set_var                            : 
 srtp_tag_32                        : false
 stir_shaken                        : false
 sub_min_expiry                     : 0
 subscribe_context                  : 
 suppress_q850_reason_headers       : false
 t38_udptl                          : false
 t38_udptl_ec                       : none
 t38_udptl_ipv6                     : false
 t38_udptl_maxdatagram              : 0
 t38_udptl_nat                      : false
 timers                             : yes
 timers_min_se                      : 90
 timers_sess_expires                : 1800
 tone_zone                          : 
 tos_audio                          : 0
 tos_video                          : 0
 transport                          : 0.0.0.0-udp
 trust_connected_line               : yes
 trust_id_inbound                   : false
 trust_id_outbound                  : false
 use_avpf                           : false
 use_ptime                          : false
 user_eq_phone                      : false
 voicemail_extension                : 
 webrtc                             : no

(Henri) #17

Here is the section from pjsip.endpoint.conf

[Zamtel]
type=endpoint
transport=0.0.0.0-udp
context=from-pstn
disallow=all
allow=alaw,ulaw,g723,g729
aors=Zamtel
send_connected_line=false
language=en
user_eq_phone=no
t38_udptl=no
t38_udptl_ec=none
fax_detect=no
trust_id_inbound=no
t38_udptl_nat=no
force_rport=no
direct_media=no
rtp_symmetric=yes
dtmf_mode=auto

I have also activated the Enable Debug by Asterisk SIP settings > SIP Settings [chan_pjsip].


#18

Great. I hope that you have also issued
pjsip set logger on
after the last reload. However, the purpose of both is to log additional information in the Asterisk log. Please paste the log for a failing call at pastebin.freepbx.org and post the link here.

I see something strange that might be related to your issue, although I don’t see how it could cause your issue: In your deleted post (Oct 15 at 08:41, assuming your timezone is UTC+2), the pjsip show endpoint Zamtel displayed different IP addresses for Contact and Match, while the replacement shows the same address. Are they actually different? Can the Zamtel trunk send calls from more than one IP address? If so, is that correlated with when the failure occurs? If not, what do these addresses represent?