Executing apt as an example. Add to /etc/sudoers
lexus ALL=(root) NOPASSWD:/usr/bin/apt
Executing apt as an example. Add to /etc/sudoers
lexus ALL=(root) NOPASSWD:/usr/bin/apt
This is about adding a display name to the calls from registered users. An analogue of Asterisk’s Set(CALLERID(name)=John Doe).
The idea was to move SIP accounts from Asterisk to OpenSIPS.
In case of using Asterisk we would configure something like:
[user222]
context=o.local
secret=4EwIWikV
callerid=Alexey Kazantsev <222>
How to achieve the same with OpenSIPS? This is the solution:

modparam("auth_db", "load_credentials", "$avp(display)=rpid")
modparam("registrar", "attr_avp", "$avp(display)")
# call from registered user -> add callerid# and forward to mediaserver for call recording, etc.if(is_registered("location")){# replace only display and do not touch uriuac_replace_from("$avp(display)","");rewritehostport("10.145.213.63:5067");route(relay);}
How it looks like?
This is the INVITE coming to OpenSIPS:
2019/11/21 14:16:55.247856 10.145.213.64:5061 -> 10.145.213.63:5060
INVITE sip:111@taxsee.com SIP/2.0
Via: SIP/2.0/UDP 10.145.213.64:5061;branch=z9hG4bK-3822b894
From: <sip:222@taxsee.com>;tag=48b014547f398294o1
And this is the same INVITE leaving OpenSIPS, being modified:
2019/11/21 14:16:55.252518 10.145.213.63:5060 -> 10.145.213.63:5067
INVITE sip:111@10.145.213.63:5067 SIP/2.0
Record-Route: <sip:10.145.213.63;lr;ftag=48b014547f398294o1>
Via: SIP/2.0/UDP 10.145.213.63:5060;branch=z9hG4bK77e6.9bb3aa72.0
Via: SIP/2.0/UDP 10.145.213.64:5061;branch=z9hG4bK-3822b894
From: "Alexey Kazantsev" <sip:222@taxsee.com>;tag=48b014547f398294o1
The information stored in the ‘rpid’ column (in our example, or some custom in your architecture) is fetched to AVP at each REGISTER/save, so you do not need to reload anything to take changes in effect.
The callerid info is seen in console output via ‘opensipsctl fifo ul_dump’ command:
AOR:: 222@taxsee.com
Contact:: sip:222@10.145.213.64:5061 Q=
ContactID:: 3039507536010050217
Expires:: 42
Callid:: 9fdd26c2-6de37105@10.145.213.64
Cseq:: 35746
User-agent:: Cisco/SPA303-7.6.2c
State:: CS_NEW
Flags:: 0
Cflags::
Socket:: udp:10.145.213.63:5060
Methods:: 5247
Attr:: Alexey Kazantsev
Some notes how to configure Linphone and Cisco SPA-303 to send INVITE with domain in RURI, assuming that your proxy has a different IP address than the resolved address of the domain.



That’s all. Have fun!
Let’s imagine that we’ve upgraded our VoIP network which was formerly based on geographically distributed Asterisks.
We configured OpenSIPS servers as registrars, connected them together in a full-sharing usrloc cluster and now we need to route calls between endpoints not directly, but through Asterisks – to handle our calls in a familiar way (CDR records, call recording via MixMonitor, some AGI scripts, etc).
We have to create something like that:

This is a code snippet of OpenSIPS with IP address 10.145.213.63:
# initial INVITE
if(is_method("INVITE") && !has_totag())
{
t_on_failure("1");
# call from registered user ->
# forward to mediaserver for call recording, etc.
if(is_registered("location"))
{
$ru="sip:" + $oU + "@" + "10.145.213.63:5067";
route(relay);
}
# call from Asterisk? -> change domain part before doing lookup
if($sp=="5067")
{
$rd="taxsee.com";
}
$var(lookup_flags) = "m";
if(cluster_check_addr("1", "$si")) {
xlog("si: $si . $rm from cluster, doing local lookup only\n");
} else {
xlog("si: $si . $rm from outside, doing global lookup\n");
$var(lookup_flags) = $var(lookup_flags) + "g";
}
if(!lookup("location", "$var(lookup_flags)"))
{
t_reply("404", "Not Found");
exit;
}
if(has_body("application/sdp"))
{
rtpengine_offer("RTP/AVP replace-origin replace-session-connection ICE=remove");
}
} # initial INVITE end
route(relay);
A SIP peer to this OpenSIPS in Asterisk sip.conf looks like this:
[opensips]
type=peer
context=office
host=10.145.213.63
port=5060
And a dialplan for CDR/MixMonitor/etc:
context office
{
_XXX =>
{
NoOp(imagine this is CDR, MixMonitor, AGI);
Dial(SIP/opensips/${EXTEN});
Hangup();
};
};
UPD: assuming your SIP acoounts DB has moved from Asterisk to OpenSIPS cluster, its desirable not just processing REGISTER requests and doing authentication, but also adding caller ids to your SIP accounts.
UPD: 2019-november-5. An official tutorial is available now! And some discussion on the mail list.
Draft/some notes…
2 OpenSIPS nodes without MongoDB

Key settings:
loadmodule “usrloc.so”
modparam(“usrloc”, “db_url”, “mysql://opensips:pass@10.145.213.63/opensips”)
modparam(“usrloc”, “nat_bflag”, “NAT”)
modparam(“usrloc”, “working_mode_preset”, “full-sharing-cluster”)
modparam(“usrloc”, “location_cluster”, 1)
modparam(“usrloc”, “use_domain”, 1)
loadmodule “clusterer.so” # requires proto_bin.so
modparam(“clusterer”, “current_id”, 1)
modparam(“clusterer”, “db_mode”, 1)
modparam(“clusterer”, “db_url”, “mysql://opensips:pass@10.145.213.63/opensips”)
# initial INVITE
if(is_method("INVITE")) {
t_on_failure("1");
$var(lookup_flags) = "m";
if (cluster_check_addr("1", "$si")) {
xlog("si: $si . $rm from cluster, doing local lookup only\n");
} else {
xlog("si: $si . $rm from outside, doing global lookup\n");
$var(lookup_flags) = $var(lookup_flags) + "g";
}
if (!lookup("location", "$var(lookup_flags)")) {
t_reply("404", "Not Found");
exit;
}
if (has_body("application/sdp")) {
rtpengine_offer("RTP/AVP replace-origin replace-session-connection ICE=remove");
}
} # initial invite END
UPD: some useful notes from Liviu Chircu: http://lists.opensips.org/pipermail/users/2019-October/041819.html
Pay attention: according to his advice, we don’t need any data in ‘sip_addr’ columns when creating a full-sharing usrloc cluster. In case of federated cluster we have to fill them with IP addresses on which OpenSIPS nodes are listening.
Formerly we’ve learned how to restrict access with permission.so module based on source IP addresses. Today I’ll show how to restrict access to your OpenSIPS based on usernames, being registering.
loadmodule "permissions.so" # no deps
...
if (is_method("REGISTER")) {
if(!allow_register("register")) {
sl_send_reply(403, "Forbidden by permissions");
exit;
}
“Deny all, but …” policy – we will allow registrations of explicitly defined usernames and drop anybody else.
register.deny file:
ALL : ALL
register.allow file:
# this allows lexus, lexus2, lexus3 to register
"^sip:lexus[23]?@alexeyka.zantsev.com" : ALL
# regexp seems to be CORRECT, but for some reason lexus2 and lexus3 can not register
# "^sip:lexus[\d]?@alexeyka.zantsev.com" : ALL
Have a look how it’s working! A good guy is being registered successfully:

While a bad guy had been kicked:

Another solution using regex.so module from Pavel Eremin. The pros of this method is that it allows editing a txt file with usernames defined and reload regex.so module via MI interface (no restart needed).
And even one more from Răzvan Crainea.

This note will instruct you how to protect each DID number connected to your OpenSIPS from SIP DDoS, limiting not the total amount of INVITE requests going to your OpenSIPS server, but only INVITEs to some certain RURI.
Check it out, I hope you like it!
This is useful when you have a plenty of SIP numbers (DIDs) connected to your server and each one accepts inbound calls, e.g. a call centre or a taxi ordering service, etc. And you have to check each destination and drop too much requests, without degradation of any other incoming calls.
This is a nice solution to prevent the situation seen on the graph in the previous post.
PS: clustering support is not described here.
loadmodule "ratelimit.so" # no deps
modparam("ratelimit", "window_size", 2) # ban timeout, sec
Add start limit value to the startup_route:
startup_route {
cache_store("local", "inc:rl", "8");
}
Somewhere in the initial INVITE section:
# AntiDDoS for each inbound call
if($si !~ "^10\..*") {
cache_fetch("local", "inc:rl", $var(rl));
# $var(rl) invites/sec going to each $rU.
# SBT is the most precise policy.
if (!rl_check("pipe_$rU", "$(var(rl){s.int})", "SBT")) {
sl_send_reply("503", "Service Unavailable. AntiDDoS");
xlog("L_INFO", "call $ci from $fU@$si:$sp to $oU@$Ri drp by rl");
exit;
};
};
Live statistics:
voip-sipgw01 opensips # opensipsctl fifo rl_list
PIPE:: id=pipe_9618688830 algorithm=SBT limit=8 counter=0
PIPE:: id=pipe_9020578345 algorithm=SBT limit=8 counter=0
PIPE:: id=pipe_9611157347 algorithm=SBT limit=8 counter=0
PIPE:: id=pipe_79190224444 algorithm=SBT limit=8 counter=0
...
PIPE:: drop_rate=581
Change the limit on the fly up to 10 INVITES to each $rU:
opensipsctl fifo cache_store local inc:rl 10
Situation: VoIP ISP server suddenly became unavailable and you have some thousands of dialogs like this:
dialog:: ID=17580696317398
state:: 3
user_flags:: 0
timestart:: 1556697836
datestart:: 2019-05-01 13:03:56
timeout:: 1556701436
dateout:: 2019-05-01 14:03:56
callid:: 7EB7F3F9-6B1E11E9-90F3C2ED-81742C80@XX.YY.168.28
from_uri:: sip:ZZZXXX7146@XX.YY.168.28
to_uri:: sip:NNNN902290@XX.YY.169.130
caller_tag:: 8999291C-450
caller_contact:: sip:ZZZXXX7146@XX.YY.168.28:5060
callee_cseq:: 0
caller_route_set:: <sip:XX.YY.169.130;lr=on;ftag=8999291C-450;did=dff3.a92b;nat=yes>
caller_bind_addr:: udp:EE.FF.116.74:5060
caller_sdp::
CALLEES::
callee::
callee_tag:: as3d7dee61
callee_contact:: sip:abc@EE.FF.116.62:5060;transport=udp
caller_cseq:: 101
callee_route_set::
callee_bind_addr:: udp:EE.FF.116.74:5060
callee_sdp::
To kill them in some seconds (not to wait when OpenSIPS will terminate them according to SIP timers), do:
for i in `opensipsctl fifo dlg_list | grep callid | grep \@XX.YY.168.28 | awk '{print $2}'` ; do opensipsctl fifo dlg_end_dlg $i ; done

In fact, the situation was as follows: VoIP software on the ISP side (we have a DID from it connected to our OpenSIPS cluster) had some problems and they suddenly started sending us a bunch of unique INVITES (with different Call-IDs) for any certain inbound call.
Very soon the total number of dialogs dramatically increased up to enormous values. And this is a theme of my next article!
bastion@host:~$ cat pids.txt
1111
2222
3333
4444
bastion@host:~$ echo $(cat pids.txt)
1111 2222 3333 4444
for i in ` ; do kill -9 $i ; doneecho $(cat killpids.txt)`
UPD: a note with alternative commands from Liviu Chircu, OpenSIPS core developer:
1. instead of `echo $(cat pids.txt)`, a better alternative would be: `cat pids.txt | xargs` 2. instead of "for i in `echo $(cat pids.txt)`; do kill -9 $i; done", a better option would be: `cat pids.txt | xargs kill -9`
dpz2-pbx ~ # cat /usr/lib/tmpfiles.d/tmp.conf
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# See tmpfiles.d(5) for details
# Clear tmp directories separately, to make them easier to override
v /tmp 1777 root root 10d
v /var/tmp 1777 root root 30d
# Exclude namespace mountpoints created with PrivateTmp=yes
x /tmp/systemd-private-%b-*
X /tmp/systemd-private-%b-*/tmp
x /var/tmp/systemd-private-%b-*
X /var/tmp/systemd-private-%b-*/tmp
# Disable auto-remove of /tmp/opensips_fifo x /tmp/opensips_fifo