Custom, config file based, pjsip trunks for land line

Hi all,

I am creating a small (but overkill, let’s be honest) phone system for our home as our ISP has just switched us over to a sip-based landline rather than POTS.

Unfortunately, they require some very specific settings and custom configurations which means it must be defined in a file rather than through the trunks tab on freePBX.
I have put all the information under pjsip_custom.conf and can see that it has successfully registered under asterisk info.

I am however struggling to mark this as a trunk and apply in and outbound routes to it.
is this done with a custom trunk or is there a more appropriate file to use? I can’t find a simple answer.

thanks for your help.

Best practices is to create and configure the trunk in the GUI, then add one or more entries to pjsip_custom_post.conf to override a value or add a new one.

Please post the settings requested by the ISP. Mask personal data such as phone numbers, usernames and passwords, but make it clear what each masked item represents. For example, use uuuu for the username, +44nnnn or 0nnnn for the phone number, pppp for the password.

hear is the pjsip_custom as it stands:

user_agent = "Vox 3.0"

type = acl
deny =
permit =
permit =
permit =

type = transport
protocol = udp
tos = af31
bind =
local_net =
local_net =
;external_media_address = ${insert public IP}
;external_signaling_address = ${insert public IP}

type = registration
transport = transport-udp
contact_user = voi00XXXXXXXX
client_uri = sip:[email protected]
server_uri =
outbound_proxy =\;lr\;hide
outbound_auth = auth_vf
max_retries = 4294967295

type = auth
auth_type = userpass
username = voi00XXXXXXXX
password = PASSWORD

type = aor
outbound_proxy =\;lr\;hide
contact = sip:[email protected]

type = identify
match =
endpoint = voi00XXXXXXXX

type = endpoint
transport = transport-udp
context = vf-in
tos_audio = ef
disallow = all
allow = alaw,g729
from_user = voi00XXXXXXXX
from_domain =
outbound_proxy =\;lr\;hide
outbound_auth = auth_vf
aors = voi00XXXXXXXX

I think I can get away with putting most of this in the GUI, the only important things are in [transport-udp] from what I can tell. I am currently looking at defining only that but some guidance would be much appreciated.
They also require some custom rtp values but they are sorted.

Other than setting user_agent (if Vodafone actually requires it), I don’t believe that you need any custom config at all.

I would not bother with an ACL. If you don’t have any external extensions, your router/firewall will block everything from outside. If you do have external extensions, this will be an admin hassle. Better to use the router/firewall and/or FreePBX Firewall instead.

Set Port to Listen On to 5065.

Set this in Asterisk SIP Settings, Local Networks. You don’t need to include the loopback address

This is all standard trunk settings. You can leave Client URI blank (that’s the default) and can probably leave Server URI blank (most providers ignore the username here anyhow).

Just set Outbound Proxy; the rest is automatic.
Why do you need a custom context?
I would not bother with g729 unless vodafone requires it on some calls.

Just set up the trunk in the GUI and if it won’t register or calls fail, we can help.

thanks for your help so far

I should have gone into more detail about what they require but Vodaphone only accept packets with specific TOS values (af31), a source port of 6056, etc
The configuration I have used comes from here. So far, this is the only way people have managed to get this working as this is not officially supported by Vodafone, they expect you to only use their ISP-provided routers to make this connexion.
I don’t know why all the values are specified,I just know that that’s what’s needed for it to work.

I created a trunk in the GUI as you suggested and filled out all the necessary information. I’ve tried my best to compare the config output with the one that is needed and modify the settings to make it work.

At current the only major difference I can see is this:

  1. GUI created config:

config in GitHub:

type = identify
match =
endpoint = voi00XXXXXXXXX

NOTE: voi00XXXXXXXX == landline_trunk, just a different naming scheme between different configs

  1. GUI created config:

config in GitHub:

type = endpoint
transport = transport-udp
context = vf-in
tos_audio = ef         
disallow = all
allow = alaw,g729
from_user = voi00AAAAAAAA
from_domain = 
outbound_proxy =\;lr\;hide
outbound_auth = auth_vf
aors = voi00AAAAAAAAAA    
  1. this is missing from the GUI config:
type = registration

I followed this thread to specify [transport-udp] in pjsip.transports_custom_post.conf as I could see from a packet capture it was not sending the right details.

After that, running a packet capture shows freePBX is using the correct TOS and port numbers however it is being met with 403 forbidden

Finally, how do I tell if it has registered correctly, reports > asterisk info shows it as green but cannot find where it says whether or not it has successfully registered.

My background is Asterisk, not FreePBX, and the online FreePBX User Guide is out of date, so this is incomplete, but …

You need to set registration to outbound.

You have to set match / permit to this.

You need to provide the full URI, complete with options.

This is very weird. I’d want to see what an incoming call looks like. It basically invalidates the type=identify section

If they send calls from other than the address to which you register, you can add those addresses to the Match (Permit) field and they will appear in the identify section.

You have to add the
to the end of your Outbound Proxy entry.

Possibly an issue with the Outbound Proxy setting. Otherwise, please post a (redacted) copy of the outbound REGISTER (if that’s what’s failing) or INVITE (if outbound calls fail).

Changing the pjsip settings: authentication to outbound (Was already set) and registration to “send” (was none) as you suggested I now have pjsip.registration.conf in the config files.
However, it is set to use the default transport= rather than the custom [transport-udp] rule which means Vodafone ignores all registration attempts.

how would I go about setting transport= to transport=transport-udp (Doing as the link I mentioned did not help)

All other changes you’ve suggested have been made so in theory once transport is sorted out it should work but you know how it is :smile:

Try this in pjsip_custom_post.conf:

I believe you need to restart Asterisk after this change.

Or, instead of using a custom transport, could you change the regular to use the custom tos value, and use 5065 as Port to Listen On? (You would have to change your extensions to register to port 5065.)

This worked perfectly and now all outgoing traffic has the correct content
It appears to register fine (however I cannot tell from the GUI) but the packets sent show the following:
in the log:

72621	[2023-08-07 19:36:04] VERBOSE[2605] res_pjsip/pjsip_configuration.c: Endpoint landline_trunk is now Reachable	
72622	[2023-08-07 19:36:04] VERBOSE[2605] res_pjsip/pjsip_options.c: Contact landline_trunk/sip:[email protected]:5065 is now Reachable. RTT: 18.835 msec	
72623	[2023-08-07 19:38:25] VERBOSE[2605] netsock2.c: Using SIP RTP Audio TOS bits 184	
72624	[2023-08-07 19:38:25] VERBOSE[2605] netsock2.c: Using SIP RTP Audio TOS bits 184 in TCLASS field.	
72625	[2023-08-07 19:38:25] VERBOSE[2605] netsock2.c: Using SIP RTP Audio CoS mark 5

attempting to dial in from a mobile, you at least get a ring rather than an instant disconnect but nothing shows in the log files nor do any of the phones ring
attempting to dial out, you hear “your call cannot be completed as dialled”
inbound and outbound routes have been configured

If nothing shows in sngrep, either, check the Contact header sent with REGISTER, or any firewall between the internet and PBX.

If the incoming INVITE does show in sngrep, check that it’s going to the correct port and not being blocked by FreePBX firewall (or your own iptables/nftables rules).

What you dialed didn’t match an Outbound Route. If you are sure it did, possibly your device’s dial plan rewrote the number.

Nothing with method “invite” shows up that has anything relating to the Vodafone number. There is a lot of other junk that’s showing up but am I correct in assuming this is nothing relevant and just random things on the Internet?
there are, however, a bunch of reoccurring entries with the method “option” shown below:

Free PBX is set to listen on port 5060. I think requests from Vodafone may come from 5065 but through port forwarding, 5065 and 5060 are both mapped straight to the PBX at Port 5060

I have a feeling the line still has not quite registered properly

In regards to outbound rules, I used the wizard to select 11 digit numbers and is a basic catch all rule yet it still does not appear to be working

By logs, I mean reports > asterisk log files

This is a very advanced topic that I suggest you avoid. Unless you are doing some fancy filtering in your firewall, what port they send from is irrelevant. But forwarding destination port 5065 to 5060, if they are sending to port 5065, is a problem. The reason is that SIP has port numbers in the message contents and Asterisk will insert the port it thinks it’s listening on (made more complex by your having two transports), which may not be what the remote end expects.

IMO, you should use the built-in transport only, with Port to Listen on set to 5065, and only port external port 5065 forwarded to the PBX LAN port 5065. Unfortunately, you’ll have to change all your extensions to register to port 5065. If this is a home system, I assume you don’t have too many.

Do you know in fact that Vodafone requires port 5065 on your end?

That’s understandable, changed everything so that freepbx is listening on 5065 and all the phones have been updated

Unfortunately, the pbx server does not appear to be applying the correct transport and is still sending incorrect values to Vodafone.

Would it not be possible to define everything as was originally done in pjsip_custom.conf and map that to a trunk by adding a custom trunk?
I know you said this is not recommended but it appears to be much more reliable and easier to configure.

This sounds strange. At the Asterisk command prompt, type
pjsip show endpoint landline-trunk
and also
pjsip show registration landline-trunk
and post the output.

Sure that is possible; the format for the custom dial string is

However, IMO you are asking for more trouble. Starting from a trunk set up in the GUI, AFAIK all you need to customize is TOS and User-Agent, which can be easily done in 4 lines of pjsip_custom_post.conf .

Endpoint:  <Endpoint/CID.....................................>  <State.....>  <Channels.>
I/OAuth:  <AuthId/UserName...........................................................>
Aor:  <Aor............................................>  <MaxContact>
Contact:  <Aor/ContactUri..........................> <Hash....> <Status> <RTT(ms)..>
Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress..................>
Identify:  <Identify/Endpoint.........................................................>
Match:  <criteria.........................>
Channel:  <ChannelId......................................>  <State.....>  <Time.....>
Exten: <DialedExten...........>  CLCID: <ConnectedLineCID.......>

Endpoint:  landline_trunk                                       Not in use    0 of inf
OutAuth:  landline_trunk/voi00XXXX
Aor:  landline_trunk                                     0
Contact:  landline_trunk/sip:[email protected] f677e0f4d9 Avail        13.305
Transport:  transport-udp             udp      0    104
Identify:  landline_trunk/landline_trunk

ParameterName                      : ParameterValue
100rel                             : yes
accept_multiple_sdp_answers        : false
accountcode                        :
acl                                :
aggregate_mwi                      : true
allow                              : (alaw|g729)
allow_overlap                      : true
allow_subscribe                    : true
allow_transfer                     : true
allow_unauthenticated_options      : false
aors                               : landline_trunk
asymmetric_rtp_codec               : false
auth                               :
bind_rtp_to_media_address          : false
bundle                             : false
call_group                         :
callerid                           : <unknown>
callerid_privacy                   : allowed_not_screened
callerid_tag                       :
codec_prefs_incoming_answer        : prefer:pending, operation:intersect, keep:all, transcode:allow
codec_prefs_incoming_offer         : prefer:pending, operation:intersect, keep:all, transcode:allow
codec_prefs_outgoing_answer        : prefer:pending, operation:intersect, keep:all, transcode:allow
codec_prefs_outgoing_offer         : prefer:pending, operation:union, keep:all, transcode:allow
connected_line_method              : invite
contact_acl                        :
context                            : from-pstn
cos_audio                          : 0
cos_video                          : 0
device_state_busy_at               : 0
direct_media                       : false
direct_media_glare_mitigation      : none
direct_media_method                : invite
disable_direct_media_on_nat        : false
dtls_auto_generate_cert            : No
dtls_ca_file                       :
dtls_ca_path                       :
dtls_cert_file                     :
dtls_cipher                        :
dtls_fingerprint                   : SHA-256
dtls_private_key                   :
dtls_rekey                         : 0
dtls_setup                         : active
dtls_verify                        : No
dtmf_mode                          : auto
fax_detect                         : false
fax_detect_timeout                 : 0
follow_early_media_fork            : true
force_avp                          : false
force_rport                        : true
from_domain                        :
from_user                          : voi00XXXXXX
g726_non_standard                  : false
geoloc_incoming_call_profile       :
geoloc_outgoing_call_profile       :
ice_support                        : false
identify_by                        : username,ip
ignore_183_without_sdp             : false
inband_progress                    : false
incoming_call_offer_pref           : local
incoming_mwi_mailbox               :
language                           : en_GB
mailboxes                          :
max_audio_streams                  : 1
max_video_streams                  : 1
media_address                      :
media_encryption                   : no
media_encryption_optimistic        : false
media_use_received_transport       : false
message_context                    :
moh_passthrough                    : false
moh_suggest                        : default
mwi_from_user                      :
mwi_subscribe_replaces_unsolicited : no
named_call_group                   :
named_pickup_group                 :
notify_early_inuse_ringing         : false
one_touch_recording                : false
outbound_auth                      : landline_trunk
outbound_proxy                     :;lr;hide
outgoing_call_offer_pref           : remote_merge
overlap_context                    :
pickup_group                       :
preferred_codec_only               : false
record_off_feature                 : automixmon
record_on_feature                  : automixmon
refer_blind_progress               : true
rewrite_contact                    : false
rpid_immediate                     : false
rtcp_mux                           : false
rtp_engine                         : asterisk
rtp_ipv6                           : false
rtp_keepalive                      : 0
rtp_symmetric                      : true
rtp_timeout                        : 0
rtp_timeout_hold                   : 0
sdp_owner                          : -
sdp_session                        : Asterisk
security_mechanisms                :
security_negotiation               : no
send_aoc                           : false
send_connected_line                : yes
send_diversion                     : true
send_history_info                  : false
send_pai                           : false
send_rpid                          : false
set_var                            :
srtp_tag_32                        : false
stir_shaken                        : off
stir_shaken_profile                :
sub_min_expiry                     : 0
subscribe_context                  :
suppress_q850_reason_headers       : false
t38_bind_udptl_to_media_address    : false
t38_udptl                          : false
t38_udptl_ec                       : none
t38_udptl_ipv6                     : false
t38_udptl_maxdatagram              : 0
t38_udptl_nat                      : false
timers                             : yes
timers_min_se                      : 90
timers_sess_expires                : 1800
tone_zone                          :
tos_audio                          : 0
tos_video                          : 0
transport                          : transport-udp
trust_connected_line               : yes
trust_id_inbound                   : false
trust_id_outbound                  : false
use_avpf                           : false
use_ptime                          : false
user_eq_phone                      : false
voicemail_extension                :
webrtc                             : no
<Registration/ServerURI..............................>  <Auth....................>  <Status.......>

landline_trunk/          landline_trunk              Registered        (exp. 1105s)

ParameterName            : ParameterValue
auth_rejection_permanent : true
client_uri               : sip:[email protected]:5065
contact_header_params    :
contact_user             :
endpoint                 : landline_trunk
expiration               : 3600
fatal_retry_interval     : 30
forbidden_retry_interval : 30
line                     : true
max_random_initial_delay : 10
max_retries              : 1000000
outbound_auth            : landline_trunk
outbound_proxy           :;lr;hide
retry_interval           : 60
security_mechanisms      :
security_negotiation     : no
server_uri               :
support_outbound         : no
support_path             : false
transport                : transport-udp

there is a regular request which shows up in the packet captures after the initial registration (which appears to be a success) not sure whether this is important or what it means but it appears to be being blocked
There is also a bunch of garbage data that also doesn’t mean much

Can’t make any more posts today as this is a new account

Asterisk used the OPTIONS method to test whether the trunk is still woking and reachable (qualify). For this purpose, a 403 response is not an error (any response means it’s reachable). The INVITES you are seeing are malicious traffic probing for a system vulnerability. You will see many fewer if you stop forwarding port 5060, which (based on what you’ve said so far) is not needed. The REGISTER requests are likely also malicious, though I haven’t seen that pattern before.