Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/signalwire/freeswitch/llms.txt

Use this file to discover all available pages before exploring further.

A SIP profile in FreeSWITCH is a self-contained Sofia-SIP user agent bound to a specific IP address and port. Each profile maintains its own listener socket, SIP registration table, TLS settings, and codec preferences. mod_sofia — the FreeSWITCH SIP module — can run any number of profiles simultaneously, making it possible to serve registered phones, SIP trunks, and WebRTC clients all from the same instance. Profile configuration files live in conf/sip_profiles/ and are loaded by autoload_configs/sofia.conf.xml.

Default Profiles

The vanilla configuration ships with two profiles that cover the most common deployment scenario.

internal

Port 5060 (UDP/TCP)Intended for SIP endpoints that register directly with FreeSWITCH — desk phones, softphones, and WebRTC clients. Authentication is required (auth-calls=true). The profile’s default context is public, but authenticated users are routed into the default context via the user_context variable set in their directory entry.

external

Port 5080 (UDP/TCP)Intended for outbound SIP trunks and PSTN gateways. Authentication is disabled on this profile (auth-calls=false) because the remote carrier authenticates at the trunk level via gateways. Inbound DID calls arrive on this port and land in the public dialplan context.

internal.xml (key settings)

<profile name="internal">
  <gateways>
    <!-- Outbound registrations (gateways) go here or in sip_profiles/internal/*.xml -->
  </gateways>

  <domains>
    <!-- alias="true" makes this profile accept calls for all configured domains -->
    <domain name="all" alias="true" parse="false"/>
  </domains>

  <settings>
    <param name="sip-port"           value="$${internal_sip_port}"/>  <!-- 5060 -->
    <param name="sip-ip"             value="$${local_ip_v4}"/>
    <param name="rtp-ip"             value="$${local_ip_v4}"/>
    <param name="ext-sip-ip"         value="$${external_sip_ip}"/>
    <param name="ext-rtp-ip"         value="$${external_rtp_ip}"/>

    <param name="context"            value="public"/>
    <param name="dialplan"           value="XML"/>

    <param name="auth-calls"         value="$${internal_auth_calls}"/>  <!-- true -->
    <param name="auth-subscriptions" value="true"/>
    <param name="nonce-ttl"          value="60"/>

    <param name="inbound-codec-prefs"  value="$${global_codec_prefs}"/>
    <param name="outbound-codec-prefs" value="$${global_codec_prefs}"/>
    <param name="inbound-codec-negotiation" value="generous"/>
    <param name="inbound-late-negotiation"  value="true"/>

    <param name="hold-music"         value="$${hold_music}"/>
    <param name="manage-presence"    value="true"/>
    <param name="presence-hosts"     value="$${domain},$${local_ip_v4}"/>

    <!-- Force all registrations into the single configured domain -->
    <param name="force-register-domain"    value="$${domain}"/>
    <param name="force-subscription-domain" value="$${domain}"/>
    <param name="force-register-db-domain"  value="$${domain}"/>

    <!-- WebSocket / WebRTC support -->
    <param name="ws-binding"  value=":5066"/>
    <param name="wss-binding" value=":7443"/>

    <!-- TLS (disabled by default) -->
    <param name="tls"          value="$${internal_ssl_enable}"/>
    <param name="tls-sip-port" value="$${internal_tls_port}"/>    <!-- 5061 -->
    <param name="tls-version"  value="$${sip_tls_version}"/>
    <param name="tls-ciphers"  value="$${sip_tls_ciphers}"/>
  </settings>
</profile>

Key Parameters

sip-ip
string
required
Local IP address to bind the SIP listener to. Must be an IP address — do not use hostnames.Default: $${local_ip_v4} (auto-detected local address)
sip-port
integer
required
UDP/TCP port to listen for SIP traffic.Internal default: 5060 | External default: 5080
rtp-ip
string
required
Local IP to use for RTP media streams. Must be an IP address — do not use hostnames.Default: $${local_ip_v4}
ext-sip-ip
string
Public (NAT) IP advertised in SIP Contact and Via headers. Accepts an IP address, stun:server, host:fqdn, auto, or auto-nat.Default: $${external_sip_ip} (resolved via STUN)
ext-rtp-ip
string
Public (NAT) IP written into the SDP c= and m= lines for RTP.Default: $${external_rtp_ip} (resolved via STUN)
context
string
required
Dialplan context that unauthenticated (or pre-auth) inbound calls are sent to.Default (both profiles): public
dialplan
string
Dialplan module to use for call routing.Default: XML (uses mod_dialplan_xml)
auth-calls
boolean
Whether to challenge INVITEs with a 407 Proxy Authentication Required response.Internal: true | External: false
nonce-ttl
integer
Lifetime in seconds for SIP digest authentication nonces.Default: 60
inbound-reg-force-matching-username
boolean
Forces the SIP username and auth username to match during REGISTER.Default: true
inbound-codec-prefs
string
Ordered list of codecs offered/accepted for inbound calls.Default: $${global_codec_prefs}OPUS,G722,PCMU,PCMA,H264,VP8
outbound-codec-prefs
string
Ordered list of codecs offered/accepted for outbound calls.Default: $${global_codec_prefs}
inbound-codec-negotiation
string
How to resolve codec disagreements. generous accepts the remote’s preference; greedy enforces the local list order.Default: generous
inbound-late-negotiation
boolean
When true, codec negotiation is deferred until the dialplan runs, allowing the dialplan to influence codec selection.Default: true

SIP Gateways

A gateway tells mod_sofia how to register with an upstream SIP provider (e.g., a PSTN carrier or SIP trunk). Gateways are defined inside the <gateways> block of a profile, or in individual XML files under sip_profiles/external/. The following example is drawn from the vanilla sip_profiles/external/example.xml (which ships fully commented-out as a template):
<include>
  <gateway name="my-carrier">
    <!-- Required: SIP account username at the provider -->
    <param name="username"       value="myaccount"/>

    <!-- Auth realm — defaults to the gateway name if omitted -->
    <param name="realm"          value="sip.carrier.com"/>

    <!-- Account password -->
    <param name="password"       value="s3cr3t"/>

    <!-- Proxy/registrar hostname or IP -->
    <param name="proxy"          value="sip.carrier.com"/>

    <!-- Register with the provider (set false for IP-authenticated trunks) -->
    <param name="register"       value="true"/>

    <!-- Registration expiry in seconds -->
    <param name="expire-seconds" value="3600"/>

    <!-- Retry interval on failure -->
    <param name="retry-seconds"  value="30"/>

    <!-- Transport: udp, tcp, or tls -->
    <param name="register-transport" value="udp"/>
  </gateway>
</include>
To route outbound calls through this gateway, use the sofia dial string in your dialplan:
<action application="bridge" data="sofia/external/+15551234567@sip.carrier.com"/>

Profile Management

Use these commands at the fs_cli console to inspect and control SIP profiles without restarting FreeSWITCH.
# List all profiles and their current status
sofia status

# Show detailed info for the internal profile (registrations, settings, gateways)
sofia status profile internal

# Show gateway status
sofia status gateway my-carrier

# Reload a profile after editing its XML
sofia profile internal rescan

# Full stop and restart of a profile (briefly drops registrations)
sofia profile internal restart

# Reload all SIP configuration
sofia reload

# Recover existing calls after a crash or restart
sofia recover
You can reload a single profile’s configuration without restarting FreeSWITCH or dropping active calls:
sofia profile internal rescan
Use rescan for parameter changes. Use restart only when you need to rebind the socket (e.g., changing sip-port). The sofia reload command reloads the entire sofia.conf.xml including all profiles and gateways.

NAT Traversal

When FreeSWITCH sits behind a NAT router, the SIP and SDP packets must advertise the public IP rather than the private one. The vanilla config handles this through two mechanisms:
1

STUN resolution at startup

vars.xml uses stun-set to query stun.freeswitch.org and store the public IP:
<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"/>
These values are then referenced in every profile via $${external_rtp_ip} and $${external_sip_ip}.
2

Manual override (recommended for production)

For stable servers with a fixed public IP, replace the STUN entries with a hard-coded address:
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=203.0.113.10"/>
<X-PRE-PROCESS cmd="set" data="external_sip_ip=203.0.113.10"/>
Alternatively, use a DNS hostname:
<X-PRE-PROCESS cmd="set" data="external_sip_ip=host:pbx.example.com"/>
3

NAT ACL and auto-detection

The internal profile also includes:
<param name="apply-nat-acl" value="nat.auto"/>
<param name="local-network-acl" value="localnet.auto"/>
nat.auto is a built-in ACL that FreeSWITCH populates with RFC 1918 private ranges at startup. Packets from these ranges are treated as coming from behind NAT, and FreeSWITCH adjusts the Contact/Via headers accordingly.

TLS / SRTP

TLS transport and SRTP media encryption are disabled by default in the vanilla config. To enable them, adjust vars.xml and the relevant profile:
<!-- In vars.xml: enable TLS on the internal profile -->
<X-PRE-PROCESS cmd="set" data="internal_ssl_enable=true"/>

<!-- In sip_profiles/internal.xml: point to your certificate directory -->
<param name="tls"          value="$${internal_ssl_enable}"/>
<param name="tls-only"     value="false"/>
<param name="tls-sip-port" value="$${internal_tls_port}"/>  <!-- 5061 -->
<param name="tls-cert-dir" value="/etc/freeswitch/tls"/>
<param name="tls-version"  value="$${sip_tls_version}"/>    <!-- tlsv1,tlsv1.1,tlsv1.2 -->
<param name="tls-ciphers"  value="$${sip_tls_ciphers}"/>    <!-- ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH -->
The certificate directory must contain agent.pem (the server certificate + private key) and cafile.pem (the CA chain). FreeSWITCH will log an error at startup if the files are missing. For SRTP, set the rtp_secure_media channel variable in the dialplan or configure rtp_sdes_suites in vars.xml to control which cipher suites are offered.

Build docs developers (and LLMs) love