Move extension 7101 outside the LAN
In episode 9, extensions 7101 and 7102 called each other on the LAN via training-internal, which listens on 5090. Move 7101 to an external network with a known test egress address and leave 7102 on the LAN. A pass means either extension can call the other, both parties can repeat a phrase from the other end, and both can hang up normally. Reuse the directory, dialplan, queue agents and tiers from the previous exercises.
The lab host uses 10.20.30.10 and the edge uses 203.0.113.10. Replace the documentation-only public address with the IPv4 address allocated to your test entry point. This lab uses IPv4, UDP SIP and RTP anchored at FreeSWITCH. Use a test instance with a rollback path and an external endpoint that can exchange media. If the carrier uses upstream NAT and offers no inbound mapping, arrange a reachable path through a public SBC or a VPN before changing the profile.
Forward signaling and media at the edge
Forward UDP 5090 to 10.20.30.10:5090 and restrict access to the agreed test sources. On 7101, set the public transport destination and port while keeping the authentication user, password and directory domain. A separate outbound proxy field can carry the transport destination on clients that offer one. Leave 7102 on the private address. Check signaling and media source allowlists separately, especially if an SBC uses separate addresses.
Look in autoload_configs/switch.conf.xml for rtp-start-port and rtp-end-port. The v1.11.2 template shows 16384 and 32768 in commented examples. Check the active range and change records before creating same-port UDP forwarding and host firewall rules for the actual range. Port 5090 is for SIP in this lab. The negotiated SDP identifies media ports per call. Verify RTCP against the negotiation and actual packets as well. Keep the existing RTP pool. Shrinking the pool affects the whole instance, including allocations for other profiles.
Set the four addresses in training-internal.xml
In fs_cli, run eval $${conf_dir} to find the configuration root. Back up sip_profiles/training-internal.xml outside the include path. This is the complete lab profile from the previous episode with the NAT settings added. Use the actual lab addresses and preserve unrelated settings on a customized instance.
<profile name="training-internal">
<!-- 继续使用现有目录域,不创建别名或加载网关 -->
<aliases/>
<gateways/>
<domains>
<domain name="all" alias="false" parse="false"/>
</domains>
<settings>
<!-- 内网网卡地址,5090 是本实验的 SIP 端口 -->
<param name="sip-ip" value="10.20.30.10"/>
<param name="sip-port" value="5090"/>
<param name="rtp-ip" value="10.20.30.10"/>
<!-- 换成边界实际转发到测试机的公网 IPv4 -->
<param name="ext-sip-ip" value="203.0.113.10"/>
<param name="ext-rtp-ip" value="203.0.113.10"/>
<!-- 保留上期的鉴权与默认路由入口 -->
<param name="auth-calls" value="true"/>
<param name="dialplan" value="XML"/>
<param name="context" value="public"/>
</settings>
</profile>
sip-ip and sip-port select the local SIP socket. rtp-ip selects the local media address. When the router owns the public IP, both local addresses still belong to the FreeSWITCH host. ext-sip-ip is the advertised external SIP address, which you can inspect in headers such as Contact on the relevant leg. ext-rtp-ip is the external media address to verify in that leg's audio SDP. These two address settings create no forwarding rules and do not rewrite the advertised m=audio port. This lab uses same-port mappings. If the ports differ, handle the translation at the edge or SBC and verify the packets from outside.
auth-calls keeps INVITE authentication enabled. dialplan selects XML. context sets the default route context, and an authenticated user's directory user_context can affect the effective route. Review what public permits and retain the restricted routes from episode 9. The empty gateway block leaves carrier trunks on their original profiles.
Load the profile and verify the packets
Wait for lab calls to finish, then run the following in fs_cli. A profile restart can interrupt its calls, so drain the profile before a production change. The last line lists registrations for the test profile. After both phones register again, check whether old contacts on the original listener are still used for lookup.
reloadxml
sofia profile training-internal restart
sofia status profile training-internal
sofia status profile training-internal reg
Call 7102 from the external 7101, then call in the other direction. Find the INVITE and 200 OK on the external leg by Call-ID. In the response from FreeSWITCH, verify that the peer can reach the host and port in Contact. Check c= for the media address and m=audio for the port, using the audio-level c= when it is present. Compare captures outside the firewall and on the FreeSWITCH interface, following both directions on the UDP tuples for this call. Two SIP legs may use different Call-IDs. Correlate them using the test time, extensions and channels. Redact accounts, numbers and addresses before sharing captures.
After verifying two-way audio, check hangup and hold/resume. A resumed call may negotiate new SDP, so check the new addresses and ports. If this profile also serves queue agents, call 7190 and verify an actual delivery. Registering a phone does not change its agent or tier. Check for an agent contact pinned to the old listener if the queue cannot reach it.
Follow the symptom
- Registration times out. If UDP 5090 appears outside the edge but never arrives at FreeSWITCH, check forwarding, source rules and the host firewall. If FreeSWITCH issues a challenge, inspect the authentication domain and user.
- Calls connect but hangup fails. Follow the external dialog's Contact, route set and actual ACK and BYE destinations. Compare captures across a SIP ALG to see whether it rewrote the addresses.
- 7101 cannot hear 7102. Follow the media from FreeSWITCH to 7101 and compare the endpoint's advertised and actual receive addresses. If 7102 cannot hear 7101, follow the reverse path through the public mapping to FreeSWITCH.
- An external test works but the public address fails from the same Wi-Fi. Check whether the edge supports hairpin NAT, or use the private listener from the LAN. Where VPN or private links cross subnets, verify local-network-acl and the actual address shown to both sides. Registration permission is handled separately by access controls and authentication.
Other settings you may encounter
A fixed public address is straightforward to verify in a capture. The manual also lists host:hostname, stun:server and auto-nat. These depend on DNS, STUN, or NAT-PMP/UPnP respectively. After an address change, verify both the resolved profile address and the edge mapping again. Discovery through STUN does not establish inbound reachability through a carrier's NAT.
apply-nat-acl and aggressive-nat-detection are useful when troubleshooting a phone behind its own NAT. The latter considers differences between the SIP packet source and Contact. A proxy or SBC can also introduce those differences in normal operation. Compare Contact and packet destinations before and after a change on a single test phone. The ext settings describe the FreeSWITCH side of the path.
Roll back to the original listener
Wait for lab calls to end, then remove the public entry point. Restore the backed-up XML, reload XML and restart the lab profile. Set both phones back to their previous server addresses and repeat the LAN calls. Restore only the firewall rules changed for this exercise. The example was checked against the vendor templates and standards. The expected results are acceptance criteria for your own lab.