VirtualBox: mastering console usage, starting/stopping/restarting VMs, getting VM’s IP addresses

April 9th, 2023

A new post after nearly a year of lull!

Imagine the situation when there is some remote host machine with several VMs. You have an SSH access to host machine, but no VNC to manage easily those VMs, even doing the most elementary actions.

Listing all your VMs:

alexey@amd:~$ vboxmanage list vms
"centos7-orig" {e4077fae-1be5-42f4-ae40-b399f98c6e3d}
"debian9.rtpengine" {d2fb6655-29ab-4103-a70c-b7234c835a79}
"debian9.opensips1" {757f6235-27d4-470d-a461-c12fbfe0cfd7}
"debian9.opensips2" {09b11945-d696-409d-b90b-e5f2b5af6c4a}
"centos7-ast-16" {21eaceac-f85e-4622-a52b-c586352aa9eb}
"centos7-rtpengine8" {935a0191-a17e-4c95-8cf4-022f7ad1a398}
"centos7.osips3.2" {e39ddc59-70cc-4bcb-8f6d-3b6bd9e78d3d}
"centos7.osips3.2_node2" {ecb64a86-aa90-4f53-bd12-5bb253d02058}

Listing all your running VMs:

alexey@amd:~$ vboxmanage list runningvms

Starting VM (vm remains working even if you log out from host machine):

alexey@amd:~$ vboxmanage startvm centos7-ast-16
Waiting for VM "centos7-ast-16" to power on...
VM "centos7-ast-16" has been successfully started.

Stopping VM:

alexey@amd:~$ vboxmanage controlvm centos7-ast-16 poweroff
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

The more the better.

Now I would like to get the IP address of some VM. But there is no any way to do it until we use GuestAdditions. I mean that you’ve already started your VM with the appropriate console command and now need to log in via SSH, but you don’t know it’s IP address (e.g. in case of bridged network settings of the VM).

To be able to see VM’s IP address from host’s machine console, you have to install VitualBox to your guest machine. Then you need to “insert” an .iso containing GuestAdditions to your guest machine (the easiest way is to do it using VirtualBox GUI, but I’m sure there is also a console command).

If the VM’s cd-rom with this .iso is not mounted automatically, do it manually:

[root@flexisip ~]# mount /dev/cdrom /mnt/cdrom/

After that the .iso’s files are available:

[root@flexisip cdrom]# ls -l /mnt/cdrom/
total 47008
-r--r--r--. 1 root root      763 feb 20  2020 AUTORUN.INF
-r-xr-xr-x. 1 root root     6384 jan 14  2022 autorun.sh
dr-xr-xr-x. 2 root root      792 jan 14  2022 cert
dr-xr-xr-x. 2 root root     1824 jan 14  2022 NT3x
dr-xr-xr-x. 2 root root     2652 jan 14  2022 OS2
-r-xr-xr-x. 1 root root     4821 jan 14  2022 runasroot.sh
-r--r--r--. 1 root root      592 jan 14  2022 TRANS.TBL
-r--r--r--. 1 root root  4029558 jan 14  2022 VBoxDarwinAdditions.pkg
-r-xr-xr-x. 1 root root     3949 jan 14  2022 VBoxDarwinAdditionsUninstall.tool
-r-xr-xr-x. 1 root root  7474611 jan 14  2022 VBoxLinuxAdditions.run
-r--r--r--. 1 root root  9439232 jan 14  2022 VBoxSolarisAdditions.pkg
-r-xr-xr-x. 1 root root 16895432 jan 14  2022 VBoxWindowsAdditions-amd64.exe
-r-xr-xr-x. 1 root root   270840 jan 14  2022 VBoxWindowsAdditions.exe
-r-xr-xr-x. 1 root root 10000520 jan 14  2022 VBoxWindowsAdditions-x86.exe
-r--r--r--. 1 root root      259 oct  4  2021 windows11-bypass.reg

Now we need to install GuestAdditions to the guest machine (VM):

[root@flexisip ~]# cd /mnt/cdrom
[root@flexisip cdrom]# sh ./VBoxLinuxAdditions.run 
Verifying archive integrity... All good.
Uncompressing VirtualBox 6.1.32 Guest Additions for Linux........
VirtualBox Guest Additions installer
Copying additional installer modules ...
Installing additional modules ...
VirtualBox Guest Additions: Starting.
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel 
modules.  This may take a while.
VirtualBox Guest Additions: To build modules for other installed kernels, run
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup <version>
VirtualBox Guest Additions: or
VirtualBox Guest Additions:   /sbin/rcvboxadd quicksetup all
VirtualBox Guest Additions: Building the modules for kernel 
3.10.0-1160.88.1.el7.x86_64.

And now you can see VM’s IP address from your host machine console (NAT network settings):

alexey@amd:~$ VBoxManage guestproperty get centos-flexisip "/VirtualBox/GuestInfo/Net/0/V4/IP"
Value: 10.0.2.15

The same for bridged networking:

alexey@amd:~$ VBoxManage guestproperty get centos-flexisip "/VirtualBox/GuestInfo/Net/0/V4/IP"
Value: 192.168.88.239

More VM properties:

alexey@amd:~$ VBoxManage guestproperty enumerate centos-flexisip

But this command still does not show the IP address of the VM, though it shows its MAC:

alexey@amd:~$ vboxmanage showvminfo centos-flexisip

After this you may unattach an .iso from your VM cd-rom.

How long the process is running?

April 18th, 2022
voip-sipgw02 ~ # ps --pid `pidof rsyslogd` -o etime,pid,user,args
    ELAPSED    PID USER     COMMAND
261-20:58:45  1228 root     /usr/sbin/rsyslogd -n

The etime option means elapsed time since the process was started, in the form [[DD-]hh:]mm:ss.

RTPEngine 10: rpm compilation in Centos 7

March 31st, 2022

This is a note without detailed examples.

Main idea: 1) update kernel, 2) add RPM Fusion repository and install ffmpeg from it.

If trying to compile RTPEngine 10 in CentOS 7 with ffmpeg installed from some other repository (e.g. nux-desktop, as I had) – you’ll get an error! (see screenshot)


Update kernel (my system had 3.10.0-957.el7.x86_64 after installation):

[root@localhost ~]# uname -a
Linux localhost.localdomain 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

[root@localhost ~]# cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)

Updated to the newest available from standard repository (3.10.0-1160.59.1.el7.x86_64):

yum --showduplicates list available kernel.x86_64

yum install kernel-3.10.0-1160.59.1.el7

reboot

[root@localhost ~]]# uname -a
Linux localhost.localdomain 3.10.0-1160.59.1.el7.x86_64 #1 SMP Wed Feb 23 16:47:03 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Add RPM Fusion repository as described here: https://rpmfusion.org/Configuration

I’ll duplicate instructions:

yum install dnf

dnf install --nogpgcheck https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E %rhel).noarch.rpm

dnf install --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-$(rpm -E %rhel).noarch.rpm

https://mirrors.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-$(rpm -E %rhel).noarch.rpm

Then disable nux-desktop (if you previously installed ffmpeg from it) repository (‘enabled=0’ in /etc/yum.repos.d/nux-dextop.repo).

Ensure that ffmpeg and ffmpeg-devel now are available from just added RPM Fusion repository and install them (you’ll see repo name in the yum output, not shown here):

yum --showduplicates list available ffmpeg
yum check-update 
yum install ffmpeg ffmpeg-devel

Then create build directory structure (use rpmbuild tool).

Download version 10 ZIP archive from RTPEngine git, somewhere from here https://github.com/sipwise/rtpengine/tree/mr10.4 . Unzip it.

Put rtpengine/el/rtpengine.spec to rpmbuild/SPECS/

Then archive again into tar.gz format with such name (according to settings in .spec file!):

tar czvf ngcp-rtpengine-10.4.0.0+0~mr10.4.0.0.tar.gz rtpengine-mr10.Y.Z/

Put ngcp-rtpengine-10.4.0.0+0~mr10.4.0.0.tar.gz to rpmbuild/SOURCES/

Fire!

rpmbuild -ta rpmbuild/SOURCES/ngcp-rtpengine-10.4.0.0+0~mr10.4.0.0.tar.gz

Ready rpms will be under rpmbuild/RPMS/ .

Install them in this sequence: ngcp-rtpengine-dkms, ngcp-rtpengine, ngcp-rtpengine-debuginfo, ngcp-rtpengine-kernel, ngcp-rtpengine-recording .

OpenSIPS: monitoring with Zabbix: HTTP Agent, JSONPath

March 24th, 2022

This guide will help you to understand how OpenSIPS can be monitored with Zabbix, sharing its statistic data via HTTP interface in JSON format. This article assumes using OpenSIPS 3.2 and Zabbix 6.

Enable embedded HTTP server and HTTP support for Management Interface in your OpenSIPS:

loadmodule "httpd.so"
modparam("httpd", "ip", "192.168.88.244")
modparam("httpd", "port", 8888)

# :8888/mi
loadmodule "mi_http.so"
modparam("mi_http", "root", "mi")

Now we may try to send a JSON-RPC OpenSIPS MI command from the command-line, using curl (official example at the very bottom of the page):

/usr/bin/curl -X POST 192.168.88.244:8888/mi -H 'Content-Type: application/json' -d '{"jsonrpc": "2.0", "id": "1", "method": "uptime"}'

The official documentation does not have other more complicated examples, e.g. “get_statistics sl:”, that’s why I decided to write this article, maybe it’s more about JSON, JSONPath and working with all this in Zabbix.

As an example, we’ll get stateless replier module statistics, like shown by invoking a CLI command “opensips-cli -x mi get_statistics sl:” .

/usr/bin/curl -X POST 192.168.88.244:8888/mi -H 'Content-Type: application/json' -d '{"jsonrpc": "2.0", "id": "1", "method": "get_statistics", "params": {"statistics": ["sl:"]}}'

I’ll also duplicate the command with a screenshot (to be sure that you see it in a right way, because markup may cut some special characters):

Tip: if you need statistics from several groups, for example several modules (not only SL), the request will be as follows:

/usr/bin/curl -X POST 192.168.88.244:8888/mi -H 'Content-Type: application/json' -d '{"jsonrpc": "2.0", "id": "1", "method": "get_statistics", "params": {"statistics": ["sl:", "tm:"]}}'

OpenSIPS will answer and you’ll see SL module statistics after sending this request with CURL.

But the responce is a one-liner, so we need to convert this one line to JSON format and then to create a JSONPath, to be able to extract the value we need.

Let’s monitor not all SL module statistics received from OpenSIPS, but the number of 2xx replies only.

I use https://www.jsonformatter.io/ for JSON formatting and https://jsonpath.com/ for creating JSONPath. After formatting and specifying JSONPath we can configure Zabbix.


Now it’s time to add items to your OpenSIPS host in Zabbix. Item parameters:

Type: HTTP Agent
Type of information: Numeric (unsigned)
Request type: POST
Request body type: JSON data
Request body: {"jsonrpc": "2.0", "id": "1", "method": "get_statistics", "params": {"statistics": ["sl:"]}}
Retrieve mode: Body
Convert to JSON (enabled)

Screenshots as usual:


Item Preprocessing parameters:

1st step - JSONPath
Parameters: $.body.result.["sl:2xx_replies"]
Type of information: Numeric (unsigned)

Screen – item Preprocessing and successful testing:


Now we add a graph with this item (I hope you know how to create graphs in Zabbix) and it’s time to test. I will generate thousands of OPTIONS requests to my OpenSIPS with the sipp tool (I also recommend this sipp cheatsheet).

Download OPTIONS.xml scenario file, and generate 10000 OPTIONS requests with call rate of 10 (I assume that your OpenSIPS, like mine, answers “200 OK”):

sipp 192.168.88.244 -sf OPTIONS.xml -l 10000 -m 10000 -r 10

Finally, here is the graph showing your OpenSIPS SL module 2xx processed replies statistics:

This is how you can monitor OpenSIPS with Zabbix using JSON.

Have fun!

Asterisk: removing all queue dynamic members

March 20th, 2022

Users add themselves as queue members by dialing some short number (AddQueueMember dialplan app is used). The queue may contain several dynamic members.

The task is to remove all queue members by dialing some number, no matter how much members are in this queue. Queue name is ‘superQueue’ (example for AEL, Asterisk 13):

// remove all dynamic queue members
0000 =>
{
    NoOp(superQueue member  list: ${QUEUE_MEMBER_LIST(superQueue)});

    // count members of a queue
    count=${QUEUE_MEMBER(superQueue,count)};

    // and remove all, one by one
    while (${count} >= 1) {
        Set(QMLsuperQueue=${QUEUE_MEMBER_LIST(superQueue)});
        Set(kicked=${CUT(QMLsuperQueue,\,,1)});
        Log(NOTICE, removing dynamic member: ${kicked});
        RemoveQueueMember(superQueue,${kicked});
        count=${count}-1;
    }

    Hangup();
};

systemd: cleaning journal service logs

March 1st, 2022
voip ~ # journalctl --disk-usage
Archived and active journals take up 4.2G on disk.
voip ~ # du -sh /var/log/journal/
4,3G /var/log/journal/

Let’s leave 500M of logs only:

voip ~ # journalctl --vacuum-size=500M

Vacuuming done, freed 3.5G of archived journals on disk.

Check once again:

voip ~ # journalctl --disk-usage
Archived and active journals take up 744.2M on disk.
voip ~ #
voip ~ # du -sh /var/log/journal/
745M /var/log/journal/

rsyslog: slicing & dicing application log files

December 1st, 2021

Let’s slice log file of an application to store separate log files during each hour and keep them in separate directories accroding to the date.


Example for RTPEngine:

  1. create file /etc/rsyslog.d/10-rtpengine.conf

2. add to it the following settings:

template(
    name="rtpengine-tmpl" type="string"
    string="/var/log/rtpengine/%$NOW%/rtpengine-%HOSTNAME%-%$YEAR%%$MONTH%%$DAY%.%$HOUR%.log"
)

template(
    name="rtpengine-fmt" type="string"
    string="%timegenerated% %HOSTNAME% %syslogtag% %msg:::drop-last-lf%\n"
)

if $app-name == ["rtpengine"] then {
    action(type="omfile" dynaFile="rtpengine-tmpl" template="rtpengine-fmt")
    stop
}

3. restart rsyslog.

4. profit

screenshot of a config file
the result

Example for OpenSIPS:

  1. create /etc/rsyslog.d/20-opensips.conf
  2. add to it:
# :msg, startswith, "ACC:" /var/log/opensips/acc.log
# & stop
#
# :syslogtag, contains, "opensips" /var/log/opensips/opensips.log
# & stop

template(
	name="opensips-tmpl" type="string"
	string="/var/log/opensips/opensips/%$NOW%/opensips-%HOSTNAME%-%$YEAR%%$MONTH%%$DAY%.%$HOUR%.log"
)

template(
        name="opensips-acc-tmpl" type="string"
        string="/var/log/opensips/acc/%$NOW%/acc-%HOSTNAME%-%$YEAR%%$MONTH%%$DAY%.%$HOUR%.log"
)

template(
	name="opensips-fmt" type="string"
	string="%timegenerated% %HOSTNAME% [%procid%] %syslogseverity-text% %msg%\n"
)

if $syslogtag contains "opensips" and $msg contains "ACC:" then {
        action(type="omfile" dynaFile="opensips-acc-tmpl" template="opensips-fmt")
        stop
}

if $syslogtag contains "opensips" then {
	action(type="omfile" dynaFile="opensips-tmpl" template="opensips-fmt")
	stop
}

3. restart rsyslog.

yum: show pkg versions, install certain version

August 31st, 2021

Show available versions of ‘ngcp-rtpengine’ package from repository:

yum --showduplicates list available ngcp-rtpengine

Show available versions from repository of packages which name starts with ‘ngcp-rtpengine’:

yum --showduplicates list available ngcp-rtpengine*

… will result:

ngcp-rtpengine.x86_64 6.5.2-1.el7 repo_name
ngcp-rtpengine.x86_64 6.5.3-1.el7 repo_name

ngcp-rtpengine-dkms.noarch 6.5.2-1.el7 repo_name
ngcp-rtpengine-dkms.noarch 6.5.3-1.el7 repo_name

Install certain version:

yum install ngcp-rtpengine-8.5.3-3.el7

CentOS: remove old/unused kernels

August 24th, 2021

Install ‘yum-utils’ package.

Before:

voip ~ # uname -sr
Linux 3.10.0-327.36.2.el7.x86_64
voip ~ # rpm -q kernel
kernel-3.10.0-327.el7.x86_64
kernel-3.10.0-327.10.1.el7.x86_64
kernel-3.10.0-327.18.2.el7.x86_64
kernel-3.10.0-327.36.2.el7.x86_64


voip ~ # df -h | grep boot
/dev/md126p1 283M 212M 52M 81% /boot

Let’s leave 2 kernels, others will be removed. Use ‘package-cleanup’ tool:

voip ~ # package-cleanup --oldkernels --count=2
...

Result:

voip ~ # uname -sr
Linux 3.10.0-327.36.2.el7.x86_64
voip ~ # rpm -q kernel
kernel-3.10.0-327.18.2.el7.x86_64
kernel-3.10.0-327.36.2.el7.x86_64


voip ~ # df -h | grep boot
/dev/md126p1 283M 127M 138M 48% /boot

RTPEngine set weight

August 23rd, 2021

Undocumented feature –
how to configure weight for a rtpengine set (default value is 1):

modparam("rtpengine", "rtpengine_sock", "udp:localhost:12222=2")

http://lists.opensips.org/pipermail/users/2021-August/045084.html