动态

详情 返回 返回

FreeSWITCH跨NAT部署 - 动态 详情

本文僅討論FreeSWITCH部署在NAT之後(裏面)這種場景,假設私網地址與公網地址有一個確定的映射關係。
這裏只涉及mod_sofia(SIP信令及媒體)相關配置,其他模塊不在本文討論之列。

配置

mod_sofia默認提供兩個profile,可以理解成是兩套配置,最主要的區別是監聽端口不一樣,其他的區別包括是否啓用TLS加密,使用哪個撥號計劃等等。這裏以internal profile為例。

1、配置預處理變量

FreeSWITCH的慣例是把預處理變量定義在vars.xml文件中,然後再由其他配置文件去引用。這裏我們主要關注公網地址以及SIP監聽端口。

etc/freeswitch/vars.xml

<include>
  <!-- 注意,X-PRE-PROCESS開頭的配置都是預處理配置,有點像是定義全局變量,但是變量的值可以在程序啓動時動態獲取到 -->
 
  <!-- 這兩個變量必須要設置成公網IP,有3種方法配置公網IP: -->
  <!-- 1、配一個固定的公網IP -->
  <X-PRE-PROCESS cmd="set" data="external_rtp_ip=172.21.221.137"/>
  <X-PRE-PROCESS cmd="set" data="external_sip_ip=172.21.221.137"/>
  <!-- 2、通過公網上的stun服務動態獲取 -->
  <X-PRE-PROCESS cmd="stun-set" data="external_rtp_ip=stun:stun.freeswitch.org"/>
  <X-PRE-PROCESS cmd="stun-set" data="external_sip_ip=stun:stun.freeswitch.org"/>
  <!-- 3、通過域名解析動態獲取 -->
  <X-PRE-PROCESS cmd="set" data="external_rtp_ip=host:host.server.com"/>
  <X-PRE-PROCESS cmd="set" data="external_sip_ip=host:host.server.com"/>
 
  <!-- 配置兩個profile所監聽的SIP端口: -->
  <!-- Internal SIP Profile -->
  <X-PRE-PROCESS cmd="set" data="internal_auth_calls=true"/>
  <X-PRE-PROCESS cmd="set" data="internal_sip_port=5060"/>
  <X-PRE-PROCESS cmd="set" data="internal_tls_port=5061"/>
  <X-PRE-PROCESS cmd="set" data="internal_ssl_enable=false"/>
  <!-- External SIP Profile -->
  <X-PRE-PROCESS cmd="set" data="external_auth_calls=false"/>
  <X-PRE-PROCESS cmd="set" data="external_sip_port=5080"/>
  <X-PRE-PROCESS cmd="set" data="external_tls_port=5081"/>
  <X-PRE-PROCESS cmd="set" data="external_ssl_enable=false"/>
</include>
2、配置sip profiles

這裏才是mod_sofia真正會讀取的配置。這裏以internal profile為例,external同理。

etc/freeswitch/sip_profiles/internal.xml

  1. 首先配置SIP監聽端口,這裏引用了vars.xml中定義的全局變量。
    注意,要以$${var}的形式引用全局變量!

    <!-- port to bind to for sip traffic -->
    <param name="sip-port" value="$${internal_sip_port}"/>
  2. 配置用於接收SIP信令與RTP媒體流的IP地址,此處就使用默認配置$${local_ip_v4}
    local_ip_v4是fs_core自動設置的,不要手動改。若機器有多個IP,則為系統第一個返回的IP,詳見官方文檔。

    <!-- ip address to use for rtp, DO NOT USE HOSTNAMES ONLY IP ADDRESSES -->
    <param name="rtp-ip" value="$${local_ip_v4}"/>
    <!-- ip address to bind to, DO NOT USE HOSTNAMES ONLY IP ADDRESSES -->
    <param name="sip-ip" value="$${local_ip_v4}"/>
  3. 配置SIP與SDP的通告地址,當mod_sofia檢測到NAT時,會將這些地址填在SIP header和SDP消息中。

    <!-- 檢測到NAT時,SDP的媒體地址會填這個 -->
    <param name="ext-rtp-ip" value="$${external_rtp_ip}"/>
    <!-- 這個地址會出現在Contact等header中 -->
    <param name="ext-sip-ip" value="$${external_sip_ip}"/>
  4. NAT檢測。如果配置了ext-sip-ip,mod_sofia會檢查remote_sip_ip是否命中loopback.auto和local-network-acl這兩個ACL,若命中則SDP的媒體地址填rtp-ip,否則SDP的媒體地址填ext-rtp-ip。
    此處代碼詳見switch_core_media_choose_port()

    <!--
      為了簡單起見,直接把這裏改成none。
      這樣只要SIP報文的遠端IP不命中loopback.auto(127.0.0.x),
      它就會認為檢測到NAT,從而在SDP中填ext-rtp-ip。
    -->
    <param name="local-network-acl" value="none"/>
3、配置媒體端口範圍

有些NAT或防火牆只能允許一個範圍內的端口,這就需要調整FreeSWITCH接收RTP媒體流所用的端口範圍。
注意:FreeSWITCH使用偶數端口接收RTP流,使用奇數端口收發RTCP消息。假如需要承載50路通話,則至少要映射100個端口!

etc/freeswitch/autoload_configs/switch.conf.xml

<configuration name="switch.conf" description="Core Configuration">
  <settings>
    <!-- RTP port range -->
    <param name="rtp-start-port" value="40000"/>
    <param name="rtp-end-port" value="40009"/>
  </settings>
</configuration>

驗證

人為改一下ext-rtp-ipext-sip-ip,觀察它們的作用:

此時有一個到達internal profile的呼叫,從FreeSWITCH回覆的200 OK中可以看到,Contact header中填的是ext-sip-ip,而SDP部分填的是ext-rtp-ip

問題

  1. 私網端口號與公網端口號不一樣怎麼辦?比如:私網:5060 <==> 公網:8060
    恐怕只能修改代碼了。
user avatar wodekouwei 头像 lucia_onmyway 头像
点赞 2 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.