オンライン学習・ビデオ会議システム BigBlueButton on Docker (導入メモ)

Ubuntu18.04BigBlueButton Version2.3の開発版で構築中。本記事は構築メモと捉えて下さい。正常動作確認後別記事で纏めます。

:warning: v2.4の最新版が公開されたため、あくまで参考として閲覧願います。v2.4についての投稿は以下参照願います。

Jitsiと同様、会議システムですが、遠隔教育システムとして利用されています。
Dockerによりシステム構築します。

BigBlueButon

STUNサーバリスト(参考)

Docker

Architecture

https://docs.bigbluebutton.org/2.2/architecture.html

BigBlueButtonとは、以下のブロック図による各コンポーネントを一纏めにした会議システムです。各コンポーネントを統括する司令塔は、非同期で並列処理を実行するアクターモデルによるプログラミング言語ScalaとそのツールキットであるAkkaにより作成されたアプリである bbb-apps-akka( + akka-fsesl ) が担います。

以下bbb-confスクリプトの起動時または停止時のスクリプトからも、各コンポーネントの確認ができます。

ブロック図に示した各コンポーネント毎にコンテナを配備する方法とは別に、一つのOSコンテナ(ubuntu18.04:ver2.3)に纏めてインストールしたい場合は以下を参照願います。

手軽に構築できます。とにかく動作を確認したい、試験的に運用したい方向けです。

https://github.com/bigbluebutton/docker/tree/v2.3.x

各コンポーネント毎にコンテナを配備する場合は下記フォークされたレポジトリを推奨します。

bbb-webrtc-sfu

bbb-webrtc-sfuは別レポジトリとなっているため、以下クローン後にイメージをビルド

$ docker build -t bbb-webrtc-sfu .

Kurento dockerイメージのビルド

kurento-media-server

以下 Dockerfile 内の Build arguments を参照して新規イメージをビルド。

# Build arguments
# ---------------
#
# --build-arg UBUNTU_CODENAME=<UbuntuCodename>
#
#   <UbuntuCodename> is like "xenial", "bionic", etc.
#
#   Optional. Default: "xenial".
#
# --build-arg KMS_VERSION=<KmsVersion>
#
#   <KmsVersion> is like "6.7.2", "6.9.0", etc.
#   Alternatively, "dev" is used to build a nightly version of KMS.
#
#   Optional. Default: "dev".
#
#

オプションとして、 Ubuntu:bionic(18.04) ベース、バージョン 6.14.0 を指定してビルド。

$ docker build --tag kurento/kurento-media-server:6.14.0 --build-arg UBUNTU_CODENAME="bionic" --build-arg KMS_VERSION="6.14.0" .

このイメージをベースにbbb-kurentoイメージをビルド

Dockerfile

FROM kurento/kurento-media-server:6.14.0

$ cd labs/docker/kurento/
$ docker build -t bbb-kurento .

<参考>
Kurento設定ファイル、機能拡張設定ファイル、STUNサーバ設定など
https://kurento.readthedocs.io/en/stable/doc/admin_guide.html#installation

  • /etc/kurento/kurento.conf.json: The main Kurento Media Server configuration file
  • /etc/kurento/modules/kurento/MediaElement.conf.ini: Generic parameters for Media Elements.
  • /etc/kurento/modules/kurento/SdpEndpoint.conf.ini: Audio/video parameters for SdpEndpoints (i.e. WebRtcEndpoint and RtpEndpoint).
  • /etc/kurento/modules/kurento/WebRtcEndpoint.conf.ini: Specific parameters for WebRtcEndpoint.
  • /etc/kurento/modules/kurento/HttpEndpoint.conf.ini: Specific parameters for HttpEndpoint.

STUNサーバによりポートの割当が適宜行われるため、ポートオプションにより予め必要なポートレンジは確保しないこと(メモリーオーバフロー対策)。

ポートの割当が多くなるとコンテナによるメモリー負荷が増えるため、ネットワークモードはホストとするか、レンジを小さく設定すること。

iptablesによりポートフォワードを利用する方法がベスト。FreeSWITCH<ポート割当ヒント> 参照のこと。

Why host networking?

Check your installation

$ sudo netstat -tupln | grep -e kurento -e 8888
tcp6  0  0  :::8888  :::*  LISTEN  7688/kurento-media-
$ curl \
  --include \
  --header "Connection: Upgrade" \
  --header "Upgrade: websocket" \
  --header "Host: 127.0.0.1:8888" \
  --header "Origin: 127.0.0.1" \
  http://127.0.0.1:8888/kurento

HTTP/1.1 500 Internal Server Error
Server: WebSocket++/0.7.0

Server Errorは無視して構いません。

BigBlueButton on Docker に必要な新規作成したイメージファイル一覧

REPOSITORY                                    TAG                  IMAGE ID            CREATED             SIZE
bbb-coturn                                    latest               8add43c854f8        19 hours ago        92.8MB
bbb-webhooks                                  latest               8610d7753621        2 days ago          161MB
bbb-html5                                     latest               439daac50083        2 days ago          4.9GB
node                                          12-slim              544e10fd4863        2 days ago          142MB
bbb-web                                       latest               2c4bf867271b        5 days ago          2.08GB
bbb-nginx                                     latest               42a7f92d54e0        9 days ago          133MB
bbb-freeswitch                                latest               68cd11a3e2ea        13 days ago         613MB
bbb-webrtc-sfu                                latest               0c5047c1ada8        2 weeks ago         995MB
redis                                         6.0-bionic           4547a49212e6        3 weeks ago         94.3MB
mongo                                         4.2-bionic           f57898cf435c        3 weeks ago         388MB
bbb-lti                                       latest               15f6b7a57389        3 weeks ago         504MB
bbb-kurento                                   latest               5761d94dec46        3 weeks ago         792MB
kurento/kurento-media-server                  6.14.0               dcced31b05df        3 weeks ago         716MB
bigbluebutton/greenlight                      v2                   08ae3c304ddc        3 weeks ago         286MB
bbb-fsesl-akka                                latest               4659696111a4        3 weeks ago         388MB
bbb-apps-akka                                 latest               5ca10ae678e4        3 weeks ago         390MB
bbb-fsesl-client                              latest               f1dc1bc1b3cb        3 weeks ago         1.18GB
bbb-common-web                                latest               1c45577365a7        3 weeks ago         1.28GB
bbb-common-message                            latest               18cb41e0d64e        3 weeks ago         1.13GB
sbt                                           1.2.8                8716b05626d5        3 weeks ago         608MB
ubuntu                                        bionic               6526a1858e5d        4 weeks ago         64.2MB
postgres                                      9.5                  a4924338843c        5 weeks ago         196MB
nginx                                         latest               4bb46517cac3        5 weeks ago         133MB
node                                          12                   cfcf3e70099d        6 weeks ago         917MB
openjdk                                       8                    5684f3366a1f        6 weeks ago         511MB

Mongo Dockerイメージファイル作成

$ git clone https://github.com/docker-library/mongo.git
$ cd mongo/4.2
$ docker build --tag mongo:4.2-bionic .

Redis Dockerイメージファイル作成

$ git clone https://github.com/docker-library/redis.git
$ cd redis/6.0

DockerfileのベースOSをUbuntu:bionic(18.04)へ変更してビルド

FROM ubuntu:bionic

$ docker build --tag redis:6.0-bionic .

.envファイルの作成

TURN_DOMAIN=<turn domain>
TURN_PORT=443
TURN_SECRET=<Please produce it by openssh rand command >
SERVER_DOMAIN=<server domain>
SHARED_SECRET=<Please produce it by openssh rand command >

# Stun Server Global IP
EXTERNAL_IP=xx.xx.xx.xx

# Nginx Reverse Proxy Local IP
SERVER_LOCAL_IP=192.168.x.xxx

SCREENSHARE_EXTENSION_KEY=akgoaoikmbmhcopjgakkcepdgdgkjfbc
SCREENSHARE_EXTENSION_LINK=https://chrome.google.com/webstore/detail/bigbluebutton-screenshare/akgoaoikmbmhcopjgakkcepdgdgkjfbc
POSTGRES_DB=<db_name>
POSTGRES_USER=<db_user>
POSTGRES_PASSWORD=<db_password>

STUNサーバドメインとサーバドメインを指定して下さい。
TURN_SECRET, SHARED_SECRETについては、以下opensslコマンド(コマンドオプションは任意)で作成します。

$ openssl rand -hex 16
911d53c0a899fd26d596c505394b2ce8

Docker-Composeファイル

${xxxxxx} 変数は .env ファイルにより指定。 コンテナ外のNginxリバースプロキシから直接ルーティング。

version: '3.5'

services:
  mongo:
    image: mongo:4.2-bionic
    restart: unless-stopped
    networks:
      - bbb-network

  redis:
    image: redis:6.0-bionic
    restart: unless-stopped
    networks:
      - bbb-network

  bbb-html5:
    image: bbb-html5:latest
    restart: unless-stopped
    depends_on:
      - mongo
      - redis
    environment:
      MONGO_URL: mongodb://mongo:27017/bbbhtml5
#      MONGO_URL: mongodb://mongo:27017/html5client
      METEOR_SETTINGS_MODIFIER: ".public.kurento.wsUrl = \"wss://${SERVER_DOMAIN}/bbb-webrtc-sfu\" | .public.kurento.enableVideo = true | .public.kurento.enableScreensharing = true | .public.kurento.chromeDefaultExtensionKey = \"${SCREENSHARE_EXTENSION_KEY}\" | .public.kurento.chromeDefaultExtensionLink = \"${SCREENSHARE_EXTENSION_LINK}\" | .public.kurento.enableVideoStats = true | .public.kurento.enableListenOnly = true"
      REDIS_HOST: redis
      ROOT_URL: http://127.0.0.1/html5client
#      ROOT_URL: https://${SERVER_DOMAIN}/html5client
    extra_hosts:
      - ${SERVER_DOMAIN}:${SERVER_LOCAL_IP}
    ports:
      - 3000:3000
    networks:
      - bbb-network

  bbb-webhooks:
    image: bbb-webhooks:latest
    restart: unless-stopped
    depends_on:
      - redis
    environment:
      REDIS_HOST: redis
      SHARED_SECRET: ${SHARED_SECRET}
      BEARER_AUTH: 1
      SERVER_DOMAIN: ${SERVER_DOMAIN}
    extra_hosts:
      - ${SERVER_DOMAIN}:${SERVER_LOCAL_IP}
    networks:
      - bbb-network

  bbb-freeswitch:
    image: bbb-freeswitch:latest
    restart: unless-stopped
    depends_on:
      - coturn
    expose: 
      - 8021
    ports:
      - 7443:7443
    extra_hosts:
      - ${SERVER_DOMAIN}:${SERVER_LOCAL_IP}
    volumes:
      - ./media-audio:/var/freeswitch/meetings
    networks:
      - bbb-network

  bbb-webrtc-sfu:
    image: bbb-webrtc-sfu:latest
    restart: unless-stopped
    depends_on:
      - redis
      - kurento
      - bbb-freeswitch
    expose:
      - 3010
    ports:
      - 3008:3008
#   defined bbb/webrtc-sfu/config/default.example.yml
    environment:
#      KURENTO_NAME: kurento
      KURENTO_URL: ws://kurento:8888/kurento
      REDIS_HOST: redis
      FREESWITCH_CONN_IP: bbb-freeswitch
      LOG_LEVEL: debug
    extra_hosts:
      - ${SERVER_DOMAIN}:${SERVER_LOCAL_IP}
    networks:
      - bbb-network

  coturn:
    image: bbb-coturn:latest
    restart: unless-stopped
    environment:
      TURN_DOMAIN: ${TURN_DOMAIN}
#     TURN_PORT: 443
      TURN_PORT: ${TURN_PORT}
      SECRET: ${TURN_SECRET}
      EXTERNAL_IP: ${EXTERNAL_IP}
      ENABLE_REST_API: 1
      PORT: 3478
    networks:
      - bbb-network
#        aliases: 
#          - ${TURN_DOMAIN}

  kurento:
    image: bbb-kurento:latest
    restart: unless-stopped
    volumes:
      - ./media-video:/var/kurento/recordings
      - ./media-screenshare:/var/kurento/screenshare
    environment:
      STUN_IP: ${EXTERNAL_IP}
      STUN_PORT: ${TURN_PORT}
    networks:
      - bbb-network

  bbb-apps-akka:
    image: bbb-apps-akka:latest
    restart: unless-stopped
    depends_on:
      - redis
    environment:
      JAVA_OPTS: -Dredis.host=redis
    networks:
      - bbb-network

  bbb-fsesl-akka:
    image: bbb-fsesl-akka:latest
    restart: unless-stopped
    depends_on:
      - bbb-freeswitch
      - redis
#    command: ["wait-for-it.sh", "bbb-freeswitch:8021", "--timeout=60", "--strict", "--", "/usr/share/bbb-fsesl-akka/bin/bbb-fsesl-akka"]
    command: bash -c "cd /usr/share/bbb-fsesl-akka/ && wait-for-it.sh bbb-freeswitch:8021 --timeout=60 --strict -- /usr/share/bbb-fsesl-akka/bin/bbb-fsesl-akka"
    environment:
      JAVA_OPTS: -Dredis.host=redis -Dfreeswitch.esl.host=bbb-freeswitch
    networks:
      - bbb-network

  bbb-web:
    image: bbb-web:latest
    restart: unless-stopped
    depends_on:
      - redis
    volumes:
      - ./bigbluebutton:/var/bigbluebutton
    environment:
      SERVER_DOMAIN: ${SERVER_DOMAIN}
      SHARED_SECRET: ${SHARED_SECRET}
      TURN_DOMAIN: ${TURN_DOMAIN}
      TURN_PORT: ${TURN_PORT}
      TURN_SECRET: ${TURN_SECRET}
    ports: 
      - 8090:8090
    networks:
      - bbb-network

  bbb-greenlight:
    image: bigbluebutton/greenlight:v2
    restart: unless-stopped
    depends_on:
      - gl-db
    volumes:
      - ./greenlight_logs:/usr/src/app/log
      - ./greenlight_db:/usr/src/app/storage
    env_file:
      - .env
      - greenlight.env
    extra_hosts:
      - ${SERVER_DOMAIN}:${SERVER_LOCAL_IP}
    ports:
      - 80:80
    networks:
      - bbb-network

  gl-db:
    image: postgres:9.5
    restart: unless-stopped
    expose:
      - 5432
    volumes:
      - ./db/production:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    networks:
      - bbb-network

networks:
  bbb-network:

Greenlight Dockerイメージファイルの作成

docke-composeコマンドによる各コンテナ起動前に、BigBlueButtonのウェブインターフェイスであるGreenlightのイメージファイルも事前に作成しておきましょう。

Github

DockerHub
https://hub.docker.com/r/bigbluebutton/greenlight/tags

$ git clone -b v2 --single-branch https://github.com/bigbluebutton/greenlight.git
$ cd greenlight
$ docker build -t bigbluebutton/greenlight:v2 .

コンテナ内でドメインの名前解決が出来ない問題が発生した場合

名前解決出来ているかどうか、以下コマンドまたは curl コマンドでチェックします。

# bundle exec rake conf:check
Checking environment: Passed
Checking Connection: Failed
Error connecting to BigBlueButton server - Failed to open TCP connection to www.your-domain.com:443 (Connection refused - connect(2) for "www.your-domain.com" port 443)

エラーが発生した場合、コンテナ内で /etc/hosts にドメインに対応したサーバのローカルIPを追加します。

$ docker exec -ti  docker_bbb-greenlight_1 bash

# vi /etc/hosts
192.168.xx.xx www.your-domain.com

再度上記チェックコマンドで確認して下さい。

上記は、docker-compose ファイルで、以下の extra_hosts セクションを追加することと同義です。

Greenlight専用の環境変数ファイルgreenright.envを、下記サンプルファイルを雛形に新規作成してdocker-composeファイルで指定します。

FreeSWITCH

Github

Dockerfileに以下PostgreSQL関連ライブラリのインストールを追加すること。

mod_spandsp

$ docker exec -ti docker_bbb-freeswitch_1 bash
# apt update
# apt install libtiff5-dev

PostgreSQL in the core

$ docker exec -ti docker_bbb-freeswitch_1 bash
# apt-get install libpq-dev

<ポート割当ヒント>

https://hub.docker.com/r/bettervoice/freeswitch-container/

Running the Container
CID=$(sudo docker run --name freeswitch -p 5060:5060/tcp -p 5060:5060/udp -p 5080:5080/tcp -p 5080:5080/udp -p 8021:8021/tcp -p 7443:7443/tcp -p 60535-65535:60535-65535/udp -v /home/ubuntu/freeswitch/conf:/usr/local/freeswitch/conf bettervoice/freeswitch-container:1.6.6)

Keep in mind that freeswitch has to be able to read the mounted volume.

Large port range issue
Because of an issue in docker, mapping a large port range like in -p 60535-65535:60535-65535/udp can eat a lot of memory. Starting docker with --userland-proxy=false solves this partially, but startup will still be slow. As a workaround you can remove this from the docker commandline and manually add the iptables rules instead:

CIP=$(sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' $CID)

$ sudo iptables -A DOCKER -t nat -p udp -m udp ! -i docker0 --dport 60535:65535 -j DNAT --to-destination $CIP:60535-65535
$ sudo iptables -A DOCKER -p udp -m udp -d $CIP/32 ! -i docker0 -o docker0 --dport 60535:65535 -j ACCEPT
$ sudo iptables -A POSTROUTING -t nat -p udp -m udp -s $CIP/32 -d $CIP/32 --dport 60535:65535 -j MASQUERADE

Etherpad

https://etherpad.org/

Shared Secret Keyの変更

https://docs.bigbluebutton.org/2.2/customize.html#change-the-shared-secret

In bbb-web container

/usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties

beans.dynamicConferenceService.securitySalt=<value_of_salt>

以下サイトでUUID(Universal Unique ID)を作成

DockerコンテナNginxリバースプロキシーによるSSL接続エラーのヒント

アドミンユーザホーム画面

エラー:ブルースクリーン

参照:ブルースクリーンエラー

bbb-html5 v2.3-α2

設定ファイル(コンテナ内)

# /app/bundle/programs/server/assets/app/config/settings.yml

Coturn: Stun/Turn Server

Session Traversal Utilities for NAT (STUN)
音声・ビデオ通話する際、LAN内に配備されたユーザ双方のグローバルIPを特定するために使用されます。ユーザ双方のIP特定後、データは直接遣り取りされます。

Traversal Using Relay around NAT (TURN)
上記データの直接の遣り取りが許可されない場合、TURNサーバを仲介役にデータを遣り取りします。

Network address translation ( NAT )

STUNサーバ確認用クライアントstun-clientによる動作確認

$ sudo apt-get install stun-client
$ stun 172.217.212.127:19302
STUN client version 0.97
Primary: Open
Return value is 0x000001

STUN/TURNサーバ動作確認サイト

/etc/turnserver.conf

listening-port={{ .Env.PORT }}
tls-listening-port={{ .Env.TURN_PORT }}

# Fingerprints in TURN messages are required for WebRTC
fingerprint

# The long-term credential mechanism is required for WebRTC
lt-cred-mech

use-auth-secret
static-auth-secret={{ .Env.TURN_SECRET }}

# If the realm value is unspecified, it defaults to the TURN server hostname.
# You probably want to configure it to a domain name that you control to
# improve log output. There is no functional impact.
realm={{ .Env.TURN_DOMAIN }}

# Configure TLS support.
# Adjust these paths to match the locations of your certificate files

#cert=/etc/letsencrypt/live/ssl/fullchain.pem
#pkey=/etc/letsencrypt/live/ssl/privkey.pem

# Limit the allowed ciphers to improve security
# Based on https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
cipher-list="ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS:!AESCCM;"

# Enable longer DH TLS key to improve security
dh2066

# All WebRTC-compatible web browsers support TLS 1.2 or later, so disable
# older protocols
no-tlsv1
no-tlsv1_1

# Log to a single filename (rather than new log files each startup). You'll
# want to install a logrotate configuration (see below)
log-file=/var/log/coturn.log

Ubuntu18.04ベース開発版変更点

2.3以降flash関連アプリ、red5等を削除。

akka-bbb-transcode
bbb-apps-common
bbb-client-check
bbb-screenshare
bbb-video
bbb-voice
bigbluebutton-apps
bigbluebutton-client
clients/flash
deskshare
video-broadcast
scripts
web-polling
labs/applet-jni
labs/bbb-deskshare-installer
labs/bbb-deskshare-udp
labs/webminer

BigBlueButton API

https://docs.bigbluebutton.org/dev/api.html#overview

.envファイルまたはdocker-composeファイルで指定

https://hostname/bigbluebutton/api

Configure BigBluebutton/FreeSWITCH to support IPV6

AppleのiOS端末との接続にはIPv6が必須のため、FreeSwitchのWeb Socketへの接続もIPv6に対応する必要があります。

https://docs.bigbluebutton.org/install#configure-bigbluebuttonfreeswitch-to-support-ipv6

Nginxの設定ファイル /etc/nginx/conf.d/bigbluebutton_sip_addr_map.conf またはデフォルトファイルの先頭に以下を追加します。

map $remote_addr $freeswitch_addr {
    "~:"    [2001:db8::1];
    default    192.0.2.1;
}

192.0.2.12001:db8::1 をIPv4、IPv6のグローバルアドレスへ置換えます。

NginxFreeSwith(SIP) 設定オプションファイル /etc/bigbluebutton/nginx/sip.nginx を以下のようにします。

location /ws {
        proxy_pass https://$freeswitch_addr:7443;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Ssl on; 
        proxy_read_timeout 6h;
        proxy_send_timeout 6h;
        client_body_timeout 6h;
        send_timeout 6h;
        
        auth_request /bigbluebutton/connection/checkAuthorization;
        auth_request_set $auth_status $upstream_status;
}

sip_profiles/external-ipv6.xml の各パラメータも確認して下さい。

<profile name="external-ipv6">
  <!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
  <!-- This profile is only for outbound registrations to providers -->
  <gateways>
    <X-PRE-PROCESS cmd="include" data="external-ipv6/*.xml"/>
  </gateways>

  <aliases>
    <!--
        <alias name="outbound"/>
        <alias name="nat"/>
    -->
  </aliases>

  <domains>
    <!--<domain name="all" alias="false" parse="true"/>-->
  </domains>

  <settings>
    <param name="debug" value="0"/>
    <!-- If you want FreeSWITCH to shutdown if this profile fails to load, uncomment the next line. -->
    <!-- <param name="shutdown-on-fail" value="true"/> -->
    <param name="sip-trace" value="no"/>
    <param name="sip-capture" value="no"/>
    <param name="rfc2833-pt" value="101"/>
    <!-- RFC 5626 : Send reg-id and sip.instance -->
    <!--<param name="enable-rfc-5626" value="true"/> -->
    <param name="sip-port" value="$${external_sip_port}"/>
    <param name="dialplan" value="XML"/>
    <param name="context" value="public"/>
    <param name="dtmf-duration" value="2000"/>
    <param name="inbound-codec-prefs" value="$${global_codec_prefs}"/>
    <param name="outbound-codec-prefs" value="$${outbound_codec_prefs}"/>
    <param name="hold-music" value="$${hold_music}"/>
    <param name="rtp-timer-name" value="soft"/>
    <!--<param name="enable-100rel" value="true"/>-->
    <!--<param name="disable-srv503" value="true"/>-->
    <!-- This could be set to "passive" -->
    <param name="local-network-acl" value="localnet.auto"/>
    <param name="manage-presence" value="false"/>

    <!-- Added for Microsoft Edge support 
    <param name="apply-candidate-acl" value="wan_v6.auto"/>
    <param name="apply-candidate-acl" value="rfc1918.auto"/>
    <param name="apply-candidate-acl" value="any_v6.auto"/>
    <param name="apply-candidate-acl" value="wan_v4.auto"/>
    <param name="apply-candidate-acl" value="any_v4.auto"/>
    -->
    <param name="apply-candidate-acl" value="deny_private_v6"/>

    <!-- used to share presence info across sofia profiles
         manage-presence needs to be set to passive on this profile
         if you want it to behave as if it were the internal profile
         for presence.
    -->
    <!-- Name of the db to use for this profile -->
    <!--<param name="dbname" value="share_presence"/>-->
    <!--<param name="presence-hosts" value="$${domain}"/>-->
    <!--<param name="force-register-domain" value="$${domain}"/>-->
    <!--all inbound reg will stored in the db using this domain -->
    <!--<param name="force-register-db-domain" value="$${domain}"/>-->
    <!-- ************************************************* -->

    <!--<param name="aggressive-nat-detection" value="true"/>-->
    <param name="inbound-codec-negotiation" value="generous"/>
    <param name="nonce-ttl" value="60"/>
    <param name="auth-calls" value="false"/>
    <param name="inbound-late-negotiation" value="true"/>
    <param name="inbound-zrtp-passthru" value="true"/> <!-- (also enables late negotiation) -->
    <!--
        DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
    -->
    <param name="rtp-ip" value="$${external_ip_v6}"/>
    <param name="sip-ip" value="$${local_ip_v6}"/>
    <!-- Shouldn't set these on IPv6 -->
    <!--<param name="ext-rtp-ip" value="auto-nat"/>-->
    <!--<param name="ext-sip-ip" value="auto-nat"/>-->
    <param name="rtp-timeout-sec" value="300"/>
    <param name="rtp-hold-timeout-sec" value="1800"/>
    <!--<param name="enable-3pcc" value="true"/>-->

    <!-- TLS: disabled by default, set to "true" to enable -->
    <param name="tls" value="$${external_ssl_enable}"/>
    <!-- Set to true to not bind on the normal sip-port but only on the TLS port -->
    <param name="tls-only" value="false"/>
    <!-- additional bind parameters for TLS -->
    <param name="tls-bind-params" value="transport=tls"/>
    <!-- Port to listen on for TLS requests. (5081 will be used if unspecified) -->
    <param name="tls-sip-port" value="$${external_tls_port}"/>
    <!-- Location of the agent.pem and cafile.pem ssl certificates (needed for TLS server) -->
    <!--<param name="tls-cert-dir" value=""/>-->
    <!-- Optionally set the passphrase password used by openSSL to encrypt/decrypt TLS private key files -->
    <param name="tls-passphrase" value=""/>
    <!-- Verify the date on TLS certificates -->
    <param name="tls-verify-date" value="true"/>
    <!-- TLS verify policy, when registering/inviting gateways with other servers (outbound) or handling inbound registration/invite requests how should we verify their certificate -->
    <!-- set to 'in' to only verify incoming connections, 'out' to only verify outgoing connections, 'all' to verify all connections, also 'subjects_in', 'subjects_out' and 'subjects_all' for subject validation. Multiple policies can be split with a '|' pipe -->
    <param name="tls-verify-policy" value="none"/>
    <!-- Certificate max verify depth to use for validating peer TLS certificates when the verify policy is not none -->
    <param name="tls-verify-depth" value="2"/>
    <!-- If the tls-verify-policy is set to subjects_all or subjects_in this sets which subjects are allowed, multiple subjects can be split with a '|' pipe -->
    <param name="tls-verify-in-subjects" value=""/>
    <!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
    <param name="tls-version" value="$${sip_tls_version}"/>
    <param name="ws-binding" value=":5066"/>
    <param name="wss-binding" value=":7443"/>
    <param name="rtcp-audio-interval-msec" value="5000"/>
    <param name="rtcp-video-interval-msec" value="5000"/>
    <param name="dtmf-type" value="info"/>
    <param name="liberal-dtmf" value="true"/>
  </settings>
</profile>

各コンポーネント設定ファイル(Debian)

BigBlueButton FreeSwitchコアソース

$ apt-get install -y software-properties-common
$ add-apt-repository -y ppa:bigbluebutton/support
$ apt-get install -y libopusfile-dev opus-tools libopusenc-dev
$ git clone https://github.com/signalwire/freeswitch.git
$ git fetch --tags
$ git checkout v1.10.2
$ ./bootstrap.sh
$ ./configure --disable-core-odbc-support --disable-core-pgsql-support \
    --without-python --without-erlang --without-java \
    --prefix=/opt/freeswitch CFLAGS="-Wno-error -Og -ggdb" CXXFLAGS="-Wno-error -Og -ggdb"
$ make install

FreeSwitchのDockerfile

FreeSwitchをソースからコンパイルする場合、以下のDockerfileを作成してコンテナを稼働して下さい。

FROM debian:buster-slim
# Build from source
RUN apt-get update && \ 
apt-get install -yq subversion gnupg2 wget lsb-release ca-certificates iptables && \
wget -O - https://files.freeswitch.org/repo/deb/debian-release/fsstretch-archive-keyring.asc | apt-key add - && \
echo "deb http://files.freeswitch.org/repo/deb/debian-release/ `lsb_release -sc` main" > /etc/apt/sources.list.d/freeswitch.list && \
echo "deb-src http://files.freeswitch.org/repo/deb/debian-release/ `lsb_release -sc` main" >> /etc/apt/sources.list.d/freeswitch.list

# jre installation require man folder これは FROMに -slim 版を選択しなければ不要
RUN mkdir -p /usr/share/man/man1

RUN apt-get update && \
# Install dependencies required for the build
apt-get -y build-dep freeswitch
  
# then let's get the source. Use the -b flag to get a specific branch
RUN cd /usr/src/ && \
git clone https://github.com/signalwire/freeswitch.git -b v1.10.5 freeswitch && \
cd freeswitch && \
# Because we're in a branch that will go through many rebases, it's
# better to set this one, or you'll get CONFLICTS when pulling (update).
git config pull.rebase true && \
  
# ... and do the build
./bootstrap.sh -j && \
./configure --disable-core-odbc-support --disable-core-pgsql-support \
    --without-python --without-erlang --without-java \
    --prefix=/opt/freeswitch CFLAGS="-Wno-error -Og -ggdb" CXXFLAGS="-Wno-error -Og -ggdb" && \
make && make install

# install dockerize
ENV DOCKERIZE_VERSION v0.6.1
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
    && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
    && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz

# -- get official bbb freeswitch config
# we use svn for retrieving the files since the repo is quite large,
# git sparse-checkout is not yet available with buster and there
# is no other sane way of downloading a single directory via git
ENV GIT_TAG v2.2.9-freeswitch
RUN cd /opt/freeswitch/etc \
    && svn checkout https://github.com/alangecker/bbb-packages/tags/$GIT_TAG/bbb-freeswitch-core/data/opt/freeswitch/etc/freeswitch \
    && rm -rf /opt/freeswitch/etc/freeswitch/.svn

# add modifications
COPY ./conf /opt/freeswitch/etc/freeswitch/

COPY ./entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh

注) ディレクトリオプション ./configure ... ... --prefix=/opt/freeswitch は任意。このオプションを指定する場合は、設定ファイルのディレクトリも /opt/freeswitch/etc となることに注意。
次の entrypoint.sh の該当箇所も /opt/freeswitch ディレクトリに対応させること。

entrypoint.sh

#!/bin/bash

# remove all SIP (port 5060) iptable rules
iptables -S INPUT | grep "\-\-dport 5060 " | cut -d " " -f 2- | xargs -rL1 iptables -D

# block requests to 5060 (tcp/udp)
iptables -A INPUT -p tcp --dport 5060 -s 0.0.0.0/0 -j REJECT
iptables -A INPUT -p udp --dport 5060 -s 0.0.0.0/0 -j REJECT

# allow some IPs 
IFS=',' read -ra ADDR <<< "$SIP_IP_ALLOWLIST"
for IP in "${ADDR[@]}"; do
    # process "$i"
    echo "allow port 5060/udp for $IP"
    iptables -I INPUT  -p udp --dport 5060 -s $IP -j ACCEPT
done

# create user 'freeswitch'
# add it to group 'freeswitch'
# change owner and group of the freeswitch installation
cd /opt
groupadd freeswitch
adduser --quiet --system --home /opt/freeswitch --gecos "FreeSWITCH open source softswitch" --ingroup freeswitch freeswitch --disabled-password
chown -R freeswitch:freeswitch /opt/freeswitch/
chmod -R ug=rwX,o= /opt/freeswitch/
chmod -R u=rwx,g=rx /opt/freeswitch/bin/*

chown -R freeswitch:freeswitch /opt/freeswitch/var/freeswitch/meetings
chmod 777 /opt/freeswitch/var/freeswitch/meetings

dockerize \
    -template /opt/freeswitch/etc/freeswitch/vars.xml.tmpl:/opt/freeswitch/etc/freeswitch/vars.xml \
    -template /opt/freeswitch/etc/freeswitch/autoload_configs/conference.conf.xml.tmpl:/opt/freeswitch/etc/freeswitch/autoload_configs/conference.conf.xml \
    /opt/freeswitch/bin/freeswitch -u freeswitch -g freeswitch -nonat -nf

Debian10/Buster ソースからコンパイル

インストール後のユーザとディレクトリのアクセス権の設定
https://freeswitch.org/confluence/display/FREESWITCH/Debian+Post-Install+Tasks