first commit

This commit is contained in:
zhongjin
2023-02-14 23:15:32 +08:00
commit bdc09c1b07
100 changed files with 5578 additions and 0 deletions

34
mod/apps-akka/Dockerfile Normal file
View File

@@ -0,0 +1,34 @@
ARG BBB_BUILD_TAG
FROM gitlab.senfcall.de:5050/senfcall-public/docker-bbb-build:$BBB_BUILD_TAG AS builder
ARG TAG_COMMON_MESSAGE
# download bbb-common-message
RUN svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_COMMON_MESSAGE/bbb-common-message /bbb-common-message \
&& cd /bbb-common-message \
&& ./deploy.sh \
&& rm -rf /bbb-common-message
# ===================================================
ARG TAG_APPS_AKKA
RUN svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_APPS_AKKA/akka-bbb-apps /source \
&& rm -rf /source/.svn
# compile and unzip bin
RUN cd /source \
&& sbt universal:packageBin \
&& unzip /source/target/universal/bbb-apps-akka-0.0.4.zip -d /
# ===================================================
FROM alangecker/bbb-docker-base-java
COPY --from=builder /bbb-apps-akka-0.0.4 /bbb-apps-akka
COPY bbb-apps-akka.conf /etc/bigbluebutton/bbb-apps-akka.conf.tmpl
COPY logback.xml /bbb-apps-akka/conf/logback.xml
COPY entrypoint.sh /entrypoint.sh
USER bigbluebutton
ENTRYPOINT /entrypoint.sh

View File

@@ -0,0 +1,14 @@
// include default config from upstream
include "/bbb-apps-akka/conf/application.conf"
redis {
host="10.7.7.5"
}
services {
bbbWebAPI="https://DOMAIN/bigbluebutton/api"
sharedSecret="SHARED_SECRET"
}
http {
interface = "0.0.0.0"
}

9
mod/apps-akka/entrypoint.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/sh -e
TARGET=/etc/bigbluebutton/bbb-apps-akka.conf
cp /etc/bigbluebutton/bbb-apps-akka.conf.tmpl $TARGET
sed -i "s/DOMAIN/$DOMAIN/" $TARGET
sed -i "s/SHARED_SECRET/$SHARED_SECRET/" $TARGET
cd /bbb-apps-akka
/bbb-apps-akka/bin/bbb-apps-akka

16
mod/apps-akka/logback.xml Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"} %-5level %logger{35} - %msg%n</Pattern>
</layout>
</appender>
<logger name="akka" level="INFO" />
<logger name="org.bigbluebutton" level="DEBUG" />
<logger name="io.lettuce" level="INFO" />
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</configuration>

24
mod/base-java/Dockerfile Normal file
View File

@@ -0,0 +1,24 @@
FROM openjdk:11-jre-slim-bullseye
RUN apt-get update && apt-get install -y \
wget unzip gosu locales \
imagemagick xpdf-utils curl \
&& sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
# add user & group
RUN groupadd -g 998 bigbluebutton \
&& useradd -m -u 998 -g bigbluebutton bigbluebutton \
&& mkdir /etc/bigbluebutton \
&& chown bigbluebutton:bigbluebutton /etc/bigbluebutton
# add dockerize
ENV DOCKERIZE_VERSION v0.6.1
RUN wget -q 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

18
mod/bbb-pads/Dockerfile Normal file
View File

@@ -0,0 +1,18 @@
FROM node:14.19.1-bullseye-slim AS builder
COPY ./bbb-pads /bbb-pads
RUN cd /bbb-pads && rm -r .git && npm install --production
RUN chmod 777 /bbb-pads/config
# ------------------------------
FROM node:14.19.1-bullseye-slim
RUN apt update && apt install -y jq moreutils \
&& useradd --uid 2003 --user-group bbb-pads
COPY --from=builder /bbb-pads /bbb-pads
USER bbb-pads
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh

15
mod/bbb-pads/entrypoint.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
set -e
TARGET=/bbb-pads/config/settings.json
cp /bbb-pads/config/settings.json.template $TARGET
sed -i "s/ETHERPAD_API_KEY/\"$ETHERPAD_API_KEY\"/g" $TARGET
jq '.etherpad.host = "etherpad"' $TARGET | sponge $TARGET
jq '.express.host = "0.0.0.0"' $TARGET | sponge $TARGET
jq '.redis.host = "redis"' $TARGET | sponge $TARGET
cd /bbb-pads
export NODE_ENV=production
npm start

69
mod/bbb-web/Dockerfile Normal file
View File

@@ -0,0 +1,69 @@
ARG BBB_BUILD_TAG
FROM gitlab.senfcall.de:5050/senfcall-public/docker-bbb-build:$BBB_BUILD_TAG AS builder
ARG TAG_COMMON_MESSAGE
# download bbb-common-message
RUN svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_COMMON_MESSAGE/bbb-common-message /bbb-common-message \
&& cd /bbb-common-message \
&& ./deploy.sh \
&& rm -rf /bbb-common-message
# ===================================================
ARG TAG_BBB_WEB
# download bbb-common-web
RUN svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_BBB_WEB/bbb-common-web /bbb-common-web \
&& rm -rf /bbb-common-message/.svn
# compile bbb-common-web
RUN cd /bbb-common-web \
&& ./deploy.sh
# download bbb-web
RUN svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_BBB_WEB/bigbluebutton-web /bbb-web \
&& rm -rf /bbb-web/.svn
# compile bbb-web
RUN cd /bbb-web && grails assemble
# compile pres-checker
RUN cd /bbb-web/pres-checker && gradle resolveDeps
# extract .war
RUN unzip -q /bbb-web/build/libs/bigbluebutton-0.10.0.war -d /dist
# ===================================================
FROM alangecker/bbb-docker-base-java
# add blank presentation files and allow conversation to pdf/svg
RUN mkdir -p /usr/share/bigbluebutton/blank \
&& cd /usr/share/bigbluebutton/blank \
&& wget \
https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/v2.4.0/bigbluebutton-config/slides/blank-svg.svg \
https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/v2.4.0/bigbluebutton-config/slides/blank-thumb.png \
https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/v2.4.0/bigbluebutton-config/slides/blank-presentation.pdf \
https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/v2.4.0/bigbluebutton-config/slides/blank-png.png \
&& sed -i 's/<policy domain="coder" rights="none" pattern="PDF" \/>/<policy domain="coder" rights="write" pattern="PDF" \/>/g' /etc/ImageMagick-6/policy.xml \
&& sed -i '/potrace/d' /etc/ImageMagick-6/delegates.xml
# get bbb-web
COPY --from=builder /dist /usr/share/bbb-web
# get pres-checker
COPY --from=builder /bbb-web/pres-checker/lib /usr/share/prescheck/lib
COPY --from=builder /bbb-web/pres-checker/run.sh /usr/share/prescheck/prescheck.sh
COPY mocked-ps /usr/bin/ps
# add entrypoint and templates
COPY entrypoint.sh /entrypoint.sh
COPY bbb-web.properties /etc/bigbluebutton/bbb-web.properties.tmpl
COPY turn-stun-servers.xml /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml.tmpl
COPY logback.xml /usr/share/bbb-web/WEB-INF/classes/logback.xml
COPY office-convert.sh /usr/share/bbb-libreoffice-conversion/convert.sh
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -0,0 +1,22 @@
defaultWelcomeMessage={{ .Env.WELCOME_MESSAGE }}
defaultWelcomeMessageFooter={{ .Env.WELCOME_FOOTER }}
{{ if isTrue .Env.ENABLE_RECORDING }}
disableRecordingDefault=false
{{ else }}
disableRecordingDefault=true
{{ end }}
bigbluebutton.web.serverURL=https://{{ .Env.DOMAIN }}
securitySalt={{ .Env.SHARED_SECRET }}
redisHost=redis
{{ if isTrue .Env.DEV_MODE }}
beans.presentationService.defaultUploadedPresentation=https://test.bigbluebutton.org/default.pdf
{{else}}
beans.presentationService.defaultUploadedPresentation=${bigbluebutton.web.serverURL}/default.pdf
{{end}}
learningDashboardEnabled={{ .Env.ENABLE_LEARNING_DASHBOARD }}

29
mod/bbb-web/entrypoint.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
set -e
# create recording directory structure if it doesn't exist yet
mkdir -p /var/bigbluebutton/recording/raw
mkdir -p /var/bigbluebutton/recording/process
mkdir -p /var/bigbluebutton/recording/publish
mkdir -p /var/bigbluebutton/recording/status/recorded
mkdir -p /var/bigbluebutton/recording/status/archived
mkdir -p /var/bigbluebutton/recording/status/processed
mkdir -p /var/bigbluebutton/recording/status/sanity
mkdir -p /var/bigbluebutton/recording/status/ended
mkdir -p /var/bigbluebutton/recording/status/published
mkdir -p /var/bigbluebutton/captions/inbox
mkdir -p /var/bigbluebutton/published
mkdir -p /var/bigbluebutton/published/notes
mkdir -p /var/bigbluebutton/deleted
mkdir -p /var/bigbluebutton/unpublished
chown -R bigbluebutton:bigbluebutton /var/bigbluebutton
echo "$NUMBER_OF_BACKEND_NODEJS_PROCESSES" > /tmp/NUMBER_OF_BACKEND_NODEJS_PROCESSES
cd /usr/share/bbb-web/
dockerize \
-template /etc/bigbluebutton/bbb-web.properties.tmpl:/etc/bigbluebutton/bbb-web.properties \
-template /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml.tmpl:/usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml \
gosu bigbluebutton java -Dgrails.env=prod -Dserver.address=0.0.0.0 -Dserver.port=8090 -Xms384m -Xmx384m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/bigbluebutton/diagnostics -cp WEB-INF/lib/*:/:WEB-INF/classes/:. org.springframework.boot.loader.WarLauncher

28
mod/bbb-web/logback.xml Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"} %-5level %logger{35} - %msg%n</Pattern>
</layout>
</appender>
<logger name="akka" level="INFO" />
<logger name="io.lettuce" level="INFO" />
<logger name="org.bigbluebutton" level="DEBUG" />
<logger name="grails.app.controllers" level="DEBUG" />
<logger name="grails.app.services" level="DEBUG" />
<logger name="org.grails.web.servlet" level="ERROR" />
<logger name="org.grails.web.pages" level="ERROR" />
<logger name="org.grails.web.sitemesh" level="ERROR" />
<logger name="org.grails.web.mapping.filter" level="ERROR" />
<logger name="org.grails.web.mapping" level="ERROR" />
<logger name="org.grails.commons" level="ERROR" />
<logger name="org.springframework" level="ERROR" />
<root level="ERROR">
<appender-ref ref="STDOUT" />
</root>
</configuration>

8
mod/bbb-web/mocked-ps Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
echo "(mocked-ps for HTML5LoadBalancingService.java)"
# fake random process load to distribute meetings equally
for i in `seq $(cat /tmp/NUMBER_OF_BACKEND_NODEJS_PROCESSES)`; do
randomLoad=$(echo $(( $RANDOM % 100 )))
echo " $randomLoad.1 /usr/share/node-v12.16.1-linux-x64/bin/node main.js NODEJS_BACKEND_INSTANCE_ID=$i"
done

30
mod/bbb-web/office-convert.sh Executable file
View File

@@ -0,0 +1,30 @@
#!/bin/bash
set -e
set -u
PATH="/bin/:/usr/bin/"
# This script receives three params
# Param 1: Input office file path (e.g. "/tmp/test.odt")
# Param 2: Output pdf file path (e.g. "/tmp/test.pdf")
# Param 3: Destination Format (pdf default)
if (( $# == 0 )); then
echo "Missing parameter 1 (Input office file path)";
exit 1
elif (( $# == 1 )); then
echo "Missing parameter 2 (Output pdf file path)";
exit 1
fi;
source="${1}"
dest="${2}"
#If output format is missing, define PDF
convertTo="${3:-pdf}"
curl -v -X POST "http://jodconverter:8080/lool/convert-to/$convertTo" \
-H "accept: application/octet-stream" \
-H "Content-Type: multipart/form-data" \
-F "data=@${source}" > "${dest}"
exit 0

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="stun1" class="org.bigbluebutton.web.services.turn.StunServer">
<constructor-arg index="0" value="{{ .Env.STUN_SERVER }}"/>
</bean>
{{if .Env.TURN_SERVER }}
<bean id="turn0" class="org.bigbluebutton.web.services.turn.TurnServer">
<constructor-arg index="0" value="{{ .Env.TURN_SECRET }}"/>
<constructor-arg index="1" value="{{ .Env.TURN_SERVER }}"/>
<constructor-arg index="2" value="86400"/>
</bean>
{{end}}
<bean id="stunTurnService" class="org.bigbluebutton.web.services.turn.StunTurnService">
<property name="stunServers">
<set>
<ref bean="stun1" />
</set>
</property>
<property name="turnServers">
<set>
{{if .Env.TURN_SERVER }}
<ref bean="turn0" />
{{end}}
</set>
</property>
<property name="remoteIceCandidates">
<set>
</set>
</property>
</bean>
</beans>

31
mod/coturn/entrypoint.sh Executable file
View File

@@ -0,0 +1,31 @@
#!/bin/sh
set -e
apk add jq su-exec
if [ "$ENABLE_HTTPS_PROXY" == true ]; then
while [ ! -f /etc/resty-auto-ssl/storage/file/*latest ]
do
echo "ERROR: certificate doesn't exist yet."
echo "Certificate gets create on the first request to the HTTPS proxy."
echo "We will try again..."
sleep 10
done
# extract cert
cat /etc/resty-auto-ssl/storage/file/*%3Alatest | jq -r '.fullchain_pem' > /tmp/cert.pem
cat /etc/resty-auto-ssl/storage/file/*%3Alatest | jq -r '.privkey_pem' > /tmp/key.pem
fi
if [ ! -f /tmp/cert.pem ] || [ ! -f /tmp/key.pem ]; then
echo "ERROR: certificate not found, but coturn relies on it."
echo "Use either auto HTTPS proxy or"
echo "provide path to certificates in .env file"
exit 1
fi
# If command starts with an option, prepend with turnserver binary.
if [ "${1:0:1}" == '-' ]; then
set -- turnserver "$@"
fi
su-exec nobody $(eval "echo $@")

View File

@@ -0,0 +1,73 @@
# Example coturn configuration for BigBlueButton
# These are the two network ports used by the TURN server which the client
# may connect to. We enable the standard unencrypted port 3478 for STUN,
listening-port=3478
# and since TLS over SMTP port (465) is now blocked by major browser vendors,
# we reverted to the most common coturn TLS port 5349, which has limitations
# in restrictive firewall environments. For maximum client support run
# coturn on a dedicated host on port 443.
tls-listening-port=5349
# If the server has multiple IP addresses, you may wish to limit which
# addresses coturn is using. Do that by setting this option (it can be
# specified multiple times). The default is to listen on all addresses.
# You do not normally need to set this option.
#listening-ip=172.17.19.101
# If the server is behind NAT, you need to specify the external IP address.
# If there is only one external address, specify it like this:
#external-ip=172.17.19.120
# If you have multiple external addresses, you have to specify which
# internal address each corresponds to, like this. The first address is the
# external ip, and the second address is the corresponding internal IP.
#external-ip=172.17.19.131/10.0.0.11
#external-ip=172.17.18.132/10.0.0.12
# Fingerprints in TURN messages are required for WebRTC
fingerprint
# The long-term credential mechanism is required for WebRTC
lt-cred-mech
# Configure coturn to use the "TURN REST API" method for validating time-
# limited credentials. BigBlueButton will generate credentials in this
# format. Note that the static-auth-secret value specified here must match
# the configuration in BigBlueButton's turn-stun-servers.xml
# You can generate a new random value by running the command:
# openssl rand -hex 16
use-auth-secret
# static-auth-secret=<random value>
# 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=example.com
# Configure TLS support.
# Adjust these paths to match the locations of your certificate files
cert=/tmp/cert.pem
pkey=/tmp/key.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"
# 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
# To enable single filename logs you need to enable the simple-log flag
syslog
#verbose
# Allocate Address Family according
# If enabled then TURN server allocates address family according the TURN
# Client <=> Server communication address family.
# (By default Coturn works according RFC 6156.)
# !!Warning: Enabling this option breaks RFC6156 section-4.2 (violates use default IPv4)!!
keep-address-family

28
mod/etherpad/Dockerfile Normal file
View File

@@ -0,0 +1,28 @@
FROM etherpad/etherpad:1.8.18
USER root
RUN apt-get update \
&& apt-get install -y git curl
USER etherpad
RUN npm install \
ep_cursortrace@3.1.16 \
git+https://github.com/mconf/ep_pad_ttl.git#360136cd38493dd698435631f2373cbb7089082d \
git+https://github.com/mconf/ep_redis_publisher.git#a30a48e4bc1e501b5b102884b9a0b26c30798484 \
ep_disable_chat@0.0.8 \
ep_auth_session@1.1.1 \
# remove npm lockfile, because somehow it prevents etherpad from detecting the manual added plugin ep_bigbluebutton_patches
&& rm package-lock.json
# add skin from git submodule
COPY --chown=etherpad:0 ./bbb-etherpad-skin /opt/etherpad-lite/src/static/skins/bigbluebutton
# add plugin from git submodule
COPY --chown=etherpad:0 ./bbb-etherpad-plugin /opt/etherpad-lite/node_modules/ep_bigbluebutton_patches
COPY settings.json /opt/etherpad-lite/settings.json
COPY etherpad-export.sh /etherpad-export.sh
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

5
mod/etherpad/entrypoint.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
echo $ETHERPAD_API_KEY > /tmp/apikey
export NODE_ENV=production
node /opt/etherpad-lite/node_modules/ep_etherpad-lite/node/server.js --apikey /tmp/apikey

12
mod/etherpad/etherpad-export.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
src="$8"
dest="$(echo $8 | sed -E -e 's/html|odt/'$7'/')"
convertTo="$7"
curl -v -X POST "http://jodconverter:8080/lool/convert-to/$convertTo" \
-H "accept: application/octet-stream" \
-H "Content-Type: multipart/form-data" \
-F "data=@$src" > $dest
exit 0

607
mod/etherpad/settings.json Normal file
View File

@@ -0,0 +1,607 @@
/*
* This file must be valid JSON. But comments are allowed
*
* Please edit settings.json, not settings.json.template
*
* Please note that starting from Etherpad 1.6.0 you can store DB credentials in
* a separate file (credentials.json).
*
*
* ENVIRONMENT VARIABLE SUBSTITUTION
* =================================
*
* All the configuration values can be read from environment variables using the
* syntax "${ENV_VAR}" or "${ENV_VAR:default_value}".
*
* This is useful, for example, when running in a Docker container.
*
* DETAILED RULES:
* - If the environment variable is set to the string "true" or "false", the
* value becomes Boolean true or false.
* - If the environment variable is set to the string "null", the value
* becomes null.
* - If the environment variable is set to the string "undefined", the setting
* is removed entirely, except when used as the member of an array in which
* case it becomes null.
* - If the environment variable is set to a string representation of a finite
* number, the string is converted to that number.
* - If the environment variable is set to any other string, including the
* empty string, the value is that string.
* - If the environment variable is unset and a default value is provided, the
* value is as if the environment variable was set to the provided default:
* - "${UNSET_VAR:}" becomes the empty string.
* - "${UNSET_VAR:foo}" becomes the string "foo".
* - "${UNSET_VAR:true}" and "${UNSET_VAR:false}" become true and false.
* - "${UNSET_VAR:null}" becomes null.
* - "${UNSET_VAR:undefined}" causes the setting to be removed (or be set
* to null, if used as a member of an array).
* - If the environment variable is unset and no default value is provided,
* the value becomes null. THIS BEHAVIOR MAY CHANGE IN A FUTURE VERSION OF
* ETHERPAD; if you want the default value to be null, you should explicitly
* specify "null" as the default value.
*
* EXAMPLE:
* "port": "${PORT:9001}"
* "minify": "${MINIFY}"
* "skinName": "${SKIN_NAME:colibris}"
*
* Would read the configuration values for those items from the environment
* variables PORT, MINIFY and SKIN_NAME.
*
* If PORT and SKIN_NAME variables were not defined, the default values 9001 and
* "colibris" would be used.
* The configuration value "minify", on the other hand, does not have a
* designated default value. Thus, if the environment variable MINIFY were
* undefined, "minify" would be null.
*
* REMARKS:
* 1) please note that variable substitution always needs to be quoted.
*
* "port": 9001, <-- Literal values. When not using
* "minify": false substitution, only strings must be
* "skinName": "colibris" quoted. Booleans and numbers must not.
*
* "port": "${PORT:9001}" <-- CORRECT: if you want to use a variable
* "minify": "${MINIFY:true}" substitution, put quotes around its name,
* "skinName": "${SKIN_NAME}" even if the required value is a number or
* a boolean.
* Etherpad will take care of rewriting it
* to the proper type if necessary.
*
* "port": ${PORT:9001} <-- ERROR: this is not valid json. Quotes
* "minify": ${MINIFY} around variable names are missing.
* "skinName": ${SKIN_NAME}
*
* 2) Beware of undefined variables and default values: nulls and empty strings
* are different!
*
* This is particularly important for user's passwords (see the relevant
* section):
*
* "password": "${PASSW}" // if PASSW is not defined would result in password === null
* "password": "${PASSW:}" // if PASSW is not defined would result in password === ''
*
* If you want to use an empty value (null) as default value for a variable,
* simply do not set it, without putting any colons: "${ABIWORD}".
*
* 3) if you want to use newlines in the default value of a string parameter,
* use "\n" as usual.
*
* "defaultPadText" : "${DEFAULT_PAD_TEXT}Line 1\nLine 2"
*/
{
/*
* Name your instance!
*/
"title": "Etherpad",
/*
* Pathname of the favicon you want to use. If null, the skin's favicon is
* used if one is provided by the skin, otherwise the default Etherpad favicon
* is used. If this is a relative path it is interpreted as relative to the
* Etherpad root directory.
*/
"favicon": null,
/*
* Skin name.
*
* Its value has to be an existing directory under src/static/skins.
* You can write your own, or use one of the included ones:
*
* - "no-skin": an empty skin (default). This yields the unmodified,
* traditional Etherpad theme.
* - "colibris": the new experimental skin (since Etherpad 1.8), candidate to
* become the default in Etherpad 2.0
*/
"skinName": "bigbluebutton",
/*
* Skin Variants
*
* Use the UI skin variants builder at /p/test#skinvariantsbuilder
*
* For the colibris skin only, you can choose how to render the three main
* containers:
* - toolbar (top menu with icons)
* - editor (containing the text of the pad)
* - background (area outside of editor, mostly visible when using page style)
*
* For each of the 3 containers you can choose 4 color combinations:
* super-light, light, dark, super-dark.
*
* For example, to make the toolbar dark, you will include "dark-toolbar" into
* skinVariants.
*
* You can provide multiple skin variants separated by spaces. Default
* skinVariant is "super-light-toolbar super-light-editor light-background".
*
* For the editor container, you can also make it full width by adding
* "full-width-editor" variant (by default editor is rendered as a page, with
* a max-width of 900px).
*/
"skinVariants": "super-light-toolbar super-light-editor light-background",
/*
* IP and port which Etherpad should bind at.
*
* Binding to a Unix socket is also supported: just use an empty string for
* the ip, and put the full path to the socket in the port parameter.
*
* EXAMPLE USING UNIX SOCKET:
* "ip": "", // <-- has to be an empty string
* "port" : "/somepath/etherpad.socket", // <-- path to a Unix socket
*/
"ip": "0.0.0.0",
"port": 9001,
/*
* Option to hide/show the settings.json in admin page.
*
* Default option is set to true
*/
"showSettingsInAdminPage": true,
/*
* Node native SSL support
*
* This is disabled by default.
* Make sure to have the minimum and correct file access permissions set so
* that the Etherpad server can access them
*/
/*
"ssl" : {
"key" : "/path-to-your/epl-server.key",
"cert" : "/path-to-your/epl-server.crt",
"ca": ["/path-to-your/epl-intermediate-cert1.crt", "/path-to-your/epl-intermediate-cert2.crt"]
},
*/
/*
* The type of the database.
*
* You can choose between many DB drivers, for example: dirty, postgres,
* sqlite, mysql.
*
* You shouldn't use "dirty" for for anything else than testing or
* development.
*
*
* Database specific settings are dependent on dbType, and go in dbSettings.
* Remember that since Etherpad 1.6.0 you can also store this information in
* credentials.json.
*
* For a complete list of the supported drivers, please refer to:
* https://www.npmjs.com/package/ueberdb2
*/
"dbType": "redis",
"dbSettings": {
"host": "redis",
"port": 6379
},
/*
* An Example of MySQL Configuration (commented out).
*
* See: https://github.com/ether/etherpad-lite/wiki/How-to-use-Etherpad-Lite-with-MySQL
*/
/*
"dbType" : "redis",
"dbSettings" : {
"host": "127.0.0.1",
"port": 6379,
"client_options": {
"password": "PASSWORD"
}
},
*/
/*
* The default text of a pad
*/
"defaultPadText" : "",
/*
* Default Pad behavior.
*
* Change them if you want to override.
*/
"padOptions": {
"noColors": true,
"showControls": true,
"showChat": false,
"showLineNumbers": false,
"useMonospaceFont": false,
"userName": false,
"userColor": false,
"rtl": false,
"alwaysShowChat": false,
"chatAndUsers": false,
"lang": "en"
},
/*
* Pad Shortcut Keys
*/
"padShortcutEnabled" : {
"altF9": true, /* focus on the File Menu and/or editbar */
"altC": false, /* focus on the Chat window */
"cmdShift2": true, /* shows a gritter popup showing a line author */
"delete": true,
"return": true,
"esc": true, /* in mozilla versions 14-19 avoid reconnecting pad */
"cmdS": true, /* save a revision */
"tab": true, /* indent */
"cmdZ": true, /* undo/redo */
"cmdY": true, /* redo */
"cmdI": true, /* italic */
"cmdB": true, /* bold */
"cmdU": true, /* underline */
"cmd5": true, /* strike through */
"cmdShiftL": true, /* unordered list */
"cmdShiftN": true, /* ordered list */
"cmdShift1": true, /* ordered list */
"cmdShiftC": true, /* clear authorship */
"cmdH": true, /* backspace */
"ctrlHome": true, /* scroll to top of pad */
"pageUp": true,
"pageDown": true
},
/*
* Should we suppress errors from being visible in the default Pad Text?
*/
"suppressErrorsInPadText": true,
/*
* If this option is enabled, a user must have a session to access pads.
* This effectively allows only group pads to be accessed.
*/
"requireSession": true,
/*
* Users may edit pads but not create new ones.
*
* Pad creation is only via the API.
* This applies both to group pads and regular pads.
*/
"editOnly": true,
/*
* If true, all css & js will be minified before sending to the client.
*
* This will improve the loading performance massively, but makes it difficult
* to debug the javascript/css
*/
"minify": true,
/*
* How long may clients use served javascript code (in seconds)?
*
* Not setting this may cause problems during deployment.
* Set to 0 to disable caching.
*/
"maxAge": 21600, // 60 * 60 * 6 = 6 hours
/*
* Absolute path to the Abiword executable.
*
* Abiword is needed to get advanced import/export features of pads. Setting
* it to null disables Abiword and will only allow plain text and HTML
* import/exports.
*/
"abiword": null,
/*
* This is the absolute path to the soffice executable.
*
* LibreOffice can be used in lieu of Abiword to export pads.
* Setting it to null disables LibreOffice exporting.
*/
"soffice": "/etherpad-export.sh",
/*
* Path to the Tidy executable.
*
* Tidy is used to improve the quality of exported pads.
* Setting it to null disables Tidy.
*/
"tidyHtml": null,
/*
* Allow import of file types other than the supported ones:
* txt, doc, docx, rtf, odt, html & htm
*/
"allowUnknownFileEnds": false,
/*
* This setting is used if you require authentication of all users.
*
* Note: "/admin" always requires authentication.
*/
"requireAuthentication": false,
/*
* Require authorization by a module, or a user with is_admin set, see below.
*/
"requireAuthorization": false,
/*
* When you use NGINX or another proxy/load-balancer set this to true.
*
* This is especially necessary when the reverse proxy performs SSL
* termination, otherwise the cookies will not have the "secure" flag.
*
* The other effect will be that the logs will contain the real client's IP,
* instead of the reverse proxy's IP.
*/
"trustProxy": true,
/*
* Settings controlling the session cookie issued by Etherpad.
*/
"cookie": {
/*
* Value of the SameSite cookie property. "Lax" is recommended unless
* Etherpad will be embedded in an iframe from another site, in which case
* this must be set to "None". Note: "None" will not work (the browser will
* not send the cookie to Etherpad) unless https is used to access Etherpad
* (either directly or via a reverse proxy with "trustProxy" set to true).
*
* "Strict" is not recommended because it has few security benefits but
* significant usability drawbacks vs. "Lax". See
* https://stackoverflow.com/q/41841880 for discussion.
*/
"sameSite": "None"
},
/*
* Privacy: disable IP logging
*/
"disableIPlogging": true,
/*
* Time (in seconds) to automatically reconnect pad when a "Force reconnect"
* message is shown to user.
*
* Set to 0 to disable automatic reconnection.
*/
"automaticReconnectionTimeout": 0,
/*
* By default, when caret is moved out of viewport, it scrolls the minimum
* height needed to make this line visible.
*/
"scrollWhenFocusLineIsOutOfViewport": {
/*
* Percentage of viewport height to be additionally scrolled.
*
* E.g.: use "percentage.editionAboveViewport": 0.5, to place caret line in
* the middle of viewport, when user edits a line above of the
* viewport
*
* Set to 0 to disable extra scrolling
*/
"percentage": {
"editionAboveViewport": 0,
"editionBelowViewport": 0
},
/*
* Time (in milliseconds) used to animate the scroll transition.
* Set to 0 to disable animation
*/
"duration": 0,
/*
* Flag to control if it should scroll when user places the caret in the
* last line of the viewport
*/
"scrollWhenCaretIsInTheLastLineOfViewport": false,
/*
* Percentage of viewport height to be additionally scrolled when user
* presses arrow up in the line of the top of the viewport.
*
* Set to 0 to let the scroll to be handled as default by Etherpad
*/
"percentageToScrollWhenUserPressesArrowUp": 0
},
/*
* User accounts. These accounts are used by:
* - default HTTP basic authentication if no plugin handles authentication
* - some but not all authentication plugins
* - some but not all authorization plugins
*
* User properties:
* - password: The user's password. Some authentication plugins will ignore
* this.
* - is_admin: true gives access to /admin. Defaults to false. If you do not
* uncomment this, /admin will not be available!
* - readOnly: If true, this user will not be able to create new pads or
* modify existing pads. Defaults to false.
* - canCreate: If this is true and readOnly is false, this user can create
* new pads. Defaults to true.
*
* Authentication and authorization plugins may define additional properties.
*
* WARNING: passwords should not be stored in plaintext in this file.
* If you want to mitigate this, please install ep_hash_auth and
* follow the section "secure your installation" in README.md
*/
/*
"users": {
"admin": {
// 1) "password" can be replaced with "hash" if you install ep_hash_auth
// 2) please note that if password is null, the user will not be created
"password": "changeme1",
"is_admin": true
},
"user": {
// 1) "password" can be replaced with "hash" if you install ep_hash_auth
// 2) please note that if password is null, the user will not be created
"password": "changeme1",
"is_admin": false
}
},
*/
/*
* Restrict socket.io transport methods
*/
"socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"],
"socketIo": {
/*
* Maximum permitted client message size (in bytes). All messages from
* clients that are larger than this will be rejected. Large values make it
* possible to paste large amounts of text, and plugins may require a larger
* value to work properly, but increasing the value increases susceptibility
* to denial of service attacks (malicious clients can exhaust memory).
*/
"maxHttpBufferSize": 10000
},
/*
* Allow Load Testing tools to hit the Etherpad Instance.
*
* WARNING: this will disable security on the instance.
*/
"loadTest": false,
/**
* Disable dump of objects preventing a clean exit
*/
"dumpOnUncleanExit": false,
/*
* Disable indentation on new line when previous line ends with some special
* chars (':', '[', '(', '{')
*/
/*
"indentationOnNewLine": false,
*/
"ep_pad_ttl": {
"ttl": 86400, // 24 hours
"timeout": 30,
"interval": 21600 // 6 hours
},
/*
* Redis publisher plugin configuration.
* npm i git+https://git@github.com/mconf/ep_redis_publisher.git
*/
"ep_redis_publisher": {
"host": "redis",
"port": 6379
},
/*
* From Etherpad 1.8.3 onwards, import and export of pads is always rate
* limited.
*
* The default is to allow at most 10 requests per IP in a 90 seconds window.
* After that the import/export request is rejected.
*
* See https://github.com/nfriedly/express-rate-limit for more options
*/
"importExportRateLimiting": {
// duration of the rate limit window (milliseconds)
"windowMs": 90000,
// maximum number of requests per IP to allow during the rate limit window
"max": 10
},
/*
* From Etherpad 1.8.3 onwards, the maximum allowed size for a single imported
* file is always bounded.
*
* File size is specified in bytes. Default is 50 MB.
*/
"importMaxFileSize": 52428800, // 50 * 1024 * 1024
/*
* From Etherpad 1.8.5 onwards, when Etherpad is in production mode commits from individual users are rate limited
*
* The default is to allow at most 10 changes per IP in a 1 second window.
* After that the change is rejected.
*
* See https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#websocket-single-connection-prevent-flooding for more options
*/
"commitRateLimiting": {
// duration of the rate limit window (seconds)
"duration": 1,
// maximum number of changes per IP to allow during the rate limit window
"points": 100
},
/*
* Toolbar buttons configuration.
*
* Uncomment to customize.
*/
"toolbar": {
"left": [
["bold", "italic", "underline", "strikethrough"],
["orderedlist", "unorderedlist", "undo", "redo"],
["importexport"]
],
"right": [[]]
},
/*
* Expose Etherpad version in the web interface and in the Server http header.
*
* Do not enable on production machines.
*/
"exposeVersion": false,
/*
* The log level we are using.
*
* Valid values: DEBUG, INFO, WARN, ERROR
*/
"loglevel": "INFO",
/* Override any strings found in locale directories */
"customLocaleStrings": {},
/* Disable Admin UI tests */
"enableAdminUITests": false
}

66
mod/freeswitch/Dockerfile Normal file
View File

@@ -0,0 +1,66 @@
FROM debian:bullseye-slim
# install dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
subversion curl wget ca-certificates gnupg gnupg2 lsb-release unzip
COPY --from=alangecker/bbb-docker-base-java /usr/local/bin/dockerize /usr/local/bin/dockerize
# install freeswitch
RUN wget -q -O /usr/share/keyrings/freeswitch-archive-keyring.gpg https://freeswitch-mirror.chandi.it/repo/deb/debian-release/signalwire-freeswitch-repo.gpg && \
echo 'deb [signed-by=/usr/share/keyrings/freeswitch-archive-keyring.gpg] http://freeswitch-mirror.chandi.it/repo/deb/debian-release/ bullseye main' > /etc/apt/sources.list.d/freeswitch.list && \
apt-get update && \
apt-get install -y \
freeswitch \
freeswitch-mod-commands \
freeswitch-mod-conference \
freeswitch-mod-console \
freeswitch-mod-dialplan-xml \
freeswitch-mod-dptools \
freeswitch-mod-event-socket \
freeswitch-mod-native-file \
freeswitch-mod-opusfile \
freeswitch-mod-opus \
freeswitch-mod-sndfile \
freeswitch-mod-spandsp \
freeswitch-mod-sofia \
freeswitch-sounds-en-us-callie \
iptables
# replace mute & unmute sounds
RUN wget -q https://gitlab.senfcall.de/senfcall-public/mute-and-unmute-sounds/-/archive/master/mute-and-unmute-sounds-master.zip && \
unzip mute-and-unmute-sounds-master.zip && \
cd mute-and-unmute-sounds-master/sounds/ && \
find . -name "*.wav" -exec /bin/bash -c "echo {};sox -v 0.3 {} /tmp/tmp.wav; mv /tmp/tmp.wav /usr/share/freeswitch/sounds/en/us/callie/conference/{}" \; && \
cd ../.. && \
rm -r mute-and-unmute-sounds-master mute-and-unmute-sounds-master.zip
# -- 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
ARG TAG_FS_CONFIG
RUN svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_FS_CONFIG/bbb-voice-conference/config/freeswitch/conf /etc/freeswitch \
&& rm -rf /etc/freeswitch/.svn
# the current available freeswitch-mod-opusfile is broken,
# it can't write any .opus files. The fix provided in
# https://github.com/signalwire/freeswitch/pull/719/files
# is not sufficient as the module still comes without opus
# write support, so we rather switch to the binary built
# by bigbluebutton and add its dependencies
RUN wget -O /usr/lib/freeswitch/mod/mod_opusfile.so https://github.com/bbb-pkg/bbb-freeswitch-core/raw/43f3a47af1fcf5ea559e16bb28b900c925a7f2c3/opt/freeswitch/lib/freeswitch/mod/mod_opusfile.so \
&& wget -O /tmp/libopusenc0_0.2.1-1bbb1_amd64.deb https://launchpad.net/~bigbluebutton/+archive/ubuntu/support/+files/libopusenc0_0.2.1-1bbb1_amd64.deb \
&& dpkg -i /tmp/libopusenc0_0.2.1-1bbb1_amd64.deb \
&& rm /tmp/libopusenc0_0.2.1-1bbb1_amd64.deb
# add modifications
COPY ./conf /etc/freeswitch/
COPY ./entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh

View File

@@ -0,0 +1,49 @@
<configuration name="acl.conf" description="Network Lists">
<network-lists>
<!--
These ACL's are automatically created on startup.
rfc1918.auto - RFC1918 Space
nat.auto - RFC1918 Excluding your local lan.
localnet.auto - ACL for your local lan.
loopback.auto - ACL for your local lan.
-->
<list name="lan" default="allow">
<node type="allow" cidr="127.0.0.1/32"/>
<node type="allow" cidr="10.130.218.147/32"/>
<node type="allow" cidr="10.0.0.0/8"/>
<node type="allow" cidr="192.168.0.0/16"/>
</list>
<!--
custom "loopback" so that traffic from docker
containers is also considered as local
-->
<list name="loopback.custom" default="deny">
<node type="allow" cidr="127.0.0.1/32"/>
<node type="allow" cidr="10.0.0.0/8"/>
<node type="allow" cidr="192.168.0.0/16"/>
<node type="allow" cidr="172.16.0.0/12" />
<node type="allow" cidr="$${external_ip_v4}/32"/>
</list>
<list name="deny_private_v6" default="allow">
<node type="deny" cidr="0.0.0.0/0"/>
<node type="deny" cidr="fe80::/10"/>
<node type="deny" cidr="fc00::/7"/>
</list>
<!--
This will traverse the directory adding all users
with the cidr= tag to this ACL, when this ACL matches
the users variables and params apply as if they
digest authenticated.
-->
<list name="domains" default="allow">
<!-- domain= is special it scans the domain from the directory to build the ACL -->
<node type="allow" domain="$${domain}"/>
<!-- use cidr= if you wish to allow ip ranges to this domains acl. -->
<!-- <node type="allow" cidr="192.168.0.0/24"/> -->
</list>
</network-lists>
</configuration>

View File

@@ -0,0 +1,285 @@
<!-- http://wiki.freeswitch.org/wiki/Mod_conference -->
<!-- None of these paths are real if you want any of these options you need to really set them up -->
<configuration name="conference.conf" description="Audio Conference">
<!-- Advertise certain presence on startup . -->
<advertise>
<room name="3001@$${domain}" status="FreeSWITCH"/>
</advertise>
<!-- These are the default keys that map when you do not specify a caller control group -->
<!-- Note: none and default are reserved names for group names. Disabled if dist-dtmf member flag is set. -->
<caller-controls>
<group name="default">
<control action="mute" digits="0"/>
<control action="deaf mute" digits="*"/>
<control action="energy up" digits="9"/>
<control action="energy equ" digits="8"/>
<control action="energy dn" digits="7"/>
<control action="vol talk up" digits="3"/>
<control action="vol talk zero" digits="2"/>
<control action="vol talk dn" digits="1"/>
<control action="vol listen up" digits="6"/>
<control action="vol listen zero" digits="5"/>
<control action="vol listen dn" digits="4"/>
<!--control action="hangup" digits="#"/ -->
</group>
</caller-controls>
<!-- Profiles are collections of settings you can reference by name. -->
<profiles>
<!--If no profile is specified it will default to "default"-->
<profile name="default">
<!-- Directory to drop CDR's
'auto' means $PREFIX/logs/conference_cdr/<confernece_uuid>.cdr.xml
a non-absolute path means $PREFIX/logs/<value>/<confernece_uuid>.cdr.xml
absolute path means <value>/<confernece_uuid>.cdr.xml
-->
<!-- <param name="cdr-log-dir" value="auto"/> -->
<!-- Domain (for presence) -->
<param name="domain" value="$${domain}"/>
<!-- Sample Rate-->
<param name="rate" value="48000"/>
<!-- Number of milliseconds per frame -->
<param name="interval" value="20"/>
<!-- Energy level required for audio to be sent to the other users -->
<param name="energy-level" value="100"/>
<!--Can be | delim of waste|mute|deaf|dist-dtmf waste will always transmit data to each channel
even during silence. dist-dtmf propagates dtmfs to all other members, but channel controls
via dtmf will be disabled. -->
<!-- <param name="member-flags" value="waste"/> -->
<!-- Name of the caller control group to use for this profile -->
<!-- <param name="caller-controls" value="some name"/> -->
<!-- Name of the caller control group to use for the moderator in this profile -->
<!-- <param name="moderator-controls" value="some name"/> -->
<!-- TTS Engine to use -->
<!-- <param name="tts-engine" value="cepstral"/> -->
<!-- TTS Voice to use -->
<!-- <param name="tts-voice" value="david"/> -->
<!-- If TTS is enabled all audio-file params beginning with -->
<!-- 'say:' will be considered text to say with TTS -->
<!-- Override the default path here, after which you use relative paths in the other sound params -->
<!-- Note: The default path is the conference's first caller's sound_prefix -->
<!-- <param name="sound-prefix" value="$${sounds_dir}/en/us/callie"/> -->
<!-- File to play to acknowledge succees -->
<!-- <param name="ack-sound" value="beep.wav"/> -->
<!-- File to play to acknowledge failure -->
<!-- <param name="nack-sound" value="beeperr.wav"/> -->
<!-- File to play to acknowledge muted -->
<param name="muted-sound" value="conference/conf-muted.wav"/>
<!-- File to play to acknowledge unmuted -->
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
<!-- File to play if you are alone in the conference -->
<param name="alone-sound" value="conference/conf-alone.wav"/>
<!-- File to play endlessly (nobody will ever be able to talk) -->
<!-- <param name="perpetual-sound" value="perpetual.wav"/> -->
<!-- File to play when you're alone (music on hold)-->
<param name="moh-sound" value="$${hold_music}"/>
<!-- File to play when you join the conference -->
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<!-- File to play when you leave the conference -->
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
<!-- File to play when you are ejected from the conference -->
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
<!-- File to play when the conference is locked -->
<param name="locked-sound" value="conference/conf-locked.wav"/>
<!-- File to play when the conference is locked during the call-->
<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
<!-- File to play when the conference is unlocked during the call-->
<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>
<!-- File to play to prompt for a pin -->
<param name="pin-sound" value="conference/conf-pin.wav"/>
<!-- File to play to when the pin is invalid -->
<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>
<!-- Conference pin -->
<!-- <param name="pin" value="12345"/> -->
<!-- <param name="moderator-pin" value="54321"/> -->
<!-- Max number of times the user can be prompted for PIN -->
<!-- <param name="pin-retries" value="3"/> -->
<!-- Default Caller ID Name for outbound calls -->
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<!-- Default Caller ID Number for outbound calls -->
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<!-- Suppress start and stop talking events -->
<!-- <param name="suppress-events" value="start-talking,stop-talking"/> -->
<!-- enable comfort noise generation -->
<param name="comfort-noise" value="true"/>
<!-- Uncomment auto-record to toggle recording every conference call. -->
<!-- Another valid value is shout://user:pass@server.com/live.mp3 -->
<!--
<param name="auto-record" value="$${recordings_dir}/${conference_name}_${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
-->
<!-- IVR digit machine timeouts -->
<!-- How much to wait between DTMF digits to match caller-controls -->
<!-- <param name="ivr-dtmf-timeout" value="500"/> -->
<!-- How much to wait for the first DTMF, 0 forever -->
<!-- <param name="ivr-input-timeout" value="0" /> -->
<!-- Delay before a conference is asked to be terminated -->
<!-- <param name="endconf-grace-time" value="120" /> -->
<!-- Can be | delim of wait-mod|audio-always|video-bridge|video-floor-only
wait_mod will wait until the moderator in,
audio-always will always mix audio from all members regardless they are talking or not -->
<!-- <param name="conference-flags" value="audio-always"/> -->
<!-- Allow live array sync for Verto -->
<!-- <param name="conference-flags" value="livearray-sync"/> -->
</profile>
<profile name="wideband">
<param name="domain" value="$${domain}"/>
<param name="rate" value="16000"/>
<param name="interval" value="20"/>
<param name="energy-level" value="100"/>
<!-- <param name="sound-prefix" value="$${sounds_dir}/en/us/callie"/> -->
<param name="muted-sound" value="conference/conf-muted.wav"/>
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
<param name="alone-sound" value="conference/conf-alone.wav"/>
<param name="moh-sound" value="$${hold_music}"/>
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
<param name="locked-sound" value="conference/conf-locked.wav"/>
<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>
<param name="pin-sound" value="conference/conf-pin.wav"/>
<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<param name="comfort-noise" value="true"/>
<!-- <param name="tts-engine" value="flite"/> -->
<!-- <param name="tts-voice" value="kal16"/> -->
</profile>
<profile name="ultrawideband">
<param name="domain" value="$${domain}"/>
<param name="rate" value="32000"/>
<param name="interval" value="20"/>
<param name="energy-level" value="100"/>
<!-- <param name="sound-prefix" value="$${sounds_dir}/en/us/callie"/> -->
<param name="muted-sound" value="conference/conf-muted.wav"/>
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
<param name="alone-sound" value="conference/conf-alone.wav"/>
<param name="moh-sound" value="$${hold_music}"/>
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
<param name="locked-sound" value="conference/conf-locked.wav"/>
<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>
<param name="pin-sound" value="conference/conf-pin.wav"/>
<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<param name="comfort-noise" value="true"/>
<!-- <param name="conference-flags" value="video-floor-only|rfc-4579|livearray-sync|auto-3d-position|transcode-video|minimize-video-encoding"/> -->
<!-- <param name="video-mode" value="mux"/> -->
<!-- <param name="video-layout-name" value="3x3"/> -->
<!-- <param name="video-layout-name" value="group:grid"/> -->
<!-- <param name="video-canvas-size" value="1280x720"/> -->
<!-- <param name="video-canvas-bgcolor" value="#333333"/> -->
<!-- <param name="video-layout-bgcolor" value="#000000"/> -->
<!-- <param name="video-codec-bandwidth" value="2mb"/> -->
<!-- <param name="video-fps" value="15"/> -->
<!-- <param name="video-auto-floor-msec" value="100"/> -->
<!-- <param name="tts-engine" value="flite"/> -->
<!-- <param name="tts-voice" value="kal16"/> -->
</profile>
<profile name="cdquality">
<param name="domain" value="$${domain}"/>
<param name="rate" value="48000"/>
<param name="interval" value="20"/>
<param name="energy-level" value="100"/>
<!-- <param name="sound-prefix" value="$${sounds_dir}/en/us/callie"/> -->
{{if not (isTrue .Env.DISABLE_SOUND_MUTED) }}
<param name="muted-sound" value="conference/conf-muted.wav"/>
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
{{end}}
{{if not (isTrue .Env.DISABLE_SOUND_ALONE) }}
<param name="alone-sound" value="conference/conf-alone.wav"/>
{{end}}
<!--
<param name="moh-sound" value="$${hold_music}"/>
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
-->
<param name="locked-sound" value="conference/conf-locked.wav"/>
<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>
<param name="pin-sound" value="conference/conf-pin.wav"/>
<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<!-- param name="comfort-noise" value="true"/ -->
<param name="comfort-noise" value="1400"/>
<param name="video-auto-floor-msec" value="2000"/>
<!-- <param name="conference-flags" value="video-floor-only|rfc-4579|livearray-sync|auto-3d-position|minimize-video-encoding"/> -->
<!-- <param name="video-mode" value="mux"/> -->
<!-- <param name="video-layout-name" value="3x3"/> -->
<!-- <param name="video-layout-name" value="group:grid"/> -->
<!-- <param name="video-canvas-size" value="1920x1080"/> -->
<!-- <param name="video-canvas-bgcolor" value="#333333"/> -->
<!-- <param name="video-layout-bgcolor" value="#000000"/> -->
<!-- <param name="video-codec-bandwidth" value="2mb"/> -->
<!-- <param name="video-fps" value="15"/> -->
</profile>
<profile name="video-mcu-stereo">
<param name="domain" value="$${domain}"/>
<param name="rate" value="48000"/>
<param name="channels" value="2"/>
<param name="interval" value="20"/>
<param name="energy-level" value="100"/>
<!-- <param name="tts-engine" value="flite"/> -->
<!-- <param name="tts-voice" value="kal16"/> -->
<param name="muted-sound" value="conference/conf-muted.wav"/>
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
<param name="alone-sound" value="conference/conf-alone.wav"/>
<param name="moh-sound" value="local_stream://stereo"/>
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
<param name="locked-sound" value="conference/conf-locked.wav"/>
<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>
<param name="pin-sound" value="conference/conf-pin.wav"/>
<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<param name="comfort-noise" value="false"/>
<param name="conference-flags" value="video-floor-only|rfc-4579|livearray-sync|minimize-video-encoding"/>
<param name="video-mode" value="mux"/>
<param name="video-layout-name" value="3x3"/>
<param name="video-layout-name" value="group:grid"/>
<param name="video-canvas-size" value="1920x1080"/>
<param name="video-canvas-bgcolor" value="#333333"/>
<param name="video-layout-bgcolor" value="#000000"/>
<param name="video-codec-bandwidth" value="1mb"/>
<param name="video-fps" value="15"/>
</profile>
<profile name="sla">
<param name="domain" value="$${domain}"/>
<param name="rate" value="16000"/>
<param name="interval" value="20"/>
<param name="caller-controls" value="none"/>
<param name="energy-level" value="200"/>
<param name="moh-sound" value="silence"/>
<param name="comfort-noise" value="true"/>
</profile>
</profiles>
</configuration>

View File

@@ -0,0 +1,10 @@
<configuration name="event_socket.conf" description="Socket Client">
<settings>
<param name="nat-map" value="false"/>
<param name="listen-ip" value="$${local_ip_v4}"/>
<param name="listen-port" value="8021"/>
<param name="password" value="$${esl_password}"/>
<param name="apply-inbound-acl" value="loopback.custom"/>
<!--<param name="stop-on-bind-error" value="true"/>-->
</settings>
</configuration>

View File

@@ -0,0 +1,30 @@
<configuration name="modules.conf" description="Modules">
<modules>
<!-- Loggers (I'd load these first) -->
<load module="mod_console"/>
<!-- Event Handlers -->
<load module="mod_event_socket"/>
<!-- Endpoints -->
<load module="mod_sofia"/>
<!-- Applications -->
<load module="mod_commands"/>
<load module="mod_conference"/>
<load module="mod_dptools"/>
<!-- Dialplan Interfaces -->
<load module="mod_dialplan_xml"/>
<!-- Codec Interfaces -->
<load module="mod_spandsp"/>
<load module="mod_opus"/>
<load module="mod_opusfile"/>
<!-- File Format Interfaces -->
<load module="mod_sndfile"/>
<load module="mod_native_file"/>
</modules>
</configuration>

View File

@@ -0,0 +1,43 @@
<!--
NOTICE:
This context is usually accessed via the external sip profile listening on port 5080.
It is recommended to have separate inbound and outbound contexts. Not only for security
but clearing up why you would need to do such a thing. You don't want outside un-authenticated
callers hitting your default context which allows dialing calls thru your providers and results
in Toll Fraud.
-->
<!-- http://wiki.freeswitch.org/wiki/Dialplan_XML -->
<include>
<context name="public">
<extension name="unloop">
<condition field="${unroll_loops}" expression="^true$"/>
<condition field="${sip_looped_call}" expression="^true$">
<action application="deflect" data="${destination_number}"/>
</condition>
</extension>
<!--
Tag anything pass thru here as an outside_call so you can make sure not
to create any routing loops based on the conditions that it came from
the outside of the switch.
-->
<extension name="outside_call" continue="true">
<condition>
<action application="set" data="outside_call=true"/>
<action application="export" data="RFC2822_DATE=${strftime(%a, %d %b %Y %T %z)}"/>
</condition>
</extension>
<!--
You can place files in the public directory to get included.
-->
<X-PRE-PROCESS cmd="include" data="public_docker/*.xml"/>
<X-PRE-PROCESS cmd="include" data="public/*.xml"/>
</context>
</include>

View File

@@ -0,0 +1,113 @@
<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="none"/>
<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>

View File

@@ -0,0 +1,128 @@
<profile name="external">
<!-- 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/*.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="none"/>
<param name="manage-presence" value="false"/>
<!-- Added for Microsoft Edge browser -->
<param name="apply-candidate-acl" value="localnet.auto"/>
<param name="apply-candidate-acl" value="wan_v4.auto"/>
<param name="apply-candidate-acl" value="rfc1918.auto"/>
<param name="apply-candidate-acl" value="any_v4.auto"/>
<!-- 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="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>
<param name="ext-rtp-ip" value="auto-nat"/>
<param name="ext-sip-ip" value="auto-nat"/>
-->
<param name="rtp-ip" value="$${external_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>
<param name="ext-rtp-ip" value="$${external_rtp_ip}"/>
<param name="ext-sip-ip" value="$${external_sip_ip}"/>
<!--
Listen only clients somehow run into this timeout
causing
Hangup sofia/external/GLOBAL_AUDIO_76116@10.7.7.1 [CS_EXECUTE] [MEDIA_TIMEOUT]
[mcs-freeswitch] Dispatching conference new video floor event released
[mcs-freeswitch] Received CHANNEL_HANGUP for
-->
<param name="rtp-timeout-sec" value="86400"/>
<param name="rtp-hold-timeout-sec" value="1800"/>
<param name="enable-3pcc" value="proxy"/>
<!-- 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 'in_subjects', 'out_subjects' and 'all_subjects' 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="0.0.0.0:5066"/>
<param name="wss-binding" value="$${local_ip_v4}:7443"/>
<!-- enable rtcp on every channel also can be done per leg basis with rtcp_audio_interval_msec variable set to passthru to pass it across a call-->
<param name="rtcp-audio-interval-msec" value="5000"/>
<param name="rtcp-video-interval-msec" value="5000"/>
<!-- Cut down in the join time -->
<param name="dtmf-type" value="info"/>
<param name="liberal-dtmf" value="true"/>
</settings>
</profile>

View File

@@ -0,0 +1,398 @@
<include>
<X-PRE-PROCESS cmd="set" data="esl_password={{ .Env.ESL_PASSWORD }}"/>
<!-- Preprocessor Variables
These are introduced when configuration strings must be consistent across modules.
NOTICE: YOU CAN NOT COMMENT OUT AN X-PRE-PROCESS line, Remove the line instead.
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
YOU SHOULD CHANGE THIS default_password value if you don't want to be subject to any
toll fraud in the future. It's your responsibility to secure your own system.
This default config is used to demonstrate the feature set of FreeSWITCH.
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-->
<X-PRE-PROCESS cmd="set" data="default_password=1234"/>
<!-- Did you change it yet? -->
<!--
The following variables are set dynamically - calculated if possible by freeswitch - and
are available to the config as $${variable}. You can see their calculated value via fs_cli
by entering eval $${variable}
hostname
local_ip_v4
local_mask_v4
local_ip_v6
switch_serial
base_dir
recordings_dir
sound_prefix
sounds_dir
conf_dir
log_dir
run_dir
db_dir
mod_dir
htdocs_dir
script_dir
temp_dir
grammar_dir
certs_dir
storage_dir
cache_dir
core_uuid
zrtp_enabled
nat_public_addr
nat_private_addr
nat_type
-->
<X-PRE-PROCESS cmd="set" data="sound_prefix={{ .Env.SOUNDS_PATH }}"/>
<!--
This setting is what sets the default domain FreeSWITCH will use if all else fails.
FreeSWICH will default to $${local_ip_v4} unless changed. Changing this setting does
affect the sip authentication. Please review conf/directory/default.xml for more
information on this topic.
-->
<X-PRE-PROCESS cmd="set" data="local_ip_v4=10.7.7.1"/>
<X-PRE-PROCESS cmd="set" data="local_ip_v6=::1"/>
<X-PRE-PROCESS cmd="set" data="external_ip_v4={{ .Env.EXTERNAL_IPv4 }}"/>
<X-PRE-PROCESS cmd="set" data="external_ip_v6={{ .Env.EXTERNAL_IPv6 }}"/>
<X-PRE-PROCESS cmd="set" data="domain={{ .Env.DOMAIN }}"/>
<X-PRE-PROCESS cmd="set" data="domain_name=$${domain}"/>
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://moh"/>
<X-PRE-PROCESS cmd="set" data="use_profile=external"/>
<X-PRE-PROCESS cmd="set" data="rtp_sdes_suites=AEAD_AES_256_GCM_8|AEAD_AES_128_GCM_8|AES_CM_256_HMAC_SHA1_80|AES_CM_192_HMAC_SHA1_80|AES_CM_128_HMAC_SHA1_80|AES_CM_256_HMAC_SHA1_32|AES_CM_192_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_32|AES_CM_128_NULL_AUTH"/>
<!--
Enable ZRTP globally you can override this on a per channel basis
http://wiki.freeswitch.org/wiki/ZRTP (on how to enable zrtp)
-->
<X-PRE-PROCESS cmd="set" data="zrtp_secure_media=true"/>
<!--
NOTICE: When using SRTP it's critical that you do not offer or accept
variable bit rate codecs, doing so would leak information and possibly
compromise your SRTP stream. (FS-6404)
Supported SRTP Crypto Suites:
AEAD_AES_256_GCM_8
____________________________________________________________________________
This algorithm is identical to AEAD_AES_256_GCM (see Section 5.2 of
[RFC5116]), except that the tag length, t, is 8, and an
authentication tag with a length of 8 octets (64 bits) is used.
An AEAD_AES_256_GCM_8 ciphertext is exactly 8 octets longer than its
corresponding plaintext.
AEAD_AES_128_GCM_8
____________________________________________________________________________
This algorithm is identical to AEAD_AES_128_GCM (see Section 5.1 of
[RFC5116]), except that the tag length, t, is 8, and an
authentication tag with a length of 8 octets (64 bits) is used.
An AEAD_AES_128_GCM_8 ciphertext is exactly 8 octets longer than its
corresponding plaintext.
AES_CM_256_HMAC_SHA1_80 | AES_CM_192_HMAC_SHA1_80 | AES_CM_128_HMAC_SHA1_80
____________________________________________________________________________
AES_CM_128_HMAC_SHA1_80 is the SRTP default AES Counter Mode cipher
and HMAC-SHA1 message authentication with an 80-bit authentication
tag. The master-key length is 128 bits and has a default lifetime of
a maximum of 2^48 SRTP packets or 2^31 SRTCP packets, whichever comes
first.
AES_CM_256_HMAC_SHA1_32 | AES_CM_192_HMAC_SHA1_32 | AES_CM_128_HMAC_SHA1_32
____________________________________________________________________________
This crypto-suite is identical to AES_CM_128_HMAC_SHA1_80 except that
the authentication tag is 32 bits. The length of the base64-decoded key and
salt value for this crypto-suite MUST be 30 octets i.e., 240 bits; otherwise,
the crypto attribute is considered invalid.
AES_CM_128_NULL_AUTH
____________________________________________________________________________
The SRTP default cipher (AES-128 Counter Mode), but to use no authentication
method. This policy is NOT RECOMMENDED unless it is unavoidable; see
Section 7.5 of [RFC3711].
SRTP variables that modify behaviors based on direction/leg:
rtp_secure_media
____________________________________________________________________________
possible values:
mandatory - Accept/Offer SAVP negotiation ONLY
optional - Accept/Offer SAVP/AVP with SAVP preferred
forbidden - More useful for inbound to deny SAVP negotiation
false - implies forbidden
true - implies mandatory
default if not set is accept SAVP inbound if offered.
rtp_secure_media_inbound | rtp_secure_media_outbound
____________________________________________________________________________
This is the same as rtp_secure_media, but would apply to either inbound
or outbound offers specifically.
How to specify crypto suites:
____________________________________________________________________________
By default without specifying any crypto suites FreeSWITCH will offer
crypto suites from strongest to weakest accepting the strongest each
endpoint has in common. If you wish to force specific crypto suites you
can do so by appending the suites in a comma separated list in the order
that you wish to offer them in.
Examples:
rtp_secure_media=mandatory:AES_CM_256_HMAC_SHA1_80,AES_CM_256_HMAC_SHA1_32
rtp_secure_media=true:AES_CM_256_HMAC_SHA1_80,AES_CM_256_HMAC_SHA1_32
rtp_secure_media=optional:AES_CM_256_HMAC_SHA1_80
rtp_secure_media=true:AES_CM_256_HMAC_SHA1_80
Additionally you can narrow this down on either inbound or outbound by
specifying as so:
rtp_secure_media_inbound=true:AEAD_AES_256_GCM_8
rtp_secure_media_inbound=mandatory:AEAD_AES_256_GCM_8
rtp_secure_media_outbound=true:AEAD_AES_128_GCM_8
rtp_secure_media_outbound=optional:AEAD_AES_128_GCM_8
rtp_secure_media_suites
____________________________________________________________________________
Optionaly you can use rtp_secure_media_suites to dictate the suite list
and only use rtp_secure_media=[optional|mandatory|false|true] without having
to dictate the suite list with the rtp_secure_media* variables.
-->
<!--
Examples of codec options: (module must be compiled and loaded)
codecname[@8000h|16000h|32000h[@XXi]]
XX is the frame size must be multples allowed for the codec
FreeSWITCH can support 10-120ms on some codecs.
We do not support exceeding the MTU of the RTP packet.
iLBC@30i - iLBC using mode=30 which will win in all cases.
DVI4@8000h@20i - IMA ADPCM 8kHz using 20ms ptime. (multiples of 10)
DVI4@16000h@40i - IMA ADPCM 16kHz using 40ms ptime. (multiples of 10)
speex@8000h@20i - Speex 8kHz using 20ms ptime.
speex@16000h@20i - Speex 16kHz using 20ms ptime.
speex@32000h@20i - Speex 32kHz using 20ms ptime.
BV16 - BroadVoice 16kb/s narrowband, 8kHz
BV32 - BroadVoice 32kb/s wideband, 16kHz
G7221@16000h - G722.1 16kHz (aka Siren 7)
G7221@32000h - G722.1C 32kHz (aka Siren 14)
CELT@32000h - CELT 32kHz, only 10ms supported
CELT@48000h - CELT 48kHz, only 10ms supported
GSM@40i - GSM 8kHz using 40ms ptime. (GSM is done in multiples of 20, Default is 20ms)
G722 - G722 16kHz using default 20ms ptime. (multiples of 10)
PCMU - G711 8kHz ulaw using default 20ms ptime. (multiples of 10)
PCMA - G711 8kHz alaw using default 20ms ptime. (multiples of 10)
G726-16 - G726 16kbit adpcm using default 20ms ptime. (multiples of 10)
G726-24 - G726 24kbit adpcm using default 20ms ptime. (multiples of 10)
G726-32 - G726 32kbit adpcm using default 20ms ptime. (multiples of 10)
G726-40 - G726 40kbit adpcm using default 20ms ptime. (multiples of 10)
AAL2-G726-16 - Same as G726-16 but using AAL2 packing. (multiples of 10)
AAL2-G726-24 - Same as G726-24 but using AAL2 packing. (multiples of 10)
AAL2-G726-32 - Same as G726-32 but using AAL2 packing. (multiples of 10)
AAL2-G726-40 - Same as G726-40 but using AAL2 packing. (multiples of 10)
LPC - LPC10 using 90ms ptime (only supports 90ms at this time in FreeSWITCH)
L16 - L16 isn't recommended for VoIP but you can do it. L16 can exceed the MTU rather quickly.
These are the passthru audio codecs:
G729 - G729 in passthru mode. (mod_g729)
G723 - G723.1 in passthru mode. (mod_g723_1)
AMR - AMR in passthru mode. (mod_amr)
These are the passthru video codecs: (mod_h26x)
H261 - H.261 Video
H263 - H.263 Video
H263-1998 - H.263-1998 Video
H263-2000 - H.263-2000 Video
H264 - H.264 Video
RTP Dynamic Payload Numbers currently used in FreeSWITCH and what for.
96 - AMR
97 - iLBC (30)
98 - iLBC (20)
99 - Speex 8kHz, 16kHz, 32kHz
100 -
101 - telephone-event
102 -
103 -
104 -
105 -
106 - BV16
107 - G722.1 (16kHz)
108 -
109 -
110 -
111 -
112 -
113 -
114 - CELT 32kHz, 48kHz
115 - G722.1C (32kHz)
116 -
117 - SILK 8kHz
118 - SILK 12kHz
119 - SILK 16kHz
120 - SILK 24kHz
121 - AAL2-G726-40 && G726-40
122 - AAL2-G726-32 && G726-32
123 - AAL2-G726-24 && G726-24
124 - AAL2-G726-16 && G726-16
125 -
126 -
127 - BV32
-->
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,speex@16000h@20i,speex@8000h@20i,G722,PCMU,PCMA"/>
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=OPUS,speex@16000h@20i,G722,PCMU,PCMA"/>
<!--
xmpp_client_profile and xmpp_server_profile
xmpp_client_profile can be any string.
xmpp_server_profile is appended to "dingaling_" to form the database name
containing the "subscriptions" table.
used by: dingaling.conf.xml enum.conf.xml
-->
<X-PRE-PROCESS cmd="set" data="xmpp_client_profile=xmppc"/>
<X-PRE-PROCESS cmd="set" data="xmpp_server_profile=xmpps"/>
<!--
THIS IS ONLY USED FOR DINGALING
bind_server_ip
Can be an ip address, a dns name, or "auto".
This determines an ip address available on this host to bind.
If you are separating RTP and SIP traffic, you will want to have
use different addresses where this variable appears.
Used by: dingaling.conf.xml
-->
<X-PRE-PROCESS cmd="set" data="bind_server_ip=auto"/>
<!-- NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
If you're going to load test FreeSWITCH please input real IP addresses
for external_rtp_ip and external_sip_ip
-->
<!-- external_rtp_ip
Can be an one of:
ip address: "12.34.56.78"
a stun server lookup: "stun:stun.server.com"
a DNS name: "host:host.server.com"
where fs.mydomain.com is a DNS A record-useful when fs is on
a dynamic IP address, and uses a dynamic DNS updater.
If unspecified, the bind_server_ip value is used.
Used by: sofia.conf.xml dingaling.conf.xml
-->
<X-PRE-PROCESS cmd="set" data="external_rtp_ip={{ .Env.EXTERNAL_IPv4 }}"/>
<!-- external_sip_ip
Used as the public IP address for SDP.
Can be an one of:
ip address: "12.34.56.78"
a stun server lookup: "stun:stun.server.com"
a DNS name: "host:host.server.com"
where fs.mydomain.com is a DNS A record-useful when fs is on
a dynamic IP address, and uses a dynamic DNS updater.
If unspecified, the bind_server_ip value is used.
Used by: sofia.conf.xml dingaling.conf.xml
-->
<X-PRE-PROCESS cmd="set" data="external_sip_ip={{ .Env.EXTERNAL_IPv4 }}"/>
<!-- unroll-loops
Used to turn on sip loopback unrolling.
-->
<X-PRE-PROCESS cmd="set" data="unroll_loops=true"/>
<!-- outbound_caller_id and outbound_caller_name
The caller ID telephone number we should use when calling out.
Used by: conference.conf.xml and user directory for default
outbound callerid name and number.
-->
<X-PRE-PROCESS cmd="set" data="outbound_caller_name=FreeSWITCH"/>
<X-PRE-PROCESS cmd="set" data="outbound_caller_id=0000000000"/>
<!-- various debug and defaults -->
<X-PRE-PROCESS cmd="set" data="call_debug=false"/>
<X-PRE-PROCESS cmd="set" data="console_loglevel=info"/>
<X-PRE-PROCESS cmd="set" data="default_areacode=918"/>
<X-PRE-PROCESS cmd="set" data="default_country=US"/>
<!-- if false or undefined, the destination number is included in presence NOTIFY dm:note.
if true, the destination number is not included -->
<X-PRE-PROCESS cmd="set" data="presence_privacy=false"/>
<X-PRE-PROCESS cmd="set" data="au-ring=%(400,200,383,417);%(400,2000,383,417)"/>
<X-PRE-PROCESS cmd="set" data="be-ring=%(1000,3000,425)"/>
<X-PRE-PROCESS cmd="set" data="ca-ring=%(2000,4000,440,480)"/>
<X-PRE-PROCESS cmd="set" data="cn-ring=%(1000,4000,450)"/>
<X-PRE-PROCESS cmd="set" data="cy-ring=%(1500,3000,425)"/>
<X-PRE-PROCESS cmd="set" data="cz-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="de-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="dk-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="dz-ring=%(1500,3500,425)"/>
<X-PRE-PROCESS cmd="set" data="eg-ring=%(2000,1000,475,375)"/>
<X-PRE-PROCESS cmd="set" data="es-ring=%(1500,3000,425)"/>
<X-PRE-PROCESS cmd="set" data="fi-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="fr-ring=%(1500,3500,440)"/>
<X-PRE-PROCESS cmd="set" data="hk-ring=%(400,200,440,480);%(400,3000,440,480)"/>
<X-PRE-PROCESS cmd="set" data="hu-ring=%(1250,3750,425)"/>
<X-PRE-PROCESS cmd="set" data="il-ring=%(1000,3000,400)"/>
<X-PRE-PROCESS cmd="set" data="in-ring=%(400,200,425,375);%(400,2000,425,375)"/>
<X-PRE-PROCESS cmd="set" data="jp-ring=%(1000,2000,420,380)"/>
<X-PRE-PROCESS cmd="set" data="ko-ring=%(1000,2000,440,480)"/>
<X-PRE-PROCESS cmd="set" data="pk-ring=%(1000,2000,400)"/>
<X-PRE-PROCESS cmd="set" data="pl-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="ro-ring=%(1850,4150,475,425)"/>
<X-PRE-PROCESS cmd="set" data="rs-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="ru-ring=%(800,3200,425)"/>
<X-PRE-PROCESS cmd="set" data="sa-ring=%(1200,4600,425)"/>
<X-PRE-PROCESS cmd="set" data="tr-ring=%(2000,4000,450)"/>
<X-PRE-PROCESS cmd="set" data="uk-ring=%(400,200,400,450);%(400,2000,400,450)"/>
<X-PRE-PROCESS cmd="set" data="us-ring=%(2000,4000,440,480)"/>
<X-PRE-PROCESS cmd="set" data="bong-ring=v=-7;%(100,0,941.0,1477.0);v=-7;>=2;+=.1;%(1400,0,350,440)"/>
<X-PRE-PROCESS cmd="set" data="beep=%(1000,0,640)"/>
<X-PRE-PROCESS cmd="set" data="sit=%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)"/>
<!--
Digits Dialed filter: (FS-6940)
The digits stream may contain valid credit card numbers or social security numbers, These digit
filters will allow you to make a valant effort to stamp out sensitive information for
PCI/HIPPA compliance. (see xml_cdr dialed_digits)
df_us_ssn = US Social Security Number pattern
df_us_luhn = Visa, MasterCard, American Express, Diners Club, Discover and JCB
-->
<X-PRE-PROCESS cmd="set" data="df_us_ssn=(?!219099999|078051120)(?!666|000|9\d{2})\d{3}(?!00)\d{2}(?!0{4})\d{4}"/>
<X-PRE-PROCESS cmd="set" data="df_luhn=?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11}"/>
<!-- change XX to X below to enable -->
<XX-PRE-PROCESS cmd="set" data="digits_dialed_filter=(($${df_luhn})|($${df_us_ssn}))"/>
<!--
Setting up your default sip provider is easy.
Below are some values that should work in most cases.
These are for conf/directory/default/example.com.xml
-->
<X-PRE-PROCESS cmd="set" data="default_provider=example.com"/>
<X-PRE-PROCESS cmd="set" data="default_provider_username=joeuser"/>
<X-PRE-PROCESS cmd="set" data="default_provider_password=password"/>
<X-PRE-PROCESS cmd="set" data="default_provider_from_domain=example.com"/>
<!-- true or false -->
<X-PRE-PROCESS cmd="set" data="default_provider_register=false"/>
<X-PRE-PROCESS cmd="set" data="default_provider_contact=5000"/>
<!--
SIP and TLS settings. http://wiki.freeswitch.org/wiki/Tls
valid options: sslv2,sslv3,sslv23,tlsv1,tlsv1.1,tlsv1.2
default: tlsv1,tlsv1.1,tlsv1.2
-->
<X-PRE-PROCESS cmd="set" data="sip_tls_version=tlsv1,tlsv1.1,tlsv1.2"/>
<!--
TLS cipher suite: default ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH
The actual ciphers supported will change per platform.
openssl ciphers -v 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH'
Will show you what is available in your verion of openssl.
-->
<X-PRE-PROCESS cmd="set" data="sip_tls_ciphers=ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"/>
<!-- Internal SIP Profile -->
<X-PRE-PROCESS cmd="set" data="internal_auth_calls=true"/>
<X-PRE-PROCESS cmd="set" data="internal_sip_port=5090"/>
<X-PRE-PROCESS cmd="set" data="internal_tls_port=5061"/>
<X-PRE-PROCESS cmd="set" data="internal_ssl_enable=false"/>
<!-- External SIP Profile -->
<X-PRE-PROCESS cmd="set" data="external_auth_calls=false"/>
<X-PRE-PROCESS cmd="set" data="external_sip_port=5060"/>
<X-PRE-PROCESS cmd="set" data="external_tls_port=5081"/>
<X-PRE-PROCESS cmd="set" data="external_ssl_enable=false"/>
<!-- Video Settings -->
<!-- Setting the max bandwdith -->
<X-PRE-PROCESS cmd="set" data="rtp_video_max_bandwidth_in=1mb"/>
<X-PRE-PROCESS cmd="set" data="rtp_video_max_bandwidth_out=1mb"/>
<!-- WebRTC Video -->
<!-- Suppress CNG for WebRTC Audio -->
<X-PRE-PROCESS cmd="set" data="suppress_cng=true"/>
<!-- Enable liberal DTMF for those that can't get it right -->
<X-PRE-PROCESS cmd="set" data="rtp_liberal_dtmf=true"/>
<!-- Helps with WebRTC Audio -->
<!-- Stock Video Avatars -->
<X-PRE-PROCESS cmd="set" data="video_mute_png=$${images_dir}/default-mute.png"/>
<X-PRE-PROCESS cmd="set" data="video_no_avatar_png=$${images_dir}/default-avatar.png"/>
</include>

52
mod/freeswitch/entrypoint.sh Executable file
View File

@@ -0,0 +1,52 @@
#!/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
chown -R freeswitch:daemon /var/freeswitch/meetings
chmod 777 /var/freeswitch/meetings
# install freeswitch sounds if missing
SOUNDS_DIR=/usr/share/freeswitch/sounds
if [ "$SOUNDS_LANGUAGE" == "de-de-daedalus3" ]; then
if [ ! -d "$SOUNDS_DIR/de/de/daedalus3" ]; then
echo "sounds package for de-de-daedalus3 not installed yet"
wget -O /tmp/freeswitch-german-soundfiles.zip https://github.com/Daedalus3/freeswitch-german-soundfiles/archive/master.zip
mkdir -p $SOUNDS_DIR/de/de/daedalus3
unzip /tmp/freeswitch-german-soundfiles.zip -d /tmp/
mv /tmp/freeswitch-german-soundfiles-master $SOUNDS_DIR/de/de/daedalus3/conference
# symlink other folders
for folder in "digits" "ivr" "misc"; do
ln -s $SOUNDS_DIR/en/us/callie/$folder $SOUNDS_DIR/de/de/daedalus3/$folder
done
fi
else
SOUNDS_PACKAGE=$(echo "freeswitch-sounds-${SOUNDS_LANGUAGE}" | tr '[:upper:]' '[:lower:]')
if ! dpkg -s $SOUNDS_PACKAGE >/dev/null 2>&1; then
echo "sounds package for $SOUNDS_LANGUAGE not installed yet"
apt-get install $SOUNDS_PACKAGE
fi
fi
export SOUNDS_PATH=$SOUNDS_DIR/$(echo "$SOUNDS_LANGUAGE" | sed 's|-|/|g')
dockerize \
-template /etc/freeswitch/vars.xml.tmpl:/etc/freeswitch/vars.xml \
-template /etc/freeswitch/autoload_configs/conference.conf.xml.tmpl:/etc/freeswitch/autoload_configs/conference.conf.xml \
/usr/bin/freeswitch -u freeswitch -g daemon -nonat -nf

38
mod/fsesl-akka/Dockerfile Normal file
View File

@@ -0,0 +1,38 @@
ARG BBB_BUILD_TAG
FROM gitlab.senfcall.de:5050/senfcall-public/docker-bbb-build:$BBB_BUILD_TAG AS builder
ARG TAG_COMMON_MESSAGE
# download bbb-common-message
RUN svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_COMMON_MESSAGE/bbb-common-message /bbb-common-message \
&& cd /bbb-common-message \
&& ./deploy.sh \
&& rm -rf /bbb-common-message
# ===================================================
ARG TAG_FSESL_AKKA
RUN svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_FSESL_AKKA/bbb-fsesl-client /bbb-fsesl-client \
&& rm -rf /bbb-fsesl-client/.svn
RUN cd /bbb-fsesl-client \
&& ./deploy.sh
RUN svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_FSESL_AKKA/akka-bbb-fsesl /source \
&& rm -rf /source/.svn
# compile and unzip bin
RUN cd /source \
&& sbt universal:packageBin
RUN unzip /source/target/universal/bbb-fsesl-akka-0.0.2.zip -d /
# # ===================================================
FROM alangecker/bbb-docker-base-java
COPY --from=builder /bbb-fsesl-akka-0.0.2 /bbb-fsesl-akka
COPY bbb-fsesl-akka.conf /etc/bigbluebutton/bbb-fsesl-akka.conf.tmpl
COPY logback.xml /bbb-fsesl-akka/conf/logback.xml
COPY entrypoint.sh /entrypoint.sh
USER bigbluebutton
ENTRYPOINT /entrypoint.sh

View File

@@ -0,0 +1,18 @@
// include default config from upstream
include "/bbb-fsesl-akka/conf/application.conf"
freeswitch {
esl {
host="10.7.7.1"
password="FSESL_PASSWORD"
}
}
redis {
host="10.7.7.5"
}
http {
interface = "0.0.0.0"
}

9
mod/fsesl-akka/entrypoint.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/sh -e
TARGET=/etc/bigbluebutton/bbb-fsesl-akka.conf
cp /etc/bigbluebutton/bbb-fsesl-akka.conf.tmpl $TARGET
sed -i "s/FSESL_PASSWORD/$FSESL_PASSWORD/" $TARGET
cd /bbb-fsesl-akka
/bbb-fsesl-akka/bin/bbb-fsesl-akka

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"} %-5level %logger{35} - %msg%n</Pattern>
</layout>
</appender>
<logger name="akka" level="INFO" />
<logger name="org.bigbluebutton" level="DEBUG" />
<logger name="org.freeswitch.esl" level="WARN" />
<logger name="io.lettuce" level="INFO" />
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE" />
</root>
</configuration>

34
mod/html5/Dockerfile Normal file
View File

@@ -0,0 +1,34 @@
ARG BBB_BUILD_TAG
FROM gitlab.senfcall.de:5050/senfcall-public/docker-bbb-build:$BBB_BUILD_TAG AS builder
# RUN groupadd -g 2000 meteor && useradd -m -u 2001 -g meteor meteor
# USER meteor
ARG TAG_HTML5
RUN svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_HTML5/bigbluebutton-html5 /source \
&& cd /source \
&& meteor npm ci --production \
&& METEOR_DISABLE_OPTIMISTIC_CACHING=1 meteor build --architecture os.linux.x86_64 --allow-superuser --directory /app \
&& rm -rf /source
RUN cd /app/bundle/programs/server \
&& npm install --production
RUN sed -i "s/VERSION/$TAG_HTML5/" /app/bundle/programs/web.browser/head.html \
&& find /app/bundle/programs/web.browser -name '*.js' -exec gzip -k -f -9 '{}' \; \
&& find /app/bundle/programs/web.browser -name '*.css' -exec gzip -k -f -9 '{}' \; \
&& find /app/bundle/programs/web.browser -name '*.wasm' -exec gzip -k -f -9 '{}' \;
# ------------------------------
FROM node:14.19.1-alpine
RUN addgroup -g 2000 meteor && \
adduser -D -u 2001 -G meteor meteor && \
apk add su-exec
COPY --from=alangecker/bbb-docker-base-java /usr/local/bin/dockerize /usr/local/bin/dockerize
COPY --from=builder --chown=meteor:meteor /app/bundle /app
COPY entrypoint.sh /entrypoint.sh
COPY bbb-html5.yml /app/bbb-html5.yml.tmpl
ENTRYPOINT ["/entrypoint.sh"]

24
mod/html5/bbb-html5.yml Normal file
View File

@@ -0,0 +1,24 @@
public:
app:
bbbServerVersion: {{ .Env.TAG_HTML5 }}-docker
listenOnlyMode: {{ .Env.LISTEN_ONLY_MODE }}
skipCheck: {{ .Env.DISABLE_ECHO_TEST }}
clientTitle: {{ .Env.CLIENT_TITLE }}
appName: BigBlueButton HTML5 Client (docker)
breakouts:
breakoutRoomLimit: {{ .Env.BREAKOUTROOM_LIMIT }}
kurento:
wsUrl: wss://{{ .Env.DOMAIN }}/bbb-webrtc-sfu
autoShareWebcam: {{ .Env.AUTO_SHARE_WEBCAM }}
skipVideoPreview: {{ .Env.DISABLE_VIDEO_PREVIEW }}
chat:
enabled: {{ .Env.CHAT_ENABLED }}
startClosed: {{ .Env.CHAT_START_CLOSED }}
pads:
url: https://{{ .Env.DOMAIN }}/pad
private:
app:
host: 0.0.0.0
redis:
host: redis
port: '6379'

43
mod/html5/entrypoint.sh Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/sh
set -e
cd /app
export MONGO_OPLOG_URL=mongodb://10.7.7.6/local
export MONGO_URL=mongodb://10.7.7.6/meteor
export ROOT_URL=http://127.0.0.1/html5client
export NODE_ENV=production
export SERVER_WEBSOCKET_COMPRESSION='{"level":5, "maxWindowBits":13, "memLevel":7, "requestMaxWindowBits":13}'
export BIND_IP=0.0.0.0
export LANG=en_US.UTF-8
export INSTANCE_MAX=1
export ENVIRONMENT_TYPE=production
export NODE_VERSION=node-v14.19.1-linux-x64
export BBB_HTML5_LOCAL_SETTINGS=/app/bbb-html5.yml
if [ "$DEV_MODE" == true ]; then
echo "DEV_MODE=true, disable TLS certificate rejecting"
export NODE_TLS_REJECT_UNAUTHORIZED=0
fi
if [ "$BBB_HTML5_ROLE" == "backend" ]; then
PARAM=NODEJS_BACKEND_INSTANCE_ID=$INSTANCE_ID
fi
# if container is the first frontend, do some additional tasks
if [ "$BBB_HTML5_ROLE" == "frontend" ] && [ "$INSTANCE_ID" == "1" ]; then
# copy static files into volume for direct access by nginx
# https://github.com/bigbluebutton/bigbluebutton/issues/10739
if [ -d "/html5-static" ]; then
rm -rf /html5-static/*
cp -r /app/programs/web.browser/* /html5-static
fi
fi
dockerize \
-template /app/bbb-html5.yml.tmpl:/app/bbb-html5.yml \
su-exec meteor \
node --max-old-space-size=2048 --max_semi_space_size=128 main.js $PARAM

View File

@@ -0,0 +1,33 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl http2 default_server;
# we at still serve https via IPv6 for the
# case that an AAAA record is set.
listen [::]:443 ssl http2 default_server;
server_name _;
include resty-server-https.conf;
location / {
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:48087;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 6h;
proxy_send_timeout 6h;
client_body_timeout 6h;
send_timeout 6h;
}
}

33
mod/https/site.conf Normal file
View File

@@ -0,0 +1,33 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
map $remote_addr $endpoint_addr {
"~:" [::1];
default 127.0.0.1;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name _;
include resty-server-https.conf;
location / {
proxy_http_version 1.1;
proxy_pass http://$endpoint_addr:48087;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 6h;
proxy_send_timeout 6h;
client_body_timeout 6h;
send_timeout 6h;
}
}

View File

@@ -0,0 +1,17 @@
FROM eugenmayer/jodconverter:rest
RUN echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | debconf-set-selections
RUN sed -i 's/main/main contrib/' /etc/apt/sources.list && apt-get update
RUN apt-get update && apt -y install --no-install-recommends \
fonts-arkpandora \
fonts-crosextra-carlito \
fonts-crosextra-caladea \
fonts-noto \
fonts-noto-cjk \
fonts-liberation \
fontconfig \
ttf-mscorefonts-installer
# avoid "APPLICATION FAILED TO START. Config data location '/etc/app/' does not exist"
# https://github.com/bigbluebutton/docker/issues/178
CMD ["--spring.config.additional-location=optional:/etc/app/"]

26
mod/mongo/init-replica.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/sh
set -e
host=${HOSTNAME:-$(hostname -f)}
# shut down again
mongod --pidfilepath /tmp/docker-entrypoint-temp-mongod.pid --shutdown
# restart again binding to 0.0.0.0 to allow a replset with 10.7.7.6
mongod --oplogSize 8 --replSet rs0 --noauth \
--config /tmp/docker-entrypoint-temp-config.json \
--bind_ip 0.0.0.0 --port 27017 \
--tlsMode disabled \
--logpath /proc/1/fd/1 --logappend \
--pidfilepath /tmp/docker-entrypoint-temp-mongod.pid --fork
# init replset with defaults
mongo 10.7.7.6 --eval "rs.initiate({
_id: 'rs0',
members: [ { _id: 0, host: '10.7.7.6:27017' } ]
})"
echo "Waiting to become a master"
echo 'while (!db.isMaster().ismaster) { sleep(100); }' | mongo
echo "I'm the master!"

33
mod/mongo/mongod.conf Normal file
View File

@@ -0,0 +1,33 @@
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
storage:
dbPath: /data/db
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
journalCompressor: none
directoryForIndexes: true
collectionConfig:
blockCompressor: none
indexConfig:
prefixCompression: false
net:
port: 27017
bindIp: 0.0.0.0
replication:
replSetName: rs0
setParameter:
diagnosticDataCollectionEnabled: false
security:
javascriptEnabled: false

22
mod/nginx/Dockerfile Normal file
View File

@@ -0,0 +1,22 @@
FROM node:14-alpine AS builder
RUN apk add subversion git
# --------------------
ARG TAG_LEARNING_DASHBOARD
RUN svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_LEARNING_DASHBOARD/bbb-learning-dashboard /bbb-learning-dashboard && rm -r /bbb-learning-dashboard/.svn
RUN cd /bbb-learning-dashboard && npm ci && npm run build
COPY ./bbb-playback /bbb-playback
RUN cd /bbb-playback && npm ci && npm run build
# --------------------
FROM nginx:1.21-alpine
COPY --from=builder /bbb-learning-dashboard/build /www/learning-analytics-dashboard/
COPY --from=builder /bbb-playback/build /www/playback/presentation/2.3
COPY ./bbb /etc/nginx/bbb
COPY ./bigbluebutton /etc/nginx/conf.d/default.conf
COPY ./nginx.conf /etc/nginx/nginx.conf

View File

@@ -0,0 +1,4 @@
location /bbb-exporter {
proxy_pass http://10.7.7.33:9688;
proxy_http_version 1.1;
}

View File

@@ -0,0 +1,40 @@
location @html5client {
proxy_pass http://poolhtml5servers; # use for production
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location /html5client/locales {
alias /html5-static/app/locales;
}
location /html5client/compatibility {
alias /html5-static/app/compatibility;
}
location /html5client/resources {
alias /html5-static/app/resources;
}
location /html5client/svgs {
alias /html5-static/app/svgs;
}
location /html5client/fonts {
alias /html5-static/app/fonts;
}
location /html5client/wasm {
types {
application/wasm wasm;
}
gzip_static on;
alias /html5-static/app/wasm;
}
location /html5client/ {
alias /html5-static;
try_files $uri @html5client;
}

26
mod/nginx/bbb/demo.nginx Normal file
View File

@@ -0,0 +1,26 @@
# Forward request to /demo to tomcat. This is for
# the BigBlueButton api demos.
location = /demo/ {
return 301 /demo/demo1.jsp;
}
location /demo {
proxy_pass http://host.docker.internal:8001;
proxy_redirect default;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Allow 30M uploaded presentation document.
client_max_body_size 30m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
include fastcgi_params;
}

View File

@@ -0,0 +1,34 @@
# Routes requests to Greenlight based on the '/b' prefix.
# Use this file to route '/b' paths on your BigBlueButton server
# to the Greenlight application. If you are using a different
# subpath, you should change it here.
location /b {
proxy_pass http://host.docker.internal:5000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
proxy_http_version 1.1;
}
location /b/cable {
proxy_pass http://host.docker.internal:5000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_http_version 1.1;
proxy_read_timeout 6h;
proxy_send_timeout 6h;
client_body_timeout 6h;
send_timeout 6h;
}
# this is necessary for the preupload_presentation feature
location /rails/active_storage {
return 301 /b$request_uri;
}

View File

@@ -0,0 +1,9 @@
location ~ /learning-analytics-dashboard/([0-9a-f]+-[0-9]+)/(.*) {
root /var/bigbluebutton/learning-analytics-dashboard/;
autoindex off;
}
location /learning-analytics-dashboard/ {
alias /www/learning-analytics-dashboard/;
autoindex off;
}

View File

@@ -0,0 +1,4 @@
# If you run this BBB node behind a proxy loadbalancer set the hostname of
# the loadbalancer here. This will be used to add CORS headers so requesting
# slides and API calls won't fail
set $bbb_loadbalancer_node '';

View File

@@ -0,0 +1,4 @@
location /notes {
root /var/bigbluebutton/published;
index index.html index.htm;
}

77
mod/nginx/bbb/notes.nginx Normal file
View File

@@ -0,0 +1,77 @@
# https://github.com/ether/etherpad-lite/wiki/How-to-put-Etherpad-Lite-behind-a-reverse-Proxy
location /pad/p/ {
# Avoid setting the user name from the embedded URL
if ($arg_userName) {
return 401;
}
rewrite /pad/p/(.*) /p/$1 break;
rewrite ^/pad/p$ /pad/p/ permanent;
proxy_pass http://etherpad:9001/p;
proxy_pass_header Server;
proxy_redirect /p /pad/p;
proxy_set_header Host $host;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr; # http://wiki.nginx.org/HttpProxyModule
proxy_set_header X-Forwarded-For $remote_addr; # EP logs to show the actual remote IP
proxy_set_header X-Forwarded-Proto $scheme; # for EP to set secure cookie flag when https is used
proxy_http_version 1.1;
auth_request /bigbluebutton/connection/checkAuthorization;
auth_request_set $auth_status $upstream_status;
}
location /pad/auth_session {
rewrite /pad/auth_session(.*) /auth_session$1 break;
proxy_pass http://etherpad:9001/;
proxy_pass_header Server;
proxy_set_header Host $host;
proxy_buffering off;
auth_request /bigbluebutton/connection/checkAuthorization;
auth_request_set $auth_status $upstream_status;
}
location /pad {
rewrite /pad/(.*) /$1 break;
rewrite ^/pad$ /pad/ permanent;
proxy_pass http://etherpad:9001/;
proxy_pass_header Server;
proxy_redirect / /pad/;
proxy_set_header Host $host;
proxy_buffering off;
}
location /pad/socket.io/socket.io.js {
rewrite /pad/socket.io/socket.io.js /socket.io/socket.io.js break;
proxy_pass http://etherpad:9001/;
proxy_set_header Host $host;
proxy_buffering off;
}
location /pad/socket.io {
rewrite /pad/socket.io/(.*) /socket.io/$1 break;
proxy_pass http://etherpad:9001/;
proxy_redirect / /pad/;
proxy_set_header Host $host;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr; # http://wiki.nginx.org/HttpProxyModule
proxy_set_header X-Forwarded-For $remote_addr; # EP logs to show the actual remote IP
proxy_set_header X-Forwarded-Proto $scheme; # for EP to set secure cookie flag when https is used
proxy_set_header Host $host; # pass the host header
proxy_http_version 1.1; # recommended with keepalive connections
# WebSocket proxying - from http://nginx.org/en/docs/http/websocket.html
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
auth_request /bigbluebutton/connection/checkAuthorization;
auth_request_set $auth_status $upstream_status;
}
location /static {
rewrite /static/(.*) /static/$1 break;
proxy_pass http://etherpad:9001/;
proxy_set_header Host $host;
proxy_buffering off;
}

View File

@@ -0,0 +1,22 @@
#
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
#
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
#
location /podcast {
root /var/bigbluebutton/published;
index index.html index.htm;
}

View File

@@ -0,0 +1,53 @@
#
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
#
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
#
# Have nginx serve the presentation slides instead of tomcat as large files
# causes tomcat to OOM. (ralam sept 20, 2018)
location ~^\/bigbluebutton\/presentation\/(?<meeting_id_1>[A-Za-z0-9\-]+)\/(?<meeting_id_2>[A-Za-z0-9\-]+)\/(?<pres_id>[A-Za-z0-9\-]+)\/svg\/(?<page_num>\d+)$ {
default_type image/svg+xml;
alias /var/bigbluebutton/$meeting_id_2/$meeting_id_2/$pres_id/svgs/slide$page_num.svg;
if ($bbb_loadbalancer_node) {
add_header 'Access-Control-Allow-Origin' $bbb_loadbalancer_node always;
}
}
location ~^\/bigbluebutton\/presentation\/(?<meeting_id_1>[A-Za-z0-9\-]+)\/(?<meeting_id_2>[A-Za-z0-9\-]+)\/(?<pres_id>[A-Za-z0-9\-]+)\/slide\/(?<page_num>\d+)$ {
alias /var/bigbluebutton/$meeting_id_2/$meeting_id_2/$pres_id/slide-$page_num.swf;
if ($bbb_loadbalancer_node) {
add_header 'Access-Control-Allow-Origin' $bbb_loadbalancer_node always;
}
}
location ~^\/bigbluebutton\/presentation\/(?<meeting_id_1>[A-Za-z0-9\-]+)\/(?<meeting_id_2>[A-Za-z0-9\-]+)\/(?<pres_id>[A-Za-z0-9\-]+)\/thumbnail\/(?<page_num>\d+)$ {
default_type image/png;
alias /var/bigbluebutton/$meeting_id_2/$meeting_id_2/$pres_id/thumbnails/thumb-$page_num.png;
if ($bbb_loadbalancer_node) {
add_header 'Access-Control-Allow-Origin' $bbb_loadbalancer_node always;
}
}
location ~^\/bigbluebutton\/presentation\/(?<meeting_id_1>[A-Za-z0-9\-]+)\/(?<meeting_id_2>[A-Za-z0-9\-]+)\/(?<pres_id>[A-Za-z0-9\-]+)\/textfiles\/(?<page_num>\d+)$ {
default_type text/plain;
alias /var/bigbluebutton/$meeting_id_2/$meeting_id_2/$pres_id/textfiles/slide-$page_num.txt;
if ($bbb_loadbalancer_node) {
add_header 'Access-Control-Allow-Origin' $bbb_loadbalancer_node always;
}
}

View File

@@ -0,0 +1,28 @@
#
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
#
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
#
location /playback/presentation/2.0/playback.html {
return 301 /playback/presentation/2.3/$arg_meetingId?$query_string;
}
location /playback/presentation/2.3 {
try_files $uri /playback/presentation/2.3/index.html;
}
location /presentation {
root /var/bigbluebutton/published;
index index.html index.htm;
}

15
mod/nginx/bbb/sip.nginx Normal file
View File

@@ -0,0 +1,15 @@
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;
}

10
mod/nginx/bbb/verto.nginx Normal file
View File

@@ -0,0 +1,10 @@
location /verto {
proxy_pass https://host.docker.internal:8082;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_read_timeout 6h;
proxy_send_timeout 6h;
client_body_timeout 6h;
send_timeout 6h;
}

180
mod/nginx/bbb/web.nginx Executable file
View File

@@ -0,0 +1,180 @@
# Handle request to bbb-web running within a SpringBoot Tomcat embedded servlet container. This is for BBB-API and Presentation.
location /bigbluebutton {
proxy_http_version 1.1;
location /bigbluebutton {
proxy_pass http://bbb-web:8090;
proxy_redirect default;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Workaround IE refusal to set cookies in iframe
add_header P3P 'CP="No P3P policy available"';
if ($bbb_loadbalancer_node) {
add_header 'Access-Control-Allow-Origin' $bbb_loadbalancer_node always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
}
}
location ~ "^\/bigbluebutton\/presentation\/(?<prestoken>[a-zA-Z0-9_-]+)/upload$" {
# Grails can't handle CORS OPTION preflight requests correctly -> lets do this in nginx
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $bbb_loadbalancer_node always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://bbb-web:8090;
proxy_redirect default;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Workaround IE refusal to set cookies in iframe
add_header P3P 'CP="No P3P policy available"';
if ($bbb_loadbalancer_node) {
add_header 'Access-Control-Allow-Origin' $bbb_loadbalancer_node always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
}
# high limit for presentation as bbb-web will reject upload if larger than configured
client_max_body_size 1000m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
include fastcgi_params;
proxy_request_buffering off;
# Send a sub-request to allow bbb-web to refuse before loading
# If file is larger than configured bbb-web will return with code 403 and Header: x-file-too-large = 1
auth_request /bigbluebutton/presentation/checkPresentation;
error_page 403 = @error403;
auth_request_set $file_too_large_header $upstream_http_x_file_too_large;
}
location /bigbluebutton/presentation/download {
return 404;
}
location ~ "^/bigbluebutton/presentation/download\/[0-9a-f]+-[0-9]+/[0-9a-f]+-[0-9]+$" {
if ($arg_presFilename !~ "^[0-9a-f]+-[0-9]+\.[0-9a-zA-Z]+$") {
return 404;
}
proxy_pass http://bbb-web:8090$uri$is_args$args;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Workaround IE refusal to set cookies in iframe
add_header P3P 'CP="No P3P policy available"';
if ($bbb_loadbalancer_node) {
add_header 'Access-Control-Allow-Origin' $bbb_loadbalancer_node always;
}
}
location = /bigbluebutton/presentation/checkPresentation {
proxy_pass http://bbb-web:8090;
proxy_redirect default;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Presentation-Token $prestoken;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header Content-Length "";
proxy_set_header X-Original-Content-Length $http_content_length;
# high limit for presentation as bbb-web will reject upload if larger than configured
client_max_body_size 1000m;
client_body_buffer_size 128k;
proxy_pass_request_body off;
proxy_request_buffering off;
}
# To check connection authentication, include:
# auth_request /bigbluebutton/connection/checkAuthorization;
# auth_request_set $auth_status $upstream_status;
#
# and make sure to add sessionToken param in the request URI
location = /bigbluebutton/connection/checkAuthorization {
internal;
proxy_pass http://bbb-web:8090;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
location = /bigbluebutton/connection/legacyCheckAuthorization {
internal;
proxy_pass http://bbb-web:8090;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
location = /bigbluebutton/connection/validatePad {
internal;
proxy_pass http://bbb-web:8090;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
location ~ "^/bigbluebutton\/textTrack\/(?<textTrackToken>[a-zA-Z0-9]+)\/(?<recordId>[a-zA-Z0-9_-]+)\/(?<textTrack>.+)$" {
# Workaround IE refusal to set cookies in iframe
add_header P3P 'CP="No P3P policy available"';
if ($bbb_loadbalancer_node) {
add_header 'Access-Control-Allow-Origin' $bbb_loadbalancer_node always;
}
# Allow 30M uploaded presentation document.
client_max_body_size 30m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
include fastcgi_params;
proxy_request_buffering off;
# Send a sub-request to allow bbb-web to refuse before loading
auth_request /bigbluebutton/textTrack/validateAuthToken;
default_type text/plain;
alias /var/bigbluebutton/captions/$recordId/$textTrack;
}
location = /bigbluebutton/textTrack/validateAuthToken {
internal;
proxy_pass http://bbb-web:8090;
proxy_redirect default;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-textTrack-token $textTrackToken;
proxy_set_header X-textTrack-recordId $recordId;
proxy_set_header X-textTrack-track $textTrack;
proxy_set_header X-Original-URI $request_uri;
}
}
location @error403 {
if ($file_too_large_header = '1') {
return 413;
}
return 403;
}

View File

@@ -0,0 +1,9 @@
# Pass to the webhooks app all requests made to the webhooks API.
location /bigbluebutton/api/hooks {
proxy_pass http://10.7.7.17:3005;
proxy_redirect default;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
}

View File

@@ -0,0 +1,22 @@
location /bbb-webrtc-sfu {
auth_request /bigbluebutton/connection/checkAuthorization;
auth_request_set $auth_status $upstream_status;
# Extra variables are annotated by bbb-web as custom headers
auth_request_set $user_id $sent_http_user_id;
auth_request_set $meeting_id $sent_http_meeting_id;
auth_request_set $voice_bridge $sent_http_voice_bridge;
proxy_pass http://10.7.7.1:3008;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
# Following custom headers are used by bbb-webrtc-sfu
proxy_set_header User-Id $user_id;
proxy_set_header Meeting-Id $meeting_id;
proxy_set_header Voice-Bridge $voice_bridge;
proxy_read_timeout 6h;
proxy_send_timeout 6h;
client_body_timeout 6h;
send_timeout 6h;
}

40
mod/nginx/bigbluebutton Normal file
View File

@@ -0,0 +1,40 @@
map $remote_addr $freeswitch_addr {
"~:" [::1];
default 10.7.7.1;
}
upstream poolhtml5servers {
zone poolhtml5servers 32k;
least_conn;
server 10.7.7.200:4100 fail_timeout=10s max_fails=4 backup;
server 10.7.7.201:4101 fail_timeout=120s max_fails=1;
server 10.7.7.202:4102 fail_timeout=120s max_fails=1;
server 10.7.7.203:4103 fail_timeout=120s max_fails=1;
# TODO: set server list based on NUMBER_OF_FRONTEND_NODEJS_PROCESSES
# server 10.7.7.204:4104 fail_timeout=120s max_fails=1;
# server 10.7.7.205:4105 fail_timeout=120s max_fails=1;
# server 10.7.7.206:4106 fail_timeout=120s max_fails=1;
# server 10.7.7.207:4107 fail_timeout=120s max_fails=1;
}
server {
listen 48087 default_server;
listen [::]:48087 default_server;
server_name _;
access_log /dev/stdout;
absolute_redirect off;
root /www/;
# opt-out of google's floc tracking
# https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea
add_header Permissions-Policy "interest-cohort=()";
# redirect to greenlight
location = / {
return 302 /b;
}
# Include specific rules for record and playback
include /etc/nginx/bbb/*.nginx;
}

BIN
mod/nginx/default.pdf Normal file

Binary file not shown.

32
mod/nginx/nginx.conf Normal file
View File

@@ -0,0 +1,32 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_rlimit_nofile 20000;
events {
worker_connections 10000;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}

10
mod/periodic/Dockerfile Normal file
View File

@@ -0,0 +1,10 @@
FROM debian:bullseye-slim
# -- install docker cli
COPY --from=library/docker:latest /usr/local/bin/docker /usr/bin/docker
COPY bbb-remove-old-recordings bbb-resync-freeswitch entrypoint.sh /
RUN chmod +x bbb-remove-old-recordings
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -0,0 +1,41 @@
#!/bin/bash
# Source: https://docs.bigbluebutton.org/admin/customize.html#delete-recordings-older-than-n-days
set -e
LOGFILE=/var/log/bigbluebutton/bbb-recording-cleanup-$(date --iso-8601='seconds' -u).log
shopt -s nullglob
NOW=$(date +%s)
echo "$(date --rfc-3339=seconds) Deleting recordings older than ${RECORDING_MAX_AGE_DAYS} days" >"${LOGFILE}"
# Find the name of recordings container in order to access `bbb-record` utility
BBB_RECORDINGS_CONTAINER_NAME=$(docker ps --filter "name=recordings" --filter "status=running" --format "{{.Names}}")
if [ $BBB_RECORDINGS_CONTAINER_NAME == "" ]; then
echo "$(date --rfc-3339=seconds) ERROR: recordings container is not running" >>"${LOGFILE}"
exit 1
fi
for donefile in /var/bigbluebutton/recording/status/published/*-presentation.done ; do
MTIME=$(stat -c %Y "${donefile}")
# Check the age of the recording
if [ $(( ( $NOW - $MTIME ) / 86400 )) -gt $RECORDING_MAX_AGE_DAYS ]; then
MEETING_ID=$(basename "${donefile}")
MEETING_ID=${MEETING_ID%-presentation.done}
echo "${MEETING_ID}" >> "${LOGFILE}"
docker exec "$BBB_RECORDINGS_CONTAINER_NAME" bbb-record --delete "${MEETING_ID}" >>"${LOGFILE}"
fi
done
for eventsfile in /var/bigbluebutton/recording/raw/*/events.xml ; do
MTIME=$(stat -c %Y "${eventsfile}")
# Check the age of the recording
if [ $(( ( $NOW - $MTIME ) / 86400 )) -gt $RECORDING_MAX_AGE_DAYS ]; then
MEETING_ID="${eventsfile%/events.xml}"
MEETING_ID="${MEETING_ID##*/}"
echo "${MEETING_ID}" >> "${LOGFILE}"
docker exec "$BBB_RECORDINGS_CONTAINER_NAME" bbb-record --delete "${MEETING_ID}" >>"${LOGFILE}"
fi
done

View File

@@ -0,0 +1,5 @@
#!/bin/bash
# https://github.com/bigbluebutton/bigbluebutton/pull/9597/files
docker exec -it bbb-freeswitch fs_cli -H 10.7.7.1 -P 8021 -x 'fsctl sync_clock_when_idle'

23
mod/periodic/entrypoint.sh Executable file
View File

@@ -0,0 +1,23 @@
#!/bin/bash
#
# How N days back to keep files
#
history=5
while :
do
# resync freeswitch
/bbb-resync-freeswitch
# delete presentations older than N days
find /var/bigbluebutton/ -maxdepth 1 -type d -name "*-[0-9]*" -mtime +$history -exec rm -rf '{}' +
# delete recordings older than $RECORDING_MAX_AGE_DAYS
if [ "$ENABLE_RECORDING" == true ] && [ "$REMOVE_OLD_RECORDING" == true ]; then
/bbb-remove-old-recordings
fi
sleep 30m
done

111
mod/recordings/Dockerfile Normal file
View File

@@ -0,0 +1,111 @@
FROM ruby:2.7-slim-buster
# install apt dependencies
RUN apt-get update && apt-get install -y \
wget \
subversion \
rsync \
build-essential \
libsystemd-dev \
python3 \
python3-attr \
python3-cairo \
python3-gi \
python3-gi-cairo \
python3-lxml \
python3-icu \
python3-pyinotify \
gir1.2-pangocairo-1.0 \
ffmpeg \
poppler-utils \
imagemagick \
supervisor \
locales \
locales-all
# TODO: missing packages
ENV LC_ALL en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8
# compile and install mkclean
RUN cd /tmp \
&& wget https://netcologne.dl.sourceforge.net/project/matroska/mkclean/mkclean-0.8.10.tar.bz2 \
&& tar -xf /tmp/mkclean-0.8.10.tar.bz2 \
&& cd /tmp/mkclean-0.8.10 \
&& sed -i 's/\r//g' ./mkclean/configure.compiled \
&& ./mkclean/configure.compiled \
&& make -C mkclean \
&& cp ./release/gcc_linux_x64/mkclean /usr/bin/mkclean \
&& rm -r /tmp/mkclean-*
# add dockerize
ENV DOCKERIZE_VERSION v0.6.1
RUN wget -q 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
# add yq for bbb-record
RUN wget -q https://github.com/mikefarah/yq/releases/download/3.4.1/yq_linux_amd64 -O /usr/bin/yq \
&& chmod +x /usr/bin/yq
RUN mkdir -p \
/usr/local/bigbluebutton \
/usr/local/bigbluebutton/core \
/etc/bigbluebutton
ARG TAG_RECORDINGS
# add bbb-record-core (lib, scripts and Gemfile)
RUN cd /usr/local/bigbluebutton/core \
&& svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_RECORDINGS/record-and-playback/core/lib \
&& svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_RECORDINGS/record-and-playback/core/scripts \
&& rm -rf /usr/local/bigbluebutton/core/*/.svn \
&& wget https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/$TAG_RECORDINGS/record-and-playback/core/Gemfile.lock \
&& wget https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/$TAG_RECORDINGS/record-and-playback/core/Gemfile \
&& wget https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/$TAG_RECORDINGS/record-and-playback/core/Rakefile
# add bbb-playback-presentation scripts
RUN cd /tmp \
&& svn checkout https://github.com/bigbluebutton/bigbluebutton/tags/$TAG_RECORDINGS/record-and-playback/presentation/scripts \
&& rsync -av /tmp/scripts/ /usr/local/bigbluebutton/core/scripts/ \
&& rm -rf /tmp/scripts
# install ruby dependencies
RUN cd /usr/local/bigbluebutton/core \
&& gem install builder \
&& gem install bundler --no-document \
&& /usr/local/bin/bundle
# log to file instead of journald
RUN sed -i 's|Journald::Logger\.new.*|Logger.new("/var/log/bigbluebutton/recording.log")|g' /usr/local/bigbluebutton/core/lib/recordandplayback.rb && \
sed -i 's|Journald::Logger\.new.*|Logger.new("/var/log/bigbluebutton/recording.log")|g' /usr/local/bigbluebutton/core/scripts/rap-caption-inbox.rb && \
sed -i 's|Logger\.new.*|Logger.new("/var/log/bigbluebutton/recording.log")|g' /usr/local/bigbluebutton/core/scripts/rap-process-worker.rb && \
sed -i 's|Logger\.new.*|Logger.new("/var/log/bigbluebutton/recording.log")|g' /usr/local/bigbluebutton/core/scripts/archive/archive.rb && \
sed -i 's|Logger\.new.*|Logger.new("/var/log/bigbluebutton/recording.log")|g' /usr/local/bigbluebutton/core/scripts/publish/presentation.rb && \
sed -i 's|Logger\.new.*|Logger.new("/var/log/bigbluebutton/recording.log")|g' /usr/local/bigbluebutton/core/scripts/utils/captions.rb && \
sed -i 's|Logger\.new.*|Logger.new("/var/log/bigbluebutton/recording.log")|g' /usr/local/bigbluebutton/core/scripts/process/presentation.rb
# add bbb-record with some adjustments so bbb-record works in this environment
RUN cd /usr/bin \
&& wget https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/$TAG_RECORDINGS/bigbluebutton-config/bin/bbb-record \
&& chmod +x /usr/bin/bbb-record \
&& sed -i 's/^BBB_WEB.*/BBB_WEB=""/' /usr/bin/bbb-record \
&& sed -i 's/systemctl.*//' /usr/bin/bbb-record \
&& echo "BIGBLUEBUTTON_RELEASE=$TAG_RECORDINGS" > /etc/bigbluebutton/bigbluebutton-release
# create user
# the ID should match the one creating the files in `core`
RUN groupadd -g 998 bigbluebutton && useradd -m -u 998 -g bigbluebutton bigbluebutton
# change owner
# https://github.com/alangecker/bigbluebutton-docker/issues/63
RUN chown -R 998:998 /usr/local/bigbluebutton
COPY bbb-web.properties /etc/bigbluebutton/bbb-web.properties.tmpl
COPY bigbluebutton.yml /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml.tmpl
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh

View File

@@ -0,0 +1 @@
securitySalt={{ .Env.SHARED_SECRET }}

View File

@@ -0,0 +1,59 @@
bbb_version: '2.1.0'
raw_audio_src: /var/freeswitch/meetings
raw_video_src: /usr/share/red5/webapps/video/streams
kurento_video_src: /var/kurento/recordings
kurento_screenshare_src: /var/kurento/screenshare
raw_screenshare_src: /usr/share/red5/webapps/screenshare/streams
raw_webrtc_deskshare_src: /usr/share/red5/webapps/video-broadcast/streams
raw_deskshare_src: /var/bigbluebutton/deskshare
raw_presentation_src: /var/bigbluebutton
notes_endpoint: http://bbb-pads:9002/p
# Specify the notes formats we archive
# txt, doc and odt are also supported
notes_formats:
- etherpad
- html
- pdf
redis_host: redis
redis_port: 6379
# Uncomment and set password if redis require it.
# redis_password: changeme
# redis_workers_host: 127.0.0.1
# redis_workers_port: 6379
# Set to true to insert recording process status into
# redis list with key "store_recording_status: true".
# This is useful if you want to track progress status
# and have another script process it.
store_recording_status: false
# Sequence of recording steps. Keys are the current step, values
# are the next step(s). Examples:
# current_step: next_step
# "current_step-format": "next_step-format"
# current_step:
# - next_step
# - another_step-format
steps:
archive: "sanity"
sanity: "captions"
captions: "process:presentation"
"process:presentation": "publish:presentation"
# For PRODUCTION
log_dir: /var/log/bigbluebutton
events_dir: /var/bigbluebutton/events
recording_dir: /var/bigbluebutton/recording
published_dir: /var/bigbluebutton/published
captions_dir: /var/bigbluebutton/captions
playback_host: {{ .Env.DOMAIN }}
playback_protocol: https
# For DEVELOPMENT
# This allows us to run the scripts manually
#scripts_dir: /home/ubuntu/dev/bigbluebutton/record-and-playback/core/scripts
#log_dir: /home/ubuntu/temp/log
#recording_dir: /home/ubuntu/temp/recording
#published_dir: /home/ubuntu/temp/published
#playback_host: 127.0.0.1

12
mod/recordings/entrypoint.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
touch /var/log/bigbluebutton/recording.log
touch /var/log/bigbluebutton/bbb-web.log
mkdir -p /var/log/bigbluebutton/presentation
chown -R bigbluebutton:bigbluebutton /var/log/bigbluebutton
dockerize \
-template /usr/local/bigbluebutton/core/scripts/bigbluebutton.yml.tmpl:/usr/local/bigbluebutton/core/scripts/bigbluebutton.yml \
-template /etc/bigbluebutton/bbb-web.properties.tmpl:/etc/bigbluebutton/bbb-web.properties \
-stdout /var/log/bigbluebutton/recording.log \
/usr/bin/supervisord --nodaemon

View File

@@ -0,0 +1,34 @@
[supervisord]
user=root
[program:rasque_workers]
command=rake resque:workers
directory=/usr/local/bigbluebutton/core/scripts
environment=QUEUE="rap:archive,rap:publish,rap:process,rap:sanity,rap:captions,rap:events",COUNT="1",VVERBOSE="1",HOME="/home/bigbluebutton"
user=bigbluebutton
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/dev/fd/2
stderr_logfile_maxbytes=0
[program:rap_starter]
command=bundle exec ruby /usr/local/bigbluebutton/core/scripts/rap-starter.rb
directory=/usr/local/bigbluebutton/core/scripts
environment=HOME="/home/bigbluebutton"
user=bigbluebutton
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/dev/fd/2
stderr_logfile_maxbytes=0
[program:rap_caption_inbox]
command=bundle exec ruby /usr/local/bigbluebutton/core/scripts/rap-caption-inbox.rb
directory=/usr/local/bigbluebutton/core/scripts
environment=HOME="/home/bigbluebutton"
user=bigbluebutton
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/dev/fd/2
stderr_logfile_maxbytes=0

25
mod/webhooks/Dockerfile Normal file
View File

@@ -0,0 +1,25 @@
FROM node:14.18.3-bullseye-slim AS builder
RUN apt-get update && apt-get install -y git wget
RUN wget -q https://github.com/mikefarah/yq/releases/download/v4.25.1/yq_linux_amd64 -O /usr/bin/yq \
&& chmod +x /usr/bin/yq
COPY ./bbb-webhooks /bbb-webhooks
RUN cd /bbb-webhooks && npm install --production
RUN chmod 777 /bbb-webhooks/config
# ------------------------------
FROM node:14.18.3-bullseye-slim
RUN useradd --uid 2004 --user-group bbb-webhooks
COPY --from=builder /usr/bin/yq /usr/bin/yq
COPY --from=builder /bbb-webhooks /bbb-webhooks
COPY entrypoint.sh /entrypoint.sh
RUN mkdir /bbb-webhooks/log && chmod 777 /bbb-webhooks/log
USER bbb-webhooks
ENTRYPOINT /entrypoint.sh

17
mod/webhooks/entrypoint.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/sh
set -e
TARGET=/bbb-webhooks/config/production.yml
cp /bbb-webhooks/config/default.example.yml $TARGET
yq e -i ".bbb.sharedSecret = \"$SHARED_SECRET\"" $TARGET
yq e -i ".bbb.serverDomain = \"$DOMAIN\"" $TARGET
yq e -i ".bbb.auth2_0 = true" $TARGET
yq e -i ".server.bind = \"0.0.0.0\"" $TARGET
yq e -i ".hooks.getRaw = false" $TARGET
yq e -i ".redis.host = \"redis\"" $TARGET
export NODE_ENV=production
cd /bbb-webhooks
node app.js

35
mod/webrtc-sfu/Dockerfile Normal file
View File

@@ -0,0 +1,35 @@
ARG BBB_BUILD_TAG
FROM gitlab.senfcall.de:5050/senfcall-public/docker-bbb-build:$BBB_BUILD_TAG AS builder
RUN useradd --uid 2004 --user-group webrtc-sfu
ADD ./bbb-webrtc-sfu /app
ENV NODE_ENV production
# due to the git submodule npm install crashes with following error:
# npm ERR! fatal: Not a git repository: ../.git/modules/bbb-webrtc-sfu
# we simply delete the .git file
RUN cd /app \
&& cp config/default.example.yml config/production.yml \
&& rm .git \
&& npm install --unsafe-perm \
&& npm cache clear --force \
&& rm -rf node_modules/mediasoup/worker/out/Release/subprojects \
&& rm -rf node_modules/mediasoup/worker/out/Release/mediasoup-worker.p \
&& rm -rf node_modules/mediasoup/worker/out/Release/deps
# =============================
FROM node:14.19.1-bullseye-slim
RUN useradd --uid 2004 --user-group webrtc-sfu
ENV NODE_ENV production
COPY --from=builder /app /app
RUN chown -R webrtc-sfu:webrtc-sfu /app/config
USER webrtc-sfu
WORKDIR /app
CMD [ "npm", "start" ]