Ubuntu 20.04 linphone-sdk Docker Image >>> build linphone-desktop and flexisip

LinphoneFlexispをビルドする際に必要なlinphone-sdkDockerイメージを事前にビルドします。Ubuntu 20.04版Dockerfileは提供されていないため、Ubuntu18.04版Dockerfileをベースに新規作成します。

linphone-sdkソースのダウンロード

必要なのは、 Ubuntu20.04 ベースで linphone-sdk に必要なパッケージをインストールしたイメージファイル作成のための docker-files ディレクトリのみです。
docker-files ディレクトリを任意の場所にコピーペースト後、ダウンロードした linphone-sdk は削除して下さい。

$ git clone https://gitlab.linphone.org/BC/public/linphone-sdk.git

dcoker-files ディレクトリ内で bc-dev-ubuntu-18-04-lts をコピーし bc-dev-ubuntu-20-04-lts を作成します。

変更箇所: 18.04 ---> 20.04

追加箇所: 'ENV DEBIAN_FRONTEND=noninteractive`

変更箇所:cmakeバージョン 3.11—>3.21

# Install CMake 3.21
RUN curl -o cmake.tar.gz https://cmake.org/files/v3.21/cmake-3.21.3.tar.gz && \
    tar xvzf cmake.tar.gz && rm cmake.tar.gz && cd cmake-3.21.3 && cmake . && make -j5 install && cd .. && rm -rf cmake-3.21.3

変更箇所:python2, python-pip

# Install python3 and python modules.
# This must be done as 'bc' user because some python modules are installed into /usr/local/lib when pip is invoked
# as root, and rpmbuild prevent python from seaching its modules in this prefix. Using 'bc' user make the python
# modules to be installed into /home/bc/.local/lib.
RUN curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py && \
    sudo apt-get install -y python2 python3-pip && sudo apt-get clean -y && \
    sudo ln -s /usr/bin/python2.7 /usr/bin/python && \
    sudo python2 get-pip.py
# Run the below command after "docker run" in /home/bc    
#    pip install --user six pystache graphviz && \
#    pip3 install --user six pystache graphviz

bc-dev-ubuntu-20-04-lts

FROM ubuntu:20.04

MAINTAINER Ghislain MARY <[email protected]>

# Use a french mirror
RUN sed -i -E 's/(archive|security)\.ubuntu\.com/fr.archive.ubuntu.com/' /etc/apt/sources.list

# Configure locale
RUN apt-get update && \
    apt-get install -y locales && \
    apt-get clean && \
    echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
    locale-gen
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'

ENV SHELL=/bin/bash
ENV PS1='\[\e[33m\]\[email protected]>\[\e[0m\] '
# For the problem is tzdata, which stops with the interactive dialog
ENV DEBIAN_FRONTEND=noninteractive

# Install common general tools
RUN apt-get update && \
    apt-get install -y nano sudo vim && \
    apt-get clean

# Install development tools
RUN apt-get update && \
    apt-get install -y alien at autoconf bison ccache clang cmake doxygen elfutils g++ gdb git graphviz intltool libtool lsb-release make nasm ninja-build openssh-client patch yasm && \
    apt-get clean

# Install linphone dependencies development packages
RUN apt-get update && \
    apt-get install -y libasound2-dev libavcodec-dev libavutil-dev libbsd-dev libegl1-mesa-dev libglew-dev libgsm1-dev libmariadb-dev-compat libmbedtls-dev libopus-dev libpq-dev libpulse-dev libqt5svg5-dev libspeex-dev libspeexdsp-dev libsqlite3-dev libsrtp2-dev libssl-dev libswscale-dev libturbojpeg0-dev libv4l-dev libvpx-dev libxerces-c-dev libxml2-dev libxv-dev qt3d5-dev qt5-default qtbase5-dev qtbase5-dev-tools qtconnectivity5-dev qtdeclarative5-dev qtdeclarative5-dev-tools qtdeclarative5-dev-tools qtquickcontrols2-5-dev qttools5-dev qttools5-dev-tools xsdcxx && \
    apt-get clean

# Install CMake 3.21
RUN curl -o cmake.tar.gz https://cmake.org/files/v3.21/cmake-3.21.3.tar.gz && \
    tar xvzf cmake.tar.gz && rm cmake.tar.gz && cd cmake-3.21.3 && cmake . && make -j5 install && cd .. && rm -rf cmake-3.21.3

# Configure user bc
RUN useradd -ms /bin/bash bc && \
    echo 'bc:cotcot' | chpasswd && \
    echo 'bc ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

# Switch for 'bc' user
USER bc
WORKDIR /home/bc

# Install python3 and python modules.
# This must be done as 'bc' user because some python modules are installed into /usr/local/lib when pip is invoked
# as root, and rpmbuild prevent python from seaching its modules in this prefix. Using 'bc' user make the python
# modules to be installed into /home/bc/.local/lib.
RUN curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py && \
    sudo apt-get install -y python2 python3-pip && sudo apt-get clean -y && \
    sudo ln -s /usr/bin/python2.7 /usr/bin/python && \
    sudo python2 get-pip.py
# Run the below command after "docker run" in /home/bc    
#    pip install --user six pystache graphviz && \
#    pip3 install --user six pystache graphviz

COPY --chown=bc rpmmacros /home/bc/.rpmmacros
CMD bash

Makefileに上記dockerfileイメージのビルドセクションを追加します。

ubuntu-20.04-LTS:
	docker build -f bc-dev-ubuntu-20-04-lts -t $(BASE_NAME)/bc-dev-ubuntu:20.04 --rm .

Ubuntu20.04版linphone-sdk イメージをビルドします。

$ make ubuntu-20.04-LTS

作成イメージ

$ docker images
REPOSITORY                                                      TAG       IMAGE ID       CREATED         SIZE
gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu   20.04     88d9f4a2c038   9 minutes ago   2.52GB
ubuntu                                                          20.04     597ce1600cf4   3 days ago      72.8MB

イメージからコンテナ起動

$ docker run --name linphone-desktop -v $PWD:/home/bc -it gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:20.04

bc@410eda0ead5c:~$ 

Docker Container for building linphone-desktop on Ubuntu20.04

linphone-sdk on ubuntu 20.04 Docker イメージを利用して、linphone-desktop on ubuntu 20.04 をビルドします。任意のディレクトリ(projects)内で以下 Docker コンテナを起動します。

$ docker run --env="DISPLAY" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" --name linphone-desktop -v $PWD:/home/bc -it gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:20.04

注) --env="DISPLAY" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw"
コンテナ内で動作確認しない場合、必要ないオプションです。

In the docker container

コンテナ内でビルドします。

$ pip install --user six pystache graphviz
$ pip3 install --user six pystache graphviz

$ eval "$(qtchooser -print-env)"
$ export Qt5_DIR=${QTLIBDIR}/cmake/Qt5
$ export PATH=${QTTOOLDIR}:$PATH

$ git clone https://gitlab.linphone.org/BC/public/linphone-desktop.git --recursive

$ cd linphone-desktop
$ mkdir build
$ cd  build

$ cmake .. -DCMAKE_BUILD_PARALLEL_LEVEL=10 -DCMAKE_BUILD_TYPE=RelWithDebInfo
$ cmake --build . --target install --parallel 10 --config RelWithDebInfo

注)コンテナ内で動作確認するのではなく、ホストマシンでの動作確認を推奨します。

コンテナ内で起動する場合、以下のパッケージが必要です。

$ sudo apt install qt5-default qttools5-dev qttools5-dev-tools libqt5svg5-dev libqt5texttospeech5-dev qtdeclarative5-dev qtdeclarative5-dev-tools qtquickcontrols2-5-dev qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs qml-module-qtqml-models2 qml-module-qtquick-templates2 qml-module-qt-labs-folderlistmodel qml-module-qt-labs-settings qml-module-qt-labs-platform

Start

./OUTPUT/bin/linphone --verbose

linphone-desktop-version

linphone-desktop

コンテナ内追加パッケージ

DockerコンテナからGUIアプリの起動方法
http://wiki.ros.org/docker/Tutorials/GUI

Ubuntu 20.04ホストマシン上で起動する場合

ビルドする際に使用したDockerコンテナ linphone-desktop は必要なければ削除して構いません。コンテナから出て削除します。

$ exit
$ docker rm linphone-desktop

ホストマシンに以下パッケージをインストールします。

$ sudo apt install qt5-default qttools5-dev qttools5-dev-tools libqt5svg5-dev libqt5texttospeech5-dev qtdeclarative5-dev qtdeclarative5-dev-tools qtquickcontrols2-5-dev qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs qml-module-qtqml-models2 qml-module-qtquick-templates2 qml-module-qt-labs-folderlistmodel qml-module-qt-labs-settings qml-module-qt-labs-platform

ビルドした project/linphone-desktop/build ディレクトリ内で以下コマンドを実行し起動。

$ ./OUTPUT/bin/linphone --verbose

またはビルドしたバイナリファイルと関連ライブラリは OUTPUT ディレクトリに格納されているため、この中身を /opt ディレクトリへコピーしパスを通すことで

$ linphone

で起動できます。

Build Flexisip on Ubuntu20.04

linphone-sdk on ubuntu 20.04 Docker イメージを利用して、flexisip on ubuntu 20.04 をビルドします。任意のディレクトリ(projects )内で以下 Docker コンテナを起動します。

$ docker run --name flexisip-desktop -v $PWD:/home/bc -it gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:20.04

In the docker container

以下コンテナ内での作業

コンテナ内でFlexisipの開発依存パッケージをインストールします。

$ sudo su -c 'apt-get -y update && apt-get -y install libhiredis-dev libjansson-dev libnghttp2-dev libprotobuf-dev libsnmp-dev protobuf-compiler wget && apt-get -y clean'

ソースをダウンロードしパッケージ化オプションなどを指定しビルドします。

$ git clone https://gitlab.linphone.org/BC/public/flexisip.git --recursive
$ cd flexisip
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_INSTALL_PREFIX=/opt/belledonne-communications -DCMAKE_BUILD_TYPE=RelWithDebInfo -DSYSCONF_INSTALL_DIR=/etc -DCPACK_GENERATOR=DEB
$ make package

特定バージョンのダウンロードとサブモジュールを含めたレポジトリ履歴をダウンサイズする場合

$ git clone -b release/2.1 --recursive --shallow-submodules  https://gitlab.linphone.org/BC/public/flexisip.git 

以下のパッケージが作成されます。

bc-flexisip_2.1.0-0.alpha.178+de018388_amd64.deb
bc-flexisip-dbgsym_2.1.0-0.alpha.178+de018388_amd64.ddeb

上記パッケージをUbuntu20.04ホストマシンにインストールするか、新たにFlexisipのDockerイメージを作成する際に利用して下さい。

Added dockerfiles for Ubuntu 20.04 in flexisip/docker folder

既にビルドしたflexisipDEBパッケージをインストールして、flexisipDockerコンテナ として稼働させるDockerfileflexisip/docker ディレクトリに作成します。

このDockerfileからイメージをビルドするためのコマンドをMakefileに追加します。

Makefile

BASE_NAME=gitlab.linphone.org:4567/bc/public/flexisip
$(eval GIT_DESCRIBE = $(shell sh -c "git describe"))
DOCKER_TAG=$(BASE_NAME):$(GIT_DESCRIBE)
DOCKER_FILE=flex-from-src

# We cannot use dockerfile's COPY outside build context
# we use then flexisip directory as context for flex-from-src instead of docker directory

ifeq ($(DOCKER_FILE), flex-from-src)
  CONTEXT=..
else
  CONTEXT=.
endif

flexisip-build:
	docker build -f $(DOCKER_FILE) --pull --no-cache -t $(DOCKER_TAG) --rm $(CONTEXT)

flexisip-push:
	docker push $(DOCKER_TAG)

flexisip-clean:
	docker image rm $(DOCKER_TAG)

flexisip-deb-before:
	$(eval DOCKER_FILE = flex-from-deb)
	# forcing context to .
	# at the moment of the condition above being executed, $DOCKER_FILE doesn't have the right value
	$(eval CONTEXT = .)
	$(eval DOCKER_TAG = $(DOCKER_TAG)-deb)

# For Ubuntu 20.04
flexisip-ubuntu-deb-before:
	$(eval DOCKER_FILE = flex-ubuntu-from-deb)
	# forcing context to .
	# at the moment of the condition above being executed, $DOCKER_FILE doesn't have the right value
	$(eval CONTEXT = .)
	$(eval DOCKER_TAG = $(DOCKER_TAG)-deb)

flexisip-deb-build: flexisip-deb-before flexisip-build

flexisip-deb-push: flexisip-deb-before flexisip-push

flexisip-deb-clean: flexisip-deb-before flexisip-clean

# For Ubuntu 20.04
flexisip-ubuntu-deb-build: flexisip-ubuntu-deb-before flexisip-build

flexisip-ubuntu-deb-push: flexisip-ubuntu-deb-before flexisip-push

flexisip-ubuntu-deb-clean: flexisip-ubuntu-deb-before flexisip-clean

.PHONY: flexisip-build

NEW:flex-ubuntu-from-deb

FROM ubuntu:20.04
MAINTAINER  Takanobu Fuse <[email protected]>

ENV DEBIAN_FRONTEND=noninteractive

# Prepare dependencies + SNMP:https://wiki.linphone.org/xwiki/wiki/public/view/Flexisip/Configuration/SNMP/
RUN apt-get update && apt-get install -y xsdcxx gdb libmariadb3 net-tools iptables snmp snmpd snmp-mibs-downloader

# Get flexisip package
COPY DEBS/*.deb DEBS/*.ddeb deb-packages/
RUN apt-get install -y /deb-packages/bc-*.deb /deb-packages/bc-*.ddeb
RUN rm -rf /deb-packages

# Add it to the default path
ENV PATH=$PATH:/opt/belledonne-communications/bin
ENV LD_LIBRARY_PATH=/opt/belledonne-communications/lib

WORKDIR /opt/belledonne-communications

# Generate a default configuration
RUN flexisip --dump-default all > /etc/flexisip/flexisip.conf

VOLUME /etc/opt/belledonne-communications/flexisip
VOLUME /var/opt/belledonne-communications/log/flexisip
COPY flexisip-entrypoint.sh /
COPY flexisip-snmpd.sh /
COPY backtrace.gdb /
COPY snmp.conf /etc/snmp/snmp.conf
COPY snmpd.conf /etc/snmp/snmpd.conf
RUN chmod a+x /flexisip-entrypoint.sh /flexisip-snmpd.sh

# Script to wait db before launch flexisip [Licence Apache2]
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.2.1/wait /wait
RUN chmod +x /wait

ENTRYPOINT ["/flexisip-entrypoint.sh"]
CMD ["/flexisip-snmpd.sh"]

NEW:flexisip-snmpd.sh

#!/bin/bash

# turn on bash's job control
set -m

# Start the primary process and put it in the background
flexisip &

# Start the helper process
/etc/init.d/snmpd start

# the my_helper_process might need to know how to wait on the
# primary process to start before it does its work and returns


# now we bring the primary process back into the foreground
# and leave it there
fg %1

SNMPについては以下参照の上設定ファイルを作成のこと。

Snmpd-ArchiWiki
https://wiki.archlinux.org/title/snmpd

Flexisip Docker Image
ホストマシンで以下コマンドを実行してFlexisipイメージを作成して下さい。

$ make flexisip-ubuntu-deb-build

Docker-Composeファイルの作成

上記新規に作成したFlexisipイメージとRedis, Nginx, MariaDB, phpMyAdminなどの関連イメージからflexisipによるSIPサーバを構築します。

Redis

Alpineイメージには redis.conf が格納されていないため以下サイトからサンプル入手

Redisコンテナ内で設定確認 redis-cli > config get

$ docker exec -ti redis sh
/data # redis-cli
127.0.0.1:6379> config get *max-*-entries*
1) "hash-max-ziplist-entries"
2) "512"
3) "set-max-intset-entries"
4) "512"
5) "zset-max-ziplist-entries"
6) "128"
127.0.0.1:6379>

HELP

# redis-server -h
Usage: ./redis-server [/path/to/redis.conf] [options] [-]
       ./redis-server - (read config from stdin)
       ./redis-server -v or --version
       ./redis-server -h or --help
       ./redis-server --test-memory <megabytes>

Examples:
       ./redis-server (run the server with default conf)
       ./redis-server /etc/redis/6379.conf
       ./redis-server --port 7777
       ./redis-server --port 7777 --replicaof 127.0.0.1 8888
       ./redis-server /etc/myredis.conf --loglevel verbose -
       ./redis-server /etc/myredis.conf --loglevel verbose

Sentinel mode:
       ./redis-server /etc/sentinel.conf --sentinel

redis.confの編集

Dockerネットワーク内の他のコンテナからもアクセス出来るように、bindの項目にdocker-composeファイルで指定したredisコンテナのIPを追加すること。

################################## NETWORK #####################################

# By default, if no "bind" configuration directive is specified, Redis listens
# for connections from all available network interfaces on the host machine.
# It is possible to listen to just one or multiple selected interfaces using
# the "bind" configuration directive, followed by one or more IP addresses.
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only on the
# IPv4 loopback interface address (this means Redis will only be able to
# accept client connections from the same host that it is running on).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT OUT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 127.0.0.1 172.16.0.2

パスワード設定

下記opensslコマンドから60文字から成るランダムパスワードを作成します。

$ openssl rand 60 | openssl base64 -A
ZeXT9aNJc3FjrVZ3i7XYAiqaUXq6OU40C9hbrF3d9oG+Ox+BB51/6O4aZaalXQzQ8UxTqRQx86CnEEiR

作成されたパスワードをredis.confrequirepass にコピーして下さい。

requirepass ZeXT9aNJc3FjrVZ3i7XYAiqaUXq6OU40C9hbrF3d9oG+Ox+BB51/6O4aZaalXQzQ8UxTqRQx86CnEEiR

参考 Redis Install

OpenSSLによるパスワード生成

https://www.openssl.org/docs/manmaster/man1/openssl-passwd.html

EXAMPLES

  % openssl passwd -1 -salt xxxxxxxx password
  $1$xxxxxxxx$UYCIxa628.9qXjpQCjM4a.

  % openssl passwd -apr1 -salt xxxxxxxx password
  $apr1$xxxxxxxx$dxHfLAsjHkDRmG83UXe8K0

  % openssl passwd -aixmd5 -salt xxxxxxxx password
  xxxxxxxx$8Oaipk/GPKhC64w/YVeFD/

flexisip --help

# flexisip --help
USAGE: 
   flexisip  [-h] [-v] [--] [--server <server function>] [-c <file>] [--daemon]
             [-d] [-p <file>] [--syslog] [-t <sips:* sip:*>] [--dump-default
             <all>] [--dump-all-default] [--dump-format <file>] [--list-modules]
             [--list-sections] [--rewrite-config] [--dump-mibs]
             [--p12-passphrase-file <file>] [--show-experimental]
             [--list-overrides <module>] [-s <global/debug=true>] ...  [--hosts
             <host=ip>] ...  [--track-allocations]
Where: 
  -h,  --help             Displays usage information and exits.
  -v,  --version          Displays version information and exits.
  --,  --ignore_rest      Ignores the rest of the labeled arguments following this
                          flag.
  --server <server function>
                          Specify the server function to operate: 'proxy',
                          'presence', 'regevent', 'conference', or 'all'.
  -c,  --config <file>    Specify the location of the configuration file.
  --daemon                Launch in daemon mode.
  -d,  --debug            Force output of all logs, including debug logs, to the
                          terminal (does not affect the log level applied to log
                          files).
  -p,  --pidfile <file>   PID file location, used when running in daemon mode.
  --syslog                Use syslog for logging.
  -t,  --transports <sips:* sip:*>
                          The list of transports to handle (overrides the ones
                          defined in the configuration file).
  --dump-default <all>    Dump default config, with specifier for the module to
                          dump. Use 'all' to dump all modules, or 'MODULENAME'
                          to dump a specific module. For instance, to dump the
                          Router module default config, issue 'flexisip
                          --dump-default module::Router.
  --dump-all-default      Will dump all the configuration. This is equivalent to
                          '--dump-default all'. This option may be combined with
                          '--set global/plugins=<plugin_list>' to also generate
                          the settings of listed plugins.
  --dump-format <file>    Select the format in which the dump-default will print.
                          The default is 'file'. Possible values are: file, tex,
                          doku, media, xwiki.
  --list-modules          Will print a list of available modules. This is useful
                          if you want to combine with --dump-default to have
                          specific documentation for a module.
  --list-sections         Will print a list of available sections. This is useful
                          if you want to combine with --dump-default to have
                          specific documentation for a section.
  --rewrite-config        Load the configuration file and dump a new one on stdout
                          , adding the new settings and updating documentations.
                          All the existing settings are kept even if they are
                          equal to the default value and the default value has
                          changed.
  --dump-mibs             Will dump the MIB files for Flexisip performance
                          counters and other related SNMP items.
  --p12-passphrase-file <file>
                          Specify the location of the pkcs12 passphrase file.
  --show-experimental     Use in conjunction with --dump-default: will dump the
                          configuration for a module even if it is marked as
                          experiemental.
  --list-overrides <module>
                          List the configuration values that you can override.
                          Useful in conjunction with --set. Pass a module to
                          specify the module for which to dump the available
                          values. Use 'all' to get all possible overrides.
  -s,  --set <global/debug=true>  (accepted multiple times)
                          Allows to override the configuration file setting. Use
                          --list-overrides to get a list of values that you can
                          override.
  --hosts <host=ip>  (accepted multiple times)
                          Overrides a host address by passing it. You can use this
                          flag multiple times. Also, you can remove an
                          association by providing an empty value: '--hosts
                          myhost='.
  --track-allocations     Tracks allocations of SIP messages, only use with
                          caution.

Nginx(Alpine)コンテナでクローンデーモン起動

certbotによる認証更新をスケジュール管理するため、デフォルトのジョブNginxにクローンデーモンcrondによるジョブを追加します。

Dockerfile

nginx-alpine

FROM nginx:alpine

# Set working directory
WORKDIR /var/www/html

RUN apk add --no-cache bash nano tzdata certbot-nginx \
    && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && echo "Asia/Tokyo" > /etc/timezone \
    && apk del tzdata
COPY nginx_default.conf /etc/nginx/conf.d/default.conf
COPY nginx_crond /etc/periodic/monthly
COPY nginx-crond.sh /
RUN chmod a+x /nginx-crond.sh
CMD ["/nginx-crond.sh"]

以下シェルスクリプトをクロンジョブのマンスリーディレクトリにコピー。
nginx-crond

#!/bin/sh
certbot renew
nginx -s reload

コンテナのマルチサービスを実行するスクリプト作成

nginx-crond.sh

#!/bin/bash

# turn on bash's job control
set -m

# Start the primary process and put it in the background
nginx -g 'daemon off;' &

# Start the helper process
crond

# the my_helper_process might need to know how to wait on the
# primary process to start before it does its work and returns

# now we bring the primary process back into the foreground
# and leave it there
fg %1

Docker-Compose ファイル

Docker-Composeブロック図

以下FlexisipによるSIPサーバとユーザ管理ページを統合したDocker-Composeファイルです。

version: '3'

services:
##### redis-server
  redis:
    container_name: redis
    build: 
      context: ./docker_files
      dockerfile: redis-alpine
    # need to download default config file:redis.conf from https://redis.io/topics/config
    # then modify it to enable the auth access(password), and input it into /redis/etc directory.
    # NOTE: maybe no need to run with redis.conf, because of it is running only inside the docker network.
    # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. 
    # To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or 
    # run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
    command: ["redis-server", "/etc/redis/redis.conf"]
    privileged: true
    restart: always
    networks: 
      proxy-tier:
        ipv4_address: 172.16.0.2

##### nginx
  # after "docker-compose up -d", enter the container and execute the following commands. 
  # "certbot certonly --standalone --agree-tos -n -m [email protected] -d ficus-home.duckdns.org"
  # or
  # "certbot --nginx --agree-tos -n -m [email protected] -d ficus-home.duckdns.org"
  # then
  # "cd /etc/letsencrypt/live/ficus-home.duckdns.org"
  # "cp fullchain.pem cafile.pem"
  # "awk 1 privkey.pem cert.pem > agent.pem"
  nginx:
    container_name: nginx
    build: 
      context: ./docker_files
      dockerfile: nginx-alpine
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      # nginx config
      - ./nginx:/etc/nginx/conf.d
      # certbot letsencrypt certification
      - letsencrypt:/etc/letsencrypt
      # shared the directory /var/www/html in php-fpm container
      - ./html:/var/www/html
      # shared the directory /var/www/html in phpmysql-fpm container
      - phpmyadmin:/var/www/html/phpmyadmin
      # for flexisip-account-manager
      #- ./flexisip-account-manager:/var/www/html/flexisip-account-manager
    depends_on:
      - phpmyadmin-fpm
      - php-fpm-laravel
    restart: always
    networks: 
      proxy-tier:
        ipv4_address: 172.16.0.3        

##### mariadb
  flexisip-mariadb:
    container_name: flexisip-mariadb
    image: mariadb
    restart: always
    volumes:
      - ./db:/var/lib/mysql
      - ./mariadb:/etc/mysql/conf.d
    # refer to .env
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
    networks: 
      proxy-tier:
        ipv4_address: 172.16.0.5

### flexisip
  ubuntu-flexisip:
    container_name: ubuntu-flexisip
    image: gitlab.linphone.org:4567/bc/public/flexisip:2.1.0-beta-14-g0ba5e300-deb
    ports:
      - 5060-5061:5060-5061
      #### Presence-Server
      - 5065:5065
      #### Conference and RegEvent Server
      - 6064-6065:6064-6065
     # - 10000-10050:10000-10050/udp
     #### STUN Server
      - 3478:3478/udp   
    volumes:
      - letsencrypt:/etc/flexisip/tls
      # previously need to add "flexisip" directory and input "flexisip.conf" into it.
      - ./flexisip:/etc/flexisip
    depends_on:
      - nginx
      - flexisip-mariadb
    restart: always
    networks: 
      proxy-tier:
        ipv4_address: 172.16.0.6
    ## allow the privilege of network to the container
    #ulimits:
    #  nofile:
    #    soft: 200000
    #    hard: 400000
    cap_add:
      - NET_ADMIN
    #  - SYS_RESOURCE
    privileged: true
    
##### phpmyadmin-fpm
  phpmyadmin-fpm:
    container_name: phpmyadmin-fpm
    build: 
      context: ./docker_files
      dockerfile: phpmyadmin-alpine
    tty: true
    expose: 
      - "9000"
    environment:
      - PMA_HOST=flexisip-mariadb
      - PMA_PORT=3306
      - PMA_ABSOLUTE_URI=http://localhost/phpmyadmin
    volumes:
      - phpmyadmin:/var/www/html
      - /sessions
    depends_on:
      - flexisip-mariadb
    restart: always
    networks: 
      proxy-tier:
        ipv4_address: 172.16.0.7
        
##### php-fpm-laravel
  php-fpm-laravel:
    container_name: php-fpm-laravel
    build: 
      context: ./docker_files
      dockerfile: php-fpm-alpine-laravel      
    tty: true
    expose: 
      - "9000"
    # "php artisan serve" commmand default port
    ports:
      - 8000:8000
    volumes:
      # for laravel php framework
      - ./html:/var/www/html
      - ./etc/conf:/etc/flexisip-account-manager
    depends_on:
      - flexisip-mariadb
    restart: always
    networks: 
      proxy-tier:
        ipv4_address: 172.16.0.8

### $ docker network create --gateway 172.16.0.1 --subnet 172.16.0.0/24 nginx-proxy
networks:
  proxy-tier:
    external:
      name: nginx-proxy

### $ docker volume create phpmyadmin letsencrypt     
volumes:
  phpmyadmin:
    external: true
  letsencrypt:
    external: true

flexisip.confの編集

各々の環境に合わせ、設定ファイルの内容を編集・定義します。

Configuration Reference Guide

Redisの設定

TLS access, Registrar with Redis, authentication from database and media relay

[global]
aliases=sip.example.org
debug=true
transports=sips:* sip:*
tls-certificates-dir=/etc/flexisip/tls

[module::Registrar]
reg-domains=sip.example.org
db-implementation=redis
redis-server-domain=172.16.0.1
redis-server-port=6379
redis-record-serializer=protobuf
redis-auth-password=the_random_very_long_string_also_defined_in_redis.conf_83cb1dfd2e3617

[module::MediaRelay]
enabled=true

[module::Authentication]
enabled=true
auth-domains=sip.example.org
db-implementation=soci
soci-password-request=select password from accounts where login = :id and activated = "1"
soci-connection-string=db=mydb user=dbuser password='database_password' host=database.example.org

Push Gatewayの設定

[global]

# if user agents connect on the push gateway by using an host name instead of its IP address you must
# add the host name into that list. You can put several host name.
aliases=localhost

# you may change that value if you want your push gateway does not listen on SIP standard ports
transports=sip:*

[module::Registrar]

# the Registrar module must be enabled
enabled=true

# A '*' means the push gateway will register identities whatever the domain.
# That is safe because the registration will be done only if the backend server answers 200 to
# the forwarded REGISTER.
reg-domains=*

# Tell the registrar module to do the registration once the backend server answers 200.
reg-on-response=true


[module::Router]

# That rules must be enabled if you intend to use the push gateway as outbound proxy.
# With that rule, only requests coming from the backend server will enter in the module::Router. The
# others will be forwarded directly. The ''doroute'' tag is automatically inserted into the masqueraded
# contact address by the module::ContactRouteInserter before to be forwarded to the backend server.
# So, requests that will come from the backend server will have a ''doroute'' parameter in their
# request URI.
filter=(is_request && request.uri.params contains 'doroute') || is_response

# do not fail immediately when the push gateway cannot connect to a user agent but wait for a register
# from the last one before trying again.
fork-late=true


[module::PushNotification]

# The push notification module must be enabled of course. Be care to set all the information needed
# by Flexisip to send pushes for each platforms.
# See https://wiki.linphone.org/wiki/index.php/Flexisip:flexisip_configuration#Push_notificationf
enabled=true

# You may change that value if you want the push gateway wait lesser time before sending a push notification
timeout=5


# This module will masquerade contact headers before forwarding a REGISTER request.
# Settings for that module are not displayed in the default configuration file. So, you have
# to add it yourself.
[module::ContactRouteInserter]
enabled=true

# if not true, Flexisip will put the IP address of the user agent in the CtRt parameter instead of
# the domain used in the request URI of the REGISTER.
insert-domain=true

フィルター定義

フィルターで定義できる内容は以下の通り。

Strings write them surrounded by single quotes:linphone.org
List of strings whitespace separated words: toto titi tata
integers write them normally: 5223
Parenthesis used to separate different nested expressions: ( from.uri.user == ‘toto’ ) (from.uri.user == ‘titi’)
Booleans: true and false

EX)

# A boolean expression applied to current SIP message being processed.
# When matched, logs are output provided that there level is greater
# than the value defined in contextual-log-level. The definition
# of the SIP boolean expression is the same as for entry filters
# of modules, which is documented here: https://wiki.linphone.org/xwiki/wiki/public/view/Flexisip/Configuration/Filter%20syntax/
# Default: 
contextual-log-filter=from.uri.domain contains 'sip.linphone.org'

# Verbosity of contextual logs to output when the condition defined
# in 'contextual-log-filter' is met.
# Default: debug
contextual-log-level=debug

イベントログ

各ユーザのイベント毎の詳細ログ。デフォルトでは無効。
Event logs contain per domain and user information about processed
registrations, calls and messages.

presence-server

Configuration options:

Name Description Default Value Type
enabled Enable presence server true Boolean
transports List of white space separated SIP URIs where the presence server must listen. Must not be tls. sip:127.0.0.1:5065;transport=tcp StringList
expires Default expires of PUBLISH request in second. 600 Integer
notify-limit Max number of presentity sent in a single NOTIFY by default. 200 Integer
long-term-enabled Enable long-term presence notifies false Boolean
rls-database-connection Soci connection string for the resource list database. String
rls-database-request SQL request to obtain the list of the users corresponding to an resource list subscription.Named parameters are: ‘:from’ : the URI of the sender of the SUBSCRIBE. (mandatory) ‘:to’ : the URI of the users list which the sender want to subscribe to. (mandatory) String
rls-database-max-thread Max number of threads. 50 Integer
rls-database-max-thread-queue-size Max legnth of threads queue. 50 Integer
soci-user-with-phone-request Soci SQL request used to obtain the username associated with a phone alias.The string MUST contains the ‘:phone’ keyword which will be replaced by the phone number to look for.The result of the request is a 1x1 table containing the name of the user associated with the phone number.Example: select login from accounts where phone = :phone String
soci-users-with-phones-request Same as ‘soci-user-with-phone-request’ but allows to fetch several users by a unique SQL request.The string MUST contains the ‘:phones’ keyword which will be replaced by the list of phone numbers to look for. Each element of the list is seperated by a comma character and is protected by simple quotes (e.g. ‘0336xxxxxxxx’,‘0337yyyyyyyy’,‘034zzzzzzzzz’).If you use phone number linked accounts you’ll need to select login, domain, phone in your request for flexisip to work.Example: select login, domain, phone from accounts where phone in (:phones) String
bypass-condition If user agent contains it, can bypass extended notifiy verification. false String
leak-detector Enable belle-sip leak detector false Boolean

Tags:

Deploy Flexisip for one domain

Flexisipに必要なデータベースの構築とデータベースにアクセスする必要のある機能の設定例の提示。

User database

1. Install MariaDB:

yum install mariadb-server
systemctl enable --now mariadb

2. Create the database and grant access to Flexisip:

echo "
CREATE DATABASE flexisip_accounts;
GRANT ALL PRIVILEGES ON flexisip_accounts.* TO flexisip@localhost;
" | mysql

3. It is your responsibility to create the schema of the database and to populate the tables. Alternatively, you may use the following schema for testing:

echo "
CREATE TABLE accounts (
  id int(11) unsigned NOT NULL AUTO_INCREMENT,
  username varchar(64) NOT NULL,
  domain varchar(64) NOT NULL,
  password varchar(255) NOT NULL,
  algorithm varchar(10) NOT NULL DEFAULT 'MD5',
  PRIMARY KEY (id),
  UNIQUE KEY identity (username,domain)
);

INSERT INTO accounts VALUES
  (1,'user1','mydomain1.com','secret','CLRTXT'),
  (2,'user2','mydomain1.com','secret','CLRTXT'),
  (3,'user3','mydomain1.com','secret','CLRTXT');
" | mysql flexisip_accounts

Conference database

The conference database ensures the persistence of the chat rooms of which the conference server is in charge.

1. Create user for Flexisip:

echo "CREATE USER flexisip@localhost IDENTIFIED BY '<db_password>';" | mysql

2. Create the database and grant access to Flexisip:

echo "
CREATE DATABASE flexisip_conference;
GRANT ALL PRIVILEGES ON flexisip_conference.* TO flexisip@localhost;
" | mysql

Set up Flexisip

1. Instructions for the installation of Flexisip are available here.

2. Ensure that Soci backend for MySQL and SQlite are installed:

yum install bc-soci-mysql bc-soci-sqlite3

3. Edit /etc/flexisip/flexisip.conf to set the following parameters:

## PROXY SETTINGS ##
[global]

# Use TLS only for public communications and
# TCP for connections with services running
# on localhost (conference server, presence server, ...)
transports=sips:mydomain1.com:5061 sip:127.0.0.1:5060;transport=tcp

# Enable digest authentication
[module::Authentication]
enabled=true
auth-domains=mydomain1.com
available-algorithms=SHA-256
trusted-hosts=127.0.0.1
db-implementation=soci
soci-backend=mysql
soci-connection-string=db='flexisip_accounts' user='<db_user>' password='<db_password>' host='localhost'
soci-password-request=select password, algorithm from accounts where where username= :id and domain= :domain;

# Enable Registrar feature by using the Redis database
[module::Registrar]
enabled=true
reg-domains=mydomain1.com
db-implementation=redis
redis-server-domain=localhost
redis-server-port=6379

# Allow user agents to be registered for
# seven days in order they can receive
# push notifications seven days after
# disconnection.
max-expires=604800

[module::Router]
# Enable fork-late because it is required
# to send push notifications.
fork-late=true

# Chat messages will be kept by the proxy
# for seven days at the most if it cannot
# be delivered to the recipient immediately.
message-delivery-timeout=604800

# Enable push notifications for iOS and Android clients.
[module::PushNotification]
enabled=true
apple=true
firebase=true
firebase-projects-api-keys=<your_project_api_key>

## PRESENCE SERVER SETTINGS ##
[presence-server]
enabled=true
transports=sip:127.0.0.1:5065;transport=tcp

[module::Presence]
enabled=true
presence-server=sip:127.0.0.1:5065;transport=tcp

## CONFERENCE SERVER SETTINGS ##
[conference-server]
enabled=true
transport=sip:127.0.0.1:6064;transport=tcp
conference-factory-uris=sip:[email protected]
outbound-proxy=sip:127.0.0.1:5060;transport=tcp
local-domains=mydomain1.com
database-backend=mysql
database-connection-string=db='flexisip_conference' user='<db_user>' password='<db_password>' host='localhost'

4. Put the server certificate and key in /etc/flexisip/tls/agent.pem

5. Put chain certificates in /etc/flexisip/tls/cafile.pem

6. Put client certificates for authenticate against Apple’s push notification server into /etc/flexisip/apn. See documentation about PushNotification module for more information.

Start the service

systemctl start flexisip-{proxy,presence,conference}

Flexisip Account Managerのデプロイ

flexisip-account-manager

題目の内容については別フォーラム記事でも何度か記載していますが、最新情報として改めて記載します。

flexisip-account-managerは以下2つの機能:プロビジョニングとウェブインターフェイスを含んでいます。

1.プロビジョニング

プロビジョニングとは、Linphoneアプリでサーバに登録済のユーザ情報を読み込む(書換え)ことであり、XML-RPCサーバでXMLフォーマットに変換されたユーザ情報が提供されます。conf, srcフォルダの中身がこの機能に関係します。

サンプルファイル
https://www.linphone.org/remote_provisioning.xml

confフォルダに格納された設定ファイルを以下 ページの

7. アカウントマネージャの設定
(データベースのテーブル作成phpコード tools/create_tables.php は既にありません。後述のLaravelのArtisanコンソールにより作成します。)

8. カスタム設定の読込(Provisioning)

を参照して変更して下さい。

2.ウェブインターフェイス

Laravel PHPフレームワークによるユーザ登録・管理用のウェブインターフェイスです。flexiapiフォルダがこれに該当します。

docker-composeファイルで定義したphp-fpm-laravelコンテナに入り、
flexiapiディレクトリ内で以下コマンドを実行します。

$ docker exec -ti php-fpm-laravel bash

# cd flexiapi
# composer install --no-dev
# cp .env.example .env
# php artisan key:generate

APP_KEYが追加された .envファイル でデータベースの設定などを行います。

APP_NAME=FlexiAPI
APP_ENV=local
APP_KEY=base64:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
APP_DEBUG=false
APP_URL=https://www.example.com
APP_SIP_DOMAIN=www.example.com
APP_FLEXISIP_PROXY_PID=/var/run/flexisip-proxy.pid
APP_FLEXISIP_PUSHER_PATH=
APP_EVERYONE_IS_ADMIN=false

# SIP server parameters
ACCOUNT_PROXY_REGISTRAR_ADDRESS=ficus-home.duckdns.org # Proxy registrar address, can be different than the SIP domain
ACCOUNT_TRANSPORT_PROTOCOL_TEXT="TLS (recommended), TCP or UDP" # Simple text, to explain how the SIP server can be reached
ACCOUNT_REALM=null # Default realm for the accounts, fallback to the domain if not set, enforce null by default

# Account provisioning
ACCOUNT_PROVISIONING_RC_FILE=
ACCOUNT_PROVISIONING_OVERWRITE_ALL=

# Instance specific parameters
INSTANCE_COPYRIGHT= # Simple text displayed in the page footer
INSTANCE_INTRO_REGISTRATION= # Markdown text displayed in the home page
INSTANCE_CUSTOM_THEME=false
INSTANCE_CONFIRMED_REGISTRATION_TEXT= # Markdown text displayed when an account is confirmed

NEWSLETTER_REGISTRATION_ADDRESS= # Address to contact when a user wants to register to the newsletter
PUBLIC_REGISTRATION=true # Toggle to enable/disable the public registration forms
PHONE_AUTHENTICATION=true # Toggle to enable/disable the SMS support, requires public registration
DEVICES_MANAGEMENT=false # Toggle to enable/disable the devices management support

TERMS_OF_USE_URL= # A URL pointing to the Terms of Use
PRIVACY_POLICY_URL= # A URL pointing to the Privacy Policy

LOG_CHANNEL=stack

# External FlexiSIP database
# Ensure that you have the proper SELinux configuration to allow database connections, see the README
DB_DRIVER=mysql
DB_HOST=database_host
DB_PORT=3306
DB_DATABASE=flexisip
DB_USERNAME=flexisip
DB_PASSWORD=password

# Logs
# Ensure that you have the proper SELinux configuration to write in the storage directory, see the README
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=cookie
SESSION_LIFETIME=120

# SMTP and emails
# Ensure that you have the proper SELinux configuration to allow emails sending, see the README
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=xxxxxxxxxxxxxxxxxx
MAIL_PASSWORD=xxxxxxxxxxxxxxxxxx
MAIL_ENCRYPTION=tls
[email protected]
MAIL_FROM_NAME=xxxxxxxxxxxx
MAIL_ALLOW_SELF_SIGNED=false
MAIL_VERIFY_PEER=true
MAIL_VERIFY_PEER_NAME=true
MAIL_SIGNATURE="The xxxxx Team"
MAIL_ENCRYPTION=tls

# OVH SMS API variables
OVH_APP_KEY=
OVH_APP_SECRET=
OVH_APP_ENDPOINT=ovh-eu
OVH_APP_CONSUMER_KEY=
OVH_APP_SENDER=

# Google reCaptcha v2 parameters
NOCAPTCHA_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NOCAPTCHA_SITEKEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Flexisipに必要なテーブルを作成します。事前にphpからmysqlへ接続するドライバ拡張モジュール pdo_mysql をインストールします(これはphp-fpmイメージ作成時にインストールするようDockerfileに事前に記述しておきましょう)。
https://www.php.net/manual/en/ref.pdo-mysql.php

# docker-php-ext-install pdo_mysql

LaravelのArtisanコンソールによりテーブルを作成します。

# php artisan migrate

.envファイルで設定したURLにアクセスすると以下ページが表示されます。
なお、ユーザ登録を有効にするには、.envファイルの SMTP and emails(email認証する場合)OVH SMS API variables(SMS認証する場合) セクションの設定とreCAPTCHAの設定が必要です。

アカウント作成・管理ホーム画面

Email認証によるユーザ登録画面

注)500サーバエラーが表示された場合、flexiapiのアクセス権を見直すか、コンテナを再起動して下さい。

管理者ユーザの設定

登録した任意のユーザを管理者ユーザに設定します。
php-fpm-laravelコンテナ内で以下のLaravelphp artisan コマンドにより既存ユーザを管理者登録します。登録ユーザのIDを指定します。

$ dcoker exec -ti php-fpm-laravel bash
# php artisan accounts:set-admin USER_ID_NUMBER

php artisan ヘルプ

# php artisan --help

php artisan “accounts:set-admin” ヘルプ

# php artisan accounts:set-admin --help
Description:
  Give the admin role to an account

Usage:
  accounts:set-admin <id>

Arguments:
  id                    

管理者ユーザになることにより、他ユーザアカウントの管理・追加・編集権限が付与されます。

管理メニュー

ユーザアカウントリスト

ユーザアカウント

テーマのカスタマイズ

Custom theme

If you set INSTANCE_CUSTOM_THEME to true, FlexiAPI will try to load a CSS file located in public/css/$APP_ENV.style.css. If the file doesn’t exists it will fallback to public/css/style.css.

We advise you to copy the style.css file and rename it to make your custom CSS configurations for your instance.

エラーログ

log-directory=/var/opt/belledonne-communications/log/flexisip/flexisip-proxy+presence.log

①2021-10-28 07:58:52:100 flexisip-error-Cannot open domain registration configuration file '/etc/flexisip/domain-registrations.conf'
2021-10-28 09:18:30:677 bctbx-message-Starting flexisip proxy+presence-server version 2.1.0-beta-14-g0ba5e300
②2021-10-28 09:18:30:677 bctbx-error-setrlimit(RLIMIT_NOFILE) failed: Operation not permitted. Limit of number of file descriptors is low (1048576).
③2021-10-28 09:18:30:677 bctbx-error-Flexisip will not be able to process a big number of calls.
④2021-10-28 09:18:30:702 flexisip-error-DoSProtection: '/sbin/iptables -w -F FLEXISIP 2>&1' failed with output 'iptables: No chain/target/match by that name.
'.
⑤2021-10-28 09:18:30:705 flexisip-error-DoSProtection: '/sbin/ip6tables -w -F FLEXISIP 2>&1' failed with output 'ip6tables v1.8.4 (legacy): can't initialize ip6tables table `filter': Table does not exist (do you need to insmod?)
Perhaps ip6tables or your kernel needs to be upgraded.
'.
2021-10-28 09:18:30:709 flexisip-error-DoSProtection: '/sbin/ip6tables -w -N FLEXISIP 2>&1' failed with output 'ip6tables v1.8.4 (legacy): can't initialize ip6tables table `filter': Table does not exist (do you need to insmod?)
Perhaps ip6tables or your kernel needs to be upgraded.
'.
2021-10-28 09:18:30:715 flexisip-error-DoSProtection: '/sbin/ip6tables -w -t filter -A INPUT -j FLEXISIP 2>&1' failed with output 'ip6tables v1.8.4 (legacy): can't initialize ip6tables table `filter': Table does not exist (do you need to insmod?)
Perhaps ip6tables or your kernel needs to be upgraded.
'.

① flexisip-error-Cannot open domain registration

flexisip.conf [inter-domain-connections]
https://lists.gnu.org/archive/html/flexisip-developers/2018-06/msg00003.html

② ③ bctbx-error

setrlimit(RLIMIT_NOFILE) failed: Operation not permitted

解決。—> https://github.com/BelledonneCommunications/flexisip/blob/master/docker/flexisip-entrypoint.sh

起動スクリプトにulimit -c unlimitedを追加。
併せてDocker Composeファイルに下記のホストマシンへの制限付き管理者権限を付与。

    cap_add:
      - NET_ADMIN
      - SYS_RESOURCE

④ flexisip-error-DoSProtection

flexisip.conf [module::DoSProtection]
起動時のみのエラー。無視して構いません。

⑤ flexisip-error-DoSProtection

flexisip.conf [module::DoSProtection]

https://github.com/husarnet/docker-example/issues/1

flexisipコンテナ内で以下実行(またはDockerイメージ作成時に指定)

# update-alternatives --set ip6tables /usr/sbin/ip6tables-nft
# update-alternatives --set iptables /usr/sbin/iptables-nft

nftables Debian Wiki
https://wiki.debian.org/nftables

nftables Wiki
https://wiki.nftables.org/wiki-nftables/index.php/Moving_from_iptables_to_nftables

iptables関連のエラーについては、以下のDockerブリッジネットワークとiptablesの記事も参照のこと。

Firewall configuration

On a fresh RedHat or CentOS installation, the firewall is turned ON by default, with almost all ports forbidden. Flexisip won’t be able to operate at all under these conditions.

Simply turning off the firewall will allow full operation:

sudo systemctl stop firewalld

however your system administrator may not like this approach, and will prefer enabling selective ports. A Flexisip server will generally need:

  • the TCP ports for SIP/SIPS: these are the ports mentionned in the transports definition of global section of flexisip.conf ;
  • the 3478 UDP port for the builtin STUN server that helps clients to use ICE for efficient media stream transmissions ;
  • the media relay UDP ports, for the media relay service of Flexisip, which uses randomly selected ports in a configurable range.

ICE

MediaRelay

[module::Registrar]

# List of contact URI parameters that can be used to identify a
# user's device. The contact parameters are searched in the order
# of the list, the first matching parameter is used and the others
# ignored.
# Default: +sip.instance pn-tok line

unique-id-parameters=+sip.instance pn-tok line

+sip.instance

Mariadb カスタム設定

2021-11-01  8:22:18 67 [Warning] Aborted connection 67 to db: 'flexisip' user: 'flexisip' host: '172.16.0.6' (Got an error reading communication packets)
2021-11-01  8:22:18 66 [Warning] Aborted connection 66 to db: 'flexisip' user: 'flexisip' host: '172.16.0.6' (Got an error reading communication packets)
.....
.....

ベースとなる設定ファイルを下記コンテナ内からコピー。

$ docker cp flexisip-mariadb:/etc/mysql/mariadb.conf.d/50-server.cnf ./custom-server.cnf
[mysqld]

# copied from mariadb container /etc/mysql/mariadb.conf.d/50-server.cnf

key_buffer_size        = 64M
max_allowed_packet     = 128M
thread_stack           = 192K
thread_cache_size      = 8
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam_recover_options = BACKUP
max_connections        = 100
table_cache   

セッション確立時のネットステータス

2者間通話時:音声4ポート+映像4ポートで合計8個のUDPポート追加

CONNECTION ESTABLISHED

# netstat -antpu
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.11:38039        0.0.0.0:*               LISTEN      -                   
tcp        0      0 172.16.0.6:5060         0.0.0.0:*               LISTEN      8/flexisip          
tcp        0      0 172.16.0.6:5061         0.0.0.0:*               LISTEN      8/flexisip          
tcp        0      0 127.0.0.1:5065          0.0.0.0:*               LISTEN      8/flexisip          
tcp        0      0 172.16.0.6:5061         133.106.245.48:40072    ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57206        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
tcp        0      0 172.16.0.6:5061         219.100.37.241:38951    ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57202        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
tcp        0      0 172.16.0.6:5060         172.16.0.1:57088        ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57174        172.16.0.5:3306         ESTABLISHED 8/flexisip          
        
tcp        0      0 127.0.0.1:5065          172.16.0.6:45429        ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57214        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
tcp        0      0 172.16.0.6:60390        172.16.0.2:6379         ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57190        172.16.0.5:3306         ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:45716        192.168.1.137:5060      ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57192        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
tcp        0      0 172.16.0.6:60392        172.16.0.2:6379         ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57234        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
tcp        0      0 172.16.0.6:45429        127.0.0.1:5065          ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57228        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
udp        0      0 0.0.0.0:10012           0.0.0.0:*                           8/flexisip          
udp        0      0 0.0.0.0:10013           0.0.0.0:*                           8/flexisip          
udp        0      0 0.0.0.0:10014           0.0.0.0:*                           8/flexisip          
udp        0      0 0.0.0.0:10015           0.0.0.0:*                           8/flexisip          
udp        0      0 0.0.0.0:10016           0.0.0.0:*                           8/flexisip          
udp        0      0 0.0.0.0:10017           0.0.0.0:*                           8/flexisip          
udp        0      0 0.0.0.0:10028           0.0.0.0:*                           8/flexisip          
udp        0      0 0.0.0.0:10029           0.0.0.0:*                           8/flexisip          
udp        0      0 0.0.0.0:3478            0.0.0.0:*                           8/flexisip          
udp        0      0 127.0.0.11:45242        0.0.0.0:*                           -                   
udp        0      0 172.16.0.6:5060         0.0.0.0:*                           8/flexisip         

DISCONNECTION

# netstat -antpu
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.11:38039        0.0.0.0:*               LISTEN      -                   
tcp        0      0 172.16.0.6:5060         0.0.0.0:*               LISTEN      8/flexisip          
tcp        0      0 172.16.0.6:5061         0.0.0.0:*               LISTEN      8/flexisip          
tcp        0      0 127.0.0.1:5065          0.0.0.0:*               LISTEN      8/flexisip          
tcp        0      0 172.16.0.6:5061         133.106.245.48:40072    ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57206        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
tcp        0      0 172.16.0.6:5061         219.100.37.241:38951    ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57202        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
tcp        0      0 172.16.0.6:5060         172.16.0.1:57088        ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57174        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
tcp        0      0 127.0.0.1:5065          172.16.0.6:45429        ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57214        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
tcp        0      0 172.16.0.6:60390        172.16.0.2:6379         ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57190        172.16.0.5:3306         ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:45716        192.168.1.137:5060      ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57192        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
tcp        0      0 172.16.0.6:60392        172.16.0.2:6379         ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57234        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
tcp        0      0 172.16.0.6:45429        127.0.0.1:5065          ESTABLISHED 8/flexisip          
tcp        0      0 172.16.0.6:57228        172.16.0.5:3306         ESTABLISHED 8/flexisip          
         
udp        0      0 0.0.0.0:3478            0.0.0.0:*                           8/flexisip          
udp        0      0 127.0.0.11:45242        0.0.0.0:*                           -                   
udp        0      0 172.16.0.6:5060         0.0.0.0:*                           8/flexisip         

プロビジョニングによるユーザアカウントの読み込み

読み込まれるユーザアカウントの例

LinphoneのアシスタントメニューからQRコードまたは下記アドレスを指定して読み込み。

https://www.linphone.org/remote_provisioning.xml


<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://www.linphone.org/xsds/lpconfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.linphone.org/xsds/lpconfig.xsd lpconfig.xsd">
  <section name="sip">
    <entry name="default_proxy" overwrite="true">0</entry>
  </section>
  <section name="net">
    <entry name="nat_policy_ref" overwrite="true">~OuCpkaPzCwyvMo</entry>
  </section>
  <section name="misc">
    <entry name="transient_provisioning" overwrite="true">1</entry> <!-- apply remote provisioning only once-->
  </section>
  <section name="nat_policy_default_values">
    <entry name="stun_server">stun.linphone.org</entry>
    <entry name="protocols">stun,ice</entry>
  </section>
  <section name="nat_policy_0">
    <entry name="ref" overwrite="true">~OuCpkaPzCwyvMo</entry>
    <entry name="stun_server" overwrite="true">stun.linphone.org</entry>
    <entry name="protocols" overwrite="true">stun,ice</entry>
  </section>
  <section name="auth_info_0" overwrite="true">
    <entry name="username" overwrite="true">bilbo.baggins</entry>
    <entry name="ha1" overwrite="true">7f37aeccfad9855e4584c5465d6b4638</entry>
    <entry name="realm" overwrite="true">sip.linphone.org</entry>
    <entry name="domain" overwrite="true">sip.linphone.org</entry>
    <entry name="algorithm" overwrite="true">MD5</entry>
  </section>
  <section name="proxy_0" overwrite="true">
    <entry name="reg_proxy" overwrite="true">&lt;sip:sip.linphone.org;transport=tls&gt;</entry>
    <entry name="reg_route" overwrite="true">&lt;sip:sip.linphone.org;transport=tls&gt;</entry>
    <entry name="reg_identity" overwrite="true">"Bilbo Baggins" &lt;sip:[email protected]&gt;</entry>
    <entry name="realm" overwrite="true">sip.linphone.org</entry>
    <entry name="quality_reporting_collector" overwrite="true">sip:[email protected];transport=tls</entry>
    <entry name="quality_reporting_enabled" overwrite="true">1</entry>
    <entry name="quality_reporting_interval" overwrite="true">180</entry>
    <entry name="reg_expires" overwrite="true">31536000</entry>
    <entry name="reg_sendregister" overwrite="true">1</entry>
    <entry name="publish" overwrite="true">1</entry>
    <entry name="avpf" overwrite="true">1</entry>
    <entry name="avpf_rr_interval" overwrite="true">1</entry>
    <entry name="nat_policy_ref" overwrite="true">~OuCpkaPzCwyvMo</entry>
  </section>
</config>

プロビジョニングによるLinphone設定ファイルの読み込み

Linphoneアプリの標準設定ファイルは以下から入手可能。これをカスタマイズして読み込ませることでデフォルト設定が上書きされるかどうか検証中。
flexisipにSTUNサーバ(ICE)を指定する場合、以下のファイルを編集して読み込ませないと設定は反映されないようです。

GitHub : Flexisip + Account Manager on Ubuntu 20.04

以下GitHubに関連ファイルをアップロード。一部設定ファイルなどはセキュリティ上割愛。docker-composeファイルのコメント欄を一読願います。