commit 8ecde30969b257ca2cd7e4363658e206f6b93f8a Author: oscar.garcia Date: Mon Oct 6 16:07:51 2025 -0500 Inicial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a91e6e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Environment file +issabel_ver.env diff --git a/README.md b/README.md new file mode 100644 index 0000000..af1e031 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +IssabelPBX +========== + +IssabelPBX is an opensource GUI (graphical user interface) that controls and manages Asterisk (PBX). + +IssabelPBX is derived/forked from FreePBX that was also forked/renamed from the original AMP released +on 2004 by Coalescent Systems Inc. + +#### Environmental Variables: +Prior to running `install-issabel-debian.sh`, an `issabel_var.env` file must be created. There is +a sample file, `issabel_var.env.sample` here which provides a template. The values are needed: + +- **ASTERISK_URL_CERTIFIED**: It is the url to download asterisk certified version, by default the value +is https://downloads.asterisk.org/pub/telephony/certified-asterisk/releases + +- **ASTERISK_URL**: It is the url to download asterisk version, the possible value are +for new version https://downloads.asterisk.org/pub/telephony/asterisk and old releases +https://downloads.asterisk.org/pub/telephony/asterisk/old-releases + +- **ASTERISK_SRC_FILE**: It is the source asterisk files that we are going to install. + + For get a list the asterisk certified version run: +```sh +curl -s https://downloads.asterisk.org/pub/telephony/certified-asterisk/releases/ | grep -Po '">\K.+.tar.gz' | grep -v "patch"` +``` + + For new asterisk version run: +```sh +curl -s https://downloads.asterisk.org/pub/telephony/asterisk/ | grep -Po '">\K.+.tar.gz' | grep -v "patch"` +``` + + For old releases asterisk version run: + +```sh +curl -s https://downloads.asterisk.org/pub/telephony/asterisk/old-releases/ | grep -Po '">\K.+.tar.gz' | grep -Pv "patch|addons|sounds" +``` + +- **ISSABEL_ADMIN_PASSWORD**: It is the password for user 'admin' that will +be used for: Issabel Web Login and IssabelPBX. + +- **LANGUAGE**: This should be the English "en_EN" or EspaƱol "es_ES" + +- **ISSABLE_SETTINGS_TABLE**: It is the mysql table that contains the issabel setting. +By default the values is: issabelpbx_settings + +- **LETSENCRYPT_HTTPS_URL**: It is Domain that your associated with your public ip. + +- **LETSENCRYPT_EMAIL**: This is your email for generate the certificate with +letsencrypt. + +- **HTTPSCERTFILE**: It is the location of the ssl certificate file +/etc/asterisk/keys/asterisk_cert_file.pem + +- **HTTPSPRIVATEKEY**: It is the location of the ssl certificate private key file +/etc/asterisk/keys/asterisk_privkey.pem + +Installation +------------ + +Clone repository + +Fill issabel_var.env + +Run +```sh +./install-issabel-debian.sh +``` + +Generates and config certificates +--------------------------------- + +Run +```sh +./config_certificates.sh +``` \ No newline at end of file diff --git a/asterisk/asterisk_issabel.tar.gz b/asterisk/asterisk_issabel.tar.gz new file mode 100644 index 0000000..6b95a56 Binary files /dev/null and b/asterisk/asterisk_issabel.tar.gz differ diff --git a/config_certificates.sh b/config_certificates.sh new file mode 100644 index 0000000..46e3861 --- /dev/null +++ b/config_certificates.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +apt install -y cron + +SOURCE_DIR_SCRIPT=$(pwd) + +[[ -s issabel_var.env ]] || { + echo "Please create y complete file issabel_var.env" + exit 1 +} +source issabel_var.env +DNS_ADDRRESS=$(nslookup $LETSENCRYPT_HTTPS_URL | grep -Po "Address: \K.+") +PUBLIC_IP_ADDRESS=$(curl -s -4 ip.me) + +[[ "$DNS_ADDRRESS" != "$PUBLIC_IP_ADDRESS" ]] && { + echo -e "" + echo -e "The url: $LETSENCRYPT_HTTPS_URL not resolve $PUBLIC_IP_ADDRESS" + echo -e "Update or associate $LETSENCRYPT_HTTPS_URL with $PUBLIC_IP_ADDRESS" + echo -e "Run again script\n" + exit 1 +} + +grep -q "ServerName $LETSENCRYPT_HTTPS_URL" /etc/apache2/sites-available/000-default.conf || sed -Ei "s/()/\1\n ServerName $LETSENCRYPT_HTTPS_URL\n ServerAlias $LETSENCRYPT_HTTPS_URL\n/" /etc/apache2/sites-available/000-default.conf + +if [ -z "${LETSENCRYPT_EMAIL}" ]; then + echo -e "" + echo -e "Please fill LETSENCRYPT_EMAIL var in issabel_var.env file" + echo -e "Run again script\n" + exit 1 +fi + +certbot certificates -d $LETSENCRYPT_HTTPS_URL 2>&1 | grep -q "VALID" || { + certbot --apache --non-interactive --agree-tos -d $LETSENCRYPT_HTTPS_URL -m $LETSENCRYPT_EMAIL +} + +certbot certificates -d $LETSENCRYPT_HTTPS_URL 2>&1 | grep -q "VALID" && { + CERTFILE=$(readlink -e $(certbot certificates -d $LETSENCRYPT_HTTPS_URL 2>&1 | grep -Po "Certificate Path: \K.+")) + PRIVATE_KEY=$(readlink -e $(certbot certificates -d $LETSENCRYPT_HTTPS_URL 2>&1 | grep -Po "Private Key Path: \K.+")) + rm -rf $HTTPSCERTFILE + rm -rf $HTTPSPRIVATEKEY + /usr/bin/cp -rf $CERTFILE $HTTPSCERTFILE + /usr/bin/cp -rf $PRIVATE_KEY $HTTPSPRIVATEKEY + chown asterisk: $HTTPSCERTFILE $HTTPSPRIVATEKEY + chmod 400 $HTTPSCERTFILE $HTTPSPRIVATEKEY + mysql asterisk -e "update issabelpbx_settings set value='$HTTPSCERTFILE' where keyword='HTTPSCERTFILE';" + mysql asterisk -e "update issabelpbx_settings set value='$HTTPSPRIVATEKEY' where keyword='HTTPSPRIVATEKEY';" + su -c "/var/lib/asterisk/bin/module_admin reload" -s /bin/bash asterisk + /usr/sbin/asterisk -rx 'core restart now' + cat > /usr/bin/asterisk_reload_certifies.sh <&1 | grep -Po "Certificate Path: \K.+")) +PRIVATE_KEY=\$(readlink -e \$(certbot certificates -d $LETSENCRYPT_HTTPS_URL 2>&1 | grep -Po "Private Key Path: \K.+")) + +rm -rf \$HTTPSCERTFILE +rm -rf \$HTTPSPRIVATEKEY + +/usr/bin/cp -rf \$CERTFILE \$HTTPSCERTFILE +/usr/bin/cp -rf \$PRIVATE_KEY \$HTTPSPRIVATEKEY + +/usr/bin/chown asterisk: \$HTTPSCERTFILE \$HTTPSPRIVATEKEY +/usr/sbin/asterisk -rx 'core restart now' +EOF + chmod 755 /usr/bin/asterisk_reload_certifies.sh + crontab -l | grep -q "/usr/bin/certbot" || { + crontab -l | { cat; echo '30 3 * * * /usr/bin/certbot renew --quiet --no-self-upgrade --post-hook "/usr/bin/asterisk_reload_certifies.sh"'; } | crontab - + } +} diff --git a/fail2ban/action.d/iptables-common.conf b/fail2ban/action.d/iptables-common.conf new file mode 100644 index 0000000..6542471 --- /dev/null +++ b/fail2ban/action.d/iptables-common.conf @@ -0,0 +1,91 @@ +# Fail2Ban configuration file +# +# Author: Daniel Black +# +# This is a included configuration file and includes the definitions for the iptables +# used in all iptables based actions by default. +# +# The user can override the defaults in iptables-common.local +# +# Modified: Alexander Koeppe , Serg G. Brester +# made config file IPv6 capable (see new section Init?family=inet6) + +[INCLUDES] + +after = iptables-blocktype.local + iptables-common.local +# iptables-blocktype.local is obsolete + +[Definition] + +# Option: actionflush +# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action) +# Values: CMD +# +actionflush = -F f2b- + + +[Init] + +# Option: chain +# Notes specifies the iptables chain to which the Fail2Ban rules should be +# added +# Values: STRING Default: INPUT +chain = INPUT + +# Default name of the chain +# +name = default + +# Option: port +# Notes.: specifies port to monitor +# Values: [ NUM | STRING ] Default: +# +port = ssh + +# Option: protocol +# Notes.: internally used by config reader for interpolations. +# Values: [ tcp | udp | icmp | all ] Default: tcp +# +protocol = tcp + +# Option: blocktype +# Note: This is what the action does with rules. This can be any jump target +# as per the iptables man page (section 8). Common values are DROP +# REJECT, REJECT --reject-with icmp-port-unreachable +# Values: STRING +blocktype = REJECT --reject-with icmp-port-unreachable + +# Option: returntype +# Note: This is the default rule on "actionstart". This should be RETURN +# in all (blocking) actions, except REJECT in allowing actions. +# Values: STRING +returntype = RETURN + +# Option: lockingopt +# Notes.: Option was introduced to iptables to prevent multiple instances from +# running concurrently and causing irratic behavior. -w was introduced +# in iptables 1.4.20, so might be absent on older systems +# See https://github.com/fail2ban/fail2ban/issues/1122 +# Values: STRING +lockingopt = -w + +# Option: iptables +# Notes.: Actual command to be executed, including common to all calls options +# Values: STRING +iptables = iptables + + +[Init?family=inet6] + +# Option: blocktype (ipv6) +# Note: This is what the action does with rules. This can be any jump target +# as per the iptables man page (section 8). Common values are DROP +# REJECT, REJECT --reject-with icmp6-port-unreachable +# Values: STRING +blocktype = REJECT --reject-with icmp6-port-unreachable + +# Option: iptables (ipv6) +# Notes.: Actual command to be executed, including common to all calls options +# Values: STRING +iptables = ip6tables diff --git a/fail2ban/action.d/iptables-multiport-asterisk.conf b/fail2ban/action.d/iptables-multiport-asterisk.conf new file mode 100644 index 0000000..3ef97d6 --- /dev/null +++ b/fail2ban/action.d/iptables-multiport-asterisk.conf @@ -0,0 +1,58 @@ +# Fail2Ban configuration file +# +# Author: Cyril Jaquier +# Modified by Yaroslav Halchenko for multiport banning +# + +[INCLUDES] + +before = iptables-common.conf + +[Definition] + +actionstart_on_demand = false + +# Option: actionstart +# Notes.: command executed once at the start of Fail2Ban. +# Values: CMD +# +actionstart = -N F2B_INPUT + -C INPUT -j F2B_INPUT || -I INPUT 2 -j F2B_INPUT || -I INPUT -j F2B_INPUT + -N f2b- + -A f2b- -j + -I -p -m multiport --dports -j f2b- + +# Option: actionstop +# Notes.: command executed once at the end of Fail2Ban +# Values: CMD +# +actionstop = -D -p -m multiport --dports -j f2b- + -D INPUT -j INPUT_F2B + -F f2b- + -X f2b- + +# Option: actioncheck +# Notes.: command executed once before each actionban command +# Values: CMD +# +actioncheck = -n -L | grep -q 'f2b-[ \t]' + +# Option: actionban +# Notes.: command executed when banning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionban = -I f2b- 1 -s -j + +# Option: actionunban +# Notes.: command executed when unbanning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionunban = -D f2b- -s -j + +[Init] + + diff --git a/fail2ban/filter.d/asterisk.conf b/fail2ban/filter.d/asterisk.conf new file mode 100644 index 0000000..e15d7bf --- /dev/null +++ b/fail2ban/filter.d/asterisk.conf @@ -0,0 +1,55 @@ +# Fail2Ban filter for asterisk authentication failures +# + +[INCLUDES] + +# Read common prefixes. If any customizations available -- read them from +# common.local +before = common.conf + +[Definition] + +_daemon = asterisk + +__pid_re = (?:\s*\[\d+\]) + +iso8601 = \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+[+-]\d{4} + +# All Asterisk log messages begin like this: +log_prefix= (?:NOTICE|SECURITY|WARNING)%(__pid_re)s:?(?:\[C-[\da-f]*\])?:? [^:]+:\d*(?:(?: in)? [^:]+:)? + +prefregex = ^%(__prefix_line)s%(log_prefix)s .+$ + +failregex = ^Registration from '[^']*' failed for '(:\d+)?' - (?:Wrong password|Username/auth name mismatch|No matching peer found|Not a local domain|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$ + ^Call from '[^']*' \((?:(?:TCP|UDP):)?:\d+\) to extension '[^']*' rejected because extension not found in context + ^(?:Host )? (?:failed (?:to authenticate\b|MD5 authentication\b)|tried to authenticate with nonexistent user\b) + ^No registration for peer '[^']*' \(from \)$ + ^hacking attempt detected ''$ + ^SecurityEvent="(?:FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)"(?:(?:,(?!RemoteAddress=)\w+="[^"]*")*|.*?),RemoteAddress="IPV[46]/[^/"]+//\d+"(?:,(?!RemoteAddress=)\w+="[^"]*")*$ + ^"Rejecting unknown SIP connection from (?::\d+)?"$ + ^Request (?:'[^']*' )?from '(?:[^']*|.*?)' failed for '(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\s*$ + +# FreePBX (todo: make optional in v.0.10): +# ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )[^:]+: Friendly Scanner from $ + +ignoreregex = + +datepattern = {^LN-BEG} + +# Author: Xavier Devlamynck / Daniel Black +# +# General log format - main/logger.c:ast_log +# Address format - ast_sockaddr_stringify +# +# First regex: channels/chan_sip.c +# +# main/logger.c:ast_log_vsyslog - "in {functionname}:" only occurs in syslog + +journalmatch = _SYSTEMD_UNIT=asterisk.service + + +[lt_journal] + +# asterisk can log timestamp if logs into systemd-journal (optional part matching this timestamp, gh-2383): +__extra_timestamp = (?:\[[^\]]+\]\s+)? +__prefix_line = %(known/__prefix_line)s%(__extra_timestamp)s diff --git a/fail2ban/jail.d/asterisk.conf b/fail2ban/jail.d/asterisk.conf new file mode 100644 index 0000000..4f778ca --- /dev/null +++ b/fail2ban/jail.d/asterisk.conf @@ -0,0 +1,9 @@ +[asterisk] +enabled = true +filter = asterisk +banaction = iptables-multiport-asterisk +logpath = /var/log/asterisk/messages +maxretry = 10 +bantime = 43200 +ignoreip = 127.0.0.1 +port = 0:65535 diff --git a/fail2ban/jail.d/defaults-debian.conf b/fail2ban/jail.d/defaults-debian.conf new file mode 100644 index 0000000..0480281 --- /dev/null +++ b/fail2ban/jail.d/defaults-debian.conf @@ -0,0 +1,3 @@ +[sshd] +backend=systemd +enabled=true \ No newline at end of file diff --git a/install-issabel-debian.sh b/install-issabel-debian.sh new file mode 100644 index 0000000..0cabe21 --- /dev/null +++ b/install-issabel-debian.sh @@ -0,0 +1,587 @@ +#!/bin/bash + +SOURCE_DIR_SCRIPT=$(pwd) + +[[ -s issabel_var.env ]] || { + echo "Please create y complete file issabel_var.env" + exit 1 +} +source issabel_var.env + +#Add sbin to path +if ! grep -Pq 'export PATH=.*/usr/sbin.*' /etc/bash.bashrc; then + echo "export PATH=$PATH:/usr/local/sbin:/usr/sbin" >> /etc/bash.bashrc +fi + +if ! $(echo "$PATH" | grep -Fq "sbin") ; then + echo -e "Error: /usr/sbin is not in PATH\n" + echo -e "Run: source /etc/bash.bashrc \n" + echo -e "and run ./install-issabel-debian.sh\n" + exit 1 +fi + + +# Enable non free and contrib repos +if ! grep -Pq '^(deb.+)main(.+)contrib non-free' /etc/bash.bashrc; then + sed -i -E 's/^(deb.+)main(.+)/\1main contrib non-free\2/g' /etc/apt/sources.list +fi + +#Updata and upgrade package +apt update +apt upgrade -y +apt install -y apt-transport-https lsb-release ca-certificates wget curl aptitude + +#Uninstall apparmor +if service --status-all | grep -Fq 'apparmor'; then + systemctl stop apparmor + apt remove -y apparmor +fi + +#Package installation +apt install -y \ + git apache2 gettext sngrep\ + unixodbc odbcinst unixodbc-dev \ + mariadb-server mariadb-client \ + libmariadb-dev cockpit net-tools \ + dialog locales-all libwww-perl \ + mpg123 sox fail2ban \ + cracklib-runtime dnsutils \ + certbot python3-certbot-apache \ + iptables + +#Install docker +mkdir -p /etc/apt/keyrings +curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ + $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +apt -y update +apt -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin + +#Add user asterisk +if ! id -u "asterisk" >/dev/null 2>&1; then + adduser asterisk --uid 5000 --gecos "Asterisk PBX" --disabled-password --disabled-login --home /var/lib/asterisk +fi + +#Download Asterisk +ASTERISK_SRC_DIR="$(basename $ASTERISK_SRC_FILE .tar.gz)" +ASTERISK_URL_DOWNLOAD=$ASTERISK_URL/$ASTERISK_SRC_FILE +if echo "$ASTERISK_SRC_FILE" | grep -Fq "certified" ; then + ASTERISK_URL_DOWNLOAD=$ASTERISK_URL_CERTIFIED/$ASTERISK_SRC_FILE +fi + + +cd /usr/src +[[ -f $ASTERISK_SRC_FILE ]] || { + wget $ASTERISK_URL_DOWNLOAD +} + +[[ -d /usr/src/${ASTERISK_SRC_DIR} ]] || mkdir -p /usr/src/${ASTERISK_SRC_DIR} + +tar zxvf $ASTERISK_SRC_FILE -C /usr/src/${ASTERISK_SRC_DIR} --strip-components=1 +cd ${ASTERISK_SRC_DIR}/ + +#Install Asterisk dependencies +contrib/scripts/install_prereq install + +#Install asterisk +./configure +make menuselect.makeopts +menuselect/menuselect \ + --disable-category MENUSELECT_ADDONS \ + --disable app_flash \ + --disable app_skel \ + --disable-category MENUSELECT_CDR \ + --disable-category MENUSELECT_CEL \ + --disable cdr_pgsql \ + --disable cel_pgsql \ + --disable-category MENUSELECT_CHANNELS \ + --enable chan_iax2 \ + --enable chan_pjsip \ + --enable chan_rtp \ + --enable-category MENUSELECT_CODECS \ + --enable-category MENUSELECT_FORMATS \ + --enable-category MENUSELECT_FUNCS \ + --enable-category MENUSELECT_PBX \ + --enable app_macro \ + --enable pbx_config \ + --enable pbx_loopback \ + --enable pbx_spool \ + --enable pbx_realtime \ + --enable res_agi \ + --enable res_ari \ + --enable res_ari_applications \ + --enable res_ari_asterisk \ + --enable res_ari_bridges \ + --enable res_ari_channels \ + --enable res_ari_device_states \ + --enable res_ari_endpoints \ + --enable res_ari_events \ + --enable res_ari_mailboxes \ + --enable res_ari_model \ + --enable res_ari_playbacks \ + --enable res_ari_recordings \ + --enable res_ari_sounds \ + --enable res_clialiases \ + --enable res_clioriginate \ + --enable res_config_curl \ + --enable res_config_odbc \ + --disable res_config_sqlite3 \ + --enable res_convert \ + --enable res_crypto \ + --enable res_curl \ + --enable res_fax \ + --enable res_format_attr_celt \ + --enable res_format_attr_g729 \ + --enable res_format_attr_h263 \ + --enable res_format_attr_h264 \ + --enable res_format_attr_ilbc \ + --enable res_format_attr_opus \ + --enable res_format_attr_silk \ + --enable res_format_attr_siren14 \ + --enable res_format_attr_siren7 \ + --enable res_format_attr_vp8 \ + --enable res_http_media_cache \ + --enable res_http_post \ + --enable res_http_websocket \ + --enable res_limit \ + --enable res_manager_devicestate \ + --enable res_manager_presencestate \ + --enable res_musiconhold \ + --enable res_mutestream \ + --enable res_mwi_devstate \ + --disable res_mwi_external \ + --disable res_mwi_external_ami \ + --disable res_odbc \ + --disable res_odbc_transaction \ + --enable res_parking \ + --enable res_pjproject \ + --enable res_pjsip \ + --enable res_pjsip_acl \ + --enable res_pjsip_authenticator_digest \ + --enable res_pjsip_caller_id \ + --enable res_pjsip_config_wizard \ + --enable res_pjsip_dialog_info_body_generator \ + --enable res_pjsip_diversion \ + --enable res_pjsip_dlg_options \ + --enable res_pjsip_dtmf_info \ + --enable res_pjsip_empty_info \ + --enable res_pjsip_endpoint_identifier_anonymous \ + --enable res_pjsip_endpoint_identifier_ip \ + --enable res_pjsip_endpoint_identifier_user \ + --enable res_pjsip_exten_state \ + --enable res_pjsip_header_funcs \ + --enable res_pjsip_logger \ + --enable res_pjsip_messaging \ + --enable res_pjsip_mwi \ + --enable res_pjsip_mwi_body_generator \ + --enable res_pjsip_nat \ + --enable res_pjsip_notify \ + --enable res_pjsip_one_touch_record_info \ + --enable res_pjsip_outbound_authenticator_digest \ + --enable res_pjsip_outbound_publish \ + --enable res_pjsip_outbound_registration \ + --enable res_pjsip_path \ + --enable res_pjsip_pidf_body_generator \ + --enable res_pjsip_pidf_digium_body_supplement \ + --enable res_pjsip_pidf_eyebeam_body_supplement \ + --enable res_pjsip_publish_asterisk \ + --enable res_pjsip_pubsub \ + --enable res_pjsip_refer \ + --enable res_pjsip_registrar \ + --enable res_pjsip_rfc3326 \ + --enable res_pjsip_sdp_rtp \ + --enable res_pjsip_send_to_voicemail \ + --enable res_pjsip_session \ + --enable res_pjsip_sips_contact \ + --enable res_pjsip_t38 \ + --enable res_pjsip_transport_websocket \ + --enable res_pjsip_xpidf_body_generator \ + --enable res_realtime \ + --enable res_resolver_unbound \ + --enable res_rtp_asterisk \ + --enable res_rtp_multicast \ + --enable res_security_log \ + --enable res_sorcery_astdb \ + --enable res_sorcery_config \ + --enable res_sorcery_memory \ + --enable res_sorcery_memory_cache \ + --enable res_sorcery_realtime \ + --enable res_speech \ + --enable res_srtp \ + --enable res_stasis \ + --enable res_stasis_answer \ + --enable res_stasis_device_state \ + --enable res_stasis_mailbox \ + --enable res_stasis_playback \ + --enable res_stasis_recording \ + --enable res_stasis_snoop \ + --enable res_stasis_test \ + --enable res_stun_monitor \ + --enable res_timing_dahdi \ + --enable res_timing_timerfd \ + --disable res_ael_share \ + --disable res_calendar \ + --disable res_calendar_caldav \ + --disable res_calendar_ews \ + --disable res_calendar_exchange \ + --disable res_calendar_icalendar \ + --disable res_chan_stats \ + --disable res_config_ldap \ + --enable res_config_pgsql \ + --disable res_corosync \ + --disable res_endpoint_stats \ + --disable res_fax_spandsp \ + --enable res_hep \ + --enable res_hep_pjsip \ + --enable res_hep_rtcp \ + --disable res_phoneprov \ + --disable res_pjsip_history \ + --disable res_pjsip_phoneprov_provider \ + --disable res_pktccops \ + --disable res_remb_modifier \ + --disable res_smdi \ + --disable res_snmp \ + --disable res_statsd \ + --enable res_timing_kqueue \ + --disable res_timing_pthread \ + --disable res_adsi \ + --enable res_config_sqlite3 \ + --disable res_monitor \ + --disable res_digium_phone \ + --disable res_mwi_external \ + --disable res_stasis_mailbox \ + --enable cdr_adaptive_odbc \ + --enable cdr_custom \ + --enable cdr_manager \ + --enable cdr_csv \ + menuselect.makeopts + +make +make install + +#Asterisk service systemd +cat > /lib/systemd/system/asterisk.service < /var/www/html/index.html < + + + + + +EOF + +# Apache Configuration +sed -i -e "s/www-data/asterisk/" /etc/apache2/envvars +echo "" >/etc/apache2/conf-available/pbxapi.conf +echo " AllowOverride All" >>/etc/apache2/conf-available/pbxapi.conf +echo "" >>/etc/apache2/conf-available/pbxapi.conf +ln -s /etc/apache2/conf-available/pbxapi.conf /etc/apache2/conf-enabled +a2enmod rewrite + +# Enable SSL +a2enmod ssl +ln -s /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-enabled/ + +#Restart apache +systemctl restart apache2 + + +# UnixODBC config + +cat > /etc/odbc.ini < \/run\/mysqld\/mysqld.sock/' /etc/odbc.ini +elif [ -e "/var/run/mysqld/mysqld.sock" ]; then + sed -i -e 's/Socket=\/var\/lib\/mysql\/mysql.sock/astdatadir => \/var\/lib\/mysql\/mysql.sock/' /etc/odbc.ini +fi + +if [ -f /etc/lsb-release ]; then + DLFILE="https://dlm.mariadb.com/1936476/Connectors/odbc/connector-odbc-3.1.15/mariadb-connector-odbc-3.1.15-ubuntu-focal-amd64.tar.gz" +elif [ -f /etc/debian_version ]; then + if [ $(cat /etc/debian_version | cut -d. -f1) = 12 ]; then + DLFILE="https://dlm.mariadb.com/1936451/Connectors/odbc/connector-odbc-3.1.15/mariadb-connector-odbc-3.1.15-debian-buster-amd64.tar.gz" + elif [ $(cat /etc/debian_version | cut -d. -f1) = 11 ]; then + DLFILE="https://dlm.mariadb.com/1936451/Connectors/odbc/connector-odbc-3.1.15/mariadb-connector-odbc-3.1.15-debian-buster-amd64.tar.gz" + elif [ $(cat /etc/debian_version | cut -d. -f1) = 10 ]; then + DLFILE="https://dlm.mariadb.com/1936451/Connectors/odbc/connector-odbc-3.1.15/mariadb-connector-odbc-3.1.15-debian-buster-amd64.tar.gz" + elif [ $(cat /etc/debian_version | cut -d. -f1) = 9 ]; then + DLFILE="https://dlm.mariadb.com/1936481/Connectors/odbc/connector-odbc-3.1.15/mariadb-connector-odbc-3.1.15-debian-9-stretch-amd64.tar.gz" + fi +fi + +FILENAME=$(basename $DLFILE) +rm $FILENAME +wget $DLFILE +tar zxvf $FILENAME +rm $FILENAME$A +cp $(find /usr/src/ -name libmaodbc.so) /usr/local/lib + +cat > /etc/odbcinst.ini </etc/asterisk/manager_general_additional.conf +echo "timestampevents=yes" >>/etc/asterisk/manager_general_additional.conf +echo "webenabled=no" >>/etc/asterisk/manager_general_additional.conf +chown asterisk: /etc/asterisk/manager_general_additional.conf +chown asterisk: /var/lib/asterisk/agi-bin -R + +# Install PearDB +pear install DB + +# fail2ban config +sed -i 's:/var/log/asterisk/messages:/var/log/asterisk/security:' /etc/fail2ban/jail.conf + +if [ ! -f /etc/fail2ban/jail.d/issabelpbx.conf ]; then + +cat <<'EOF' >/etc/fail2ban/jail.d/issabelpbx.conf +[asterisk] +enabled=true + +[issabelpbx-auth] +enabled=true +logpath=/var/log/asterisk/issabelpbx.log +maxretry=3 +bantime=43200 +ignoreip=127.0.0.1 +port=80,443 +EOF + +cat <<'EOF' >/etc/fail2ban/filter.d/issabelpbx-auth.conf +# Fail2Ban filter for issabelpbx +# +[INCLUDES] +before = common.conf +[Definition] +failregex = ^%(__prefix_line)s\[SECURITY\].+Invalid Login.+ \s*$ +ignoreregex = +EOF +fi + +# If for some reason we do not have language set, default to english +if [ "$LANGUAGE" == "" ]; then + LANGUAGE=en_EN +fi + +if [ -z "${ISSABEL_ADMIN_PASSWORD}" ]; then + ISSABEL_ADMIN_PASSWORD=XYZADMINadmin1234 +fi + +# Compile issabelPBX language files +cd /usr/src/issabelPBX/ +build/compile_gettext.sh +systemctl restart apache2 + +# Install IssabelPBX with install_amp +framework/install_amp --dbuser=root --installdb --scripted --language=$LANGUAGE --adminpass=$ISSABEL_ADMIN_PASSWORD + +rm -f /etc/asteris/stir_shaken.conf + +# Copy fail2ban config files +/usr/bin/cp -rf $SOURCE_DIR_SCRIPT/fail2ban/action.d/*.conf /etc/fail2ban/action.d +/usr/bin/cp -rf $SOURCE_DIR_SCRIPT/fail2ban/filter.d/*.conf /etc/fail2ban/filter.d +/usr/bin/cp -rf $SOURCE_DIR_SCRIPT/fail2ban/jail.d/*.conf /etc/fail2ban/jail.d + +systemctl restart fail2ban + +# Logrotate +/usr/bin/cp -rf $SOURCE_DIR_SCRIPT/logrotate/asterisk_logrotate.conf /etc/logrotate.d/asterisk.conf + +#Vosk docker container unit systemd +cat > /lib/systemd/system/vosk.service < /etc/asterisk/res_speech_vosk.conf <'asterisk', 'version' => $matches[1], 'additional' => $matches[4], 'raw' => $verinfo); + $gotinfo = true; +- } elseif (preg_match('/Asterisk certified\/(\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches)) { ++ } elseif (preg_match('/Asterisk certified.(\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches)) { + $engine_info = array('engine'=>'asterisk', 'version' => $matches[1], 'additional' => $matches[4], 'raw' => $verinfo); + $gotinfo = true; + } elseif (preg_match('/Asterisk SVN-branch-(\d+(\.\d+)*)-r(-?(\S*))/', $verinfo, $matches)) { diff --git a/issabel/patch/install_amp.patch b/issabel/patch/install_amp.patch new file mode 100644 index 0000000..a8f7fe5 --- /dev/null +++ b/issabel/patch/install_amp.patch @@ -0,0 +1,13 @@ +diff --git a/framework/install_amp b/framework/install_amp +index 3279e840..7c8d547c 100755 +--- a/framework/install_amp ++++ b/framework/install_amp +@@ -1361,7 +1361,7 @@ $verinfo = $tmpout; + outn("Checking for Asterisk version.."); + if ((preg_match('/^Asterisk (\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches)) || + (preg_match('/^Asterisk SVN-(\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches)) || +- (preg_match('/^Asterisk certified\/(\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches))) { ++ (preg_match('/^Asterisk certified.(\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches))) { + if ((version_compare($matches[1], "1.6") < 0)) { + fatal("Asterisk 1.6, 1.8 or 10 is required for this version of IssabelPBX. Detected version is: ".$matches[1]); + } diff --git a/issabel_var.env b/issabel_var.env new file mode 100644 index 0000000..e7009ca --- /dev/null +++ b/issabel_var.env @@ -0,0 +1,16 @@ +# Asterisk +ASTERISK_URL_CERTIFIED=https://downloads.asterisk.org/pub/telephony/certified-asterisk/releases +ASTERISK_URL=https://downloads.asterisk.org/pub/telephony/asterisk +ASTERISK_SRC_FILE=asterisk-certified-16.8-cert14.tar.gz + +# Issabel +ISSABEL_ADMIN_PASSWORD='Sap64ad+' +LANGUAGE='es_ES' +TZ_REGION='America/Bogota' +ISSABLE_SETTINGS_TABLE=issabelpbx_settings + +# Letsencrypt +USE_LETSENCRYPT='no' +LETSENCRYPT_DOMAIN='issabel.dialbox.cloud' +HTTPSCERTFILE=/etc/asterisk/keys/asterisk_cert_file.pem +HTTPSPRIVATEKEY=/etc/asterisk/keys/asterisk_privkey.pem \ No newline at end of file diff --git a/issabel_var.env.sample b/issabel_var.env.sample new file mode 100644 index 0000000..1e16527 --- /dev/null +++ b/issabel_var.env.sample @@ -0,0 +1,15 @@ +# Asterisk +ASTERISK_URL_CERTIFIED=https://downloads.asterisk.org/pub/telephony/certified-asterisk/releases +ASTERISK_URL=https://downloads.asterisk.org/pub/telephony/asterisk +ASTERISK_SRC_FILE=asterisk-certified-16.8-cert14.tar.gz + +# Issabel +ISSABEL_ADMIN_PASSWORD=ADMIN +LANGUAGE=en_EN +ISSABLE_SETTINGS_TABLE=issabelpbx_settings + +# Letsencrypt +LETSENCRYPT_HTTPS_URL= +LETSENCRYPT_EMAIL= +HTTPSCERTFILE=/etc/asterisk/keys/asterisk_cert_file.pem +HTTPSPRIVATEKEY=/etc/asterisk/keys/asterisk_privkey.pem \ No newline at end of file diff --git a/logrotate/asterisk_logrotate.conf b/logrotate/asterisk_logrotate.conf new file mode 100644 index 0000000..af4d6e0 --- /dev/null +++ b/logrotate/asterisk_logrotate.conf @@ -0,0 +1,12 @@ +/var/log/asterisk/messages /var/log/asterisk/full /var/log/asterisk/queue_log /var/log/asterisk/security +{ + missingok + daily + rotate 45 + dateext + dateyesterday + su asterisk asterisk + postrotate + /usr/sbin/asterisk -rx 'logger reload' > /dev/null 2> /dev/null + endscript +} diff --git a/script/login-info.sh b/script/login-info.sh new file mode 100644 index 0000000..5fc5572 --- /dev/null +++ b/script/login-info.sh @@ -0,0 +1,48 @@ +#!/bin/bash +exec 2>&1 +user=$(whoami) +load=`cat /proc/loadavg | awk '{print $1" (1min) "$2" (5min) "$3" (15min)"}'` +memory_usage=`free -m | awk '/Mem:/ { printf("%3.0f%%", ($3/$2)*100)}'` +memory=`free -m | awk '/Mem:/ { print $2 }'` +mem_used=`free -m| grep ^Mem | awk '{print $3}'` +swap_usage=`free -m | awk '/Swap/ { printf("%3.1f%%", "exit !$2;$3/$2*100") }'` +users=` w -s | grep -v WHAT | grep -v "load average" | wc -l` +time=`uptime | grep -ohe 'up .*' | sed 's/,/\ hours/g' | awk '{ printf $2" "$3 }'` +processes_total=`ps aux | wc -l` +processes_user=`ps -U ${user} u | wc -l` + +root_total=`df -h / | awk '/\// {print $(NF-4)}'` +root_usedgb=`df -h / | awk '/\// {print $(NF-3)}' | sed 's/[^0-9\.,]//'` +root_used=`df -h / | awk '/\// {print $(NF-1)}' | sed 's/[^0-9]//'` +root_used_print=$(printf "%3.0f%%" $root_used) +root_free=$(expr 100 - $root_used) +root_used_gauge_val=`awk "BEGIN { a=($root_used/2); printf(\"%0.f\",a)}"` +root_free_gauge_val=`awk "BEGIN { a=($root_free/2); printf(\"%0.f\",a)}"` +root_used_gauge=$(seq -s= $root_used_gauge_val|tr -d '[:digit:]') +root_free_gauge=$(seq -s- $root_free_gauge_val|tr -d '[:digit:]') +root_disk_gauge=$(echo "[$root_used_gauge>$root_free_gauge] $root_used_print") + +mem_free=$(expr $memory - $mem_used) +mem_free_percent=`awk "BEGIN { a=($mem_free*100/$memory); printf(\"%0.f\",a)}"` +mem_used_percent=`awk "BEGIN { a=($mem_used*100/$memory); printf(\"%0.f\",a)}"` +mem_used_gauge_val=`awk "BEGIN { a=($mem_used_percent/2); printf(\"%0.f\",a)}"` +mem_free_gauge_val=`awk "BEGIN { a=($mem_free_percent/2); printf(\"%0.f\",a)}"` +mem_used_gauge=$(seq -s= $mem_used_gauge_val|tr -d '[:digit:]') +mem_free_gauge=$(seq -s- $mem_free_gauge_val|tr -d '[:digit:]') +mem_gauge=$(echo "[$mem_used_gauge>$mem_free_gauge] $memory_usage") + +asterisk_version=`/usr/sbin/asterisk -V 2>/dev/null| awk '{print $1" "$2}'` +asterisk_calls=`asterisk -rx "core show channels" 2>/dev/null | grep "active calls" | awk '{print $1}'` + +printf "\033[1;35mSystem load: \033[1;32m %-43s \033[1;35mUptime: \033[1;32m%s\n" "$load" "$time" +if [ -z "$asterisk_version" ]; then +echo -e "\033[1;35mAsterisk: \033[33;5mOFFLINE\033[0m" +else +printf "\033[1;35mAsterisk: \033[1;32m %-37s \033[1;35mActive Calls: \033[1;32m %s\n" "$asterisk_version" "$asterisk_calls" +fi +printf "\033[1;35mMemory: \033[1;32m %s %s/%sM\n" "$mem_gauge" "$mem_used" "$memory" +printf "\033[1;35mUsage on /: \033[1;32m %s %s/%s\n" "$root_disk_gauge" "$root_usedgb" "$root_total" +printf "\033[1;35mSwap usage: \033[1;32m %s\n" "$swap_usage" +printf "\033[1;35mSSH logins: \033[1;32m %d open sessions\n" "$users" +printf "\033[1;35mProcesses: \033[1;32m %d total, %d yours\n" "$processes_total" "$processes_user" +printf "\e[m\n";