Browse Source

initial code commit from local (no history)

Hal De 4 years ago
parent
commit
347b3c7bd6

+ 319 - 0
Dockerfile

@@ -0,0 +1,319 @@
+FROM ubuntu:focal AS build-asterisk
+ENV DEBIAN_FRONTEND=noninteractive
+ARG ASTERISK_VER=18.2.0
+ARG BCG729_VER=1.1.1
+ARG ASTERISK_G72X_VER=master
+
+WORKDIR /usr/src
+RUN apt-get update && \
+    apt-get install --no-install-recommends --yes \
+    git build-essential subversion checkinstall autoconf automake bison flex graphviz cmake curl ca-certificates libresample1-dev libiksemel-dev libopus-dev pkg-config
+
+RUN cd /usr/src && \
+  mkdir asterisk && \
+  curl -fSL --connect-timeout 30 http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-${ASTERISK_VER}.tar.gz | tar xz --strip 1 -C asterisk && \
+  cd asterisk && \
+  ./contrib/scripts/get_mp3_source.sh && \
+  ./contrib/scripts/install_prereq install
+
+RUN cd /usr/src/asterisk && git clone https://github.com/felipem1210/asterisk-res_json.git && ./asterisk-res_json/install.sh
+
+RUN cd /usr/src/asterisk && ./configure --prefix=/usr --libdir=/usr/lib --with-pjproject-bundled --with-jansson-bundled --with-resample --with-ssl=ssl --with-srtp && \
+  make menuselect/menuselect menuselect-tree menuselect.makeopts && \
+  menuselect/menuselect \
+    --enable-category MENUSELECT_ADDONS \
+    --enable-category MENUSELECT_CHANNELS \
+    --enable-category MENUSELECT_APPS \
+    --enable-category MENUSELECT_CDR \
+    --enable-category MENUSELECT_FORMATS \
+    --enable-category MENUSELECT_FUNCS \
+    --enable-category MENUSELECT_PBX \
+    --enable-category MENUSELECT_RES \
+    --enable-category MENUSELECT_CEL \
+  \
+  menuselect/menuselect \
+    --enable BETTER_BACKTRACES \
+    --enable DONT_OPTIMIZE \
+    --enable app_confbridge \
+    --enable app_macro \
+    --enable app_meetme \
+    --enable app_mysql \
+    --enable app_page \
+    --enable binaural_rendering_in_bridge_softmix \
+    --enable chan_motif \
+    --enable codec_silk \
+    --enable codec_opus \
+    --enable format_mp3 \
+    --enable res_ari \
+    --enable res_chan_stats \
+    --enable res_calendar \
+    --enable res_calendar_caldav \
+    --enable res_calendar_icalendar \
+    --enable res_endpoint_stats \
+    --enable res_pktccops \
+    --enable res_snmp \
+    --enable res_srtp \
+    --enable res_xmpp \
+    --disable-category MENUSELECT_CORE_SOUNDS \
+    --disable-category MENUSELECT_EXTRA_SOUNDS \
+    --disable-category MENUSELECT_MOH \
+    --disable BUILD_NATIVE \
+    --disable app_ivrdemo \
+    --disable app_meetme \
+    --disable app_saycounted \
+    --disable app_skel \
+    --disable cdr_pgsql \
+    --disable cel_pgsql \
+    --disable cdr_sqlite3_custom \
+    --disable cel_sqlite3_custom \
+    --disable cdr_mysql \
+    --disable cdr_tds \
+    --disable cel_tds \
+    --disable cdr_radius \
+    --disable cel_radius \
+    --disable cdr_syslog \
+    --disable chan_alsa \
+    --disable chan_console \
+    --disable chan_oss \
+    --disable chan_mgcp \
+    --disable chan_skinny \
+    --disable chan_ooh323 \
+    --disable chan_mobile \
+    --disable chan_unistim \
+    --disable res_digium_phone \
+    --disable res_calendar_ews \
+    --disable res_calendar_exchange \
+    --disable res_stasis_mailbox \
+    --disable res_mwi_external \
+    --disable res_mwi_external_ami \
+    --disable res_config_pgsql \
+    --disable res_config_mysql \
+    --disable res_config_ldap \
+    --disable res_config_sqlite3 \
+    --disable res_phoneprov \
+    --disable res_pjsip_phoneprov_provider \
+  && \
+  make && \
+  checkinstall --install=yes --default --pakdir=/usr/src/packages --pkgname=asterisk-rrt  --pkgversion=${ASTERISK_VER} && \
+  checkinstall --install=yes --default --pakdir=/usr/src/packages --pkgname=asterisk-rrt-dev --pkgversion=${ASTERISK_VER} make install-headers && \
+  checkinstall --install=yes --default --pakdir=/usr/src/packages --pkgname=asterisk-rrt-config --pkgversion=${ASTERISK_VER} make config && \
+  checkinstall --install=yes --default --pakdir=/usr/src/packages --pkgname=asterisk-rrt-samples --pkgversion=${ASTERISK_VER} make samples && \
+  ldconfig && \
+  cd /usr/src && \
+  mkdir bcg729 && \
+  curl -fSL --connect-timeout 30 https://github.com/BelledonneCommunications/bcg729/archive/${BCG729_VER}.tar.gz | tar xz --strip 1 -C bcg729 && \
+  cd bcg729 && \
+  cmake . -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_PREFIX_PATH=/usr && \
+  make && \
+  checkinstall --install=yes --default --pakdir=/usr/src/packages --pkgname=bcg729-rrt --pkgversion=${BCG729_VER} --spec=none && \
+  ldconfig && \
+  cd /usr/src && \
+  mkdir asterisk-g72x && \
+  curl -fSL --connect-timeout 30 https://bitbucket.org/arkadi/asterisk-g72x/get/${ASTERISK_G72X_VER}.tar.gz | tar xz --strip 1 -C asterisk-g72x && \
+  cd asterisk-g72x && \
+  ./autogen.sh && \
+  ./configure --prefix=/usr --with-bcg729 --enable-penryn && \
+  make && \
+  checkinstall --install=yes --default --pakdir=/usr/src/packages --pkgname=asterisk-g72x-rrt --pkgversion=0.${ASTERISK_G72X_VER} && \
+  ldconfig
+
+FROM ubuntu:focal AS rrd-freepbx
+ENV DEBIAN_FRONTEND=noninteractive
+ARG ASTERISK_VER=18.2.0
+ARG BCG729_VER=1.1.1
+ARG ASTERISK_G72X_VER=master
+ARG FREEPBX_VER=15.0
+ENV APP_PORT_HTTP         80
+ENV APP_PORT_HTTPS        443
+ENV APP_PORT_PJSIP        5160
+ENV APP_PORT_SIP          5060
+ENV APP_PORT_IAX          4569
+ENV APP_PORT_RTP_START    10000
+ENV APP_PORT_RTP_END      10200
+ENV APP_PORT_MYSQL        3306
+ENV APP_UID=1000
+ENV APP_GID=1000
+ENV APP_USR="asterisk"
+ENV APP_GRP="asterisk"
+
+COPY --from=build-asterisk /usr/src/packages /usr/src/packages
+
+RUN apt-get update && \
+    apt-get install --no-install-recommends --yes gpg gpg-agent dirmngr && \
+    apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4F4EA0AAE5267A6C && \
+    echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu focal main" >> /etc/apt/sources.list.d/ondrej-php.list && \
+    echo "deb http://ppa.launchpad.net/ondrej/apache2/ubuntu focal main" >> /etc/apt/sources.list.d/ondrej-apache2.list && \
+    apt-get update && \
+    apt-get upgrade --yes && \
+    dpkg -i /usr/src/packages/*.deb && \
+    apt-get install --no-install-recommends --yes \
+    apache2 \
+    binutils \
+    certbot \
+    codec2 \
+    cron \
+    curl \
+    fail2ban \
+    ffmpeg \
+    file \
+    freetds-bin \
+    freetds-common \
+    iptables \
+    jq \
+    lame \
+    libaudiofile1 \
+    libc-client2007e \
+    libcap2 \
+    libcfg7 \
+    libcpg4 \
+    libdbd-mysql \
+    libdbi-perl\
+    libeditline0 \
+    libevent-2.1-7 \
+    libfftw3-3 \
+    libfftw3-bin \
+    libgmime-3.0-0 \
+    libical3 \
+    libicu66 \
+    libiksemel3 \
+    libjansson4 \
+    libjpeg-turbo8 \
+    libltdl7 \
+    libncurses5 \
+    libneon27 \
+    libnewt0.52 \
+    libopus0 \
+    libosptk4 \
+    libportaudio2 \
+    libproxy1v5 \
+    libresample1 \
+    libsensors5 \
+    libsndfile1 \
+    libsnmp35 \
+    libsnmp-base \
+    libspandsp2 \
+    libspeexdsp1 \
+    libsrtp2-1 \
+    libtiff5 \
+    libtiff-tools \
+    libunbound8 \
+    liburiparser1 \
+    libvpb1 \
+    libxml2 \
+    lm-sensors \
+    logrotate \
+    lsof \
+    mariadb-client \
+    mpg123 \
+    netcat \
+    net-tools \
+    nodejs \
+    npm \
+    odbc-mariadb \
+    openssl \
+    php7.3 \
+    php7.3-mysql \
+    php7.3-curl \
+    php7.3-gd \
+    php7.3-json \
+    php7.3-mbstring \
+    php7.3-xml \
+    postfix \
+    rsync \
+    sox \
+    speex \
+    sqlite3 \
+    strace \
+    sudo \
+    supervisor \
+    unixodbc \
+    unzip \
+    uuid \
+    wget \
+    whois \
+    zip
+
+RUN groupadd -g ${APP_GID} ${APP_GRP} && \
+  useradd -u ${APP_UID} -c "Asterisk User" -g ${APP_GRP} -s /sbin/nologin ${APP_USR} && \
+  usermod -aG sudo,www-data ${APP_USR} && \
+  mkdir -p \
+    /etc/pki/pbx \
+    /home/asterisk \
+    /var/lib/asterisk/moh \
+    /var/lib/asterisk/sounds \
+    /var/spool/asterisk \
+    /var/run/fail2ban && \
+  chown -R ${APP_USR}:${APP_GRP} \
+    /etc/asterisk \
+    /home/asterisk \
+    /var/lib/asterisk \
+    /var/spool/asterisk && \
+  openssl req -subj '/CN=pbx/O=RRT/C=RU' -new -newkey rsa:2048 -sha256 -days 36500 -nodes -x509 -keyout /etc/pki/pbx/rrtpbx.key -out /etc/pki/pbx/rrtpbx.crt
+
+RUN cd /usr/src && \
+  mkdir freepbx && \
+  curl -fSL --connect-timeout 30 http://mirror.freepbx.org/modules/packages/freepbx/freepbx-${FREEPBX_VER}-latest.tgz | tar xz --strip 1 -C freepbx && \
+  cd freepbx && \
+  curl -fSL --connect-timeout 30 http://mirror1.freepbx.org/modules-${FREEPBX_VER}.xml -o modules-${FREEPBX_VER}.xml && \
+  mkdir -p amp_conf/htdocs/admin/modules/_cache && \
+  for MODULE in \
+      pm2 \
+      announcement \
+      arimanager \
+      asteriskinfo \
+      backup \
+      calendar \
+      callforward \
+      callwaiting \
+      cel \
+      certman \
+      cidlookup \
+      contactmanager \
+      daynight \
+      donotdisturb \
+      filestore \
+      findmefollow \
+      iaxsettings \
+      ivr \
+      manager \
+      miscapps \
+      miscdests \
+      parking \
+      phonebook \
+      presencestate \
+      printextensions \
+      queues \
+      soundlang \
+      timeconditions \
+      userman \
+      ucp \
+      bulkhandler \
+      speeddial \
+      weakpasswords \
+      ; do \
+  mkdir -p amp_conf/htdocs/admin/modules/$MODULE && \
+  MODULE_VER=$(php -r "echo json_encode(simplexml_load_file('modules-${FREEPBX_VER}.xml'));" | jq -r ".module[] | select(.rawname == \"${MODULE}\") | {version}".version) && \
+  curl -sfSL --connect-timeout 30 http://mirror.freepbx.org/modules/packages/$MODULE/$MODULE-${MODULE_VER}.tgz | tar xz --strip 1 -C amp_conf/htdocs/admin/modules/$MODULE/ && \
+  curl -sfSL --connect-timeout 30 http://mirror.freepbx.org/modules/packages/$MODULE/$MODULE-${MODULE_VER}.tgz.gpg -o amp_conf/htdocs/admin/modules/_cache/$MODULE-${MODULE_VER}.tgz.gpg \
+  ; done && \
+  su - ${APP_USR} -s /bin/bash -c "gpg --refresh-keys --keyserver hkp://keyserver.ubuntu.com:80" && \
+  su - ${APP_USR} -s /bin/bash -c "gpg --import /usr/src/freepbx/amp_conf/htdocs/admin/libraries/BMO/1588A7366BD35B34.key" && \
+  su - ${APP_USR} -s /bin/bash -c "gpg --import /usr/src/freepbx/amp_conf/htdocs/admin/libraries/BMO/3DDB2122FE6D84F7.key" && \
+  su - ${APP_USR} -s /bin/bash -c "gpg --import /usr/src/freepbx/amp_conf/htdocs/admin/libraries/BMO/86CE877469D2EAD9.key" && \
+  su - ${APP_USR} -s /bin/bash -c "gpg --import /usr/src/freepbx/amp_conf/htdocs/admin/libraries/BMO/9F9169F4B33B4659.key"
+
+EXPOSE ${APP_PORT_HTTP}/tcp \
+       ${APP_PORT_HTTPS}/tcp \
+       ${APP_PORT_PJSIP}/tcp \
+       ${APP_PORT_PJSIP}/udp \
+       ${APP_PORT_IAX}/tcp \
+       ${APP_PORT_IAX}/udp \
+       ${APP_PORT_SIP}/tcp \
+       ${APP_PORT_SIP}/udp \
+       ${APP_PORT_RTP_START}-${APP_PORT_RTP_END}/udp \
+       ${APP_PORT_MYSQL}/tcp
+
+ADD filesystem /
+
+ENTRYPOINT ["/entrypoint.sh"]
+CMD ["supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]

+ 656 - 0
filesystem/entrypoint-hooks.sh

@@ -0,0 +1,656 @@
+#!/bin/bash
+
+: ${ROOT_MAILTO:="root@localhost"}
+: ${ASTERISK_VER:=""}
+: ${FREEPBX_VER:=""}
+: ${APP_DATA:=""}
+
+declare -A appDataDirs=(
+  [CRONDIR]=/var/spool/cron
+  [ASTHOME]=/home/asterisk
+  [ASTETCDIR]=/etc/asterisk
+  [ASTVARLIBDIR]=/var/lib/asterisk
+  [ASTSPOOLDIR]=/var/spool/asterisk
+  [ASTRUNDIR]=/var/run/asterisk
+  [HTTPDHOME]=/var/www
+  [HTTPDLOGDIR]=/var/log/apache2
+  [CERTBOTETCDIR]=/etc/letsencrypt
+  [ASTLOGDIR]=/var/log/asterisk
+  [F2BLOGDIR]=/var/log/fail2ban
+  [F2BLIBDIR]=/var/lib/fail2ban
+  [SSLCRTDIR]=/etc/pki/pbx
+  [ROOTHOME]=/root
+)
+
+declare -A appFilesConf=(
+  [FPBXCFGFILE]=/etc/freepbx.conf
+  [AMPCFGFILE]=/etc/amportal.conf
+)
+
+declare -A appCacheDirs=(
+  [ASTRUNDIR]=/var/run/asterisk
+  [PHPOPCACHEDIR]=/var/lib/php/opcache
+  [PHPSESSDIR]=/var/lib/php/session
+  [PHPWSDLDIR]=/var/lib/php/wsdlcache
+)
+
+declare -A fpbxDirs=(
+  [AMPWEBROOT]=/var/www/html
+  [ASTETCDIR]=/etc/asterisk
+  [ASTVARLIBDIR]=/var/lib/asterisk
+  [ASTAGIDIR]=/var/lib/asterisk/agi-bin
+  [ASTSPOOLDIR]=/var/spool/asterisk
+  [ASTRUNDIR]=/var/run/asterisk
+  [ASTLOGDIR]=/var/log/asterisk
+  [AMPBIN]=/var/lib/asterisk/bin
+  [AMPSBIN]=/var/lib/asterisk/sbin
+  [AMPCGIBIN]=/var/www/cgi-bin
+  [AMPPLAYBACK]=/var/lib/asterisk/playback
+  [CERTKEYLOC]=/etc/asterisk/keys
+)
+
+declare -A fpbxDirsExtra=(
+  [ASTMODDIR]=/usr/lib/asterisk/modules
+)
+
+declare -A fpbxFilesLog=(
+  [FPBXDBUGFILE]=/var/log/asterisk/freepbx-debug.log
+  [FPBXLOGFILE]=/var/log/asterisk/freepbx.log
+  [FPBXSECLOGFILE]=/var/log/asterisk/freepbx_security.log
+)
+
+declare -A fpbxSipSettings=(
+  [rtpstart]=${APP_PORT_RTP_START}
+  [rtpend]=${APP_PORT_RTP_END}
+  [udpport-0.0.0.0]=${APP_PORT_PJSIP}
+  [tcpport-0.0.0.0]=${APP_PORT_PJSIP}
+  [bindport]=${APP_PORT_SIP}
+)
+
+[ ! -z ${APP_FQDN} ] && HOSTNAME="${APP_FQDN}"
+: ${SERVERNAME:=$HOSTNAME}
+: ${MYSQL_SERVER:="db"}
+: ${MYSQL_ROOT_PASSWORD:=""}
+: ${MYSQL_DATABASE:="asterisk"}
+: ${MYSQL_USER:="asterisk"}
+: ${MYSQL_PASSWORD:=""}
+: ${APP_PORT_MYSQL:="3306"}
+: ${HTTPD_HTTPS_ENABLED:="true"}
+: ${HTTPD_REDIRECT_HTTP_TO_HTTPS:="false"}
+: ${HTTPD_ALLOW_FROM:=""}
+: ${CRON_ENABLED:="true"}
+: ${HTTPD_ENABLED:="true"}
+: ${ASTERISK_ENABLED:="false"}
+: ${RRTPBX_ENABLED:="true"}
+: ${FAIL2BAN_ENABLED:="true"}
+: ${POSTFIX_ENABLED:="true"}
+: ${SMTP_RELAYHOST:=""}
+: ${SMTP_RELAYHOST_USERNAME:=""}
+: ${SMTP_RELAYHOST_PASSWORD:=""}
+: ${SMTP_ALLOWED_SENDER_DOMAINS:=""}
+: ${SMTP_MESSAGE_SIZE_LIMIT:="0"}
+: ${SMTP_MAIL_FROM:=""}
+: ${RELAYHOST:="$SMTP_RELAYHOST"}
+: ${RELAYHOST_USERNAME:="$SMTP_RELAYHOST_USERNAME"}
+: ${RELAYHOST_PASSWORD:="$SMTP_RELAYHOST_PASSWORD"}
+: ${ALLOWED_SENDER_DOMAINS:="$SMTP_ALLOWED_SENDER_DOMAINS"}
+: ${MESSAGE_SIZE_LIMIT:="$SMTP_MESSAGE_SIZE_LIMIT"}
+: ${SUPERVISOR_DIR:="/etc/supervisor/conf.d"}
+: ${HTTPD_CONF_DIR:="/etc/apache2"}
+: ${PHP_CONF:="/etc/php/7.4/apache2/php.ini"}
+
+dirEmpty() {
+    [ -z "$(ls -A "$1/")" ]
+}
+
+symlinkDir() {
+  local dirOriginal="$1"
+  local dirCustom="$2"
+  echo "---> directory data override detected: original:[$dirOriginal] custom:[$dirCustom]"
+  if [ -e "$dirOriginal" ] && dirEmpty "$dirCustom"; then
+    echo "---> empty dir '$dirCustom' detected copying '$dirOriginal' contents to '$dirCustom'..."
+    rsync -a -q "$dirOriginal/" "$dirCustom/"
+  fi
+  if [ ! -e "$dirOriginal" ]; then
+      echo "---> WARNING: original data directory doesn't exist... creating empty directory: '$dirOriginal'"
+      mkdir -p "$dirOriginal"
+  fi
+  if [ -e "$dirOriginal" ]; then
+      echo -e "---> renaming '${dirOriginal}' to '${dirOriginal}.dist'"
+      mv "$dirOriginal" "$dirOriginal".dist
+  fi
+  echo "---> symlinking '$dirCustom' to '$dirOriginal'"
+  ln -s "$dirCustom" "$dirOriginal"
+}
+
+symlinkFile() {
+  local fileOriginal="$1"
+  local fileCustom="$2"
+  echo "--> file data override detected: original:[$fileOriginal] custom:[$fileCustom]"
+  if [ -e "$fileOriginal" ]; then
+      if [ ! -e "$fileCustom" ]; then
+        echo "---> INFO: detected not existing file '$fileCustom'. copying '$fileOriginal' to '$fileCustom'..."
+        rsync -a -q "$fileOriginal" "$fileCustom"
+      fi
+      echo -e "---> renaming '${fileOriginal}' to '${fileOriginal}.dist'... "
+      mv "$fileOriginal" "$fileOriginal".dist
+    else
+      echo "---> WARNING: original data file doesn't exist... creating symlink from a not existing source: '$fileOriginal'"
+  fi
+  echo "---> symlinking '$fileCustom' to '$fileOriginal'"
+  [ ! -e "$(dirname "$fileCustom")" ] && mkdir -p "$(dirname "$fileCustom")"
+  ln -s "$fileCustom" "$fileOriginal"
+}
+
+chkService() {
+  local SERVICE_VAR="$1"
+  eval local SERVICE_ENABLED="\$$(echo $SERVICE_VAR)"
+  eval local SERVICE_DAEMON="\$$(echo $SERVICE_VAR | sed 's/_.*//')_DAEMON"
+  local SERVICE="$(echo $SERVICE_VAR | sed 's/_.*//' | sed -e 's/\(.*\)/\L\1/')"
+  [ -z "$SERVICE_DAEMON" ] && local SERVICE_DAEMON="$SERVICE"
+  if [ "$SERVICE_ENABLED" = "true" ]; then
+    autostart=true
+    echo "=> Enabling $SERVICE_DAEMON service... because $SERVICE_VAR=$SERVICE_ENABLED"
+    echo "--> configuring $SERVICE_DAEMON service..."
+    cfgService_$SERVICE
+   else
+    autostart=false
+    echo "=> Disabling $SERVICE_DAEMON service... because $SERVICE_VAR=$SERVICE_ENABLED"
+  fi
+  sed "s/autostart=.*/autostart=$autostart/" -i ${SUPERVISOR_DIR}/$SERVICE_DAEMON.conf
+}
+
+cfgService_postfix() {
+postconf -e inet_protocols=ipv4
+
+if [ ! -z "$HOSTNAME" ]; then
+	postconf -e myhostname="$HOSTNAME"
+else
+	postconf -# myhostname
+fi
+
+postconf -# relayhost
+postconf -# smtp_sasl_auth_enable
+postconf -# smtp_sasl_password_maps
+postconf -# smtp_sasl_security_options
+if [ ! -z "$MYNETWORKS" ]; then
+	postconf -e mynetworks=$MYNETWORKS
+else
+	postconf -e "mynetworks=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
+fi
+[ ! -f /etc/aliases ] && echo "postmaster: root" > /etc/aliases
+[ ${ROOT_MAILTO} ] && echo "root: ${ROOT_MAILTO}" >> /etc/aliases && newaliases
+postconf -e "maillog_file = /dev/stdout"
+postconf -e "inet_protocols = ipv4"
+postconf -e "mailbox_size_limit = 0"
+postconf -e "message_size_limit = ${MESSAGE_SIZE_LIMIT}"
+if [ ! -z "$SMTP_MAIL_FROM" ]; then
+  echo "/.+/ $SMTP_MAIL_FROM" > /etc/postfix/sender_canonical_maps
+  echo "/From:.*/ REPLACE From: $SMTP_MAIL_FROM" > /etc/postfix/header_checks
+  postconf -e "sender_canonical_maps = regexp:/etc/postfix/sender_canonical_maps"
+  postconf -e "smtp_header_checks = regexp:/etc/postfix/header_checks"
+fi
+postconf -M telegram-mailgate/unix="telegram-mailgate unix   -   n   n   -   -   pipe flags= user=list argv=/usr/local/bin/telegram-mailgate.py --key ${TG_BOT_APIKEY} --chatid ${TG_BOT_CHATID} --queue-id \${queue_id} \${recipient}"
+postconf -e "content_filter = telegram-mailgate"
+}
+
+cfgService_cron() {
+  ls -la /var/spool/cron/crontabs
+}
+
+cfgService_letsencrypt() {
+  if [ -e "/etc/letsencrypt/live/${APP_FQDN}/privkey.pem" ] ; then
+    echo "--> Let's Encrypt certificate already exist... trying to renew"
+    certbot renew --standalone
+  else
+    echo "--> generating HTTPS Let's Encrypt certificate"
+    certbot certonly --standalone --expand -n --agree-tos --email ${ROOT_MAILTO} -d ${APP_FQDN}
+  fi
+  echo '#!/bin/bash
+/usr/bin/certbot renew --noninteractive --no-random-sleep-on-renew --deploy-hook "/usr/bin/supervisorctl restart httpd"
+exit $?' > /etc/cron.daily/certbot && chmod 755 /etc/cron.daily/certbot
+}
+
+iniParser() {
+  ini="$@"
+  while read setting ; do
+    section="$(echo $setting | awk -F" " '{print $1}')"
+    k=$(echo $setting | sed -e "s/^${section} //" | awk -F"=" '{print $1}' | tr '[:upper:]' '[:lower:]')
+    v=$(echo $setting | sed -e "s/'//g" | awk -F"=" '{print $2}')
+    sed -e "/^\[${section}\]$/I,/^\(\|;\|#\)\[/ s/^\(;\|#\)${k}/${k}/" -e "/^\[${section}\]$/I,/^\[/ s|^${k}.*=.*|${k}=${v}|I" -i "${ini}"
+  done
+}
+
+cfgService_fail2ban() {
+  echo "--> reconfiguring Fail2ban settings..."
+  echo "DEFAULT LOGTARGET=/var/log/fail2ban/fail2ban.log" | iniParser /etc/fail2ban/fail2ban.conf
+  sed "s/%(mta)s-whois\[/%(mta)s\[/g" -i /etc/fail2ban/jail.conf
+  touch /var/log/fail2ban/fail2ban.log
+  set | grep ^"FAIL2BAN_" | sed -e 's/^FAIL2BAN_//' | sed -e 's/_/ /' | iniParser "/etc/fail2ban/jail.d/99-local.conf"
+}
+
+cfgService_httpd() {
+  if [ "${HTTPD_HTTPS_ENABLED}" = "true" ]; then
+    echo "--> enabling Apache ssl module"
+    a2enmod ssl
+  else
+    echo "--> disabling Apache ssl module"
+    a2dismod ssl
+  fi
+  a2enmod rewrite
+  rm -f /var/www/html/index.html
+  echo "--> setting Apache ServerName to ${SERVERNAME}"
+  sed "s/#ServerName .*/ServerName ${SERVERNAME}/" -i "${HTTPD_CONF_DIR}/sites-enabled/000-default.conf"
+  echo "ServerName ${SERVERNAME}" >> "${HTTPD_CONF_DIR}/apache2.conf"
+  echo "--> setting Apache user and group"
+  sed -i "s/^User.*/User ${APP_USR}/" /etc/apache2/apache2.conf
+  sed -i "s/^Group.*/Group ${APP_GRP}/" /etc/apache2/apache2.conf
+  sed -i "s/AllowOverride None/AllowOverride All/" /etc/apache2/apache2.conf
+
+print_AllowFrom() {
+  if [ ! -z "${HTTPD_ALLOW_FROM}" ]; then
+      for IP in $(echo ${HTTPD_ALLOW_FROM} | sed -e "s/'//g") ; do
+        echo "    Require ip ${IP}"
+      done
+  else
+      echo "    Require all granted"
+  fi
+}
+
+echo "# default HTTP virtualhost
+<VirtualHost *:${APP_PORT_HTTP}>
+  DocumentRoot /var/www/html
+$(if [ "${HTTPD_REDIRECT_HTTP_TO_HTTPS}" = "true" ]; then
+echo "  <IfModule mod_rewrite.c>
+    RewriteEngine on
+    RewriteCond %{REQUEST_URI} !\.well-known/acme-challenge
+    RewriteCond %{HTTPS} off
+    #RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
+    RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
+  </IfModule>"
+fi)
+  <Directory /var/www/html>
+    Options Includes FollowSymLinks MultiViews
+    AllowOverride All
+$(print_AllowFrom)
+  </Directory>
+</VirtualHost>
+
+$(if [ ! -z "${APP_FQDN}" ]; then
+echo "# HTTP virtualhost
+<VirtualHost *:${APP_PORT_HTTP}>
+  ServerName ${APP_FQDN}
+$(if [ "${HTTPD_REDIRECT_HTTP_TO_HTTPS}" = "true" ]; then
+echo "# enable http to https automatic rewrite
+<IfModule mod_rewrite.c>
+  RewriteEngine on
+  RewriteCond %{REQUEST_URI} !\.well-known/acme-challenge
+  RewriteCond %{HTTPS} off
+  #RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
+  RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
+</IfModule>"
+fi)
+  <Directory /var/www/html>
+    Options Includes FollowSymLinks MultiViews
+    DirectoryIndex index.php
+    AllowOverride All
+$(print_AllowFrom)
+  </Directory>
+</VirtualHost>"
+fi)
+
+$(if [ "${HTTPD_HTTPS_ENABLED}" = "true" ]; then
+echo "SSLPassPhraseDialog    builtin
+SSLSessionCache        shmcb:/run/apache2/sslcache(512000)
+SSLSessionCacheTimeout 300
+SSLCryptoDevice        builtin"
+fi)
+
+$(if [[ "${HTTPD_HTTPS_ENABLED}" = "true" && "${LETSENCRYPT_ENABLED}" != "true" ]]; then
+echo "# enable default ssl virtualhost with self signed certificate
+<VirtualHost _default_:${APP_PORT_HTTPS}>
+  ErrorLog                 ${appDataDirs[HTTPDLOGDIR]}/ssl_error.log
+  TransferLog              ${appDataDirs[HTTPDLOGDIR]}/ssl_access.log
+  LogLevel                 warn
+  SSLProtocol              all -SSLv3 -TLSv1 -TLSv1.1
+  SSLCipherSuite           ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
+  SSLHonorCipherOrder      off
+  SSLSessionTickets        off
+  SSLCertificateFile       ${appDataDirs[SSLCRTDIR]}/rrtpbx.crt
+  SSLCertificateKeyFile    ${appDataDirs[SSLCRTDIR]}/rrtpbx.key
+  #SSLCertificateChainFile ${appDataDirs[SSLCRTDIR]}/chain.crt
+
+  <Directory /var/www/html>
+    Options Includes FollowSymLinks MultiViews
+    AllowOverride All
+$(print_AllowFrom)
+  </Directory>
+</VirtualHost>"
+fi)
+
+$(if [[ ! -z "${APP_FQDN}" && "${LETSENCRYPT_ENABLED}" = "true" && -e "/etc/letsencrypt/live/${APP_FQDN}/cert.pem" ]]; then
+echo "# HTTPS virtualhost
+<VirtualHost *:${APP_PORT_HTTPS}>
+  ServerName ${APP_FQDN}
+
+  SSLProtocol              all -SSLv3 -TLSv1 -TLSv1.1
+  SSLCipherSuite           ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
+  SSLHonorCipherOrder      off
+  SSLSessionTickets        off
+  SSLCertificateChainFile /etc/letsencrypt/live/${APP_FQDN}/chain.pem
+  SSLCertificateFile      /etc/letsencrypt/live/${APP_FQDN}/cert.pem
+  SSLCertificateKeyFile   /etc/letsencrypt/live/${APP_FQDN}/privkey.pem
+
+  <Directory /var/www/html>
+    Options Includes FollowSymLinks MultiViews
+    AllowOverride All
+$(print_AllowFrom)
+  </Directory>
+</VirtualHost>"
+fi)
+
+" > "${HTTPD_CONF_DIR}/conf-enabled/virtual.conf"
+
+}
+
+cfgService_asterisk() {
+  echo "=> Starting Asterisk"
+}
+
+cfgService_rrtpbx() {
+  freepbx_reload() {
+    echo "---> reloading FreePBX..."
+    su - ${APP_USR} -s /bin/bash -c "fwconsole reload"
+  }
+  echo "---> verifing FreePBX configurations"
+  if [ ! -z "${APP_DATA}" ]; then
+    echo "---> using '${APP_DATA}' as basedir for FreePBX install"
+    for k in ${!fpbxDirs[@]}; do
+      v="${fpbxDirs[$k]}"
+      eval fpbxDirs[$k]=${APP_DATA}$v
+      [ ! -e "$v" ] && mkdir -p "$v"
+      if [ "$(stat -c "%U %G" "$v" 2>/dev/null)" != "${APP_USR} ${APP_GRP}" ];then
+      echo "---> fixing permissions for: $k=$v"
+      chown ${APP_USR}:${APP_GRP} "$v"
+      fi
+    done
+
+    for k in ${!fpbxFilesLog[@]}; do
+      v="${fpbxFilesLog[$k]}"
+      eval fpbxFilesLog[$k]=${APP_DATA}$v
+      [ ! -e "$v" ] && touch "$v"
+      if [ "$(stat -c "%U %G" "$v" 2>/dev/null)" != "${APP_USR} ${APP_GRP}" ];then
+      echo "---> fixing permissions for: $k=$v"
+      chown ${APP_USR}:${APP_GRP} "$v"
+      fi
+    done
+  fi
+  echo "[MySQL-asteriskcdrdb]
+Description = MariaDB connection to 'asteriskcdrdb' database
+driver = MySQL
+server = ${MYSQL_SERVER}
+database = asteriskcdrdb
+Port = ${APP_PORT_MYSQL}
+option = 3
+Charset=utf8" > /etc/odbc.ini
+
+  if [[ -e "${appFilesConf[FPBXCFGFILE]}" && ! -e ${APP_DATA}/.initialized ]]; then
+    echo "--> INFO: found '${appFilesConf[FPBXCFGFILE]}' configuration file but missing '${APP_DATA}/.initialized'... creating it right now"
+    echo "--> NOTE: if you want make an initial install, remove '${appFilesConf[FPBXCFGFILE]}' and '${APP_DATA}/.initialized' file"
+    touch "${APP_DATA}/.initialized"
+  fi
+  if [ ! -e ${APP_DATA}/.initialized ]; then
+      cfgService_freepbx_install
+    else
+      echo "--> INFO: FreePBX installation DETECTED! found '${APP_DATA}/.initialized' file"
+      [ ! -e "${appFilesConf[FPBXCFGFILE]}" ] && echo "---> WARNING: missing configuration file: ${appFilesConf[FPBXCFGFILE]}"
+      echo "---> reconfiguring '${appFilesConf[FPBXCFGFILE]}'..."
+      [[ ! -z "${APP_PORT_MYSQL}" && ${APP_PORT_MYSQL} -ne 3306 ]] && export MYSQL_SERVER="${MYSQL_SERVER}:${APP_PORT_MYSQL}"
+      sed "s/^\$amp_conf\['AMPDBUSER'\] =.*/\$amp_conf\['AMPDBUSER'\] = '${MYSQL_USER}';/"     -i "${appFilesConf[FPBXCFGFILE]}"
+      sed "s/^\$amp_conf\['AMPDBPASS'\] =.*/\$amp_conf\['AMPDBPASS'\] = '${MYSQL_PASSWORD}';/" -i "${appFilesConf[FPBXCFGFILE]}"
+      sed "s/^\$amp_conf\['AMPDBHOST'\] =.*/\$amp_conf\['AMPDBHOST'\] = '${MYSQL_SERVER}';/"   -i "${appFilesConf[FPBXCFGFILE]}"
+      sed "s/^\$amp_conf\['AMPDBNAME'\] =.*/\$amp_conf\['AMPDBNAME'\] = '${MYSQL_DATABASE}';/" -i "${appFilesConf[FPBXCFGFILE]}"
+  fi
+  echo "---> applying workarounds for FreePBX and Asterisk..."
+  [ ! -e "${fpbxDirs[ASTLOGDIR]}/full" ] && touch "${fpbxDirs[ASTLOGDIR]}/full" && chown ${APP_USR}:${APP_GRP} "${file}" "${fpbxDirs[ASTLOGDIR]}/full"
+  [ ! -e "/usr/sbin/fwconsole" ] && ln -s ${fpbxDirs[AMPBIN]}/fwconsole /usr/sbin/fwconsole
+  [ ! -e "/usr/sbin/amportal" ]  && ln -s ${fpbxDirs[AMPBIN]}/amportal  /usr/sbin/amportal
+  echo "---> reconfiguring FreePBX Advanced Settings if needed..."
+  set | grep ^"FREEPBX_" | grep -v -e ^"FREEPBX_MODULES_" -e ^"FREEPBX_VER=" | sed -e 's/^FREEPBX_//' -e 's/=/ /' | while read setting ; do
+    k="$(echo $setting | awk '{print $1}')"
+    v="$(echo $setting | awk '{print $2}')"
+    currentVal=$(fwconsole setting $k | awk -F"[][{}]" '{print $2}')
+    [ "$currentVal" = "true" ] && currentVal="1"
+    [ "$currentVal" = "false" ] && currentVal="0"
+    if [ "$currentVal" != "$v" ]; then
+      echo "---> reconfiguring advanced setting: ${k}=${v}"
+      fwconsole setting $k $v
+    fi
+  done
+
+  echo "---> reconfiguring FreePBX SIP Settings if needed..."
+  for k in ${!fpbxSipSettings[@]}; do
+    v="${fpbxSipSettings[$k]}"
+    cVal=$(echo "<?php include '/etc/freepbx.conf'; \$FreePBX = FreePBX::Create(); echo \$FreePBX->sipsettings->getConfig('${k}');?>" | php)
+    if [ "$cVal" != "${v}" ];then
+      echo "---> reconfiguring sip setting: ${k}=${v}"
+      echo "<?php include '/etc/freepbx.conf'; \$FreePBX = FreePBX::Create(); \$FreePBX->sipsettings->setConfig('${k}',${v}); needreload();?>" | php
+    fi
+  done
+
+  echo "---> FIXME: temporary workarounds for FreePBX broken modules and configs..."
+  sed 's/^preload = chan_local.so/;preload = chan_local.so/' -i ${fpbxDirs[ASTETCDIR]}/modules.conf
+  sed 's/^enabled =.*/enabled = yes/' -i ${fpbxDirs[ASTETCDIR]}/hep.conf
+}
+
+cfgService_freepbx_install() {
+  n=1 ; t=5
+
+  until [ $n -eq $t ]; do
+  echo "=> !!! FreePBX IS NOT INITIALIZED :: NEW INSTALLATION DETECTED !!!"
+  echo "--> missing '${APP_DATA}/.initialized' file... initializing FreePBX right now... try:[$n/$t]"
+  cd /usr/src/freepbx
+  if ! asterisk -r -x "core show version" 2>/dev/null ; then ./start_asterisk start ; fi
+  myn=1 ; myt=10
+  until [ $myn -eq $myt ]; do
+    mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e "SELECT 1;" >/dev/null
+    RETVAL=$?
+    if [ $RETVAL = 0 ]; then
+        myn=$myt
+      else
+        let myn+=1
+        echo "--> WARNING: cannot connect to MySQL database '${MYSQL_SERVER}'... waiting database to become ready... retrying in 10 seconds... try:[$myn/$myt]"
+        sleep 10
+    fi
+  done
+
+  mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e "CREATE DATABASE IF NOT EXISTS asteriskcdrdb;"
+  mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e "GRANT ALL PRIVILEGES ON asteriskcdrdb.* TO 'asterisk'@'%' WITH GRANT OPTION;"
+  mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e \
+    "CREATE TABLE IF NOT EXISTS asteriskcdrdb.voicemessages \
+    (msgnum INT(11) NULL DEFAULT NULL, \
+     dir VARCHAR(80) NOT NULL, \
+     context VARCHAR(80) NULL DEFAULT NULL, \
+     macrocontext VARCHAR(80) NULL DEFAULT NULL, \
+     callerid VARCHAR(40) NULL DEFAULT NULL, \
+     origtime VARCHAR(40) NULL DEFAULT NULL, \
+     duration VARCHAR(20) NULL DEFAULT NULL, \
+     flag VARCHAR(8) NULL DEFAULT NULL, \
+     mailboxuser VARCHAR(80) NULL DEFAULT NULL, \
+     mailboxcontext VARCHAR(80) NULL DEFAULT NULL, \
+     recording LONGBLOB NULL DEFAULT NULL, \
+     msg_id VARCHAR(40) NULL DEFAULT NULL) ENGINE = InnoDB;"
+
+  FPBX_OPTS+=" --webroot=${fpbxDirs[AMPWEBROOT]}"
+  FPBX_OPTS+=" --astetcdir=${fpbxDirs[ASTETCDIR]}"
+  FPBX_OPTS+=" --astmoddir=${fpbxDirs[ASTMODDIR]}"
+  FPBX_OPTS+=" --astvarlibdir=${fpbxDirs[ASTVARLIBDIR]}"
+  FPBX_OPTS+=" --astagidir=${fpbxDirs[ASTAGIDIR]}"
+  FPBX_OPTS+=" --astspooldir=${fpbxDirs[ASTSPOOLDIR]}"
+  FPBX_OPTS+=" --astrundir=${fpbxDirs[ASTRUNDIR]}"
+  FPBX_OPTS+=" --astlogdir=${fpbxDirs[ASTLOGDIR]}"
+  FPBX_OPTS+=" --ampbin=${fpbxDirs[AMPBIN]}"
+  FPBX_OPTS+=" --ampsbin=${fpbxDirs[AMPSBIN]}"
+  FPBX_OPTS+=" --ampcgibin=${fpbxDirs[AMPCGIBIN]}"
+  FPBX_OPTS+=" --ampplayback=${fpbxDirs[AMPPLAYBACK]}"
+
+  echo "--> installing FreePBX in '${fpbxDirs[AMPWEBROOT]}'"
+  echo "---> START install FreePBX @ $(date)"
+  [[ ! -z "${APP_PORT_MYSQL}" && ${APP_PORT_MYSQL} -ne 3306 ]] && export MYSQL_SERVER="${MYSQL_SERVER}:${APP_PORT_MYSQL}"
+  set -x
+  ./install -n --skip-install --no-ansi --dbhost=${MYSQL_SERVER} --dbuser=${MYSQL_USER} --dbpass=${MYSQL_PASSWORD} ${FPBX_OPTS}
+  RETVAL=$?
+  set +x
+  echo "---> END install FreePBX @ $(date)"
+  unset FPBX_OPTS
+
+  if [ $RETVAL = 0 ]; then
+    [ ! -e "/usr/sbin/fwconsole" ] && ln -s ${fpbxDirs[ASTVARLIBDIR]}/bin/fwconsole /usr/sbin/fwconsole
+    [ ! -e "/usr/sbin/amportal" ]  && ln -s ${fpbxDirs[ASTVARLIBDIR]}/bin/amportal  /usr/sbin/amportal
+
+    if [ ! -z "${APP_DATA}" ]; then
+      for file in ${appFilesConf[@]}; do
+        chown ${APP_USR}:${APP_GRP} "${file}"
+      done
+      echo "--> fixing directory system paths in db configuration..."
+      for k in ${!fpbxDirs[@]} ${!fpbxFilesLog[@]}; do
+        fwconsole setting ${k} ${fpbxDirs[$k]}
+      done
+    fi
+
+    : ${FREEPBX_MODULES_CORE="
+      framework
+      core
+      dashboard
+      sipsettings
+      voicemail
+    "}
+
+    : ${FREEPBX_MODULES_PRE:="
+      userman
+    "}
+
+    : ${FREEPBX_MODULES_EXTRA:="
+      soundlang
+      callrecording
+      cdr
+      conferences
+      customappsreg
+      featurecodeadmin
+      infoservices
+      logfiles
+      music
+      manager
+      arimanager
+      filestore
+      recordings
+      announcement
+      asteriskinfo
+      backup
+      callforward
+      callwaiting
+      daynight
+      calendar
+      certman
+      cidlookup
+      contactmanager
+      donotdisturb
+      fax
+      findmefollow
+      iaxsettings
+      miscapps
+      miscdests
+      ivr
+      parking
+      phonebook
+      presencestate
+      printextensions
+      queues
+      cel
+      timeconditions
+      pm2
+    "}
+
+    : ${FREEPBX_MODULES_DISABLED="
+      bulkhandler
+      speeddial
+      weakpasswords
+      ucp
+    "}
+    echo "--> enabling EXTENDED FreePBX repo..."
+    su - ${APP_USR} -s /bin/bash -c "fwconsole ma enablerepo extended"
+    su - ${APP_USR} -s /bin/bash -c "fwconsole ma enablerepo unsupported"
+    echo "--> starting cron to avoid crontab checks error..."
+    cron
+    echo "--> installing prerequisite FreePBX modules from local install into '${fpbxDirs[AMPWEBROOT]}/admin/modules'"
+    for module in ${FREEPBX_MODULES_PRE}; do
+      su - ${APP_USR} -s /bin/bash -c "echo \"---> installing module: ${module}\" && fwconsole ma install ${module}"
+    done
+    echo "--> fixing FreePBX permissions..."
+    fwconsole chown
+    freepbx_reload
+    echo "--> installing Extra FreePBX modules from local install into '${fpbxDirs[AMPWEBROOT]}/admin/modules'"
+    for module in ${FREEPBX_MODULES_EXTRA}; do
+      su - ${APP_USR} -s /bin/bash -c "echo \"---> installing module: ${module}\" && fwconsole ma install ${module}"
+    done
+    echo "--> fixing FreePBX permissions..."
+    fwconsole chown
+    freepbx_reload
+    echo "--> stopping cron..."
+    killall -9 cron
+    touch "${APP_DATA}/.initialized"
+  fi
+
+  if [ $RETVAL = 0 ]; then
+      n=$t
+    else
+      let n+=1
+      echo "--> problem detected... restarting in 10 seconds... try:[$n/$t]"
+      sleep 10
+  fi
+  done
+
+  if asterisk -r -x "core show version" 2>/dev/null ; then
+    echo "--> stopping Asterisk"
+    asterisk -r -x "core stop now"
+    echo "=> Finished installing FreePBX"
+  fi
+}
+
+runHooks() {
+  mkdir -p /var/log/supervisor /var/log/dbconfig-common /var/log/apt /var/log/apache2 /var/log/asterisk/cdr-csv
+  touch /var/log/wtmp /var/log/lastlog
+  [ ! -e /sbin/nologin ] && ln -s /usr/sbin/nologin /sbin/nologin
+
+  if [ ! -z "${APP_DATA}" ]; then
+    echo "=> Persistent storage path detected... relocating and reconfiguring system data and configuration files using base: ${APP_DATA}"
+    for dir in ${appDataDirs[@]}
+      do
+        dir="${APP_DATA}${dir}"
+        if [ ! -e "${dir}" ];then
+          echo "--> creating missing dir: '$dir'"
+          mkdir -p "${dir}"
+        fi
+      done
+
+    for dir in ${appDataDirs[@]}; do
+      symlinkDir "${dir}" "${APP_DATA}${dir}"
+    done
+
+    for file in ${appFilesConf[@]}; do
+      symlinkFile "${file}" "${APP_DATA}${file}"
+    done
+   else
+    echo "=> WARNING: No Persistent storage path detected... the configurations will be lost on container restart"
+  fi
+
+  chkService POSTFIX_ENABLED
+  chkService CRON_ENABLED
+  chkService FAIL2BAN_ENABLED
+  chkService HTTPD_ENABLED
+  chkService ASTERISK_ENABLED
+  chkService RRTPBX_ENABLED
+  [[ ! -z "${APP_FQDN}" && "${LETSENCRYPT_ENABLED}" = "true" ]] && cfgService_letsencrypt
+}
+
+runHooks

+ 62 - 0
filesystem/entrypoint.sh

@@ -0,0 +1,62 @@
+#!/bin/bash
+
+appHooks() {
+  : ${APP_RELINK:=false}
+
+  if [ "$APP_RELINK" = "true" ]; then
+  [ ! -z "${APP_CONF}" ] && relink_dir "${APP_CONF_DEFAULT}" "${APP_CONF}"
+  [ ! -z "${APP_DATA}" ] && relink_dir "${APP_DATA_DEFAULT}" "${APP_DATA}"
+  [ ! -z "${APP_LOGS}" ] && relink_dir "${APP_LOGS_DEFAULT}" "${APP_LOGS}"
+  [ ! -z "${APP_TEMP}" ] && relink_dir "${APP_TEMP_DEFAULT}" "${APP_TEMP}"
+  [ ! -z "${APP_WORK}" ] && relink_dir "${APP_WORK_DEFAULT}" "${APP_WORK}"
+  [ ! -z "${APP_SHARED}" ] && relink_dir "${APP_SHARED_DEFAULT}" "${APP_SHARED}"
+  else
+    echo "=> Skipping APP directories relinking: APP_RELINK=$APP_RELINK"
+  fi
+
+  echo "=> Executing hooks:"
+  . /entrypoint-hooks.sh
+  echo "-------------------------------------------------------------------------------"
+}
+
+relink_dir() {
+	local dir_default="$1"
+	local dir_custom="$2"
+	[ ! -e "$dir_default" ] && mkdir -p "$dir_default"
+	[ ! -e "$(dirname "$dir_custom")" ] && mkdir -p "$(dirname "$dir_custom")"
+	echo "Directory container override detected! default: $dir_default custom: $dir_custom"
+	if [ ! -e "$dir_custom" ]; then
+		echo -e -n "=> moving the $dir_default directory to $dir_custom ..."
+		mv "$dir_default" "$dir_custom"
+	else
+		echo -e -n "=> directory $dir_custom already exist... "
+		mv "$dir_default" "$dir_default".dist
+	fi
+	echo "linking $dir_custom into $dir_default"
+	ln -s "$dir_custom" "$dir_default"
+}
+
+appHooks
+
+: ${APP_RUNAS:=false}
+: ${ENTRYPOINT_TINI:=false}
+: ${MULTISERVICE:=false}
+
+if [ "$MULTISERVICE" = "true" ]; then
+    CMD="runsvdir -P /etc/service"
+elif [ "$APP_RUNAS" = "true" ]; then
+    CMD="runuser -p -u $APP_USR -- $@"
+  else
+    CMD="$@"
+fi
+
+[ "$ENTRYPOINT_TINI" = "true" ] && CMD="tini -g -- $CMD"
+
+echo "=> Executing entrypoint command: $CMD"
+echo "==============================================================================="
+[ ! -z "$UMASK" ] && umask $UMASK
+set -x
+
+exec $CMD
+
+exit $?

+ 9 - 0
filesystem/etc/fail2ban/filter.d/freepbx.conf

@@ -0,0 +1,9 @@
+[INCLUDES]
+
+[Definition]
+
+failregex = .* Authentication failure for .* from <HOST>\.
+
+ignoreregex =
+
+

+ 55 - 0
filesystem/etc/fail2ban/jail.d/99-local.conf

@@ -0,0 +1,55 @@
+[DEFAULT]
+ignoreip = 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
+bantime  = 300
+findtime  = 3600
+maxretry = 10
+banaction = iptables-allports
+destemail = root@localhost
+sender = fail2ban@localhost.localdomain
+
+action = %(action_)s
+
+logtarget = /var/log/fail2ban/fail2ban.log
+apache_error_log = /var/log/apache2/*error*log
+apache_access_log = /var/log/apache2/*access*log
+
+[recidive]
+enabled  = true
+logpath  = /var/log/fail2ban/fail2ban.log
+action   = %(action_mwl)s
+protocol = all
+bantime  = 1814400 ; 3 weeks (ipset support max of 2147483 secs)
+findtime = 15552000 ;6 months
+maxretry = 30
+
+[asterisk]
+enabled = true
+logpath = /var/log/asterisk/full
+
+[freepbx]
+enabled = true
+logpath = /var/log/asterisk/freepbx_security.log
+
+[apache-auth]
+enabled = true
+
+[apache-badbots]
+enabled = true
+
+[apache-noscript]
+enabled = true
+
+[apache-overflows]
+enabled = true
+
+[apache-nohome]
+enabled = true
+
+[apache-botsearch]
+enabled = true
+
+[apache-fakegooglebot]
+enabled = true
+
+[apache-shellshock]
+enabled = true

+ 2 - 0
filesystem/etc/fail2ban/jail.d/defaults-debian.conf

@@ -0,0 +1,2 @@
+[sshd]
+enabled = false

+ 15 - 0
filesystem/etc/logrotate.d/apache2

@@ -0,0 +1,15 @@
+/var/log/httpd/*log {
+  daily
+  ifempty
+  rotate 7
+  missingok
+  compress
+  dateext
+  copytruncate
+  sharedscripts
+  postrotate
+    if /usr/bin/supervisorctl status httpd > /dev/null 2>/dev/null ; then \
+      /usr/bin/supervisorctl restart httpd > /dev/null 2>/dev/null; \
+    fi;
+  endscript
+} 

+ 15 - 0
filesystem/etc/logrotate.d/asterisk

@@ -0,0 +1,15 @@
+/var/log/asterisk/full
+/var/log/asterisk/messages
+/var/log/asterisk/security
+/var/log/asterisk/freepbx_dbug
+/var/log/asterisk/*_log
+/var/log/asterisk/*.log {
+    daily
+    rotate 7
+    compress
+    dateext
+    ifempty
+    missingok
+    su asterisk asterisk
+    copytruncate
+}

+ 14 - 0
filesystem/etc/logrotate.d/fail2ban

@@ -0,0 +1,14 @@
+/var/log/fail2ban/fail2ban.log {
+    monthly
+    ifempty
+    rotate 12
+    missingok
+    compress
+    dateext
+    missingok
+    notifempty
+    postrotate
+      /usr/bin/fail2ban-client flushlogs >/dev/null || true
+    endscript
+}
+ 

+ 17 - 0
filesystem/etc/odbcinst.ini

@@ -0,0 +1,17 @@
+# Driver from the mysql-connector-odbc package
+# Setup from the unixODBC package
+[MySQL]
+Description	= ODBC for MySQL
+Driver		= /usr/lib/x86_64-linux-gnu/odbc/libmaodbc.so
+Setup		= /usr/lib/x86_64-linux-gnu/odbc/libodbcmyS.so
+Driver64	= /usr/lib/x86_64-linux-gnu/odbc/libmaodbc.so
+Setup64		= /usr/lib/x86_64-linux-gnu/odbc/libodbcmyS.so
+FileUsage	= 1
+
+# Driver from the mariadb-connector-odbc package
+# Setup from the unixODBC package
+[MariaDB]
+Description     = ODBC for MariaDB
+Driver          = /usr/lib/x86_64-linux-gnu/odbc/libmaodbc.so
+Driver64        = /usr/lib/x86_64-linux-gnu/odbc/libmaodbc.so
+FileUsage       = 1

+ 24 - 0
filesystem/etc/php/7.3/apache2/conf.d/99-local.ini

@@ -0,0 +1,24 @@
+short_open_tag = On
+max_execution_time = 600
+memory_limit = 512M
+error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
+display_startup_errors = On
+display_errors = On
+log_errors = On
+post_max_size = 128M
+upload_max_filesize = 128M
+allow_url_include = On
+magic_quotes_gpc = off
+date.timezone = Europe/Moscow
+
+zlib.output_compression = Off
+
+opcache.enable=1
+opcache.enable_cli=0
+opcache.memory_consumption=128
+opcache.interned_strings_buffer=8
+opcache.max_accelerated_files=50000
+opcache.file_update_protection=5
+opcache.validate_timestamps=1
+opcache.revalidate_freq=5
+opcache.fast_shutdown=1

+ 15 - 0
filesystem/etc/supervisor/conf.d/asterisk.conf

@@ -0,0 +1,15 @@
+[program:asterisk]
+command=asterisk -f -U asterisk -G asterisk -vvvg -c
+autostart=false
+autorestart=true
+startretries=3
+startsecs=5
+user=asterisk
+killasgroup=true
+stopasgroup=true
+stdout_logfile=/dev/stdout
+stderr_logfile=/dev/stderr
+stdout_logfile_maxbytes=0
+stderr_logfile_maxbytes=0
+stdout_events_enabled = true
+stderr_events_enabled = true

+ 15 - 0
filesystem/etc/supervisor/conf.d/cron.conf

@@ -0,0 +1,15 @@
+[program:cron]
+command=cron -f
+autostart=false
+autorestart=true
+startretries=3
+startsecs=1
+user=root
+killasgroup=true
+stopasgroup=true
+stdout_logfile=/dev/stdout
+stderr_logfile=/dev/stderr
+stdout_logfile_maxbytes=0
+stderr_logfile_maxbytes=0
+stdout_events_enabled = true
+stderr_events_enabled = true

+ 15 - 0
filesystem/etc/supervisor/conf.d/fail2ban.conf

@@ -0,0 +1,15 @@
+[program:fail2ban]
+command=fail2ban-server -xf start
+autostart=false
+autorestart=true
+startretries=3
+startsecs=5
+user=root
+killasgroup=true
+stopasgroup=true
+stdout_logfile=/dev/stdout
+stderr_logfile=/dev/stderr
+stdout_logfile_maxbytes=0
+stderr_logfile_maxbytes=0
+stdout_events_enabled = true
+stderr_events_enabled = true

+ 15 - 0
filesystem/etc/supervisor/conf.d/httpd.conf

@@ -0,0 +1,15 @@
+[program:httpd]
+command=/usr/bin/pidproxy /var/run/apache2/apache2.pid /bin/bash -c "/usr/sbin/apache2ctl -D FOREGROUND"
+autostart=false
+autorestart=true
+startretries=3
+startsecs=1
+user=root
+killasgroup=true
+stopasgroup=true
+stdout_logfile=/dev/stdout
+stderr_logfile=/dev/stderr
+stdout_logfile_maxbytes=0
+stderr_logfile_maxbytes=0
+stdout_events_enabled = true
+stderr_events_enabled = true

+ 15 - 0
filesystem/etc/supervisor/conf.d/postfix.conf

@@ -0,0 +1,15 @@
+[program:postfix]
+command=sh -c "postfix start-fg || postfix stop"
+autostart=false
+autorestart=true
+startretries=3
+startsecs=1
+user=root
+killasgroup=true
+stopasgroup=true
+stdout_logfile=/dev/stdout
+stderr_logfile=/dev/stderr
+stdout_logfile_maxbytes=0
+stderr_logfile_maxbytes=0
+stdout_events_enabled = true
+stderr_events_enabled = true

+ 15 - 0
filesystem/etc/supervisor/conf.d/rrtpbx.conf

@@ -0,0 +1,15 @@
+[program:rrtpbx]
+command=startrrtpbx
+autostart=false
+autorestart=true
+startretries=3
+startsecs=1
+user=root
+killasgroup=true
+stopasgroup=true
+stdout_logfile=/dev/stdout
+stderr_logfile=/dev/stderr
+stdout_logfile_maxbytes=0
+stderr_logfile_maxbytes=0
+stdout_events_enabled = true
+stderr_events_enabled = true

+ 28 - 0
filesystem/usr/local/bin/telegram-mailgate.py

@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+import sys
+import argparse
+import email
+import requests
+
+if __name__ == '__main__':
+  arg_parser = argparse.ArgumentParser()
+  arg_parser.add_argument('--from')
+  arg_parser.add_argument('--key')
+  arg_parser.add_argument('--chatid')
+  arg_parser.add_argument('--queue-id', default=0)
+  arg_parser.add_argument('to', nargs='+')
+  group = arg_parser.add_mutually_exclusive_group()
+  group.add_argument('--raw', action='store_true')
+  args = arg_parser.parse_args()
+  raw_content = sys.stdin.read()
+  if args.raw:
+    content = raw_content
+  else:
+    mail = email.message_from_string(raw_content)
+    content = mail.get_payload()
+  if ((args.key is not None) and
+      (args.chatid is not None)):
+    content = content.replace("\n\n","\n")
+    params = {'chat_id':args.chatid, 'text':content}
+    requests.post('https://api.telegram.org/bot' + args.key + '/sendMessage', data=params)
+  exit(0)

+ 16 - 0
filesystem/usr/local/sbin/startrrtpbx

@@ -0,0 +1,16 @@
+#! /usr/bin/env bash
+set -eu
+pidfile=/var/run/asterisk/asterisk.pid
+command=/usr/sbin/fwconsole
+function kill_app(){
+    $command stop
+    exit $?
+}
+trap "kill_app" SIGINT SIGTERM
+$command chown
+$command start -q
+sleep 2
+while [ -f $pidfile ] && kill -0 $(cat $pidfile) ; do
+    sleep 5
+done
+exit 1000