The phones were fine until the router was replaced. Now calls connect and caller ID shows up, but one side hears nothing, or calls die at about thirty seconds, or desk phones drift to unregistered by lunch, which is the classic SIP ALG one-way audio pattern and its two close relatives.
The fix is often one setting on the new firewall, but which setting, and how to prove it worked, differ by platform. Knowing why the break happens also tells you when disabling the ALG will not be enough.
Why do calls connect when the audio does not?
SIP sets the call up; the audio is RTP, and where it should go is written inside the SIP message body as a session description (SDP). RFC 4566 defines the connection line as c=<nettype> <addrtype> <connection-address> and the media line as m=<media> <port> <proto> <fmt>, where the port is the transport port to which the media stream is sent. A phone on a typical office LAN will say something like c=IN IP4 192.168.1.40 and m=audio 49170 RTP/AVP 0: send my audio to this private address, on this port.
RFC 3550 adds that RTP should use an even destination port and RTCP the next higher odd port. RFC 6314 states the core problem plainly: during the offer/answer exchange each client specifies an IP address and port for receiving media, and trouble arises when that address sits in a private network that is not accessible from outside the NAT. The signaling reached a public server; the audio was told to go somewhere unroutable.
What a SIP ALG tries to do, and how it gets it wrong
An application layer gateway is the firewall editing SIP messages in flight to fix this. SonicWall describes SIP ALG as a mechanism that rewrites packets transmitted across the device, and notes that it modifies the destination addresses of VoIP packets, causing reliability issues. Fortinet's documentation says its legacy SIP session helper opens SIP and RTP pinholes and performs NAT of the addresses in SIP messages, and that by default all SIP traffic is processed by the SIP ALG.
The trouble is that most hosted voice providers already solve NAT on their side. RFC 6314 recommends that clients use the same IP address and port for both sending and receiving SIP so that NAT traversal hosted on a session border controller can work, and it says user agents behind a NAT using the latching technique must implement symmetric RTP, meaning they send and receive media from the same address and port. If the provider already latches onto where packets really come from, a firewall that also rewrites the SDP, inconsistently with the ports it actually used, gives one call two fixers who disagree.
RFC 4787 says NAT ALGs for UDP-based protocols should be turned off, and RFC 6314 says experience shows ALGs can have an adverse impact on SIP, including not working with encrypted signaling.
Which symptom points to which cause?
- One-way audio or no audio: the c= or m= line names an address or port the other side cannot reach, either because nothing rewrote it or because the ALG rewrote it wrongly. Netgate's pfSense documentation adds a related cause: with some providers, rewriting the source port of RTP can cause one-way audio.
- Calls drop at about 32 seconds: the ACK for the answered call never arrives. RFC 3261 sets the dialog's remote target from the Contact header of the response; if that Contact carries an unreachable address, the ACK goes nowhere. The answering side retransmits its 200 OK, and if no ACK arrives within 64*T1 seconds the session should be terminated with a BYE. With T1 at its 500 ms default, that is 32 seconds.
- Phones go unregistered or inbound calls never ring: the firewall forgot the UDP mapping between registrations, so the provider's INVITE has no path back in. RFC 5626 notes that many NATs have UDP timeouts as low as 30 seconds.
SonicWall's own list of when to disable SIP ALG matches these: one-way audio, phones that do not ring, no incoming calls, calls dropping after connecting, and calls going straight to voicemail for no known reason.
How to confirm it before changing anything
Take two packet captures at the same time, one on the LAN side of the firewall and one on the WAN side, and place a test call. Find the INVITE and the 200 OK and read their SDP. If the c= and m= lines are identical on both sides, nothing is editing the body. If they differ, you can see exactly what was written. Then check on the WAN side whether the 200 OK's Contact header is reachable and whether RTP from the provider arrives at all. RTP arriving at the WAN but never reaching the phone points at the firewall; no RTP arriving points at the address the provider was given.
On a FortiGate you can also ask the firewall directly. Fortinet documents diagnose sys session list | grep sip and lists the flags to look for: helper=sip means the session helper is handling the traffic, redir and local or helper=20 or helper=24 mean the SIP ALG is, and any flag other than ndr means one of the two is still involved.
Disabling SIP ALG on a FortiGate
Fortinet's CLI procedure for removing both the ALG and the session helper, which it says may be necessary when advised by your SIP provider, runs in this order:
- Run show system session-helper and find the entry with set name sip, set protocol 17 and set port 5060, which is entry 13 by default. Remove it with config system session-helper, delete 13, end. Repeat for other ports if your SIP traffic uses them.
- Under config system settings, set default-voip-alg-mode kernel-helper-based. This controls how SIP is handled when a policy has no VoIP profile.
- Check the policy that carries the phones' traffic with show firewall policy. If it has a VoIP profile, either disable SIP inside that profile (config voip profile, config sip, set status disable, set rtp disable) or remove it from the policy with unset voip-profile.
- Clear existing SIP sessions so the change takes effect, using diagnose sys session filter dport 5060 then diagnose sys session clear, and again with sport 5060.
Fortinet warns that clearing sessions on port 5060 terminates all active SIP calls through the FortiGate, so this is an after-hours step. Afterward, run the session list again and look for the flags above.
Disabling SIP ALG on a SonicWall
SonicWall's knowledge base gives the SonicOS 7 path as Network | VoIP | Settings: enable Consistent NAT and disable Enable SIP Transformations. Then go to Policy | Access Rules, edit the LAN to WAN rule for the zone where the phones live, and change the UDP timeout from the default 30 seconds to 120 seconds. On SonicOS 6.5 the same settings are under Manage | VoIP and Manage | Rules | Access Rules.
Consistent NAT uses an MD5 hash to assign the same public IP and UDP port pair to each internal address and port pair, which is what the provider's latching needs. SonicWall cautions that it slightly decreases overall security because the pairs become more predictable, and says to enable the SIP ALG only if your router manufacturer or VoIP provider has instructed it.
What to do instead of an ALG
Turning the ALG off removes the damage; it does not keep the path open. Four settings do that:
- Provider NAT traversal. Confirm the provider expects phones behind NAT and handles it at their edge, and that the phones send and receive on one socket.
- Keepalives. RFC 5626 says that without a Flow-Timer header from the server, STUN keepalives over UDP should go every 24 to 29 seconds, chosen because many NATs time out UDP at 30 seconds.
- Registration interval. Netgate notes that a keep-alive or re-registration timer of 20 to 30 seconds on the phone can help, and is often the better fix.
- UDP timeouts. RFC 4787 says a NAT UDP mapping timer must not expire in less than two minutes and recommends a default of five minutes or more. SonicWall's 120-second rule setting meets the floor.
On pfSense the issue is usually port rewriting rather than an ALG. Netgate says pfSense rewrites the source port on all outbound traffic by default, and that where this causes one-way audio the fix is manual outbound NAT with Static Port on UDP, potentially excluding UDP 5060. For phones that randomly disconnect, it suggests setting Firewall Optimization Options to Conservative under System > Advanced, Firewall/NAT tab.
A worked example: the new firewall and the silent receptionist
A twelve-person design studio with hosted desk phones replaces its ISP router with a FortiGate over a weekend. On Monday the receptionist cannot hear inbound callers, and some calls hang up just over half a minute in.
The LAN-side capture shows the phone's 200 OK with its private address in both the Contact header and the c= line. The WAN-side capture shows the same message with the c= line rewritten to the public address but the m= port changed to a value no RTP is actually leaving from, and the Contact header rewritten to a port the firewall has no session for. Audio goes to the wrong port and the ACK to a dead mapping, so the call is torn down at the 32-second mark. The session list shows helper=20: the SIP ALG.
After hours, the studio follows Fortinet's sequence: delete session helper 13, set default-voip-alg-mode kernel-helper-based, unset the default VoIP profile on the outbound policy, and clear the port 5060 sessions. The new capture shows identical SDP on both sides, the provider latches onto the real source, and the session list no longer shows helper or ALG flags.
Where this goes wrong
- Changing only the default mode. On FortiGate, kernel-helper-based alone hands SIP to the session helper, which still performs NAT of addresses in SIP messages, and a policy with a VoIP profile still uses the ALG.
- Not clearing sessions. Fortinet's procedure clears existing SIP sessions to ensure the changes take effect; skip that step and the setting can appear not to work.
- A second NAT upstream. If the ISP's box is still routing in front of the new firewall, it may be running its own ALG. Check both, or bridge the ISP device.
- Static port on everything. Netgate notes that static port NAT on UDP 5060 by default breaks more scenarios than it helps; apply it only where the PBX requires it.
The decision rule
If the SDP or Contact header differs between the LAN and WAN captures, turn off every SIP rewriting feature on the firewall, clear the SIP sessions, and verify with the firewall's own session view. If the SDP is untouched but phones still drop off, the problem is timers: raise the UDP timeout to at least two minutes and set phone keepalives shorter than it. Turn an ALG back on only when the provider says, in writing, that it depends on one.
