entrypoint-hooks.sh 26 KB

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