Dear community members, after numerous tweakings and tests, I am here requesting your help making stuff work.
My setup
- OS: FreeBSD 14.2, Asterisk runs within a VNET Jail (has its own network stack and dedicated virtual interface, own IP)
- Asterisk version: asterisk22-22.5.2 (installed using pkg). Using PJSIP.
- Internal IP: 192.168.8.55
- Network: Static public IP, NAT.
Firewall configuration
- Network Firewall: Opened ports
5060
and range10000 - 10255
UDP. Cannot open a wider range, apparently, as the router/modem/firewall Fritz!Box 7590 won’t allow me. - Host Firewall: Disabled, everything is allowed at the moment.
The issue
I configured two internal extensions, and they can communicate no problem within the network. Both are soft phones with an app installed.
What does not work is reaching external users, that is, making or receiving external calls.
Incoming calls scenario
The configured endpoint rings, I can pick up the call but I hear nothing, nor does the other user.
Outgoing calls scenario
In a similar way, if I initiate the call, the remote endpoint rings and can pick up the call. However, nothing is heard on neither ends.
Configuration dumps
I replaced sensitive data with placeholders:
Value | Meaning |
---|---|
externalip | public static address |
providername | SIP trunk provider |
givenusername | credentials |
givenpasswd | credentials |
custompass | endpoint custom password |
/usr/local/etc/asterisk/pjsip.conf
[providername]
type=transport
protocol=udp
bind=0.0.0.0
local_net=192.168.8.0/24
external_media_address=externalip
external_signaling_address=externalip
[providername_auth]
type=auth
auth_type=userpass
username=givenusername
password=givenpasswd
[providername_aor]
type=aor
contact=sip:voip.providername.it
max_contacts=1
qualify_frequency=300
[providername_endpoint]
type=endpoint
context=from-provider
disallow=all
allow=alaw,ulaw
aors=providername_aor
auth=providername_auth
outbound_auth=providername_auth
rtp_symmetric=yes
force_rport=yes
direct_media=no
ice_support=yes
from_user=givenusername
disable_direct_media_on_nat=yes
[providername_registration]
type=registration
outbound_auth=providername_auth
server_uri=sip:voip.providername.it
client_uri=sip:givenusername@voip.providername.it
contact_user=givenusername
retry_interval=60
forbidden_retry_interval=600
expiration=3600
transport=providername
line=yes
endpoint=providername_registration
[provider_inbound]
type=endpoint
context=from-provider
disallow=all
allow=alaw,ulaw
transport=providername
aors=providername_aor
disable_direct_media_on_nat=yes
[provider_inbound_identify]
type=identify
endpoint=provider_inbound
match=voip.providername.it
; INTERNAL
[template](!)
type=endpoint
context=from-internal
disallow=all
allow=ulaw,alaw
rewrite_contact=yes
acl=lan
direct_media=no
rtp_symmetric=yes
ice_support=yes
force_rport=yes
disable_direct_media_on_nat=yes
[101](template)
auth=101_auth
aors=101
[101_auth]
type=auth
auth_type=userpass
username=101
password=custompass
[101]
type=aor
max_contacts=10
qualify_frequency=30
[102](template)
auth=102_auth
aors=102
[102_auth]
type=auth
auth_type=userpass
username=102
password=custompass
[102]
type=aor
max_contacts=10
qualify_frequency=30
/usr/local/etc/asterisk/asterisk.conf
[directories](!)
astcachedir => /var/cache/asterisk
astetcdir => /usr/local/etc/asterisk
astmoddir => /usr/local/lib/asterisk/modules
astvarlibdir => /usr/local/share/asterisk
astdbdir => /var/db/asterisk
astkeydir => /usr/local/share/asterisk
astdatadir => /usr/local/share/asterisk
astagidir => /usr/local/share/asterisk/agi-bin
astspooldir => /var/spool/asterisk
astrundir => /var/run/asterisk
astlogdir => /var/log/asterisk
astsbindir => /usr/local/sbin
[options]
;verbose = 3
;debug = 3
;trace = 0 ; Set the trace level.
;refdebug = yes ; Enable reference count debug logging.
;alwaysfork = yes ; Same as -F at startup.
;nofork = yes ; Same as -f at startup.
;quiet = yes ; Same as -q at startup.
;timestamp = yes ; Same as -T at startup.
;execincludes = yes ; Support #exec in config files.
;console = yes ; Run as console (same as -c at startup).
;highpriority = yes ; Run realtime priority (same as -p at
; startup).
;initcrypto = yes ; Initialize crypto keys (same as -i at
; startup).
;nocolor = yes ; Disable console colors.
;dontwarn = yes ; Disable some warnings.
;dumpcore = yes ; Dump core on crash (same as -g at startup).
;languageprefix = yes ; Use the new sound prefix path syntax.
;systemname = my_system_name ; Prefix uniqueid with a system name for
; Global uniqueness issues.
;autosystemname = yes ; Automatically set systemname to hostname,
; uses 'localhost' on failure, or systemname if
; set.
;mindtmfduration = 80 ; Set minimum DTMF duration in ms (default 80 ms)
; If we get shorter DTMF messages, these will be
; changed to the minimum duration
;maxcalls = 10 ; Maximum amount of calls allowed.
;maxload = 0.9 ; Asterisk stops accepting new calls if the
; load average exceed this limit.
;maxfiles = 1000 ; Maximum amount of openfiles.
;minmemfree = 1 ; In MBs, Asterisk stops accepting new calls if
; the amount of free memory falls below this
; watermark.
;cache_media_frames = yes ; Cache media frames for performance
; Disable this option to help track down media frame
; mismanagement when using valgrind or MALLOC_DEBUG.
; The cache gets in the way of determining if the
; frame is used after being freed and who freed it.
; NOTE: This option has no effect when Asterisk is
; compiled with the LOW_MEMORY compile time option
; enabled because the cache code does not exist.
; Default yes
;cache_record_files = yes ; Cache recorded sound files to another
; directory during recording.
;record_cache_dir = /tmp ; Specify cache directory (used in conjunction
; with cache_record_files).
;transmit_silence = yes ; Transmit silence while a channel is in a
; waiting state, a recording only state, or
; when DTMF is being generated. Note that the
; silence internally is generated in raw signed
; linear format. This means that it must be
; transcoded into the native format of the
; channel before it can be sent to the device.
; It is for this reason that this is optional,
; as it may result in requiring a temporary
; codec translation path for a channel that may
; not otherwise require one.
;transcode_via_sln = yes ; Build transcode paths via SLINEAR, instead of
; directly.
;runuser = asterisk ; The user to run as.
;rungroup = asterisk ; The group to run as.
;lightbackground = yes ; If your terminal is set for a light-colored
; background.
;forceblackbackground = yes ; Force the background of the terminal to be
; black, in order for terminal colors to show
; up properly.
;defaultlanguage = en ; Default language
documentation_language = en_US ; Set the language you want documentation
; displayed in. Value is in the same format as
; locale names.
;hideconnect = yes ; Hide messages displayed when a remote console
; connects and disconnects.
;lockconfdir = no ; Protect the directory containing the
; configuration files (/etc/asterisk) with a
; lock.
;stdexten = gosub ; How to invoke the extensions.conf stdexten.
; gosub - Invoke the stdexten using a gosub as
; documented in extensions.conf.sample.
; Default gosub.
;live_dangerously = no ; Enable the execution of 'dangerous' dialplan
; functions and configuration file access from
; external sources (AMI, etc.) These functions
; (such as SHELL) are considered dangerous
; because they can allow privilege escalation.
; Configuration files are considered dangerous
; if they exist outside of the Asterisk
; configuration directory.
; Default no
;entityid=00:11:22:33:44:55 ; Entity ID.
; This is in the form of a MAC address.
; It should be universally unique.
; It must be unique between servers communicating
; with a protocol that uses this value.
; This is currently is used by DUNDi and
; Exchanging Device and Mailbox State
; using protocols: XMPP, Corosync and PJSIP.
;rtp_use_dynamic = yes ; When set to "yes" RTP dynamic payload types
; are assigned dynamically per RTP instance vs.
; allowing Asterisk to globally initialize them
; to pre-designated numbers (defaults to "yes").
;rtp_pt_dynamic = 35 ; Normally the Dynamic RTP Payload Type numbers
; are 96-127, which allow just 32 formats. The
; starting point 35 enables the range 35-63 and
; allows 29 additional formats. When you use
; more than 32 formats in the dynamic range and
; calls are not accepted by a remote
; implementation, please report this and go
; back to value 96.
;hide_messaging_ami_events = no; This option, if enabled, will
; suppress all of the Message/ast_msg_queue channel's
; housekeeping AMI and ARI channel events. This can
; reduce the load on the manager and ARI applications
; when the Digium Phone Module for Asterisk is in use.
;sounds_search_custom_dir = no; This option, if enabled, will
; cause Asterisk to search for sounds files in
; AST_DATA_DIR/sounds/custom before searching the
; normal directories like AST_DATA_DIR/sounds/<lang>.
;channel_storage_backend = ao2_legacy ; Select the channel storage backend
; to use for live operation.
; ao2_legacy: Original implementation (default)
; Depending on compile options, the following may also be
; available:
; cpp_map_name_id: Use C++ Maps to index both
; channel name and channel uniqueid.
; See http://s.asterisk.net/dc679ec3 for more information.
;disable_remote_console_shell = no; Prevent remote console CLI sessions
; from executing shell commands with the '!' prefix.
; Default: no
; Changing the following lines may compromise your security.
;[files]
;astctlpermissions = 0660
;astctlowner = root
;astctlgroup = apache
;astctl = asterisk.ctl
/usr/local/etc/asterisk/extensions.conf
[general]
static=yes
extenpatternmatchnew=yes
autofallthrough=yes
[from-provider]
exten => _X.,1,NoOp(Chiamata esterna in arrivo)
same => n,Answer()
same => n,Dial(PJSIP/101,20)
same => n,Hangup()
[from-internal]
; --- Chiamate interne ---
exten => _1XX,1,NoOp(Chiamata interna a ${EXTEN})
same => n,Dial(PJSIP/${EXTEN},20)
same => n,Hangup()
; --- Chiamate esterne che iniziano con 0 ---
exten => _0X.,1,NoOp(Chiamata uscente da ${CALLERID(all)} verso ${EXTEN})
same => n,Set(NUMBER=${EXTEN:1}) ;Rimuove il prefisso 0
same => n,Dial(PJSIP/${NUMBER}@providername_endpoint)
same => n,Hangup()
; --- Altre chiamate esterne ---
;exten => _X.,1,NoOp(Chiamata uscente da ${CALLERID(all)} verso ${EXTEN})
; same => n,Dial(PJSIP/${EXTEN}@providername_endpoint)
; same => n,Hangup()
/usr/local/etc/asterisk/rtp.conf
; RTP Configuration
;
[general]
;
; RTP start and RTP end configure start and end addresses
;
; Defaults are rtpstart=5000 and rtpend=31000
;
rtpstart=10000
rtpend=10255
;rtpend=20000
;
; Whether to enable or disable UDP checksums on RTP traffic
;
;rtpchecksums=no
;
; The amount of time a DTMF digit with no 'end' marker should be
; allowed to continue (in 'samples', 1/8000 of a second)
;
;dtmftimeout=3000
; rtcpinterval = 5000 ; Milliseconds between rtcp reports
;(min 500, max 60000, default 5000)
;
; Enable strict RTP protection. This will drop RTP packets that do not come
; from the recognized source of the RTP stream. Strict RTP qualifies RTP
; packet stream sources before accepting them upon initial connection and
; when the connection is renegotiated (e.g., transfers and direct media).
; Initial connection and renegotiation starts a learning mode to qualify
; stream source addresses. Once Asterisk has recognized a stream it will
; allow other streams to qualify and replace the current stream for 5
; seconds after starting learning mode. Once learning mode completes the
; current stream is locked in and cannot change until the next
; renegotiation.
; Valid options are "no" to disable strictrtp, "yes" to enable strictrtp,
; and "seqno", which does the same thing as strictrtp=yes, but only checks
; to make sure the sequence number is correct rather than checking the time
; interval as well.
; This option is enabled by default.
strictrtp=no
;
; Number of packets containing consecutive sequence values needed
; to change the RTP source socket address. This option only comes
; into play while using strictrtp=yes. Consider changing this value
; if rtp packets are dropped from one or both ends after a call is
; connected. This option is set to 4 by default.
; probation=8
;
; Enable sRTP replay protection. Buggy SIP user agents (UAs) reset the
; sequence number (RTP-SEQ) on a re-INVITE, for example, with Session Timers
; or on Call Hold/Resume, but keep the synchronization source (RTP-SSRC). If
; the new RTP-SEQ is higher than the previous one, the call continues if the
; roll-over counter (sRTP-ROC) is zero (the call lasted less than 22 minutes).
; In all other cases, the call faces one-way audio or even no audio at all.
; "replay check failed (index too old)" gets printed continuously. This is a
; software bug. You have to report this to the creator of that UA. Until it is
; fixed, you could disable sRTP replay protection (see RFC 3711 section 3.3.2).
; This option is enabled by default.
; srtpreplayprotection=yes
;
; Whether to enable or disable ICE support. This option is enabled by default.
icesupport=true
;
; Hostname or address for the STUN server used when determining the external
; IP address and port an RTP session can be reached at. The port number is
; optional. If omitted the default value of 3478 will be used. This option is
; disabled by default. Name resolution will occur at load time, and if DNS is
; used, name resolution will occur repeatedly after the TTL expires.
;
; e.g. stunaddr=mystun.server.com:3478
;
; stunaddr=
;
; Some multihomed servers have IP interfaces that cannot reach the STUN
; server specified by stunaddr. Blacklist those interface subnets from
; trying to send a STUN packet to find the external IP address.
; Attempting to send the STUN packet needlessly delays processing incoming
; and outgoing SIP INVITEs because we will wait for a response that can
; never come until we give up on the response.
; * Multiple subnets may be listed.
; * Blacklisting applies to IPv4 only. STUN isn't needed for IPv6.
; * Blacklisting applies when binding RTP to specific IP addresses and not
; the wildcard 0.0.0.0 address. e.g., A PJSIP endpoint binding RTP to a
; specific address using the bind_rtp_to_media_address and media_address
; options. Or the PJSIP endpoint specifies an explicit transport that binds
; to a specific IP address. Blacklisting is done via ACL infrastructure
; so it's possible to whitelist as well.
;
; stun_acl = named_acl
; stun_deny = 0.0.0.0/0
; stun_permit = 1.2.3.4/32
;
; For historic reasons stun_blacklist is an alias for stun_deny.
;
; Whether to report the PJSIP version in a SOFTWARE attribute for all
; outgoing STUN packets. This option is enabled by default.
;
; stun_software_attribute=yes
;
; Hostname or address for the TURN server to be used as a relay. The port
; number is optional. If omitted the default value of 3478 will be used.
; This option is disabled by default.
;
; e.g. turnaddr=myturn.server.com:34780
;
; turnaddr=
;
; Username used to authenticate with TURN relay server.
; turnusername=
;
; Password used to authenticate with TURN relay server.
; turnpassword=
;
; An ACL can be used to determine which discovered addresses to include for
; ICE, srflx and relay discovery. This is useful to optimize the ICE process
; where a system has multiple host address ranges and/or physical interfaces
; and certain of them are not expected to be used for RTP. For example, VPNs
; and local interconnections may not be suitable or necessary for ICE. Multiple
; subnets may be listed. If left unconfigured, all discovered host addresses
; are used.
;
ice_acl = lan
; ice_deny = 0.0.0.0/0
; ice_permit = 1.2.3.4/32
;
; For historic reasons ice_blacklist is an alias for ice_deny.
;
; The MTU to use for DTLS packet fragmentation. This option is set to 1200
; by default. The minimum MTU is 256.
; dtls_mtu = 1200
;
[ice_host_candidates]
;
; When Asterisk is behind a static one-to-one NAT and ICE is in use, ICE will
; expose the server's internal IP address as one of the host candidates.
; Although using STUN (see the 'stunaddr' configuration option) will provide a
; publicly accessible IP, the internal IP will still be sent to the remote
; peer. To help hide the topology of your internal network, you can override
; the host candidates that Asterisk will send to the remote peer.
;
; IMPORTANT: Only use this functionality when your Asterisk server is behind a
; one-to-one NAT and you know what you're doing. If you do define anything
; here, you almost certainly will NOT want to specify 'stunaddr' or 'turnaddr'
; above.
;
; The format for these overrides is:
;
; <local address> => <advertised address>,[include_local_address]
;
; The following will replace 192.168.1.10 with 1.2.3.4 during ICE
; negotiation:
;
;192.168.1.10 => 1.2.3.4
192.168.8.55 => externalip
;
; The following will include BOTH 192.168.1.10 and 1.2.3.4 during ICE
; negotiation instead of replacing 192.168.1.10. This can make it easier
; to serve both local and remote clients.
;
;192.168.1.10 => 1.2.3.4,include_local_address
;
; You can define an override for more than 1 interface if you have a multihomed
; server. Any local interface that is not matched will be passed through
; unaltered. Both IPv4 and IPv6 addresses are supported.
/usr/local/etc/asterisk/acl.conf
[lan]
deny=0.0.0.0/0.0.0.0
permit=192.168.8.0/255.255.255.0
Any hint or advice will be immensely appreciated. Let me know if you need me to add any further detail or configuration file.
Hope to hear from you soon!