diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..253bcb7 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: daily diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 2d727b2..6db050a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -29,14 +29,17 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: docker/setup-qemu-action@v1 - - uses: docker/setup-buildx-action@v1 + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - uses: docker/setup-qemu-action@v2 + - uses: docker/setup-buildx-action@v2 - name: Detect correct Git ref for image build id: git - uses: actions/github-script@v3 + uses: actions/github-script@v6 with: script: | let out = {ref: 'HEAD', ver: ''}; @@ -86,7 +89,7 @@ jobs: - name: Login to GitHub Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.repository_owner }} @@ -94,7 +97,7 @@ jobs: if: ${{ matrix.publish }} - name: Login to Quay.io - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: quay.io username: ${{ secrets.QUAYIO_ROBOT_USERNAME }} @@ -102,7 +105,7 @@ jobs: if: ${{ matrix.publish }} - name: Login to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_BOT_USER }} password: ${{ secrets.DOCKERHUB_BOT_PASS }} @@ -152,7 +155,7 @@ jobs: && startsWith(github.ref, 'refs/tags/docker/') }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Parse release version from Git tag id: release @@ -164,11 +167,10 @@ jobs: working-directory: ./docker/coturn - name: Release on GitHub - uses: actions/create-release@v1 + uses: softprops/action-gh-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: docker/${{ steps.release.outputs.VERSION }} - release_name: docker/${{ steps.release.outputs.VERSION }} + name: docker/${{ steps.release.outputs.VERSION }} body: | [Changelog](${{ steps.changelog.outputs.LINK }}) diff --git a/ChangeLog b/ChangeLog index fb0da8c..a1d0ebd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 10/01/2021 Oleg Moskalenko Mihály Mészáros Version 4.5.3 'dan Eider': + - merge PR #755(moznuy) and #825(by argggh) + * fix sqlite3_shutdown and sqlite3_config race + - merge PR #826 (by giavac) + * prom server better - merge PR #684 (by brevilo) * Define OPENSSL_VERSION_1_1_1 on systems where it doesn't (yet) exist * Regression in 4.5.2 that cause issues in openssl version < 1.1.1. diff --git a/README.md b/README.md index d9eb7ea..1f6c090 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ Supported user databases (for user repository, with passwords or keys, if authen Redis can also be used for status and statistics storage and notification. -By default a [prometheus](https://prometheus.io/) exporter endpoint is disabled, if it is enabeled it will listen on port 9641 under path /metrics +By default a [prometheus](https://prometheus.io/) exporter endpoint is disabled, if it is enabled it will listen on port 9641 under path /metrics Supported message integrity digest algorithms: diff --git a/README.turnserver b/README.turnserver index e8b4248..df56d02 100644 --- a/README.turnserver +++ b/README.turnserver @@ -281,9 +281,16 @@ Flags: check: across the session, all requests must have the same main ORIGIN attribute value (if the ORIGIN was initially used by the session). - --prometheus Enable prometheus metrics. By default it is - disabled. Would listen on port 9641 unther the path /metrics + +--prometheus Enable prometheus metrics. By default it is + disabled. Would listen on port 9641 under the path /metrics also the path / on this port can be used as a health check + --prometheus-username-labels Enable labeling prometheus traffic + metrics with client usernames. Labeling with client usernames is + disabled by default, beacuse this may cause memory leaks when using + authentication with ephemeral usernames (e.g. TURN REST API). + +--prometheus-port Prometheus listener port (Default: 9641). -h Help. @@ -812,7 +819,7 @@ in a batch script). See the file turndb/testsqldbsetup.sql as an example. 4) The same is true for MySQL database. The same schema file is applicable. The same considerations are applicable. -5) The same is true for the Redis database, but the Redis database has aa different schema - +5) The same is true for the Redis database, but the Redis database has a different schema - it can be found (in the form of explanation) in schema.userdb.redis. Also, in Redis you can store both "keys" and open passwords (for long term credentials) - the "open password" option is less secure but more convenient for low-security environments. diff --git a/configure b/configure index b8114a1..b12500a 100755 --- a/configure +++ b/configure @@ -18,11 +18,11 @@ testlibraw() { ${CC} ${TMPCPROGC} -o ${TMPCPROGB} ${OSCFLAGS} ${OSLIBS} -${1} 2>>/dev/null ER=$? if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Library option -${1} cannot be used" - return 0 + ${ECHO_CMD} "Library option -${1} cannot be used" + return 0 else - OSLIBS="${OSLIBS} -${1}" - return 1 + OSLIBS="${OSLIBS} -${1}" + return 1 fi } @@ -187,11 +187,11 @@ cleanup ######################### if [ -z "${ECHO_CMD}" ] ; then - ECHO_CMD=echo + ECHO_CMD=echo fi if [ -z "${FIND_CMD}" ] ; then - FIND_CMD=find + FIND_CMD=find fi if [ -z "${PORTNAME}" ] ; then @@ -288,12 +288,12 @@ do -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=* | -confdir=* | --confdir=*) CONFDIR=$ac_optarg ;; - + -disable-rpath | --disable-rpath) TURN_DISABLE_RPATH=1 ;; - + esac - + done if test -n "$ac_prev"; then @@ -334,13 +334,13 @@ fi if [ -z "${LOCALSTATEDIR}" ] ; then if [ -z "${localstatedir}" ] ; then - + if [ "${PREFIX}" = "/usr" ] ; then LOCALSTATEDIR=/var else LOCALSTATEDIR=${PREFIX}/var fi - + else LOCALSTATEDIR=${localstatedir} fi @@ -505,15 +505,6 @@ else fi fi -############################# -# Adjustments for Debian -############################# - -if [ -f "/etc/debian_version" ] ; then - # https://github.com/coturn/coturn/pull/754#issuecomment-824693226 - OSLIBS="${OSLIBS} -latomic" -fi - ############################# # Adjustments for Solaris ############################# @@ -706,7 +697,7 @@ fi ########################### # Test some general-purpose -# libraries +# libraries ########################### testlib socket @@ -717,7 +708,6 @@ if ! [ ${ER} -eq 0 ] ; then echo "CYGWIN ?" fi testlib wldap64 -testlib intl testlib nsl testlib resolv @@ -738,15 +728,15 @@ if [ ${ER} -ne 0 ] ; then exit 1 fi -if [ -z ${TURN_NO_THREAD_BARRIERS} ] ; then +if [ -z ${TURN_NO_THREAD_BARRIERS} ] ; then pthread_testbarriers -else +else TURN_NO_THREAD_BARRIERS="-DTURN_NO_THREAD_BARRIERS" fi -if [ -z ${TURN_IP_RECVERR} ] ; then +if [ -z ${TURN_IP_RECVERR} ] ; then ${ECHO_CMD} "Ignore IP_RECVERR" -else +else ${ECHO_CMD} "Use IP_RECVERR" TURN_IP_RECVERR="-DTURN_IP_RECVERR" OSCFLAGS="${OSCFLAGS} ${TURN_IP_RECVERR}" @@ -780,7 +770,7 @@ else ER=$? if ! [ ${ER} -eq 0 ] ; then ${ECHO_CMD} "OpenSSL Crypto lib found." - else + else ${ECHO_CMD} "ERROR: OpenSSL Crypto development libraries are not installed properly in required location." ${ECHO_CMD} "Abort." cleanup @@ -807,7 +797,7 @@ fi # Can we use GCM cipher ? ########################### -if [ -z ${TURN_NO_GCM} ] ; then +if [ -z ${TURN_NO_GCM} ] ; then gcm_testlib ER=$? @@ -853,45 +843,50 @@ fi if [ -z "${TURN_NO_PROMETHEUS}" ] ; then - testlib prom - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Prometheus lib found." - testlib promhttp - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Prometheus http lib found." - testlib microhttpd - ER=$? - if ! [ ${ER} -eq 0 ] ; then - ${ECHO_CMD} "Microhttpd lib found." - else - ${ECHO_CMD} - ${ECHO_CMD} "Warning: microhttpd development libraries are not installed properly in required location." - ${ECHO_CMD} "Prometheus support will be disabled." - ${ECHO_CMD} "See the INSTALL file." - ${ECHO_CMD} - OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" - fi - else - ${ECHO_CMD} - ${ECHO_CMD} "Warning: Libpromhttp development libraries are not installed properly in required location." - ${ECHO_CMD} "Prometheus support will be disabled." - ${ECHO_CMD} "See the INSTALL file." - ${ECHO_CMD} - OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" - fi - else - ${ECHO_CMD} - ${ECHO_CMD} "Warning: Libprom development libraries are not installed properly in required location." - ${ECHO_CMD} "Prometheus support will be disabled." - ${ECHO_CMD} "See the INSTALL file." - ${ECHO_CMD} - OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" - fi + testlib prom + ER=$? + if ! [ ${ER} -eq 0 ] ; then + ${ECHO_CMD} "Prometheus lib found." + testlib promhttp + ER=$? + if ! [ ${ER} -eq 0 ] ; then + ${ECHO_CMD} "Prometheus http lib found." + testlib microhttpd + ER=$? + if ! [ ${ER} -eq 0 ] ; then + ${ECHO_CMD} "Microhttpd lib found." + # Adjustments for Debian + # See: https://github.com/coturn/coturn/pull/754#issuecomment-824693226 + if [ -f "/etc/debian_version" ] ; then + OSLIBS="${OSLIBS} -latomic" + fi + else + ${ECHO_CMD} + ${ECHO_CMD} "Warning: microhttpd development libraries are not installed properly in required location." + ${ECHO_CMD} "Prometheus support will be disabled." + ${ECHO_CMD} "See the INSTALL file." + ${ECHO_CMD} + OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" + fi + else + ${ECHO_CMD} + ${ECHO_CMD} "Warning: Libpromhttp development libraries are not installed properly in required location." + ${ECHO_CMD} "Prometheus support will be disabled." + ${ECHO_CMD} "See the INSTALL file." + ${ECHO_CMD} + OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" + fi + else + ${ECHO_CMD} + ${ECHO_CMD} "Warning: Libprom development libraries are not installed properly in required location." + ${ECHO_CMD} "Prometheus support will be disabled." + ${ECHO_CMD} "See the INSTALL file." + ${ECHO_CMD} + OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" + fi else - OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" + OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS" fi ########################### @@ -949,7 +944,7 @@ fi ########################### if [ -z "${TURN_NO_MYSQL}" ] ; then - if testpkg_db mariadb || testpkg_db mysqlclient || test_mysql_config; then + if testpkg_db libmariadb || testpkg_db mariadb || testpkg_db mysqlclient || test_mysql_config; then ${ECHO_CMD} "MySQL found." else ${ECHO_CMD} "MySQL not found. Building without MySQL support." @@ -997,7 +992,7 @@ if [ -z "${LDCONFIG}" ] ; then ISBSD=`uname | grep -i bsd` if [ -z "${ISBSD}" ] ; then ISLINUX=`uname | grep -i linux` - if [ -z "${ISLINUX}" ] ; then + if [ -z "${ISLINUX}" ] ; then SYSTEM=`uname` if [ "${SYSTEM}" = "SunOS" ] ; then LDCONFIG="crle -u -l" diff --git a/docker/coturn/CHANGELOG.md b/docker/coturn/CHANGELOG.md index db3c734..c07e431 100644 --- a/docker/coturn/CHANGELOG.md +++ b/docker/coturn/CHANGELOG.md @@ -4,6 +4,125 @@ Coturn TURN server Docker image changelog +## [4.5.2-r13] · 2022-07-19 +[4.5.2-r13]: /../../tree/docker/4.5.2-r13 + +### Security updated + +- [Alpine Linux] 3.16.1: +- [Debian] "bullseye" 20220622: + + + + +## [4.5.2-r12] · 2022-05-24 +[4.5.2-r12]: /../../tree/docker/4.5.2-r12 + +### Upgraded + +- [Alpine Linux] 3.16: + +### Security updated + +- [Debian] "bullseye" 20220509: + + + + +## [4.5.2-r11] · 2022-04-06 +[4.5.2-r11]: /../../tree/docker/4.5.2-r11 + +### Security updated + +- [Alpine Linux] 3.15.4: + + + + +## [4.5.2-r10] · 2022-03-29 +[4.5.2-r10]: /../../tree/docker/4.5.2-r10 + +### Security updated + +- [Alpine Linux] 3.15.3: +- [Debian] "bullseye" 20220328: + + + + +## [4.5.2-r9] · 2022-03-25 +[4.5.2-r9]: /../../tree/docker/4.5.2-r9 + +### Security updated + +- [Alpine Linux] 3.15.2: +- [Debian] "bullseye" 20220316: + + + + +## [4.5.2-r8] · 2021-12-03 +[4.5.2-r8]: /../../tree/docker/4.5.2-r8 + +### Added + +- Default TLS ports. ([#860]) + +[#860]: /../../pull/860 + + + + +## [4.5.2-r7] · 2021-11-25 +[4.5.2-r7]: /../../tree/docker/4.5.2-r7 + +### Upgraded + +- [Alpine Linux] 3.15: + + + + +## [4.5.2-r6] · 2021-11-15 +[4.5.2-r6]: /../../tree/docker/4.5.2-r6 + +### Security updated + +- [Alpine Linux] 3.14.3: + + + + +## [4.5.2-r5] · 2021-08-29 +[4.5.2-r5]: /../../tree/docker/4.5.2-r5 + +### Upgraded + +- [Debian Linux] "bullseye": + + + + +## [4.5.2-r4] · 2021-08-28 +[4.5.2-r4]: /../../tree/docker/4.5.2-r4 + +### Security updated + +- [Alpine Linux] 3.14.2: + + + + +## [4.5.2-r3] · 2021-08-09 +[4.5.2-r3]: /../../tree/docker/4.5.2-r3 + +### Security updated + +- [Alpine Linux] 3.14.1: + + + + ## [4.5.2-r2] · 2021-06-21 [4.5.2-r2]: /../../tree/docker/4.5.2-r2 diff --git a/docker/coturn/CONTRIBUTING.md b/docker/coturn/CONTRIBUTING.md index edde3e8..5b5c896 100644 --- a/docker/coturn/CONTRIBUTING.md +++ b/docker/coturn/CONTRIBUTING.md @@ -49,7 +49,7 @@ To produce a new release (version tag) of `coturn/coturn` Docker image, perform 3. Update [README] with the new version declared in [`Makefile`]. -4. Perform a `make release` command inside the`docker/coturn/` directory. +4. Perform a `make release` command inside the `docker/coturn/` directory. diff --git a/docker/coturn/Makefile b/docker/coturn/Makefile index 1c6080d..2257255 100644 --- a/docker/coturn/Makefile +++ b/docker/coturn/Makefile @@ -21,7 +21,7 @@ COTURN_VER ?= 4.5.2 COTURN_MIN_VER = $(strip $(shell echo $(COTURN_VER) | cut -d '.' -f1,2)) COTURN_MAJ_VER = $(strip $(shell echo $(COTURN_VER) | cut -d '.' -f1)) -BUILD_REV ?= 2 +BUILD_REV ?= 13 NAMESPACES := coturn \ ghcr.io/coturn \ @@ -71,8 +71,7 @@ test: test.docker docker-namespaces = $(strip $(if $(call eq,$(namespaces),),\ $(NAMESPACES),$(subst $(comma), ,$(namespaces)))) -docker-tags = $(subst $(comma), ,$(strip \ - $(if $(call eq,$(tags),),$(TAGS),$(tags)))) +docker-tags = $(subst $(comma), ,$(or $(tags),$(TAGS))) docker-platforms = $(strip $(if $(call eq,$(platforms),),\ $(PLATFORMS),$(subst $(comma), ,$(platforms)))) @@ -86,11 +85,20 @@ define docker.buildx $(eval platform := $(strip $(5))) $(eval no-cache := $(strip $(6))) $(eval args := $(strip $(7))) + $(eval github_url := $(strip $(or $(GITHUB_SERVER_URL),https://github.com))) + $(eval github_repo := $(strip $(or $(GITHUB_REPOSITORY),coturn/coturn))) cd ../../ && \ docker buildx build --force-rm $(args) \ --platform $(platform) \ $(if $(call eq,$(no-cache),yes),--no-cache --pull,) \ $(if $(call eq,$(git-ref),),,--build-arg coturn_git_ref=$(git-ref)) \ + --build-arg coturn_github_url=$(github_url) \ + --build-arg coturn_github_repo=$(github_repo) \ + --label org.opencontainers.image.source=$(github_url)/$(github_repo) \ + --label org.opencontainers.image.revision=$(strip \ + $(shell git show --pretty=format:%H --no-patch)) \ + --label org.opencontainers.image.version=$(subst docker/,,$(strip \ + $(shell git describe --tags --dirty --match='docker/*'))) \ -f docker/coturn/$(dockerfile)/Dockerfile \ -t $(namespace)/$(NAME):$(tag) ./ endef @@ -130,9 +138,9 @@ docker.build.cache: docker.image: $(call docker.buildx,$(DOCKERFILE),\ coturn,\ - $(if $(call eq,$(tag),),$(VERSION),$(tag)),\ + $(or $(tag),$(VERSION)),\ $(ref),\ - $(if $(call eq,$(platform),),$(MAIN_PLATFORM),$(platform)),\ + $(or $(platform),$(MAIN_PLATFORM)),\ $(no-cache),\ --load) @@ -186,9 +194,7 @@ ifeq ($(wildcard node_modules/.bin/bats),) @make npm.install endif $(foreach platform,$(test-docker-platforms),\ - $(call test.docker.do,\ - $(if $(call eq,$(tag),),$(VERSION),$(tag)),\ - $(platform))) + $(call test.docker.do,$(or $(tag),$(VERSION)),$(platform))) define test.docker.do $(eval tag := $(strip $(1))) $(eval platform := $(strip $(2))) @@ -235,7 +241,7 @@ endif # Usage: # make git.release [ver=($(VERSION)|)] -git-release-tag = docker/$(strip $(if $(call eq,$(ver),),$(VERSION),$(ver))) +git-release-tag = docker/$(strip $(or $(ver),$(VERSION))) git.release: ifeq ($(shell git rev-parse $(git-release-tag) >/dev/null 2>&1 && echo "ok"),ok) diff --git a/docker/coturn/README.md b/docker/coturn/README.md index e902823..8bf3e97 100644 --- a/docker/coturn/README.md +++ b/docker/coturn/README.md @@ -15,8 +15,8 @@ Coturn TURN server Docker image ## Supported tags and respective `Dockerfile` links -- [`4.5.2-r2`, `4.5.2-r0-debian`, `4.5.2`, `4.5.2-debian`, `4.5`, `4.5-debian`, `4`, `4-debian`, `debian`, `latest`][d1] -- [`4.5.2-r2-alpine`, `4.5.2-alpine`, `4.5-alpine`, `4-alpine`, `alpine`][d2] +- [`4.5.2-r13`, `4.5.2-r13-debian`, `4.5.2`, `4.5.2-debian`, `4.5`, `4.5-debian`, `4`, `4-debian`, `debian`, `latest`][d1] +- [`4.5.2-r13-alpine`, `4.5.2-alpine`, `4.5-alpine`, `4-alpine`, `alpine`][d2] @@ -46,7 +46,7 @@ The TURN Server is a VoIP media traffic NAT traversal server and gateway. It can To run Coturn TURN server just start the container: ```bash -docker run -d -p 3478:3478 -p 49152-65535:49152-65535/udp coturn/coturn +docker run -d -p 3478:3478 -p 3478:3478/udp -p 5349:5349 -p 5349:5349/udp -p 49152-65535:49152-65535/udp coturn/coturn ``` @@ -56,7 +56,7 @@ As per [RFC 5766 Section 6.2], these are the ports that the TURN server will use You can change them with `min-port` and `max-port` Coturn configuration options: ```bash -docker run -d -p 3478:3478 -p 49160-49200:49160-49200/udp \ +docker run -d -p 3478:3478 -p 3478:3478/udp -p 5349:5349 -p 5349:5349/udp -p 49160-49200:49160-49200/udp \ coturn/coturn -n --log-file=stdout \ --external-ip='$(detect-external-ip)' \ --min-port=49160 --max-port=49200 diff --git a/docker/coturn/alpine/Dockerfile b/docker/coturn/alpine/Dockerfile index d88bb3b..3f716a9 100644 --- a/docker/coturn/alpine/Dockerfile +++ b/docker/coturn/alpine/Dockerfile @@ -2,7 +2,7 @@ # Dockerfile of coturn/coturn:alpine Docker image. # -ARG alpine_ver=3.14 +ARG alpine_ver=3.16 @@ -119,10 +119,13 @@ WORKDIR /app/ # Use Coturn sources from Git if `coturn_git_ref` is specified. ARG coturn_git_ref=HEAD +ARG coturn_github_url=https://github.com +ARG coturn_github_repo=coturn/coturn + RUN if [ "${coturn_git_ref}" != 'HEAD' ]; then true \ && rm -rf /app/* \ && git init \ - && git remote add origin https://github.com/coturn/coturn \ + && git remote add origin ${coturn_github_url}/${coturn_github_repo} \ && git fetch --depth=1 origin "${coturn_git_ref}" \ && git checkout FETCH_HEAD \ && true; fi @@ -173,8 +176,6 @@ COPY --from=dist-libprom /out/ /out/ # https://hub.docker.com/_/alpine FROM alpine:${alpine_ver} AS runtime -LABEL org.opencontainers.image.source="https://github.com/coturn/coturn" - # Update system packages. RUN apk update \ && apk upgrade \ @@ -206,7 +207,7 @@ RUN apk add --no-cache libcap \ USER nobody:nogroup -EXPOSE 3478 3478/udp +EXPOSE 3478 3478/udp 5349 5349/udp VOLUME ["/var/lib/coturn"] diff --git a/docker/coturn/debian/Dockerfile b/docker/coturn/debian/Dockerfile index 20d2580..c3b4384 100644 --- a/docker/coturn/debian/Dockerfile +++ b/docker/coturn/debian/Dockerfile @@ -2,7 +2,7 @@ # Dockerfile of coturn/coturn:debian Docker image. # -ARG debian_ver=buster +ARG debian_ver=bullseye @@ -11,14 +11,13 @@ ARG debian_ver=buster # Stage 'dist-libprom' creates prometheus-client-c distribution. # -# We compile prometheus-client-c from sources, because Alpine doesn't provide +# We compile prometheus-client-c from sources, because Debian doesn't provide # it as its package yet. # # TODO: Re-check this to be present in packages on next Debian major version update. # https://hub.docker.com/_/debian -# We use 'bullseye' here due to too old cmake on 'buster'. -FROM debian:bullseye-slim AS dist-libprom +FROM debian:${debian_ver}-slim AS dist-libprom # Install tools for building. RUN apt-get update \ @@ -76,60 +75,6 @@ RUN LIBS_DIR=/out/$(dirname $(find /usr/ -name libc.so)) \ -# -# Stage 'dist-mongoc' creates mongo-c-driver distribution. -# - -# We compile mongo-c-driver from sources, because buster Debian `libmongoc` packages -# cointain too old driver version, being not compatible with latest MongoDB versions well. -# -# TODO: Reconsider this on next stable Debian version update. - -# https://hub.docker.com/_/debian -FROM debian:${debian_ver}-slim AS dist-mongoc - -# Install tools for building. -RUN apt-get update \ - && apt-get install -y --no-install-recommends --no-install-suggests \ - ca-certificates cmake g++ gcc git make python \ - && update-ca-certificates - -# Install mongo-c-driver build dependencies. -RUN apt-get install -y --no-install-recommends --no-install-suggests \ - libssl-dev - -# Prepare mongo-c-driver sources for building. -ARG mongoc_ver=1.17.5 -RUN mkdir -p /tmp/mongoc/src/ && cd /tmp/mongoc/src/ \ - && git init \ - && git remote add origin https://github.com/mongodb/mongo-c-driver \ - && git fetch --depth=1 origin "${mongoc_ver}" \ - && git checkout FETCH_HEAD \ - && python build/calc_release_version.py > VERSION_CURRENT - -# Build mongo-c-driver from sources. -RUN mkdir -p /tmp/mongoc/build/ && cd /tmp/mongoc/build/ \ - && cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF \ - -DCMAKE_BUILD_TYPE=Release \ - /tmp/mongoc/src -RUN rm -rf /build && mkdir -p /build/ \ - && cd /tmp/mongoc/build/ \ - && DESTDIR=/build cmake --build . --target install - -# Install mongo-c-driver. -RUN LIBS_DIR=/out/$(dirname $(find /usr/ -name libc.so)) \ - && mkdir -p $LIBS_DIR/ \ - && cp -rf /build/usr/local/lib/* $LIBS_DIR/ \ - && mkdir -p /out/usr/include/ \ - && cp -rf /build/usr/local/include/libbson-1.0/* /out/usr/include/ \ - && cp -rf /build/usr/local/include/libmongoc-1.0/* /out/usr/include/ \ - # Preserve license file. - && mkdir -p /out/usr/share/licenses/mongo-c-driver/ \ - && cp /build/usr/local/share/mongo-c-driver/COPYING /out/usr/share/licenses/mongo-c-driver/ - - - - # # Stage 'dist-coturn' creates Coturn distribution. # @@ -149,10 +94,9 @@ RUN apt-get install -y --no-install-recommends --no-install-suggests \ libssl-dev \ libpq-dev libmariadb-dev libsqlite3-dev \ libhiredis-dev \ + libmongoc-dev \ libmicrohttpd-dev -# Install mongo-c-driver distribution. -COPY --from=dist-mongoc /out/ / # Install prometheus-client-c distribution. COPY --from=dist-libprom /out/ / @@ -174,18 +118,23 @@ WORKDIR /app/ # Use Coturn sources from Git if `coturn_git_ref` is specified. ARG coturn_git_ref=HEAD +ARG coturn_github_url=https://github.com +ARG coturn_github_repo=coturn/coturn + RUN if [ "${coturn_git_ref}" != 'HEAD' ]; then true \ && rm -rf /app/* \ && git init \ - && git remote add origin https://github.com/coturn/coturn \ + && git remote add origin ${coturn_github_url}/${coturn_github_repo} \ && git fetch --depth=1 origin "${coturn_git_ref}" \ && git checkout FETCH_HEAD \ && true; fi +# TODO: Remove `OSLIBS` line with next Coturn release having it in `configure`. +RUN if [ "${coturn_git_ref}" = '4.5.2' ]; then true \ + && sed -i -e '850i\OSLIBS="$\{OSLIBS\} -latomic"' ./configure \ + && true; fi # Build Coturn from sources. -# TODO: Remove `LDFLAGS` with next Coturn release containing `-latomic` flag in `configure`. -RUN LDFLAGS='-latomic' \ - ./configure --prefix=/usr \ +RUN ./configure --prefix=/usr \ --turndbdir=/var/lib/coturn \ --disable-rpath \ --sysconfdir=/etc/coturn \ @@ -215,8 +164,6 @@ RUN ln -s /usr/local/bin/detect-external-ip.sh \ /out/usr/local/bin/detect-external-ip RUN chown -R nobody:nogroup /out/var/lib/coturn/ -# Re-export mongo-c-driver distribution. -COPY --from=dist-mongoc /out/ /out/ # Re-export prometheus-client-c distribution. COPY --from=dist-libprom /out/ /out/ @@ -230,8 +177,6 @@ COPY --from=dist-libprom /out/ /out/ # https://hub.docker.com/_/debian FROM debian:${debian_ver}-slim AS runtime -LABEL org.opencontainers.image.source="https://github.com/coturn/coturn" - # Update system packages. RUN apt-get update \ && apt-get upgrade -y \ @@ -241,11 +186,12 @@ RUN apt-get update \ # Install Coturn dependencies. && apt-get install -y --no-install-recommends --no-install-suggests \ libatomic1 \ - libevent-2.1-6 libevent-core-2.1-6 libevent-extra-2.1-6 \ - libevent-openssl-2.1-6 libevent-pthreads-2.1-6 \ + libevent-2.1-7 libevent-core-2.1-7 libevent-extra-2.1-7 \ + libevent-openssl-2.1-7 libevent-pthreads-2.1-7 \ libssl1.1 \ libpq5 libmariadb3 libsqlite3-0 \ libhiredis0.14 \ + libmongoc-1.0-0 \ libmicrohttpd12 \ # Install `dig` tool for `detect-external-ip.sh`. && apt-get install -y --no-install-recommends --no-install-suggests \ @@ -269,7 +215,7 @@ RUN apt-get update \ USER nobody:nogroup -EXPOSE 3478 3478/udp +EXPOSE 3478 3478/udp 5349 5349/udp VOLUME ["/var/lib/coturn"] diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 34375de..f619972 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -422,13 +422,23 @@ The flag that sets the origin consistency check: across the session, all requests must have the same main ORIGIN attribute value (if the ORIGIN was initially used by the session). -.RS .TP .B \fB\-\-prometheus\fP Enable prometheus metrics. By default it is -disabled. Would listen on port 9641 unther the path /metrics +disabled. Would listen on port 9641 under the path /metrics also the path / on this port can be used as a health check +.TP +.B +\fB\-\-prometheus\-port\fP +Prometheus listener port (Default: 9641). +.TP +.B +\fB\-\-prometheus\-username\-labels\fP +Enable labeling prometheus traffic +metrics with client usernames. Labeling with client usernames is +disabled by default, because this may cause memory leaks when using +authentication with ephemeral usernames (e.g. TURN REST API). .RE .TP .B @@ -1114,7 +1124,7 @@ in a batch script). See the file turndb/testsqldbsetup.sql as an example. The same is true for MySQL database. The same schema file is applicable. The same considerations are applicable. .IP 5) 4 -The same is true for the Redis database, but the Redis database has aa different schema \- +The same is true for the Redis database, but the Redis database has a different schema \- it can be found (in the form of explanation) in schema.userdb.redis. Also, in Redis you can store both "keys" and open passwords (for long term credentials) \- the "open password" option is less secure but more convenient for low\-security environments. diff --git a/src/apps/natdiscovery/natdiscovery.c b/src/apps/natdiscovery/natdiscovery.c index 78d8297..54e8e54 100644 --- a/src/apps/natdiscovery/natdiscovery.c +++ b/src/apps/natdiscovery/natdiscovery.c @@ -580,7 +580,7 @@ static char Usage[] = " -p STUN server port (Default: 3478)\n" " -L Local address to use (optional)\n" " -l Local port to use (use with -L)\n" -" -A Local alrernative address to use\n" +" -A Local alternative address to use\n" " Used by collision behavior discovery\n" " -T Mapping lifetime timer (sec)\n" " Used by mapping lifetime behavior discovery\n"; diff --git a/src/apps/relay/dbdrivers/dbd_sqlite.c b/src/apps/relay/dbdrivers/dbd_sqlite.c index 06da7c1..ab8c470 100644 --- a/src/apps/relay/dbdrivers/dbd_sqlite.c +++ b/src/apps/relay/dbdrivers/dbd_sqlite.c @@ -95,28 +95,26 @@ static void sqlite_unlock(int write) ////////////////////////////////////////////////// -static int sqlite_init_multithreaded(void) { +static void sqlite_init_multithreaded(void) { #if defined(SQLITE_CONFIG_MULTITHREAD) - - sqlite3_shutdown(); - if (sqlite3_threadsafe() > 0) { int retCode = sqlite3_config(SQLITE_CONFIG_MULTITHREAD); if (retCode != SQLITE_OK) { retCode = sqlite3_config(SQLITE_CONFIG_SERIALIZED); if (retCode != SQLITE_OK) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "setting sqlite thread safe mode to serialized failed!!! return code: %d\n", retCode); - return -1; + return; } } + sqlite3_initialize(); } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Your SQLite database is not compiled to be threadsafe.\n"); - return -1; + return; } #endif - return 0; + return; } static int donot_print_connection_success = 0; @@ -175,13 +173,15 @@ static void init_sqlite_database(sqlite3 *sqliteconnection) { } static sqlite3 * get_sqlite_connection(void) { + static pthread_once_t sqlite_init_once = PTHREAD_ONCE_INIT; persistent_users_db_t *pud = get_persistent_users_db(); sqlite3 *sqliteconnection = (sqlite3 *)pthread_getspecific(connection_key); if(!sqliteconnection) { + fix_user_directory(pud->userdb); - sqlite_init_multithreaded(); + (void) pthread_once(&sqlite_init_once, sqlite_init_multithreaded); int rc = sqlite3_open(pud->userdb, &sqliteconnection); if(!sqliteconnection || (rc != SQLITE_OK)) { const char* errmsg = sqlite3_errmsg(sqliteconnection); diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 3ed4a1d..d936887 100644 --- a/src/apps/relay/mainrelay.c +++ b/src/apps/relay/mainrelay.c @@ -173,6 +173,8 @@ TURN_CREDENTIALS_NONE, /* ct */ 0, /* user_quota */ #if !defined(TURN_NO_PROMETHEUS) 0, /* prometheus disabled by default */ +DEFAULT_PROM_SERVER_PORT, /* prometheus port */ +0, /* prometheus username labelling disabled by default when prometheus is enabled */ #endif ///////////// Users DB ////////////// { (TURN_USERDB_TYPE)0, {"\0"}, {0,NULL, {NULL,0}} }, @@ -557,8 +559,10 @@ static char Usage[] = "Usage: turnserver [options]\n" " The connection string has the same parameters as redis-userdb connection string.\n" #endif #if !defined(TURN_NO_PROMETHEUS) -" --prometheus Enable prometheus metrics. It is disabled by default. If it is enabled it will listen on port 9641 unther the path /metrics\n" +" --prometheus Enable prometheus metrics. It is disabled by default. If it is enabled it will listen on port 9641 under the path /metrics\n" " also the path / on this port can be used as a health check\n" +" --prometheus-port Prometheus metrics port (Default: 9641).\n" +" --prometheus-username-labels When metrics are enabled, add labels with client usernames.\n" #endif " --use-auth-secret TURN REST API flag.\n" " Flag that sets a special authorization option that is based upon authentication secret\n" @@ -787,6 +791,8 @@ enum EXTRA_OPTS { CHANNEL_LIFETIME_OPT, PERMISSION_LIFETIME_OPT, PROMETHEUS_OPT, + PROMETHEUS_PORT_OPT, + PROMETHEUS_ENABLE_USERNAMES_OPT, AUTH_SECRET_OPT, NO_AUTH_PINGS_OPT, NO_DYNAMIC_IP_LIST_OPT, @@ -902,6 +908,8 @@ static const struct myoption long_options[] = { #endif #if !defined(TURN_NO_PROMETHEUS) { "prometheus", optional_argument, NULL, PROMETHEUS_OPT }, + { "prometheus-port", optional_argument, NULL, PROMETHEUS_PORT_OPT }, + { "prometheus-username-labels", optional_argument, NULL, PROMETHEUS_ENABLE_USERNAMES_OPT }, #endif { "use-auth-secret", optional_argument, NULL, AUTH_SECRET_OPT }, { "static-auth-secret", required_argument, NULL, STATIC_AUTH_SECRET_VAL_OPT }, @@ -1534,6 +1542,12 @@ static void set_option(int c, char *value) case PROMETHEUS_OPT: turn_params.prometheus = 1; break; + case PROMETHEUS_PORT_OPT: + turn_params.prometheus_port = atoi(value); + break; + case PROMETHEUS_ENABLE_USERNAMES_OPT: + turn_params.prometheus_username_labels = 1; + break; #endif case AUTH_SECRET_OPT: turn_params.use_auth_secret_with_timestamp = 1; @@ -2589,9 +2603,13 @@ int main(int argc, char **argv) drop_privileges(); #if !defined(TURN_NO_PROMETHEUS) - if (start_prometheus_server()){ + int prometheus_status = start_prometheus_server(); + if (prometheus_status < 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Could not start Prometheus collector!\n"); } + else if (prometheus_status == 1) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Prometheus collector disabled, not started.\n"); + } else { TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Prometheus collector started successfully.\n"); } diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index 2e70387..9c8a28c 100644 --- a/src/apps/relay/mainrelay.h +++ b/src/apps/relay/mainrelay.h @@ -318,7 +318,9 @@ typedef struct _turn_params_ { vint total_quota; vint user_quota; #if !defined(TURN_NO_PROMETHEUS) - int prometheus; + int prometheus; + int prometheus_port; + int prometheus_username_labels; #endif diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 6088528..c51d386 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -2757,8 +2757,8 @@ void close_ioa_socket_after_processing_if_necessary(ioa_socket_handle s) { tcp_connection *tc = s->sub_session; if (tc) { - delete_tcp_connection(tc); s->sub_session = NULL; + delete_tcp_connection(tc); } } break; @@ -2945,8 +2945,8 @@ static void eventcb_bev(struct bufferevent *bev, short events, void *arg) { tcp_connection *tc = s->sub_session; if (tc) { - delete_tcp_connection(tc); s->sub_session = NULL; + delete_tcp_connection(tc); } } break; diff --git a/src/apps/relay/prom_server.c b/src/apps/relay/prom_server.c index 880786f..ec8cb13 100644 --- a/src/apps/relay/prom_server.c +++ b/src/apps/relay/prom_server.c @@ -32,20 +32,26 @@ int start_prometheus_server(void){ return 1; } prom_collector_registry_default_init(); - - const char *label[] = {"realm", "user"}; + + const char *label[] = {"realm", NULL}; + size_t nlabels = 1; + + if (turn_params.prometheus_username_labels) { + label[1] = "user"; + nlabels++; + } // Create traffic counter metrics - turn_traffic_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvp", "Represents finished sessions received packets", 2, label)); - turn_traffic_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvb", "Represents finished sessions received bytes", 2, label)); - turn_traffic_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentp", "Represents finished sessions sent packets", 2, label)); - turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentb", "Represents finished sessions sent bytes", 2, label)); + turn_traffic_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvp", "Represents finished sessions received packets", nlabels, label)); + turn_traffic_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_rcvb", "Represents finished sessions received bytes", nlabels, label)); + turn_traffic_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentp", "Represents finished sessions sent packets", nlabels, label)); + turn_traffic_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_sentb", "Represents finished sessions sent bytes", nlabels, label)); // Create finished sessions traffic for peers counter metrics - turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvp", "Represents finished sessions peer received packets", 2, label)); - turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvb", "Represents finished sessions peer received bytes", 2, label)); - turn_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentp", "Represents finished sessions peer sent packets", 2, label)); - turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentb", "Represents finished sessions peer sent bytes", 2, label)); + turn_traffic_peer_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvp", "Represents finished sessions peer received packets", nlabels, label)); + turn_traffic_peer_rcvb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_rcvb", "Represents finished sessions peer received bytes", nlabels, label)); + turn_traffic_peer_sentp = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentp", "Represents finished sessions peer sent packets", nlabels, label)); + turn_traffic_peer_sentb = prom_collector_registry_must_register_metric(prom_counter_new("turn_traffic_peer_sentb", "Represents finished sessions peer sent bytes", nlabels, label)); // Create total finished traffic counter metrics turn_total_traffic_rcvp = prom_collector_registry_must_register_metric(prom_counter_new("turn_total_traffic_rcvp", "Represents total finished sessions received packets", 0, NULL)); @@ -65,9 +71,9 @@ int start_prometheus_server(void){ promhttp_set_active_collector_registry(NULL); - struct MHD_Daemon *daemon = promhttp_start_daemon(MHD_USE_SELECT_INTERNALLY, DEFAULT_PROM_SERVER_PORT, NULL, NULL); + struct MHD_Daemon *daemon = promhttp_start_daemon(MHD_USE_SELECT_INTERNALLY, turn_params.prometheus_port, NULL, NULL); if (daemon == NULL) { - return 1; + return -1; } return 0; } @@ -75,7 +81,10 @@ int start_prometheus_server(void){ void prom_set_finished_traffic(const char* realm, const char* user, unsigned long rsvp, unsigned long rsvb, unsigned long sentp, unsigned long sentb, bool peer){ if (turn_params.prometheus == 1){ - const char *label[] = {realm, user}; + const char *label[] = {realm, NULL}; + if (turn_params.prometheus_username_labels){ + label[1] = user; + } if (peer){ prom_counter_add(turn_traffic_peer_rcvp, rsvp, label);