From 278901cc8ee1b95dbaacb71836bfe0fddf31e38e Mon Sep 17 00:00:00 2001 From: Ciprian Date: Fri, 3 Dec 2021 17:35:18 -0500 Subject: [PATCH] :tada: v1.0.0 (#1) --- LICENSE | 2 +- README.md | 52 ++++++++++++++++++++ bin/mkbuilder.sh | 65 +++++++++++++++++++++++++ bin/mkslim.sh | 124 +++++++++++++++++++++++++++++++++++++++++++++++ etc/Dockerfile | 43 ++++++++++++++++ etc/config.sh | 6 +++ 6 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 README.md create mode 100755 bin/mkbuilder.sh create mode 100755 bin/mkslim.sh create mode 100644 etc/Dockerfile create mode 100644 etc/config.sh diff --git a/LICENSE b/LICENSE index 7f754b9..9a0a554 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 rtckit +Copyright (c) 2021 Ciprian Dosoftei Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md new file mode 100644 index 0000000..36fa72a --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ + + slimswitch + + +# Build minimal FreeSWITCH Docker images + +[![Docker Pulls](https://img.shields.io/docker/pulls/rtckit/slimswitch-builder.svg)](https://hub.docker.com/r/rtckit/slimswitch-builder) +[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE) + +Tooling for creating lean FreeSWITCH Docker images; resulting containers are efficient and expose a reduced attack surface. This is achieved by layering only the FreeSWITCH core and modules alongside their its runtime dependencies. + +## Quickstart + +Decide which FreeSWITCH modules should be included and provide a basic XML core/modules configuration file! + +```sh +git clone https://github.com/rtckit/slimswitch.git +cd slimswitch + +./bin/mkslim.sh \ + -m mod_commands -m mod_dptools -m mod_sofia \ + -s local/awesome-switch +docker run --rm -it \ + -v "$(pwd)/freeswitch.xml":/etc/freeswitch/freeswitch.xml \ + local/awesome-switch:v1.10.7 +``` + +![Quickstart](https://raw.github.com/rtckit/media/master/slimswitch/demo.gif) + +## Requirements + +[Docker](https://docs.docker.com/get-docker/) and [docker-slim](https://dockersl.im/install.html) must be installed in the building environment. + +## How it works + +A generic reusable [builder image](etc/Dockerfile) is created first; the goal is to build the FreeSWITCH core and most of its modules, so then they can be mixed-and-matched as needed. The resulting image can also serve as a base for compiling third party modules. This phase is handled by the [./bin/mkbuilder.sh](./bin/mkbuilder.sh) script. Images corresponding to official FreeSWITCH releases are also [publicly available](https://hub.docker.com/r/rtckit/slimswitch-builder). + +The trimming is achieved via the [./bin/mkslim.sh](./bin/mkslim.sh) script, which is essentially a wrapper for docker-slim; specifically, it leverages its static analysis features so dynamic dependencies are accounted for when the final image is created. + +## License + +MIT, see [LICENSE file](LICENSE). + +### Acknowledgments + +* [FreeSWITCH](https://github.com/signalwire/freeswitch), FreeSWITCH is a registered trademark of Anthony Minessale II +* [Docker](https://docker.com), Docker is a registered trademark of Docker, Inc +* [docker-slim](https://github.com/docker-slim/docker-slim) + +### Contributing + +Bug reports (and small patches) can be submitted via the [issue tracker](https://github.com/rtckit/slimswitch/issues). Forking the repository and submitting a Pull Request is preferred for substantial patches. diff --git a/bin/mkbuilder.sh b/bin/mkbuilder.sh new file mode 100755 index 0000000..811c123 --- /dev/null +++ b/bin/mkbuilder.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +ETC_PATH="`dirname $0`"/../etc + +. ${ETC_PATH}/config.sh + +if [ ! -x "$(command -v docker)" ]; then + printf "Cannot find docker\n" + exit 1 +fi + +# Process arguments +while :; do + case $1 in + -d) + if [ -n "$2" ]; then + DEBIAN_RELEASE=$2 + shift + else + printf "Cannot pass -d without Debian release argument (e.g. ${DEBIAN_RELEASE})\n" >&2 + exit 1 + fi + ;; + -t) + if [ -n "$2" ]; then + FREESWITCH_TAG=$2 + shift + else + printf "Cannot pass -t without FreeSWITCH tag argument (e.g. ${FREESWITCH_TAG})\n" >&2 + exit 1 + fi + ;; + -r) + if [ -n "$2" ]; then + BUILDER_REPOSITORY=$2 + shift + else + printf "Cannot pass -r without builder Docker image repository name argument (e.g. ${BUILDER_REPOSITORY})\n" >&2 + exit 1 + fi + ;; + -h) + printf "slimswitch mkbuilder.sh utility\n" + printf "https://github.com/rtckit/slimswitch\n\n" + printf "Usage: %s [-d ] [-t ] [-r ]\n" "$0" + printf "\t-d Base Debian image tag (default: %s)\n" "${DEBIAN_RELEASE}" + printf "\t-t Builder image tag (default: %s)\n" "${FREESWITCH_TAG}" + printf "\t-r Builder image repository (default: %s)\n" "${BUILDER_REPOSITORY}" + exit 0 + ;; + -?*) + printf "Unknown argument %s\n" "$1" >&2 + exit 1 + ;; + *) + break + esac + + shift +done + +docker build \ + --build-arg FREESWITCH_TAG=${FREESWITCH_TAG} \ + -t ${BUILDER_REPOSITORY}:${FREESWITCH_TAG} \ + -f ${ETC_PATH}/Dockerfile ${ETC_PATH} diff --git a/bin/mkslim.sh b/bin/mkslim.sh new file mode 100755 index 0000000..9f5a726 --- /dev/null +++ b/bin/mkslim.sh @@ -0,0 +1,124 @@ +#!/bin/sh + +ETC_PATH="`dirname $0`"/../etc + +. ${ETC_PATH}/config.sh + +if [ ! -x "$(command -v docker)" ]; then + printf "Cannot find docker\n" + exit 1 +fi + +if [ ! -x "$(command -v docker-slim)" ]; then + printf "Cannot find docker-slim\n" + exit 1 +fi + +SLIM_REPOSITORY="" +MODULE_FLAGS="" +INCLUDE_FLAGS="" + +# Process arguments +while :; do + case $1 in + -t) + if [ -n "$2" ]; then + FREESWITCH_TAG=$2 + shift + else + printf "Cannot pass -t without FreeSWITCH tag argument (e.g. ${FREESWITCH_TAG})\n" >&2 + exit 1 + fi + ;; + -r) + if [ -n "$2" ]; then + BUILDER_REPOSITORY=$2 + shift + else + printf "Cannot pass -r without builder Docker image repository name argument (e.g. ${BUILDER_REPOSITORY})\n" >&2 + exit 1 + fi + ;; + -s) + if [ -n "$2" ]; then + SLIM_REPOSITORY=$2 + shift + else + printf "Cannot pass -s without slim Docker image repository name argument\n" >&2 + exit 1 + fi + ;; + -m) + if [ -n "$2" ]; then + MODULE_FLAGS="${MODULE_FLAGS} --include-exe=/usr/lib/freeswitch/mod/$2.so" + shift + else + printf "Cannot pass -m without FreeSWSITCH module name argument (e.g. mod_commands)\n" >&2 + exit 1 + fi + ;; + -i) + if [ -n "$2" ]; then + INCLUDE_FLAGS="${INCLUDE_FLAGS} --include-path=$2" + shift + else + printf "Cannot pass -i without include path argument (e.g. /usr/share/freeswitch/sounds)\n" >&2 + exit 1 + fi + ;; + -h) + printf "slimswitch mkslim.sh utility\n" + printf "https://github.com/rtckit/slimswitch\n\n" + printf "Usage: %s [-t ] [-r ] [-s ] [-m ] [-i ]\n" "$0" + printf "\t-t Builder image tag (default: %s)\n" "${FREESWITCH_TAG}" + printf "\t-r Builder image repository (default: %s)\n" "${BUILDER_REPOSITORY}" + printf "\t-s Slim image repository (e.g. -s my-org/telco-project)\n" + printf "\t-m FreeSWITCH module, can be used multiple times (e.g. -m mod_mariadb -m mod_shout)\n" + printf "\t-i Keep path from builder image, can be used multiple times (e.g. -i /usr/share/freeswitch/sounds)\n" + exit 0 + ;; + -?*) + printf "Unknown argument %s\n" "$1" >&2 + exit 1 + ;; + *) + break + esac + + shift +done + +docker image inspect ${BUILDER_REPOSITORY}:${FREESWITCH_TAG} > /dev/null 2>&1 +LOCAL_BUILDER=$? + +if [ $LOCAL_BUILDER -ne 0 ]; then + printf "Local builder image not found, checking public DockerHub images ...\n" + + curl --silent -f -lSL https://index.docker.io/v1/repositories/${BUILDER_REPOSITORY}/tags/${FREESWITCH_TAG} > /dev/null 2>&1 + DOCKERHUB_BUILDER=$? + + if [ $DOCKERHUB_BUILDER -ne 0 ]; then + printf "Builder image not found on DockerHub, creating it locally ...\n" + "`dirname $0`"/mkbuilder.sh + else + printf "Pulling builder image from DockerHub ...\n" + docker pull ${BUILDER_REPOSITORY}:${FREESWITCH_TAG} + fi +else + printf "Using local builder docker image ...\n" +fi + +if [ -z "$SLIM_REPOSITORY" ]; then + SLIM_REPOSITORY=$(printf '%s' "$BUILDER_REPOSITORY" | sed -e 's/-builder/-slim/g') +fi + +docker-slim build \ + --http-probe-off \ + --continue-after 1 \ + --include-cert-all \ + --entrypoint=/bin/true \ + --include-exe=/usr/bin/freeswitch ${MODULE_FLAGS} \ + ${INCLUDE_FLAGS} \ + --exclude-pattern=/bin/true \ + --target ${BUILDER_REPOSITORY}:${FREESWITCH_TAG} \ + --tag ${SLIM_REPOSITORY}:${FREESWITCH_TAG} diff --git a/etc/Dockerfile b/etc/Dockerfile new file mode 100644 index 0000000..616d4a8 --- /dev/null +++ b/etc/Dockerfile @@ -0,0 +1,43 @@ +ARG DEBIAN_RELEASE=bullseye + +FROM debian:${DEBIAN_RELEASE} + +ARG FREESWITCH_TAG=v1.10.7 + +# Prerequisites +RUN apt-get update && \ + apt-get install -y gnupg2 wget lsb-release && \ + wget -O /usr/share/keyrings/freeswitch-archive-keyring.gpg https://files.freeswitch.org/repo/deb/debian-release/freeswitch-archive-keyring.gpg && \ + echo "deb [signed-by=/usr/share/keyrings/freeswitch-archive-keyring.gpg] http://files.freeswitch.org/repo/deb/debian-release/ `lsb_release -sc` main" > /etc/apt/sources.list.d/freeswitch.list && \ + echo "deb-src [signed-by=/usr/share/keyrings/freeswitch-archive-keyring.gpg] http://files.freeswitch.org/repo/deb/debian-release/ `lsb_release -sc` main" >> /etc/apt/sources.list.d/freeswitch.list && \ + apt-get update && \ + apt-get build-dep -y freeswitch + +# Pull desired code base +RUN mkdir -p /usr/src && \ + cd /usr/src && \ + wget https://codeload.github.com/signalwire/freeswitch/tar.gz/refs/tags/${FREESWITCH_TAG} -O - | tar zvx + +# Configure +RUN cd /usr/src/freeswitch* && \ + ./bootstrap.sh -j && \ + ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --disable-debug + +# Enable most modules +RUN cd /usr/src/freeswitch* && \ + cp ./build/modules.conf.most modules.conf && \ + sed -i \ + -e "s/#databases\/mod_mariadb/databases\/mod_mariadb/g" \ + -e "s/applications\/mod_mongo/#applications\/mod_mongo/g" \ + -e "s/applications\/mod_mp4/#applications\/mod_mp4/g" \ + -e "s/codecs\/mod_sangoma_codec/#codecs\/mod_sangoma_codec/g" \ + -e "s/codecs\/mod_siren/#codecs\/mod_siren/g" \ + modules.conf + +# Build and install +RUN cd /usr/src/freeswitch* && make -j && make install + +# Install audio files +RUN cd /usr/src/freeswitch* && make sounds-install && make moh-install + +ENTRYPOINT ["/usr/bin/freeswitch", "-nonat"] diff --git a/etc/config.sh b/etc/config.sh new file mode 100644 index 0000000..d1926ae --- /dev/null +++ b/etc/config.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +# Default configuration +export DEBIAN_RELEASE=bullseye +export FREESWITCH_TAG=v1.10.7 +export BUILDER_REPOSITORY=rtckit/slimswitch-builder