entrypoint-hooks.sh 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  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. }
  407. cfgService_freepbx_install() {
  408. n=1 ; t=5
  409. until [ $n -eq $t ]; do
  410. echo "=> !!! FreePBX IS NOT INITIALIZED :: NEW INSTALLATION DETECTED !!!"
  411. echo "--> missing '${APP_DATA}/.initialized' file... initializing FreePBX right now... try:[$n/$t]"
  412. cd /usr/src/freepbx
  413. if ! asterisk -r -x "core show version" 2>/dev/null ; then ./start_asterisk start ; fi
  414. myn=1 ; myt=10
  415. until [ $myn -eq $myt ]; do
  416. mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e "SELECT 1;" >/dev/null
  417. RETVAL=$?
  418. if [ $RETVAL = 0 ]; then
  419. myn=$myt
  420. else
  421. let myn+=1
  422. echo "--> WARNING: cannot connect to MySQL database '${MYSQL_SERVER}'... waiting database to become ready... retrying in 10 seconds... try:[$myn/$myt]"
  423. sleep 10
  424. fi
  425. done
  426. mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e "CREATE DATABASE IF NOT EXISTS asteriskcdrdb;"
  427. 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;"
  428. mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e \
  429. "CREATE TABLE IF NOT EXISTS asteriskcdrdb.voicemessages \
  430. (msgnum INT(11) NULL DEFAULT NULL, \
  431. dir VARCHAR(80) NOT NULL, \
  432. context VARCHAR(80) NULL DEFAULT NULL, \
  433. macrocontext VARCHAR(80) NULL DEFAULT NULL, \
  434. callerid VARCHAR(40) NULL DEFAULT NULL, \
  435. origtime VARCHAR(40) NULL DEFAULT NULL, \
  436. duration VARCHAR(20) NULL DEFAULT NULL, \
  437. flag VARCHAR(8) NULL DEFAULT NULL, \
  438. mailboxuser VARCHAR(80) NULL DEFAULT NULL, \
  439. mailboxcontext VARCHAR(80) NULL DEFAULT NULL, \
  440. recording LONGBLOB NULL DEFAULT NULL, \
  441. msg_id VARCHAR(40) NULL DEFAULT NULL) ENGINE = InnoDB;"
  442. mysql -h ${MYSQL_SERVER} -P ${APP_PORT_MYSQL} -u root --password=${MYSQL_ROOT_PASSWORD} -B -e \
  443. "CREATE TABLE IF NOT EXISTS asteriskcdrdb.cdr \
  444. (calldate datetime NOT NULL DEFAULT '1000-01-01 00:00:00', \
  445. clid varchar(80) NOT NULL DEFAULT '', \
  446. src varchar(80) NOT NULL DEFAULT '', \
  447. dst varchar(80) NOT NULL DEFAULT '', \
  448. dcontext varchar(80) NOT NULL DEFAULT '', \
  449. channel varchar(80) NOT NULL DEFAULT '', \
  450. dstchannel varchar(80) NOT NULL DEFAULT '', \
  451. lastapp varchar(80) NOT NULL DEFAULT '', \
  452. lastdata varchar(80) NOT NULL DEFAULT '', \
  453. duration int(11) NOT NULL DEFAULT 0, \
  454. billsec int(11) NOT NULL DEFAULT 0, \
  455. disposition varchar(45) NOT NULL DEFAULT '', \
  456. amaflags int(11) NOT NULL DEFAULT 0, \
  457. accountcode varchar(20) NOT NULL DEFAULT '', \
  458. uniqueid varchar(32) NOT NULL DEFAULT '', \
  459. userfield varchar(255) NOT NULL DEFAULT '', \
  460. did varchar(50) NOT NULL DEFAULT '', \
  461. recordingfile varchar(255) NOT NULL DEFAULT '', \
  462. cnum varchar(80) NOT NULL DEFAULT '', \
  463. cnam varchar(80) NOT NULL DEFAULT '', \
  464. outbound_cnum varchar(80) NOT NULL DEFAULT '', \
  465. outbound_cnam varchar(80) NOT NULL DEFAULT '', \
  466. dst_cnam varchar(80) NOT NULL DEFAULT '', \
  467. linkedid varchar(32) NOT NULL DEFAULT '', \
  468. peeraccount varchar(80) NOT NULL DEFAULT '', \
  469. sequence int(11) NOT NULL DEFAULT 0, \
  470. KEY calldate (calldate), \
  471. KEY dst (dst), \
  472. KEY accountcode (accountcode), \
  473. KEY uniqueid (uniqueid), \
  474. KEY did (did), \
  475. KEY recordingfile (recordingfile)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"
  476. FPBX_OPTS+=" --webroot=${fpbxDirs[AMPWEBROOT]}"
  477. FPBX_OPTS+=" --astetcdir=${fpbxDirs[ASTETCDIR]}"
  478. FPBX_OPTS+=" --astmoddir=${fpbxDirs[ASTMODDIR]}"
  479. FPBX_OPTS+=" --astvarlibdir=${fpbxDirs[ASTVARLIBDIR]}"
  480. FPBX_OPTS+=" --astagidir=${fpbxDirs[ASTAGIDIR]}"
  481. FPBX_OPTS+=" --astspooldir=${fpbxDirs[ASTSPOOLDIR]}"
  482. FPBX_OPTS+=" --astrundir=${fpbxDirs[ASTRUNDIR]}"
  483. FPBX_OPTS+=" --astlogdir=${fpbxDirs[ASTLOGDIR]}"
  484. FPBX_OPTS+=" --ampbin=${fpbxDirs[AMPBIN]}"
  485. FPBX_OPTS+=" --ampsbin=${fpbxDirs[AMPSBIN]}"
  486. FPBX_OPTS+=" --ampcgibin=${fpbxDirs[AMPCGIBIN]}"
  487. FPBX_OPTS+=" --ampplayback=${fpbxDirs[AMPPLAYBACK]}"
  488. echo "--> installing FreePBX in '${fpbxDirs[AMPWEBROOT]}'"
  489. echo "---> START install FreePBX @ $(date)"
  490. [[ ! -z "${APP_PORT_MYSQL}" && ${APP_PORT_MYSQL} -ne 3306 ]] && export MYSQL_SERVER="${MYSQL_SERVER}:${APP_PORT_MYSQL}"
  491. set -x
  492. ./install -n --skip-install --no-ansi --dbhost=${MYSQL_SERVER} --dbuser=${MYSQL_USER} --dbpass=${MYSQL_PASSWORD} ${FPBX_OPTS}
  493. RETVAL=$?
  494. set +x
  495. echo "---> END install FreePBX @ $(date)"
  496. unset FPBX_OPTS
  497. if [ $RETVAL = 0 ]; then
  498. [ ! -e "/usr/sbin/fwconsole" ] && ln -s ${fpbxDirs[ASTVARLIBDIR]}/bin/fwconsole /usr/sbin/fwconsole
  499. [ ! -e "/usr/sbin/amportal" ] && ln -s ${fpbxDirs[ASTVARLIBDIR]}/bin/amportal /usr/sbin/amportal
  500. if [ ! -z "${APP_DATA}" ]; then
  501. for file in ${appFilesConf[@]}; do
  502. chown ${APP_USR}:${APP_GRP} "${file}"
  503. done
  504. echo "--> fixing directory system paths in db configuration..."
  505. for k in ${!fpbxDirs[@]} ${!fpbxFilesLog[@]}; do
  506. fwconsole setting ${k} ${fpbxDirs[$k]}
  507. done
  508. fi
  509. : ${FREEPBX_MODULES_CORE="
  510. framework
  511. core
  512. dashboard
  513. sipsettings
  514. voicemail
  515. "}
  516. : ${FREEPBX_MODULES_PRE:="
  517. pm2
  518. userman
  519. "}
  520. : ${FREEPBX_MODULES_EXTRA:="
  521. soundlang
  522. callrecording
  523. cdr
  524. conferences
  525. customappsreg
  526. featurecodeadmin
  527. infoservices
  528. logfiles
  529. music
  530. manager
  531. arimanager
  532. filestore
  533. recordings
  534. announcement
  535. asteriskinfo
  536. backup
  537. callforward
  538. callwaiting
  539. daynight
  540. calendar
  541. certman
  542. cidlookup
  543. contactmanager
  544. donotdisturb
  545. fax
  546. findmefollow
  547. iaxsettings
  548. miscapps
  549. miscdests
  550. ivr
  551. parking
  552. phonebook
  553. presencestate
  554. printextensions
  555. queues
  556. cel
  557. timeconditions
  558. "}
  559. : ${FREEPBX_MODULES_DISABLED="
  560. bulkhandler
  561. speeddial
  562. weakpasswords
  563. ucp
  564. "}
  565. echo "--> enabling EXTENDED FreePBX repo..."
  566. su - ${APP_USR} -s /bin/bash -c "fwconsole ma enablerepo extended"
  567. su - ${APP_USR} -s /bin/bash -c "fwconsole ma enablerepo unsupported"
  568. echo "--> starting cron to avoid crontab checks error..."
  569. cron
  570. echo "--> installing prerequisite FreePBX modules from local install into '${fpbxDirs[AMPWEBROOT]}/admin/modules'"
  571. for module in ${FREEPBX_MODULES_PRE}; do
  572. su - ${APP_USR} -s /bin/bash -c "echo \"---> installing module: ${module}\" && fwconsole ma install ${module}"
  573. done
  574. echo "--> fixing FreePBX permissions..."
  575. fwconsole chown
  576. echo "--> enabling pm2 module..."
  577. fwconsole ma enable pm2
  578. freepbx_reload
  579. echo "--> installing Extra FreePBX modules from local install into '${fpbxDirs[AMPWEBROOT]}/admin/modules'"
  580. for module in ${FREEPBX_MODULES_EXTRA}; do
  581. su - ${APP_USR} -s /bin/bash -c "echo \"---> installing module: ${module}\" && fwconsole ma install ${module}"
  582. done
  583. echo "--> fixing FreePBX permissions..."
  584. fwconsole chown
  585. freepbx_reload
  586. echo "--> upgrading modules..."
  587. fwconsole ma upgradeall
  588. echo "--> fixing FreePBX permissions..."
  589. fwconsole chown
  590. freepbx_reload
  591. echo "--> stopping cron..."
  592. killall -9 cron
  593. touch "${APP_DATA}/.initialized"
  594. fi
  595. if [ $RETVAL = 0 ]; then
  596. n=$t
  597. else
  598. let n+=1
  599. echo "--> problem detected... restarting in 10 seconds... try:[$n/$t]"
  600. sleep 10
  601. fi
  602. done
  603. if asterisk -r -x "core show version" 2>/dev/null ; then
  604. echo "--> stopping Asterisk"
  605. asterisk -r -x "core stop now"
  606. echo "=> Finished installing FreePBX"
  607. fi
  608. }
  609. runHooks() {
  610. mkdir -p /var/log/supervisor /var/log/dbconfig-common /var/log/apt /var/log/apache2 /var/log/asterisk/cdr-csv
  611. touch /var/log/wtmp /var/log/lastlog
  612. [ ! -e /sbin/nologin ] && ln -s /usr/sbin/nologin /sbin/nologin
  613. if [ ! -z "${APP_DATA}" ]; then
  614. echo "=> Persistent storage path detected... relocating and reconfiguring system data and configuration files using base: ${APP_DATA}"
  615. for dir in ${appDataDirs[@]}
  616. do
  617. dir="${APP_DATA}${dir}"
  618. if [ ! -e "${dir}" ];then
  619. echo "--> creating missing dir: '$dir'"
  620. mkdir -p "${dir}"
  621. fi
  622. done
  623. for dir in ${appDataDirs[@]}; do
  624. symlinkDir "${dir}" "${APP_DATA}${dir}"
  625. done
  626. for file in ${appFilesConf[@]}; do
  627. symlinkFile "${file}" "${APP_DATA}${file}"
  628. done
  629. else
  630. echo "=> WARNING: No Persistent storage path detected... the configurations will be lost on container restart"
  631. fi
  632. chkService POSTFIX_ENABLED
  633. chkService CRON_ENABLED
  634. chkService FAIL2BAN_ENABLED
  635. chkService HTTPD_ENABLED
  636. chkService ASTERISK_ENABLED
  637. chkService RRTPBX_ENABLED
  638. [[ ! -z "${APP_FQDN}" && "${LETSENCRYPT_ENABLED}" = "true" ]] && cfgService_letsencrypt
  639. }
  640. runHooks