entrypoint-hooks.sh 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. #!/bin/bash
  2. : ${ROOT_MAILTO:="root@localhost"}
  3. : ${ASTERISK_VER:=""}
  4. : ${FREEPBX_VER:=""}
  5. : ${APP_DATA:=""}
  6. declare -A appDataDirs=(
  7. [CRONDIR]=/var/spool/cron
  8. [ASTHOME]=/home/asterisk
  9. [ASTETCDIR]=/etc/asterisk
  10. [ASTVARLIBDIR]=/var/lib/asterisk
  11. [ASTSPOOLDIR]=/var/spool/asterisk
  12. [ASTRUNDIR]=/var/run/asterisk
  13. [HTTPDHOME]=/var/www
  14. [HTTPDLOGDIR]=/var/log/apache2
  15. [CERTBOTETCDIR]=/etc/letsencrypt
  16. [ASTLOGDIR]=/var/log/asterisk
  17. [F2BLOGDIR]=/var/log/fail2ban
  18. [F2BLIBDIR]=/var/lib/fail2ban
  19. [SSLCRTDIR]=/etc/pki/pbx
  20. [ROOTHOME]=/root
  21. )
  22. declare -A appFilesConf=(
  23. [FPBXCFGFILE]=/etc/freepbx.conf
  24. [AMPCFGFILE]=/etc/amportal.conf
  25. )
  26. declare -A appCacheDirs=(
  27. [ASTRUNDIR]=/var/run/asterisk
  28. [PHPOPCACHEDIR]=/var/lib/php/opcache
  29. [PHPSESSDIR]=/var/lib/php/session
  30. [PHPWSDLDIR]=/var/lib/php/wsdlcache
  31. )
  32. declare -A fpbxDirs=(
  33. [AMPWEBROOT]=/var/www/html
  34. [ASTETCDIR]=/etc/asterisk
  35. [ASTVARLIBDIR]=/var/lib/asterisk
  36. [ASTAGIDIR]=/var/lib/asterisk/agi-bin
  37. [ASTSPOOLDIR]=/var/spool/asterisk
  38. [ASTRUNDIR]=/var/run/asterisk
  39. [ASTLOGDIR]=/var/log/asterisk
  40. [AMPBIN]=/var/lib/asterisk/bin
  41. [AMPSBIN]=/var/lib/asterisk/sbin
  42. [AMPCGIBIN]=/var/www/cgi-bin
  43. [AMPPLAYBACK]=/var/lib/asterisk/playback
  44. [CERTKEYLOC]=/etc/asterisk/keys
  45. )
  46. declare -A fpbxDirsExtra=(
  47. [ASTMODDIR]=/usr/lib/asterisk/modules
  48. )
  49. declare -A fpbxFilesLog=(
  50. [FPBXDBUGFILE]=/var/log/asterisk/freepbx-debug.log
  51. [FPBXLOGFILE]=/var/log/asterisk/freepbx.log
  52. [FPBXSECLOGFILE]=/var/log/asterisk/freepbx_security.log
  53. )
  54. declare -A fpbxSipSettings=(
  55. [rtpstart]=${APP_PORT_RTP_START}
  56. [rtpend]=${APP_PORT_RTP_END}
  57. [udpport-0.0.0.0]=${APP_PORT_PJSIP}
  58. [tcpport-0.0.0.0]=${APP_PORT_PJSIP}
  59. [bindport]=${APP_PORT_SIP}
  60. )
  61. [ ! -z ${APP_FQDN} ] && HOSTNAME="${APP_FQDN}"
  62. : ${SERVERNAME:=$HOSTNAME}
  63. : ${MYSQL_SERVER:="db"}
  64. : ${MYSQL_ROOT_PASSWORD:=""}
  65. : ${MYSQL_DATABASE:="asterisk"}
  66. : ${MYSQL_USER:="asterisk"}
  67. : ${MYSQL_PASSWORD:=""}
  68. : ${APP_PORT_MYSQL:="3306"}
  69. : ${HTTPD_HTTPS_ENABLED:="true"}
  70. : ${HTTPD_REDIRECT_HTTP_TO_HTTPS:="false"}
  71. : ${HTTPD_ALLOW_FROM:=""}
  72. : ${CRON_ENABLED:="true"}
  73. : ${HTTPD_ENABLED:="true"}
  74. : ${ASTERISK_ENABLED:="false"}
  75. : ${RRTPBX_ENABLED:="true"}
  76. : ${FAIL2BAN_ENABLED:="true"}
  77. : ${POSTFIX_ENABLED:="true"}
  78. : ${SMTP_RELAYHOST:=""}
  79. : ${SMTP_RELAYHOST_USERNAME:=""}
  80. : ${SMTP_RELAYHOST_PASSWORD:=""}
  81. : ${SMTP_ALLOWED_SENDER_DOMAINS:=""}
  82. : ${SMTP_MESSAGE_SIZE_LIMIT:="0"}
  83. : ${SMTP_MAIL_FROM:=""}
  84. : ${RELAYHOST:="$SMTP_RELAYHOST"}
  85. : ${RELAYHOST_USERNAME:="$SMTP_RELAYHOST_USERNAME"}
  86. : ${RELAYHOST_PASSWORD:="$SMTP_RELAYHOST_PASSWORD"}
  87. : ${ALLOWED_SENDER_DOMAINS:="$SMTP_ALLOWED_SENDER_DOMAINS"}
  88. : ${MESSAGE_SIZE_LIMIT:="$SMTP_MESSAGE_SIZE_LIMIT"}
  89. : ${SUPERVISOR_DIR:="/etc/supervisor/conf.d"}
  90. : ${HTTPD_CONF_DIR:="/etc/apache2"}
  91. : ${PHP_CONF:="/etc/php/7.4/apache2/php.ini"}
  92. dirEmpty() {
  93. [ -z "$(ls -A "$1/")" ]
  94. }
  95. symlinkDir() {
  96. local dirOriginal="$1"
  97. local dirCustom="$2"
  98. echo "---> directory data override detected: original:[$dirOriginal] custom:[$dirCustom]"
  99. if [ -e "$dirOriginal" ] && dirEmpty "$dirCustom"; then
  100. echo "---> empty dir '$dirCustom' detected copying '$dirOriginal' contents to '$dirCustom'..."
  101. rsync -a -q "$dirOriginal/" "$dirCustom/"
  102. fi
  103. if [ ! -e "$dirOriginal" ]; then
  104. echo "---> WARNING: original data directory doesn't exist... creating empty directory: '$dirOriginal'"
  105. mkdir -p "$dirOriginal"
  106. fi
  107. if [ -e "$dirOriginal" ]; then
  108. echo -e "---> renaming '${dirOriginal}' to '${dirOriginal}.dist'"
  109. mv "$dirOriginal" "$dirOriginal".dist
  110. fi
  111. echo "---> symlinking '$dirCustom' to '$dirOriginal'"
  112. ln -s "$dirCustom" "$dirOriginal"
  113. }
  114. symlinkFile() {
  115. local fileOriginal="$1"
  116. local fileCustom="$2"
  117. echo "--> file data override detected: original:[$fileOriginal] custom:[$fileCustom]"
  118. if [ -e "$fileOriginal" ]; then
  119. if [ ! -e "$fileCustom" ]; then
  120. echo "---> INFO: detected not existing file '$fileCustom'. copying '$fileOriginal' to '$fileCustom'..."
  121. rsync -a -q "$fileOriginal" "$fileCustom"
  122. fi
  123. echo -e "---> renaming '${fileOriginal}' to '${fileOriginal}.dist'... "
  124. mv "$fileOriginal" "$fileOriginal".dist
  125. else
  126. echo "---> WARNING: original data file doesn't exist... creating symlink from a not existing source: '$fileOriginal'"
  127. fi
  128. echo "---> symlinking '$fileCustom' to '$fileOriginal'"
  129. [ ! -e "$(dirname "$fileCustom")" ] && mkdir -p "$(dirname "$fileCustom")"
  130. ln -s "$fileCustom" "$fileOriginal"
  131. }
  132. chkService() {
  133. local SERVICE_VAR="$1"
  134. eval local SERVICE_ENABLED="\$$(echo $SERVICE_VAR)"
  135. eval local SERVICE_DAEMON="\$$(echo $SERVICE_VAR | sed 's/_.*//')_DAEMON"
  136. local SERVICE="$(echo $SERVICE_VAR | sed 's/_.*//' | sed -e 's/\(.*\)/\L\1/')"
  137. [ -z "$SERVICE_DAEMON" ] && local SERVICE_DAEMON="$SERVICE"
  138. if [ "$SERVICE_ENABLED" = "true" ]; then
  139. autostart=true
  140. echo "=> Enabling $SERVICE_DAEMON service... because $SERVICE_VAR=$SERVICE_ENABLED"
  141. echo "--> configuring $SERVICE_DAEMON service..."
  142. cfgService_$SERVICE
  143. else
  144. autostart=false
  145. echo "=> Disabling $SERVICE_DAEMON service... because $SERVICE_VAR=$SERVICE_ENABLED"
  146. fi
  147. sed "s/autostart=.*/autostart=$autostart/" -i ${SUPERVISOR_DIR}/$SERVICE_DAEMON.conf
  148. }
  149. cfgService_postfix() {
  150. postconf -e inet_protocols=ipv4
  151. if [ ! -z "$HOSTNAME" ]; then
  152. postconf -e myhostname="$HOSTNAME"
  153. else
  154. postconf -# myhostname
  155. fi
  156. postconf -# relayhost
  157. postconf -# smtp_sasl_auth_enable
  158. postconf -# smtp_sasl_password_maps
  159. postconf -# smtp_sasl_security_options
  160. if [ ! -z "$MYNETWORKS" ]; then
  161. postconf -e mynetworks=$MYNETWORKS
  162. else
  163. postconf -e "mynetworks=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
  164. fi
  165. [ ! -f /etc/aliases ] && echo "postmaster: root" > /etc/aliases
  166. [ ${ROOT_MAILTO} ] && echo "root: ${ROOT_MAILTO}" >> /etc/aliases && newaliases
  167. postconf -e "maillog_file = /dev/stdout"
  168. postconf -e "inet_protocols = ipv4"
  169. postconf -e "mailbox_size_limit = 0"
  170. postconf -e "message_size_limit = ${MESSAGE_SIZE_LIMIT}"
  171. if [ ! -z "$SMTP_MAIL_FROM" ]; then
  172. echo "/.+/ $SMTP_MAIL_FROM" > /etc/postfix/sender_canonical_maps
  173. echo "/From:.*/ REPLACE From: $SMTP_MAIL_FROM" > /etc/postfix/header_checks
  174. postconf -e "sender_canonical_maps = regexp:/etc/postfix/sender_canonical_maps"
  175. postconf -e "smtp_header_checks = regexp:/etc/postfix/header_checks"
  176. fi
  177. 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}"
  178. postconf -e "content_filter = telegram-mailgate"
  179. }
  180. cfgService_cron() {
  181. ls -la /var/spool/cron/crontabs
  182. }
  183. cfgService_letsencrypt() {
  184. if [ -e "/etc/letsencrypt/live/${APP_FQDN}/privkey.pem" ] ; then
  185. echo "--> Let's Encrypt certificate already exist... trying to renew"
  186. certbot renew --standalone
  187. else
  188. echo "--> generating HTTPS Let's Encrypt certificate"
  189. certbot certonly --standalone --expand -n --agree-tos --email ${ROOT_MAILTO} -d ${APP_FQDN}
  190. fi
  191. echo '#!/bin/bash
  192. /usr/bin/certbot renew --noninteractive --no-random-sleep-on-renew --deploy-hook "/usr/bin/supervisorctl restart httpd"
  193. exit $?' > /etc/cron.daily/certbot && chmod 755 /etc/cron.daily/certbot
  194. }
  195. iniParser() {
  196. ini="$@"
  197. while read setting ; do
  198. section="$(echo $setting | awk -F" " '{print $1}')"
  199. k=$(echo $setting | sed -e "s/^${section} //" | awk -F"=" '{print $1}' | tr '[:upper:]' '[:lower:]')
  200. v=$(echo $setting | sed -e "s/'//g" | awk -F"=" '{print $2}')
  201. sed -e "/^\[${section}\]$/I,/^\(\|;\|#\)\[/ s/^\(;\|#\)${k}/${k}/" -e "/^\[${section}\]$/I,/^\[/ s|^${k}.*=.*|${k}=${v}|I" -i "${ini}"
  202. done
  203. }
  204. cfgService_fail2ban() {
  205. echo "--> reconfiguring Fail2ban settings..."
  206. echo "DEFAULT LOGTARGET=/var/log/fail2ban/fail2ban.log" | iniParser /etc/fail2ban/fail2ban.conf
  207. sed "s/%(mta)s-whois\[/%(mta)s\[/g" -i /etc/fail2ban/jail.conf
  208. touch /var/log/fail2ban/fail2ban.log
  209. set | grep ^"FAIL2BAN_" | sed -e 's/^FAIL2BAN_//' | sed -e 's/_/ /' | iniParser "/etc/fail2ban/jail.d/99-local.conf"
  210. }
  211. cfgService_httpd() {
  212. if [ "${HTTPD_HTTPS_ENABLED}" = "true" ]; then
  213. echo "--> enabling Apache ssl module"
  214. a2enmod ssl
  215. else
  216. echo "--> disabling Apache ssl module"
  217. a2dismod ssl
  218. fi
  219. a2enmod rewrite
  220. rm -f /var/www/html/index.html
  221. echo "--> setting Apache ServerName to ${SERVERNAME}"
  222. sed "s/#ServerName .*/ServerName ${SERVERNAME}/" -i "${HTTPD_CONF_DIR}/sites-enabled/000-default.conf"
  223. echo "ServerName ${SERVERNAME}" >> "${HTTPD_CONF_DIR}/apache2.conf"
  224. echo "--> setting Apache user and group"
  225. sed -i "s/^User.*/User ${APP_USR}/" /etc/apache2/apache2.conf
  226. sed -i "s/^Group.*/Group ${APP_GRP}/" /etc/apache2/apache2.conf
  227. sed -i "s/AllowOverride None/AllowOverride All/" /etc/apache2/apache2.conf
  228. print_AllowFrom() {
  229. if [ ! -z "${HTTPD_ALLOW_FROM}" ]; then
  230. for IP in $(echo ${HTTPD_ALLOW_FROM} | sed -e "s/'//g") ; do
  231. echo " Require ip ${IP}"
  232. done
  233. else
  234. echo " Require all granted"
  235. fi
  236. }
  237. echo "# default HTTP virtualhost
  238. <VirtualHost *:${APP_PORT_HTTP}>
  239. DocumentRoot /var/www/html
  240. $(if [ "${HTTPD_REDIRECT_HTTP_TO_HTTPS}" = "true" ]; then
  241. echo " <IfModule mod_rewrite.c>
  242. RewriteEngine on
  243. RewriteCond %{REQUEST_URI} !\.well-known/acme-challenge
  244. RewriteCond %{HTTPS} off
  245. #RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
  246. RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
  247. </IfModule>"
  248. fi)
  249. <Directory /var/www/html>
  250. Options Includes FollowSymLinks MultiViews
  251. AllowOverride All
  252. $(print_AllowFrom)
  253. </Directory>
  254. </VirtualHost>
  255. $(if [ ! -z "${APP_FQDN}" ]; then
  256. echo "# HTTP virtualhost
  257. <VirtualHost *:${APP_PORT_HTTP}>
  258. ServerName ${APP_FQDN}
  259. $(if [ "${HTTPD_REDIRECT_HTTP_TO_HTTPS}" = "true" ]; then
  260. echo "# enable http to https automatic rewrite
  261. <IfModule mod_rewrite.c>
  262. RewriteEngine on
  263. RewriteCond %{REQUEST_URI} !\.well-known/acme-challenge
  264. RewriteCond %{HTTPS} off
  265. #RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
  266. RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
  267. </IfModule>"
  268. fi)
  269. <Directory /var/www/html>
  270. Options Includes FollowSymLinks MultiViews
  271. DirectoryIndex index.php
  272. AllowOverride All
  273. $(print_AllowFrom)
  274. </Directory>
  275. </VirtualHost>"
  276. fi)
  277. $(if [ "${HTTPD_HTTPS_ENABLED}" = "true" ]; then
  278. echo "SSLPassPhraseDialog builtin
  279. SSLSessionCache shmcb:/run/apache2/sslcache(512000)
  280. SSLSessionCacheTimeout 300
  281. SSLCryptoDevice builtin"
  282. fi)
  283. $(if [[ "${HTTPD_HTTPS_ENABLED}" = "true" && "${LETSENCRYPT_ENABLED}" != "true" ]]; then
  284. echo "# enable default ssl virtualhost with self signed certificate
  285. <VirtualHost _default_:${APP_PORT_HTTPS}>
  286. ErrorLog ${appDataDirs[HTTPDLOGDIR]}/ssl_error.log
  287. TransferLog ${appDataDirs[HTTPDLOGDIR]}/ssl_access.log
  288. LogLevel warn
  289. SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
  290. 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
  291. SSLHonorCipherOrder off
  292. SSLSessionTickets off
  293. SSLCertificateFile ${appDataDirs[SSLCRTDIR]}/rrtpbx.crt
  294. SSLCertificateKeyFile ${appDataDirs[SSLCRTDIR]}/rrtpbx.key
  295. #SSLCertificateChainFile ${appDataDirs[SSLCRTDIR]}/chain.crt
  296. <Directory /var/www/html>
  297. Options Includes FollowSymLinks MultiViews
  298. AllowOverride All
  299. $(print_AllowFrom)
  300. </Directory>
  301. </VirtualHost>"
  302. fi)
  303. $(if [[ ! -z "${APP_FQDN}" && "${LETSENCRYPT_ENABLED}" = "true" && -e "/etc/letsencrypt/live/${APP_FQDN}/cert.pem" ]]; then
  304. echo "# HTTPS virtualhost
  305. <VirtualHost *:${APP_PORT_HTTPS}>
  306. ServerName ${APP_FQDN}
  307. SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
  308. 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
  309. SSLHonorCipherOrder off
  310. SSLSessionTickets off
  311. SSLCertificateChainFile /etc/letsencrypt/live/${APP_FQDN}/chain.pem
  312. SSLCertificateFile /etc/letsencrypt/live/${APP_FQDN}/cert.pem
  313. SSLCertificateKeyFile /etc/letsencrypt/live/${APP_FQDN}/privkey.pem
  314. <Directory /var/www/html>
  315. Options Includes FollowSymLinks MultiViews
  316. AllowOverride All
  317. $(print_AllowFrom)
  318. </Directory>
  319. </VirtualHost>"
  320. fi)
  321. " > "${HTTPD_CONF_DIR}/conf-enabled/virtual.conf"
  322. }
  323. cfgService_asterisk() {
  324. echo "=> Starting Asterisk"
  325. }
  326. cfgService_rrtpbx() {
  327. freepbx_reload() {
  328. echo "---> reloading FreePBX..."
  329. su - ${APP_USR} -s /bin/bash -c "fwconsole reload"
  330. }
  331. echo "---> verifing FreePBX configurations"
  332. if [ ! -z "${APP_DATA}" ]; then
  333. echo "---> using '${APP_DATA}' as basedir for FreePBX install"
  334. for k in ${!fpbxDirs[@]}; do
  335. v="${fpbxDirs[$k]}"
  336. eval fpbxDirs[$k]=${APP_DATA}$v
  337. [ ! -e "$v" ] && mkdir -p "$v"
  338. if [ "$(stat -c "%U %G" "$v" 2>/dev/null)" != "${APP_USR} ${APP_GRP}" ];then
  339. echo "---> fixing permissions for: $k=$v"
  340. chown ${APP_USR}:${APP_GRP} "$v"
  341. fi
  342. done
  343. for k in ${!fpbxFilesLog[@]}; do
  344. v="${fpbxFilesLog[$k]}"
  345. eval fpbxFilesLog[$k]=${APP_DATA}$v
  346. [ ! -e "$v" ] && touch "$v"
  347. if [ "$(stat -c "%U %G" "$v" 2>/dev/null)" != "${APP_USR} ${APP_GRP}" ];then
  348. echo "---> fixing permissions for: $k=$v"
  349. chown ${APP_USR}:${APP_GRP} "$v"
  350. fi
  351. done
  352. fi
  353. echo "[MySQL-asteriskcdrdb]
  354. Description = MariaDB connection to 'asteriskcdrdb' database
  355. driver = MySQL
  356. server = ${MYSQL_SERVER}
  357. database = asteriskcdrdb
  358. Port = ${APP_PORT_MYSQL}
  359. option = 3
  360. Charset=utf8" > /etc/odbc.ini
  361. if [[ -e "${appFilesConf[FPBXCFGFILE]}" && ! -e ${APP_DATA}/.initialized ]]; then
  362. echo "--> INFO: found '${appFilesConf[FPBXCFGFILE]}' configuration file but missing '${APP_DATA}/.initialized'... creating it right now"
  363. echo "--> NOTE: if you want make an initial install, remove '${appFilesConf[FPBXCFGFILE]}' and '${APP_DATA}/.initialized' file"
  364. touch "${APP_DATA}/.initialized"
  365. fi
  366. if [ ! -e ${APP_DATA}/.initialized ]; then
  367. cfgService_freepbx_install
  368. else
  369. echo "--> INFO: FreePBX installation DETECTED! found '${APP_DATA}/.initialized' file"
  370. [ ! -e "${appFilesConf[FPBXCFGFILE]}" ] && echo "---> WARNING: missing configuration file: ${appFilesConf[FPBXCFGFILE]}"
  371. echo "---> reconfiguring '${appFilesConf[FPBXCFGFILE]}'..."
  372. [[ ! -z "${APP_PORT_MYSQL}" && ${APP_PORT_MYSQL} -ne 3306 ]] && export MYSQL_SERVER="${MYSQL_SERVER}:${APP_PORT_MYSQL}"
  373. sed "s/^\$amp_conf\['AMPDBUSER'\] =.*/\$amp_conf\['AMPDBUSER'\] = '${MYSQL_USER}';/" -i "${appFilesConf[FPBXCFGFILE]}"
  374. sed "s/^\$amp_conf\['AMPDBPASS'\] =.*/\$amp_conf\['AMPDBPASS'\] = '${MYSQL_PASSWORD}';/" -i "${appFilesConf[FPBXCFGFILE]}"
  375. sed "s/^\$amp_conf\['AMPDBHOST'\] =.*/\$amp_conf\['AMPDBHOST'\] = '${MYSQL_SERVER}';/" -i "${appFilesConf[FPBXCFGFILE]}"
  376. sed "s/^\$amp_conf\['AMPDBNAME'\] =.*/\$amp_conf\['AMPDBNAME'\] = '${MYSQL_DATABASE}';/" -i "${appFilesConf[FPBXCFGFILE]}"
  377. fi
  378. echo "---> applying workarounds for FreePBX and Asterisk..."
  379. [ ! -e "${fpbxDirs[ASTLOGDIR]}/full" ] && touch "${fpbxDirs[ASTLOGDIR]}/full" && chown ${APP_USR}:${APP_GRP} "${file}" "${fpbxDirs[ASTLOGDIR]}/full"
  380. [ ! -e "/usr/sbin/fwconsole" ] && ln -s ${fpbxDirs[AMPBIN]}/fwconsole /usr/sbin/fwconsole
  381. [ ! -e "/usr/sbin/amportal" ] && ln -s ${fpbxDirs[AMPBIN]}/amportal /usr/sbin/amportal
  382. echo "---> reconfiguring FreePBX Advanced Settings if needed..."
  383. set | grep ^"FREEPBX_" | grep -v -e ^"FREEPBX_MODULES_" -e ^"FREEPBX_VER=" | sed -e 's/^FREEPBX_//' -e 's/=/ /' | while read setting ; do
  384. k="$(echo $setting | awk '{print $1}')"
  385. v="$(echo $setting | awk '{print $2}')"
  386. currentVal=$(fwconsole setting $k | awk -F"[][{}]" '{print $2}')
  387. [ "$currentVal" = "true" ] && currentVal="1"
  388. [ "$currentVal" = "false" ] && currentVal="0"
  389. if [ "$currentVal" != "$v" ]; then
  390. echo "---> reconfiguring advanced setting: ${k}=${v}"
  391. fwconsole setting $k $v
  392. fi
  393. done
  394. echo "---> reconfiguring FreePBX SIP Settings if needed..."
  395. for k in ${!fpbxSipSettings[@]}; do
  396. v="${fpbxSipSettings[$k]}"
  397. cVal=$(echo "<?php include '/etc/freepbx.conf'; \$FreePBX = FreePBX::Create(); echo \$FreePBX->sipsettings->getConfig('${k}');?>" | php)
  398. if [ "$cVal" != "${v}" ];then
  399. echo "---> reconfiguring sip setting: ${k}=${v}"
  400. echo "<?php include '/etc/freepbx.conf'; \$FreePBX = FreePBX::Create(); \$FreePBX->sipsettings->setConfig('${k}',${v}); needreload();?>" | php
  401. fi
  402. done
  403. echo "---> FIXME: temporary workarounds for FreePBX broken modules and configs..."
  404. sed 's/^preload = chan_local.so/;preload = chan_local.so/' -i ${fpbxDirs[ASTETCDIR]}/modules.conf
  405. sed 's/^enabled =.*/enabled = yes/' -i ${fpbxDirs[ASTETCDIR]}/hep.conf
  406. sed 's/!count(\$dsn)/!@count(\$dsn)/' -i ${fpbxDirs[AMPWEBROOT]}/admin/libraries/DB.class.php
  407. }
  408. cfgService_freepbx_install() {
  409. n=1 ; t=5
  410. until [ $n -eq $t ]; do
  411. echo "=> !!! FreePBX IS NOT INITIALIZED :: NEW INSTALLATION DETECTED !!!"
  412. echo "--> missing '${APP_DATA}/.initialized' file... initializing FreePBX right now... try:[$n/$t]"
  413. cd /usr/src/freepbx
  414. if ! asterisk -r -x "core show version" 2>/dev/null ; then ./start_asterisk start ; fi
  415. myn=1 ; myt=10
  416. until [ $myn -eq $myt ]; do
  417. mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e "SELECT 1;" >/dev/null
  418. RETVAL=$?
  419. if [ $RETVAL = 0 ]; then
  420. myn=$myt
  421. else
  422. let myn+=1
  423. echo "--> WARNING: cannot connect to MySQL database '${MYSQL_SERVER}'... waiting database to become ready... retrying in 10 seconds... try:[$myn/$myt]"
  424. sleep 10
  425. fi
  426. done
  427. mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e "CREATE DATABASE IF NOT EXISTS asteriskcdrdb;"
  428. 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;"
  429. mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e \
  430. "CREATE TABLE IF NOT EXISTS asteriskcdrdb.voicemessages \
  431. (msgnum INT(11) NULL DEFAULT NULL, \
  432. dir VARCHAR(80) NOT NULL, \
  433. context VARCHAR(80) NULL DEFAULT NULL, \
  434. macrocontext VARCHAR(80) NULL DEFAULT NULL, \
  435. callerid VARCHAR(40) NULL DEFAULT NULL, \
  436. origtime VARCHAR(40) NULL DEFAULT NULL, \
  437. duration VARCHAR(20) NULL DEFAULT NULL, \
  438. flag VARCHAR(8) NULL DEFAULT NULL, \
  439. mailboxuser VARCHAR(80) NULL DEFAULT NULL, \
  440. mailboxcontext VARCHAR(80) NULL DEFAULT NULL, \
  441. recording LONGBLOB NULL DEFAULT NULL, \
  442. msg_id VARCHAR(40) NULL DEFAULT NULL) ENGINE = InnoDB;"
  443. mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e \
  444. "CREATE TABLE IF NOT EXISTS asteriskcdrdb.cdr \
  445. (calldate datetime NOT NULL DEFAULT '1000-01-01 00:00:00', \
  446. clid varchar(80) NOT NULL DEFAULT '', \
  447. src varchar(80) NOT NULL DEFAULT '', \
  448. dst varchar(80) NOT NULL DEFAULT '', \
  449. dcontext varchar(80) NOT NULL DEFAULT '', \
  450. channel varchar(80) NOT NULL DEFAULT '', \
  451. dstchannel varchar(80) NOT NULL DEFAULT '', \
  452. lastapp varchar(80) NOT NULL DEFAULT '', \
  453. lastdata varchar(80) NOT NULL DEFAULT '', \
  454. duration int(11) NOT NULL DEFAULT 0, \
  455. billsec int(11) NOT NULL DEFAULT 0, \
  456. disposition varchar(45) NOT NULL DEFAULT '', \
  457. amaflags int(11) NOT NULL DEFAULT 0, \
  458. accountcode varchar(20) NOT NULL DEFAULT '', \
  459. uniqueid varchar(32) NOT NULL DEFAULT '', \
  460. userfield varchar(255) NOT NULL DEFAULT '', \
  461. did varchar(50) NOT NULL DEFAULT '', \
  462. recordingfile varchar(255) NOT NULL DEFAULT '', \
  463. cnum varchar(80) NOT NULL DEFAULT '', \
  464. cnam varchar(80) NOT NULL DEFAULT '', \
  465. outbound_cnum varchar(80) NOT NULL DEFAULT '', \
  466. outbound_cnam varchar(80) NOT NULL DEFAULT '', \
  467. dst_cnam varchar(80) NOT NULL DEFAULT '', \
  468. linkedid varchar(32) NOT NULL DEFAULT '', \
  469. peeraccount varchar(80) NOT NULL DEFAULT '', \
  470. sequence int(11) NOT NULL DEFAULT 0, \
  471. KEY calldate (calldate), \
  472. KEY dst (dst), \
  473. KEY accountcode (accountcode), \
  474. KEY uniqueid (uniqueid), \
  475. KEY did (did), \
  476. KEY recordingfile (recordingfile)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"
  477. FPBX_OPTS+=" --webroot=${fpbxDirs[AMPWEBROOT]}"
  478. FPBX_OPTS+=" --astetcdir=${fpbxDirs[ASTETCDIR]}"
  479. FPBX_OPTS+=" --astmoddir=${fpbxDirs[ASTMODDIR]}"
  480. FPBX_OPTS+=" --astvarlibdir=${fpbxDirs[ASTVARLIBDIR]}"
  481. FPBX_OPTS+=" --astagidir=${fpbxDirs[ASTAGIDIR]}"
  482. FPBX_OPTS+=" --astspooldir=${fpbxDirs[ASTSPOOLDIR]}"
  483. FPBX_OPTS+=" --astrundir=${fpbxDirs[ASTRUNDIR]}"
  484. FPBX_OPTS+=" --astlogdir=${fpbxDirs[ASTLOGDIR]}"
  485. FPBX_OPTS+=" --ampbin=${fpbxDirs[AMPBIN]}"
  486. FPBX_OPTS+=" --ampsbin=${fpbxDirs[AMPSBIN]}"
  487. FPBX_OPTS+=" --ampcgibin=${fpbxDirs[AMPCGIBIN]}"
  488. FPBX_OPTS+=" --ampplayback=${fpbxDirs[AMPPLAYBACK]}"
  489. echo "--> installing FreePBX in '${fpbxDirs[AMPWEBROOT]}'"
  490. echo "---> START install FreePBX @ $(date)"
  491. [[ ! -z "${APP_PORT_MYSQL}" && ${APP_PORT_MYSQL} -ne 3306 ]] && export MYSQL_SERVER="${MYSQL_SERVER}:${APP_PORT_MYSQL}"
  492. set -x
  493. ./install -n --skip-install --no-ansi --dbhost=${MYSQL_SERVER} --dbuser=${MYSQL_USER} --dbpass=${MYSQL_PASSWORD} ${FPBX_OPTS}
  494. RETVAL=$?
  495. set +x
  496. echo "---> END install FreePBX @ $(date)"
  497. unset FPBX_OPTS
  498. if [ $RETVAL = 0 ]; then
  499. [ ! -e "/usr/sbin/fwconsole" ] && ln -s ${fpbxDirs[ASTVARLIBDIR]}/bin/fwconsole /usr/sbin/fwconsole
  500. [ ! -e "/usr/sbin/amportal" ] && ln -s ${fpbxDirs[ASTVARLIBDIR]}/bin/amportal /usr/sbin/amportal
  501. if [ ! -z "${APP_DATA}" ]; then
  502. for file in ${appFilesConf[@]}; do
  503. chown ${APP_USR}:${APP_GRP} "${file}"
  504. done
  505. echo "--> fixing directory system paths in db configuration..."
  506. for k in ${!fpbxDirs[@]} ${!fpbxFilesLog[@]}; do
  507. fwconsole setting ${k} ${fpbxDirs[$k]}
  508. done
  509. fi
  510. : ${FREEPBX_MODULES_CORE="
  511. framework
  512. core
  513. dashboard
  514. sipsettings
  515. voicemail
  516. "}
  517. : ${FREEPBX_MODULES_PRE:="
  518. pm2
  519. userman
  520. "}
  521. : ${FREEPBX_MODULES_EXTRA:="
  522. soundlang
  523. callrecording
  524. cdr
  525. conferences
  526. customappsreg
  527. featurecodeadmin
  528. infoservices
  529. logfiles
  530. music
  531. manager
  532. arimanager
  533. filestore
  534. recordings
  535. announcement
  536. asteriskinfo
  537. backup
  538. callforward
  539. callwaiting
  540. daynight
  541. calendar
  542. certman
  543. cidlookup
  544. contactmanager
  545. donotdisturb
  546. fax
  547. findmefollow
  548. iaxsettings
  549. miscapps
  550. miscdests
  551. ivr
  552. parking
  553. phonebook
  554. presencestate
  555. printextensions
  556. queues
  557. cel
  558. timeconditions
  559. asterisk-cli
  560. blacklist
  561. configedit
  562. "}
  563. : ${FREEPBX_MODULES_DISABLED="
  564. bulkhandler
  565. speeddial
  566. weakpasswords
  567. ucp
  568. "}
  569. echo "--> enabling EXTENDED FreePBX repo..."
  570. su - ${APP_USR} -s /bin/bash -c "fwconsole ma enablerepo extended"
  571. su - ${APP_USR} -s /bin/bash -c "fwconsole ma enablerepo unsupported"
  572. echo "--> starting cron to avoid crontab checks error..."
  573. cron
  574. echo "--> installing prerequisite FreePBX modules from local install into '${fpbxDirs[AMPWEBROOT]}/admin/modules'"
  575. for module in ${FREEPBX_MODULES_PRE}; do
  576. su - ${APP_USR} -s /bin/bash -c "echo \"---> installing module: ${module}\" && fwconsole ma install ${module}"
  577. done
  578. echo "--> fixing FreePBX permissions..."
  579. fwconsole chown
  580. echo "--> enabling pm2 module..."
  581. fwconsole ma enable pm2
  582. freepbx_reload
  583. echo "--> installing Extra FreePBX modules from local install into '${fpbxDirs[AMPWEBROOT]}/admin/modules'"
  584. for module in ${FREEPBX_MODULES_EXTRA}; do
  585. su - ${APP_USR} -s /bin/bash -c "echo \"---> installing module: ${module}\" && fwconsole ma install ${module}"
  586. done
  587. echo "--> fixing FreePBX permissions..."
  588. fwconsole chown
  589. freepbx_reload
  590. echo "--> upgrading modules..."
  591. fwconsole ma upgradeall
  592. echo "--> fixing FreePBX permissions..."
  593. fwconsole chown
  594. freepbx_reload
  595. echo "--> stopping cron..."
  596. killall -9 cron
  597. touch "${APP_DATA}/.initialized"
  598. fi
  599. if [ $RETVAL = 0 ]; then
  600. n=$t
  601. else
  602. let n+=1
  603. echo "--> problem detected... restarting in 10 seconds... try:[$n/$t]"
  604. sleep 10
  605. fi
  606. done
  607. if asterisk -r -x "core show version" 2>/dev/null ; then
  608. echo "--> stopping Asterisk"
  609. asterisk -r -x "core stop now"
  610. echo "=> Finished installing FreePBX"
  611. fi
  612. }
  613. runHooks() {
  614. mkdir -p /var/log/supervisor /var/log/dbconfig-common /var/log/apt /var/log/apache2 /var/log/asterisk/cdr-csv
  615. touch /var/log/wtmp /var/log/lastlog
  616. [ ! -e /sbin/nologin ] && ln -s /usr/sbin/nologin /sbin/nologin
  617. if [ ! -z "${APP_DATA}" ]; then
  618. echo "=> Persistent storage path detected... relocating and reconfiguring system data and configuration files using base: ${APP_DATA}"
  619. for dir in ${appDataDirs[@]}
  620. do
  621. dir="${APP_DATA}${dir}"
  622. if [ ! -e "${dir}" ];then
  623. echo "--> creating missing dir: '$dir'"
  624. mkdir -p "${dir}"
  625. fi
  626. done
  627. for dir in ${appDataDirs[@]}; do
  628. symlinkDir "${dir}" "${APP_DATA}${dir}"
  629. done
  630. for file in ${appFilesConf[@]}; do
  631. symlinkFile "${file}" "${APP_DATA}${file}"
  632. done
  633. else
  634. echo "=> WARNING: No Persistent storage path detected... the configurations will be lost on container restart"
  635. fi
  636. chkService POSTFIX_ENABLED
  637. chkService CRON_ENABLED
  638. chkService FAIL2BAN_ENABLED
  639. chkService HTTPD_ENABLED
  640. chkService ASTERISK_ENABLED
  641. chkService RRTPBX_ENABLED
  642. [[ ! -z "${APP_FQDN}" && "${LETSENCRYPT_ENABLED}" = "true" ]] && cfgService_letsencrypt
  643. }
  644. runHooks