install.sh
Rama dev · réplica de lectura del repositorio original.
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
CONTAINER_PROJECT_NAME=billionmail
PGSQL_CONTAINER_NAME="${CONTAINER_PROJECT_NAME}-pgsql-billionmail-1"
DOVECOT_CONTAINER_NAME="${CONTAINER_PROJECT_NAME}-dovecot-billionmail-1"
POSTFIX_CONTAINER_NAME="${CONTAINER_PROJECT_NAME}-postfix-billionmail-1"
RSPAMD_CONTAINER_NAME="${CONTAINER_PROJECT_NAME}-rspamd-billionmail-1"
create_time=$(date +%s)
DBNAME=billionmail
DBUSER=billionmail
SMTP_PORT=25
SMTPS_PORT=465
SUBMISSION_PORT=587
IMAP_PORT=143
IMAPS_PORT=993
POP_PORT=110
POPS_PORT=995
REDIS_PORT=127.0.0.1:26379
SQL_PORT=127.0.0.1:25432
HTTP_PORT=80
HTTPS_PORT=443
SafePath=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 8)
REDISPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 32)
ADMIN_USERNAME=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 8)
ADMIN_PASSWORD=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 8)
time=$(date +%Y_%m_%d_%H_%M_%S)
PWD_d=`pwd`
download_Url=https://node.aapanel.com
mirror=''
Default_Download_Url=""
CPU_architecture=$(uname -m)
# List of supported architectures
SUPPORTED_ARCHS=("x86_64" "aarch64")
# Check whether the current architecture is supported
if [[ ! " ${SUPPORTED_ARCHS[@]} " =~ " ${CPU_architecture} " ]]; then
echo -e "\033[31mSorry, not support the ${CPU_architecture} architecture for install. \nPlease use the x86_64, aarch64 server architecture. \033[0m"
exit 1
fi
is64bit=$(getconf LONG_BIT)
if [ "${is64bit}" != '64' ];then
echo -e "\033[31m Sorry, BillionMail does not support 32-bit systems \033[0m"
exit 1
fi
if [ $(whoami) != "root" ];then
echo -e "Non-root install, please try the following solutions: \n 1.Please switch to root user install \n 2.Try executing the following install commands: \n sudo bash $0 $@"
exit 1
fi
while [ ${#} -gt 0 ]; do
case $1 in
-h|--help)
echo "Usage: [options]"
echo "Options:"
echo " -d, --domain Set Mail Server domain. eg: example.com"
echo " -t, --TZ Set Time Zone. eg: CST"
echo " Time Zone See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones for a list of timezones"
echo " Use a column named "TZ identifier" + note the column named "Notes""
echo "eg: bash install.sh --domain example.com --TZ CST"
exit 0
;;
-d|--domain)
BILLIONMAIL_HOSTNAME=$2
shift 1
;;
-t|--TZ)
BILLIONMAIL_TIME_ZONE=$2
shift 1
;;
esac
shift 1
done
if [ -f "billionmail.conf" ]; then
read -r -p "Check that the configuration file exists, will you continue to overwrite the file?? [y/N] " gogo
case $gogo in
[Yy][eE][sS]|[Yy])
if [ ! -d "./backup/" ]; then
mkdir ./backup
fi
mv billionmail.conf ./backup/billionmail.conf_${time}
echo "Backup: billionmail.conf --> ./backup/billionmail.conf_${time}"
if [ -f ".env" ]; then
mv .env env_${time}
echo "Backup: .env --> ./backup/env_${time}"
fi
;;
*)
exit 1
;;
esac
fi
# while [ -z "${BILLIONMAIL_HOSTNAME}" ]; do
# echo "Press Enter to confirm the detected value '[value]', or enter a custom value."
# echo -e ""
# echo -e "Mail Server hostname (FQDN), \e[0;33mAs: example.com\e[0m"
# echo -e ""
# read -p "Please enter the Mail Server hostname (FQDN: e.g. example.com): " -e BILLIONMAIL_HOSTNAME
# #if [[ ! "${BILLIONMAIL_HOSTNAME}" =~ ^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9](\.[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])*$ ]]; then
# if [[ ! "${BILLIONMAIL_HOSTNAME}" =~ ^([a-zA-Z0-9]([a-zA-Z0-9-]{0,62}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$ ]]; then
# echo -e "\e[31m(${BILLIONMAIL_HOSTNAME}) is not a FQDN!\e[0m"
# echo "Please change it to a FQDN"
# exit 1
# elif [[ "${BILLIONMAIL_HOSTNAME: -1}" == "." ]]; then
# echo "(${BILLIONMAIL_HOSTNAME}) is ending with a dot. This is not a valid FQDN!"
# exit 1
# fi
# done
if [ -z "${BILLIONMAIL_HOSTNAME}" ]; then
BILLIONMAIL_HOSTNAME="example.com"
fi
# Count number of dots in the domain
DOT_COUNT=$(echo "${BILLIONMAIL_HOSTNAME}" | tr -cd '.' | wc -c)
# If only one dot, prepend "mail."
if [ "${DOT_COUNT}" -eq 1 ]; then
ADD_MAIL_BILLIONMAIL_HOSTNAME="mail.${BILLIONMAIL_HOSTNAME}"
echo "Postfix myhostname configuration use: ${ADD_MAIL_BILLIONMAIL_HOSTNAME}"
fi
# Ensure ADD_MAIL_BILLIONMAIL_HOSTNAME is always set (fallback to original if empty)
if [ -z "${ADD_MAIL_BILLIONMAIL_HOSTNAME}" ]; then
ADD_MAIL_BILLIONMAIL_HOSTNAME="${BILLIONMAIL_HOSTNAME}"
echo "Postfix myhostname configuration use: ${ADD_MAIL_BILLIONMAIL_HOSTNAME}"
fi
if [ -a /etc/timezone ]; then
SYSTEM_TIME_ZONE=$(cat /etc/timezone)
elif [ -a /etc/localtime ]; then
SYSTEM_TIME_ZONE=$(readlink /etc/localtime|sed -n 's|^.*zoneinfo/||p')
fi
# while [ -z "${BILLIONMAIL_TIME_ZONE}" ]; do
# echo -e ""
# echo -e "See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones for a list of timezones"
# echo -e "Use a column named "TZ identifier" + note the column named "Notes""
# echo -e "Please enter your time zone"
# echo -e ""
# if [ -z "${SYSTEM_TIME_ZONE}" ]; then
# read -p "Timezone: " -e BILLIONMAIL_TIME_ZONE
# else
# read -p "Timezone [${SYSTEM_TIME_ZONE}]: " -e BILLIONMAIL_TIME_ZONE
# [ -z "${BILLIONMAIL_TIME_ZONE}" ] && BILLIONMAIL_TIME_ZONE=${SYSTEM_TIME_ZONE}
# fi
# done
BILLIONMAIL_TIME_ZONE=${SYSTEM_TIME_ZONE}
if [ -z "${BILLIONMAIL_TIME_ZONE}" ]; then
BILLIONMAIL_TIME_ZONE="America/New_York"
fi
DBPASS_file=DBPASS_file.pl
if [ ! -s "${DBPASS_file}" ]; then
DBPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 32)
echo "${DBPASS}" > ${DBPASS_file}
chmod 600 ${DBPASS_file}
else
DBPASS=$(cat ${DBPASS_file})
fi
GetSysInfo(){
if [ -s "/etc/redhat-release" ];then
SYS_VERSION=$(cat /etc/redhat-release)
elif [ -s "/etc/issue" ]; then
SYS_VERSION=$(cat /etc/issue)
fi
SYS_INFO=$(uname -a)
SYS_BIT=$(getconf LONG_BIT)
MEM_TOTAL=$(free -m|grep Mem|awk '{print $2}')
CPU_INFO=$(getconf _NPROCESSORS_ONLN)
echo -e ${SYS_VERSION}
echo -e Bit:${SYS_BIT} Mem:${MEM_TOTAL}M Core:${CPU_INFO}
echo -e ${SYS_INFO}
echo -e "Please screenshot the above error message and post to the https://github.com/aaPanel/BillionMail/issues for help"
}
Red_Error(){
echo '=================================================';
printf '\033[1;31;40m%b\033[0m\n' "$@";
GetSysInfo
exit 1;
}
PORT(){
if Command_Exists ss ; then
command_port="ss"
elif Command_Exists netstat ; then
command_port="netstat"
else
echo -e "Command does not exist and cannot check whether the port is used"
command_port=""
fi
if [[ ! -z $command_port ]]; then
#check_command=$($command_port -ltnp | grep -E ':(25|465|587|110|143|993|995)\s')
check_command=$($command_port -ltnp | grep -E ":(${SMTP_PORT}|${SMTPS_PORT}|${SUBMISSION_PORT}|${POP_PORT}|${IMAP_PORT}|${IMAPS_PORT}|${POPS_PORT})\s")
if [[ ! -z "$check_command" ]]; then
echo "Checking the port is used:"
echo "$check_command"|grep -v "docker-proxy"
echo -e "\033[1;31m BillionMail need use port ${SMTP_PORT}|${SMTPS_PORT}|${SUBMISSION_PORT}|${POP_PORT}|${IMAP_PORT}|${IMAPS_PORT}|${POPS_PORT}.\033[0m There are already services ports in the system. "
# exit 1
fi
fi
}
Check_Port(){
# if ! Command_Exists docker; then
# PORT
# else
# check=$(docker ps |grep -wE "${POSTFIX_CONTAINER_NAME}|${DOVECOT_CONTAINER_NAME}")
# if [[ -z "$check" ]]; then
# PORT
# fi
# fi
PORT
}
LXC_install_tips (){
# Check if it is in the lxc container
System_Info=$(hostnamectl)
check_container=$(echo "$System_Info" |grep "Chassis"|awk -F":" '{print $2}')
#echo $check_container
if [[ "$check_container" =~ "container" ]];then
echo -e "\033[33mInstalling in an LXC container,May not install properly. \nDocker may not be able to correctly obtain the number of CPU cores, \nwhich may cause the system to crash and cause high load when nginx is running. \nRecommended use VPS or physical machine for install.\033[0m"
echo -e ""
echo -e "\033[33mMust be turned on \"Unprivileged container\", \"nesting\". Otherwise the container cannot be started.\033[0m"
echo "Please confirm whether continue install?"
while [ "$lxc" != 'y' ] && [ "$lxc" != 'n' ]; do
read -p "Please confirm whether in LXC container continue install? (y/n): " lxc;
done
if [ "$lxc" == 'n' ];then
echo "Install canceled."
exit;
fi
LXC_install="yes"
fi
}
Get_Pack_Manager(){
if [ -f "/usr/bin/yum" ] && [ -d "/etc/yum.repos.d" ]; then
PM="yum"
elif [ -f "/usr/bin/apt-get" ] && [ -f "/usr/bin/dpkg" ]; then
PM="apt-get"
fi
}
Install_RPM_Pack(){
yumPacks="wget curl tar gzip git firewalld ca-certificates";
yum install -y ${yumPacks}
for yumPack in ${yumPacks}
do
rpmPack=$(rpm -q ${yumPack})
packCheck=$(echo ${rpmPack}|grep not)
if [ "${packCheck}" ]; then
yum install ${yumPack} -y
fi
done
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
}
Install_Deb_Pack(){
debPacks="wget curl tar gzip git lsb-release ufw ca-certificates";
apt-get update -y
DEBIAN_FRONTEND=noninteractive apt-get install -y $debPacks --allow-downgrades --allow-remove-essential --allow-change-held-packages
for debPack in ${debPacks}
do
packCheck=$(dpkg -l ${debPack})
if [ "$?" -ne "0" ] ;then
apt-get install -y $debPack
fi
done
}
Command_Exists() {
command -v "$@" >/dev/null 2>&1
}
Docker_Download_Url_Check() {
echo -e "Selecting download docker address source, please wait..."
ser_names=(download.docker.com mirrors.ustc.edu.cn/docker-ce mirrors.tuna.tsinghua.edu.cn/docker-ce mirrors.aliyun.com/docker-ce mirror.azure.cn/docker-ce)
tmp_file1=/dev/shm/net_test1.pl
tmp_file2=/dev/shm/net_test2.pl
[ -f "${tmp_file1}" ] && rm -f ${tmp_file1}
[ -f "${tmp_file2}" ] && rm -f ${tmp_file2}
touch $tmp_file1
touch $tmp_file2
for ser_name in ${ser_names[@]};
do
NODE_CHECK=$(curl -k -s 2>/dev/null --connect-timeout 5 -w "%{http_code} %{time_total}" https://${ser_name} -o c${ser_name}.txt|xargs)
rm -rf c${ser_name}.txt
NODE_STATUS=$(echo ${NODE_CHECK}|awk '{print $1}')
TIME_TOTAL=$(echo ${NODE_CHECK}|awk '{print $2 * 1000 - 500 }'|cut -d '.' -f 1)
if [ "${NODE_STATUS}" == "200" ] || [ "${NODE_STATUS}" == "301" ] || [ "${NODE_STATUS}" == "403" ];then
if [ $TIME_TOTAL -lt 100 ]; then
echo "$ser_name" >> $tmp_file1
elif [ $TIME_TOTAL -gt 1500 ] && [ $TIME_TOTAL -lt 2500 ]; then
echo "$ser_name" >> $tmp_file2
fi
fi
done
Docker_NODE_URL=$(cat $tmp_file1|head -n 1|awk '{print $1}')
if [ -z "$Docker_NODE_URL" ];then
Docker_NODE_URL=$(cat $tmp_file2|head -n 1|awk '{print $1}')
fi
rm -f $tmp_file1
rm -f $tmp_file2
mirror="$Docker_NODE_URL"
echo $mirror
case "$mirror" in
mirrors.aliyun.com/docker-ce)
Default_Download_Url="https://mirrors.aliyun.com/docker-ce"
mirror="Aliyun"
;;
mirror.azure.cn/docker-ce)
Default_Download_Url="https://mirror.azure.cn/docker-ce"
mirror="AzureChinaCloud"
;;
mirrors.ustc.edu.cn/docker-ce)
Default_Download_Url="https://mirrors.ustc.edu.cn/docker-ce"
mirror="USTC"
;;
mirrors.tuna.tsinghua.edu.cn/docker-ce)
Default_Download_Url="https://mirrors.tuna.tsinghua.edu.cn/docker-ce"
mirror="tsinghua"
;;
*)
Default_Download_Url="https://download.docker.com"
mirror=""
;;
esac
DEFAULT_REPO_FILE="docker-ce.repo"
if [ -z "$REPO_FILE" ]; then
REPO_FILE="$DEFAULT_REPO_FILE"
fi
}
Get_Distribution() {
lsb_dist=""
lsb_name=""
if [ -r /etc/os-release ]; then
lsb_dist="$(. /etc/os-release && echo "$ID")"
lsb_name="$(. /etc/os-release && echo "$NAME")"
fi
echo "$lsb_dist $lsb_name"
}
Bored_waiting(){
w_time="$wait_time"
msg="$wait_msg"
progress="."
for ((i=0; i<${w_time}; i++))
do
printf "$msg %-10s %d\r" "$progress" "$((i+1))"
sleep 1
if [ "$progress" == ".........." ]; then
progress="."
else
progress+="."
fi
done
printf "$msg %-10s %d\r" ".........." "$w_time"
#echo ""
}
Docker_Start() {
if Command_Exists docker || [ -f /lib/systemd/system/docker.service ]; then
if Command_Exists systemctl; then
# systemctl mask getty@tty1.service
grep docker /etc/group >/dev/null 2>&1 || groupadd docker
systemctl enable docker
systemctl reset-failed docker.service
systemctl start docker.service
if [ "$?" != "0" ];then
systemctl reset-failed docker.service
systemctl restart docker.service
if [ "$?" != "0" ];then
docker_status=$(systemctl status docker.service)
echo "$docker_status"
if [ -f /etc/docker/daemon.json ]; then
echo "/etc/docker/daemon.json file content:"
cat /etc/docker/daemon.json
echo -e "\033[33mRecommended check the above /etc/docker/daemon.json Are the file contents correct?\033[0m"
fi
# Wait for 100 seconds of animation
echo -e "\033[31m start docker service failed, maybe too fast to start\033[0m"
wait_msg="waiting 100 seconds to start docker service"
wait_time="100"
Bored_waiting
systemctl reset-failed docker.service
systemctl restart docker.service
if [ "$?" != "0" ];then
docker_status=$(systemctl status docker.service)
echo "$docker_status"
Red_Error "docker start failed" "Please try again later execute the restart docker command: systemctl restart docker.service (no content returns normal)" "Finally, re-execute install BillionMail"
fi
fi
fi
else
chkconfig --add docker
chkconfig --level 2345 docker on
service docker start
if [ "$?" != "0" ];then
service docker.service status
cat /etc/docker/daemon.json
Red_Error "docker start failed"
fi
fi
else
Red_Error "Docker is not installed"
fi
}
Is_Darwin() {
case "$(uname -s)" in
*darwin*) true ;;
*Darwin*) true ;;
*) false ;;
esac
}
Check_Forked() {
if Command_Exists lsb_release; then
set +e
lsb_release -a -u >/dev/null 2>&1
lsb_release_exit_code=$?
if [ "$lsb_release_exit_code" = "0" ]; then
cat <<-EOF
You're using '$lsb_dist' version '$dist_version'.
EOF
lsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[:space:]')
dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[:space:]')
cat <<-EOF
Upstream release is '$lsb_dist' version '$dist_version'.
EOF
else
if [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; then
if [ "$lsb_dist" = "osmc" ]; then
lsb_dist=raspbian
else
lsb_dist=debian
fi
dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"
case "$dist_version" in
12)
dist_version="bookworm"
;;
11)
dist_version="bullseye"
;;
10)
dist_version="buster"
;;
9)
dist_version="stretch"
;;
8)
dist_version="jessie"
;;
esac
fi
fi
fi
}
Docker_Check(){
# Default value is: 0 Not installed
is_docker="0"
docker_version="docker version"
if Command_Exists $docker_version ; then
is_docker="1"
fi
echo "docker command: $is_docker"
}
create_docker_yum_repo() {
cat <<EOF >/etc/yum.repos.d/docker-ce.repo
[docker-ce-stable]
name=Docker CE Stable - \$basearch
baseurl=https://download.docker.com/linux/centos/\$releasever/\$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
EOF
}
Docker_Install() {
lsb_dist=$(Get_Distribution|awk -F " " '{print $1}')
lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"
case "$lsb_dist" in
ubuntu)
if Command_Exists lsb_release; then
dist_version="$(lsb_release --codename | cut -f2)"
fi
if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then
dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")"
fi
;;
debian | raspbian)
dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"
case "$dist_version" in
12)
dist_version="bookworm"
;;
11)
dist_version="bullseye"
;;
10)
dist_version="buster"
;;
9)
dist_version="stretch"
;;
8)
dist_version="jessie"
;;
esac
;;
centos | rhel | sles | ol | tencentos | alinux | anolis | rocky | euleros | almalinux | opencloudos |openeuler |hce | kylin |uos | kylinsecos |amzn )
if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
fi
;;
*)
if Command_Exists lsb_release; then
dist_version="$(lsb_release --release | cut -f2)"
fi
if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
fi
;;
esac
Check_Forked
case "$lsb_dist" in
ubuntu | debian | raspbian)
docker_gpg="/usr/share/keyrings/docker-archive-keyring.gpg"
apt_repo_file="/etc/apt/sources.list.d/docker.list"
pre_reqs="apt-transport-https ca-certificates curl wget"
if ! command -v gpg >/dev/null; then
pre_reqs="$pre_reqs gnupg"
fi
apt_repo="deb [arch=$(dpkg --print-architecture) signed-by=$docker_gpg] $Default_Download_Url/linux/$lsb_dist $dist_version stable"
(
DEBIAN_FRONTEND=noninteractive apt-get install -y $pre_reqs
if [ -f $docker_gpg ] && [ -f $apt_repo_file ]; then
rm -rf $docker_gpg
rm -rf $apt_repo_file
fi
#curl -fsSL --connect-time 10 --retry 5 $Default_Download_Url/linux/$lsb_dist/gpg | gpg --dearmor --yes -o $docker_gpg
#wget --no-check-certificate -qO - -t 5 -T 20 $Default_Download_Url/linux/$lsb_dist/gpg | gpg --dearmor --yes -o $docker_gpg
wget -qO - -t 5 -T 10 $Default_Download_Url/linux/$lsb_dist/gpg | gpg --dearmor --yes -o $docker_gpg
chmod a+r $docker_gpg
echo "$apt_repo" > $apt_repo_file
apt-get update -y
)
pkg_version=""
#First check whether apt-get is used. It cannot be put into the subshell, that is, () to execute, otherwise it will not exit.
# Check_apt_status
(
pkgs="$pkgs docker-ce${pkg_version%=}"
DEBIAN_FRONTEND=noninteractive apt-get install -y $pkgs docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
)
;;
centos | fedora | rhel | ol | tencentos | alinux | anolis | rocky | almalinux | opencloudos |openeuler |hce |uos |amzn )
pkg_version=""
yum_repo="$Default_Download_Url/linux/$lsb_dist/$REPO_FILE"
if [ "$lsb_dist" == "ol" ] || [ "$lsb_dist" == "tencentos" ] || [ "$lsb_dist" == "alinux" ] || [ "$lsb_dist" == "anolis" ] || [ "$lsb_dist" == "opencloudos" ] || [ "$lsb_dist" == "openeuler" ] || [ "$lsb_dist" == "hce" ] || [ "$lsb_dist" == "uos" ] || [ "$lsb_dist" == "amzn" ] ; then
yum_repo="$Default_Download_Url/linux/centos/$REPO_FILE"
fi
if [ "$lsb_dist" == "rocky" ] || [ "$lsb_dist" == "almalinux" ]; then
yum_repo="$Default_Download_Url/linux/centos/$REPO_FILE"
fi
if [ "$lsb_dist" = "fedora" ]; then
pkg_manager="dnf"
config_manager="dnf config-manager"
enable_channel_flag="--set-enabled"
disable_channel_flag="--set-disabled"
pre_reqs="dnf-plugins-core"
pkg_suffix="fc$dist_version"
else
pkg_manager="yum"
config_manager="yum-config-manager"
enable_channel_flag="--enable"
disable_channel_flag="--disable"
pre_reqs="yum-utils"
pkg_suffix="el"
fi
#wget --no-check-certificate -O /etc/yum.repos.d/docker-ce.repo $yum_repo -t 5 -T 10
wget -O /etc/yum.repos.d/docker-ce.repo $yum_repo -t 5 -T 10
if [ $? -ne "0" ]; then
create_docker_yum_repo
fi
if ! grep -q "docker" /etc/yum.repos.d/docker-ce.repo; then
create_docker_yum_repo
fi
sed -i "s|https://download.docker.com|$Default_Download_Url|g" /etc/yum.repos.d/docker-ce.repo
# cat /etc/yum.repos.d/docker-ce.repo
lsb_name=$(Get_Distribution|awk -F " " '{print $3}')
echo $lsb_name
echo $lsb_dist
#if [ "$lsb_name" = "Stream" ] || [ "$lsb_dist" = "alinux" ] || [ "$lsb_dist" = "anolis" ];then
#if [ "$lsb_name" = "Stream" ] || [ "$lsb_dist" = "anolis" ];then
if [ "$lsb_name" = "Stream" ]; then
conflicting="--allowerasing"
fi
if [ "$lsb_name" = "rocky" ] || [ "$lsb_dist" = "euleros" ] || [ "$lsb_dist" = "almalinux" ];then
conflicting="--allowerasing"
fi
if [ "$lsb_dist" = "openeuler" ];then
openeuler_v=$(cat /etc/os-release |grep "VERSION=")
if [[ $openeuler_v =~ "23.0" ]]; then
sed -i "s|\$releasever|8|g" /etc/yum.repos.d/docker-ce.repo
$pkg_manager makecache
elif [[ $openeuler_v =~ "22.0" ]]; then
sed -i "s|\$releasever|7|g" /etc/yum.repos.d/docker-ce.repo
$pkg_manager makecache
else
if [ -f "/etc/os-release" ]; then
cat /etc/os-release
fi
echo "ERROR: not support this system yum auto install docker"
fi
fi
# Amazon Linux
if [ "$lsb_dist" = "amzn" ];then
#amzn_v=$(. /etc/os-release && echo "$VERSION_ID")
sed -i "s|\$releasever|8|g" /etc/yum.repos.d/docker-ce.repo
$pkg_manager makecache
fi
# Huawei Cloud EulerOS
if [ "$lsb_dist" = "hce" ];then
hce_v=$(. /etc/os-release && echo "$VERSION_ID")
if [[ $hce_v =~ "2.0" ]]; then
sed -i "s|\$releasever|8|g" /etc/yum.repos.d/docker-ce.repo
$pkg_manager makecache
else
if [ -f "/etc/os-release" ]; then
cat /etc/os-release
fi
echo "ERROR: not support this system yum auto install docker"
fi
fi
# OpenCloudOS 9.0
if [ "$lsb_dist" = "opencloudos" ];then
pkg_manager="yum"
opencloudos_v=$(. /etc/os-release && echo "$VERSION_ID")
if [[ $opencloudos_v =~ "9.0" ]]; then
sed -i "s|\$releasever|8|g" /etc/yum.repos.d/docker-ce.repo
# centos 8
download_container_selinux="$download_Url/cloudwaf/package/container-selinux-2.224.0-1.module_el8+712+4cd1bd69.noarch.rpm"
wget --no-check-certificate -O container-selinux-2.224.0-1.module_el8+712+4cd1bd69.noarch.rpm ${download_container_selinux} -t 5 -T 10
install_docker="1"
$pkg_manager makecache
$pkg_manager install -y docker-ce$pkg_version docker-ce-cli docker-buildx-plugin docker-compose-plugin container-selinux-2.224.0-1.module_el8+712+4cd1bd69.noarch.rpm
rm -f container-selinux-2.224.0-1.module_el8+712+4cd1bd69.noarch.rpm
fi
fi
if [ "$lsb_dist" = "uos" ];then
pkg_manager="yum"
uos_v=$(. /etc/os-release && echo "$VERSION_ID")
uos_NAME=$(. /etc/os-release && echo "$NAME")
if [[ $uos_v =~ "20" ]] && [[ "$uos_NAME" == "UOS Server Euler" ]]; then
# UOS Server Euler 20 Install using the default source
if [ -f /etc/yum.repos.d/docker-ce.repo ]; then
rm -f /etc/yum.repos.d/docker-ce.repo
fi
# Define to install docker using other commands
install_docker="1"
$pkg_manager makecache
$pkg_manager install -y docker* --skip-broken
elif [[ $uos_v =~ "20" ]]; then
sed -i "s|\$releasever|8|g" /etc/yum.repos.d/docker-ce.repo
# Define to install docker using other commands
install_docker="1"
$pkg_manager makecache
$pkg_manager install -y docker-ce$pkg_version docker-ce-cli docker-buildx-plugin docker-compose-plugin
else
if [ -f "/etc/os-release" ]; then
cat /etc/os-release
fi
echo "ERROR: not support this system yum auto install docker"
fi
fi
if [[ "$install_docker" != "1" ]]; then
# 1 When docker is installed using other commands
$pkg_manager makecache
$pkg_manager install -y docker-ce$pkg_version docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin $conflicting
fi
;;
*)
if [ -z "$lsb_dist" ]; then
if Is_Darwin; then
echo
echo "ERROR: Unsupported operating system 'macOS'"
echo
exit 1
fi
fi
echo
Red_Error "ERROR: not support '$lsb_dist' this system auto install docker"
;;
esac
if ! Command_Exists docker && [ ! -f /usr/bin/docker ]; then
echo "Trying to install docker using binary package method."
Binary_package_install_docker
fi
if ! Command_Exists docker ; then
Red_Error "docker command not exists,install docker failed,please check the reason."
fi
}
Binary_package_install_docker(){
# Install docker in binary package
DOCKER_VERSION="27.3.1"
SYS_TYPE=$(uname -m)
echo "Create docker group"
groupadd docker
echo "Downloading docker ${DOCKER_VERSION}.tgz file, please wait..."
wget --no-check-certificate -O docker-${DOCKER_VERSION}.tgz ${download_Url}/src/docker-${DOCKER_VERSION}-${SYS_TYPE}.tgz -t 5 -T 10
tmp_size=$(du -b docker-${DOCKER_VERSION}.tgz |awk '{print $1}')
if [ $tmp_size -lt 60831072 ];then
ls -l docker-${DOCKER_VERSION}.tgz
Red_Error "ERROR: Failed to download, please try install again!"
fi
echo "Unzip the docker ${DOCKER_VERSION}.tgz file, please wait..."
tar -xvf docker-${DOCKER_VERSION}.tgz
\cp docker/* /usr/bin/
# rm -rf docker
rm -f docker-${DOCKER_VERSION}.tgz
wget --no-check-certificate -O /usr/bin/docker-compose ${download_Url}/src/docker-compose-linux-${SYS_TYPE} -t 5 -T 20
chmod +x /usr/bin/docker-compose
wget --no-check-certificate -O /usr/lib/systemd/system/docker.service ${download_Url}/init/systemd/docker.service -t 5 -T 20
wget --no-check-certificate -O /usr/lib/systemd/system/docker.socket ${download_Url}/init/systemd/docker.socket -t 5 -T 20
wget --no-check-certificate -O /usr/lib/systemd/system/containerd.service ${download_Url}/init/systemd/containerd.service -t 5 -T 20
systemctl enable docker.service
systemctl enable docker.socket
systemctl enable containerd.service
systemctl start containerd.service
systemctl start docker.socket
systemctl start docker.service
}
Docker_Compose_Check(){
is_docker_compose="0"
if Command_Exists docker-compose; then
is_docker_compose="1"
DOCKER_COMPOSE="docker-compose"
else
if Command_Exists docker; then
Docker_compose="docker compose version"
if $Docker_compose; then
is_docker_compose="1"
DOCKER_COMPOSE="docker compose"
fi
else
is_docker_compose="0"
fi
fi
}
Docker_Compose_Install() {
if [ $is_docker_compose == "0" ]; then
Docker_Install
fi
Compose_Download_Url="$download_Url/install/src/docker-compose-$(uname -s)-$(uname -m)"
Compose_Path="/usr/local/bin/docker-compose"
New_Compose_Path="/usr/libexec/docker/cli-plugins/docker-compose"
Compose_lin="/usr/bin/docker-compose"
if [ ! -f $New_Compose_Path ]; then
wget --no-check-certificate -t 5 -T 20 -O $New_Compose_Path $Compose_Download_Url
chmod +x $New_Compose_Path
rm -rf $Compose_lin
fi
if [ ! -f ${Compose_lin} ];then
ln -s $New_Compose_Path $Compose_lin
fi
}
Set_Firewall() {
sshPort=$(cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}')
if [ "${PM}" = "apt-get" ]; then
if [ ! -f "/usr/bin/ufw" ] && [ ! -f "/bin/ufw" ] && ! Command_Exists "ufw"; then
apt-get install -y ufw
fi
if [ -f "/usr/sbin/ufw" ]; then
ufw allow 22/tcp >/dev/null 2>&1
ufw allow 80/tcp >/dev/null 2>&1
ufw allow 443/tcp >/dev/null 2>&1
ufw allow ${SMTP_PORT}/tcp >/dev/null 2>&1
ufw allow ${SMTPS_PORT}/tcp >/dev/null 2>&1
ufw allow ${SUBMISSION_PORT}/tcp >/dev/null 2>&1
ufw allow ${IMAP_PORT}/tcp >/dev/null 2>&1
ufw allow ${IMAPS_PORT}/tcp >/dev/null 2>&1
ufw allow ${POP_PORT}/tcp >/dev/null 2>&1
ufw allow ${POPS_PORT}/tcp >/dev/null 2>&1
ufw allow ${HTTP_PORT}/tcp >/dev/null 2>&1
ufw allow ${HTTPS_PORT}/tcp >/dev/null 2>&1
ufw allow ${sshPort}/tcp >/dev/null 2>&1
# ufw_status=$(ufw status)
echo y | ufw enable >/dev/null 2>&1
ufw default deny >/dev/null 2>&1
ufw reload
fi
else
if [ -f "/etc/init.d/iptables" ]; then
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${SMTP_PORT} -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${SMTPS_PORT} -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${SUBMISSION_PORT} -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${IMAP_PORT} -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${IMAPS_PORT} -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${POP_PORT} -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${POPS_PORT} -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${HTTP_PORT} -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${HTTPS_PORT} -j ACCEPT
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${sshPort} -j ACCEPT
iptables -A INPUT -p icmp --icmp-type any -j ACCEPT
iptables -A INPUT -s localhost -d localhost -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -P INPUT DROP
service iptables save
sed -i "s#IPTABLES_MODULES=\"\"#IPTABLES_MODULES=\"ip_conntrack_netbios_ns ip_conntrack_ftp ip_nat_ftp\"#" /etc/sysconfig/iptables-config
iptables_status=$(service iptables status | grep 'not running')
if [ "${iptables_status}" == '' ]; then
service iptables restart
fi
else
AliyunCheck=$(cat /etc/redhat-release | grep "Aliyun Linux")
[ "${AliyunCheck}" ] && return
if [ ! -f "/usr/bin/firewall-cmd" ] && [ ! -f "/bin/firewall-cmd" ] && ! Command_Exists "firewall-cmd"; then
yum install firewalld -y
fi
[ "${Centos8Check}" ] && yum reinstall python3-six -y
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --set-default-zone=public >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=22/tcp >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=80/tcp >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=443/tcp > /dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=${SMTP_PORT}/tcp >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=${SMTPS_PORT}/tcp >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=${SUBMISSION_PORT}/tcp >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=${IMAP_PORT}/tcp >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=${IMAPS_PORT}/tcp >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=${POP_PORT}/tcp >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=${POPS_PORT}/tcp >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=${HTTP_PORT}/tcp >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=${HTTPS_PORT}/tcp >/dev/null 2>&1
firewall-cmd --permanent --zone=public --add-port=${sshPort}/tcp >/dev/null 2>&1
firewall-cmd --reload
fi
fi
}
Check_apt_status(){
MAX_RETRIES=30
retries=0
while [ $retries -lt $MAX_RETRIES ]; do
output=$(ps aux| grep -E '(apt|apt-get)\s' 2>&1)
check_output=$(echo "$output" | grep -E '(apt|apt-get)\s')
# If check_output is empty, terminate the loop
if [ -z "$check_output" ]; then
break
fi
retries=$((retries + 1))
echo "apt-get is in use, it will automatically exit after ${retries}/${MAX_RETRIES} times, try again after 10 seconds..."
echo "$check_output"
wait_msg="Please wait "
wait_time="10"
Bored_waiting
done
if [ $retries -ge $MAX_RETRIES ]; then
echo "$output" > /tmp/waf_install_log.txt
Red_Error "ERROR: apt-get command exceeds the maximum wait times: ${MAX_RETRIES}. Do not use the apt/apt-get command or install software during installation, please try to reinstall!"
fi
}
Check_Connect_PgSql(){
MAX_RETRIES=10
retries=0
while [ $retries -lt $MAX_RETRIES ]; do
output=$(docker exec -i -e PGPASSWORD=${DBPASS} ${PGSQL_CONTAINER_NAME} psql -U ${DBUSER} -d ${DBNAME} -c "SELECT 1;" 2>&1)
if [ $? -eq 0 ]; then
PgSql_run="1"
break
# When equal to 0, exit the loop
fi
retries=$((retries + 1))
echo "PgSql failed to connect, try again after 10 seconds, ${retries}/${MAX_RETRIES}..."
if [[ "${retries}" == "1" ]] || [[ "${retries}" == "${MAX_RETRIES}" ]]; then
# Only the first and last print information
echo "$connect_PgSql"
fi
wait_msg="Please wait.."
wait_time="10"
Bored_waiting
done
if [ $retries -ge $MAX_RETRIES ]; then
Red_Error "ERROR: The maximum number of retrys exceeded, and the connection to PgSql cannot be connected. Please try reinstalling!"
fi
}
Domain_DKIM_record(){
## DKIM key generation
docker exec -i -e BILLIONMAIL_HOSTNAME=${BILLIONMAIL_HOSTNAME} ${RSPAMD_CONTAINER_NAME} bash -c 'cat << "EOF" > /tmp/1.sh
#!/bin/bash
if [ ! -d "/var/lib/rspamd/dkim/${BILLIONMAIL_HOSTNAME}/" ]; then
mkdir -p "/var/lib/rspamd/dkim/${BILLIONMAIL_HOSTNAME}/"
fi
if [ -f "/var/lib/rspamd/dkim/${BILLIONMAIL_HOSTNAME}/default.private" ] && [ -f "/var/lib/rspamd/dkim/${BILLIONMAIL_HOSTNAME}/default.pub" ]; then
#echo "DKIM key already exists, skipping generation."
exit 0
fi
rspamadm dkim_keygen -s 'default' -b 1024 -d {domain} -k "/var/lib/rspamd/dkim/${BILLIONMAIL_HOSTNAME}/default.private" > "/var/lib/rspamd/dkim/${BILLIONMAIL_HOSTNAME}/default.pub"
if [ $? -eq 0 ]; then
# Define the root directory for private keys
DKIM_KEYS_DIR="/var/lib/rspamd/dkim"
# Configuration file path
CONFIG_FILE="/etc/rspamd/local.d/dkim_signing.conf"
# Check if the configuration file exists, if not, create it
if [ ! -f "${CONFIG_FILE}" ]; then
touch "${CONFIG_FILE}"
echo "${CONFIG_FILE}"
echo "domain {" > "${CONFIG_FILE}"
echo "#BT_DOMAIN_DKIM_BEGIN" >> "${CONFIG_FILE}"
echo "#BT_DOMAIN_DKIM_END" >> "${CONFIG_FILE}"
echo "}" >> "${CONFIG_FILE}"
fi
# Scan the DKIM_KEYS_DIR directory to get all domains
DOMAINS=()
for DOMAIN_DIR in "${DKIM_KEYS_DIR}"/*; do
if [ -d "${DOMAIN_DIR}" ]; then
DOMAIN_NAME=$(basename "${DOMAIN_DIR}")
PRIVATE_KEY_PATH="${DOMAIN_DIR}/default.private"
if [ -f "${PRIVATE_KEY_PATH}" ]; then
DOMAINS+=("${DOMAIN_NAME}:${PRIVATE_KEY_PATH}")
else
echo "Warning: Private key file ${PRIVATE_KEY_PATH} for domain ${DOMAIN_NAME} does not exist, skipping configuration."
fi
fi
done
# Add domain configurations
for DOMAIN in "${DOMAINS[@]}"; do
DOMAIN_NAME=$(echo "${DOMAIN}" | cut -d':' -f1)
PRIVATE_KEY_PATH=$(echo "${DOMAIN}" | cut -d':' -f2)
# Check if the domain already exists
if grep -wq "${DOMAIN_NAME}" "${CONFIG_FILE}"; then
# echo "Domain ${DOMAIN_NAME} already exists, skipping configuration."
continue
fi
# Insert domain configuration between #BT_DOMAIN_DKIM_BEGIN and #BT_DOMAIN_DKIM_END
sed -i "/^#BT_DOMAIN_DKIM_BEGIN$/a #${DOMAIN_NAME}_DKIM_BEGIN\n ${DOMAIN_NAME} {\n selectors [\n {\n path: \"${PRIVATE_KEY_PATH}\";\n selector: \"default\"\n }\n ]\n }\n#${DOMAIN_NAME}_DKIM_END" "${CONFIG_FILE}"
# echo "Domain ${DOMAIN_NAME} has been successfully added to the configuration file."
done
# echo "DKIM configuration update completed."
else
echo -e "DKIM key generation failed!"
exit 1
fi
chmod 755 -R "/var/lib/rspamd/dkim/${BILLIONMAIL_HOSTNAME}/"
EOF'
docker exec -i -e BILLIONMAIL_HOSTNAME=${BILLIONMAIL_HOSTNAME} ${RSPAMD_CONTAINER_NAME} bash /tmp/1.sh && rm -f /tmp/1.sh
DKIM_RECORD=$(docker exec ${RSPAMD_CONTAINER_NAME} cat "/var/lib/rspamd/dkim/${BILLIONMAIL_HOSTNAME}/default.pub")
# echo "DKIM RECORD: ${DKIM_RECORD}"
}
Domain_record() {
IPV4_ADDRESS=$(curl -sS -4 --connect-timeout 10 -m 20 https://ifconfig.me)
if [ -z "${IPV4_ADDRESS}" ]; then
IPV4_ADDRESS=$(curl -sSk --connect-timeout 10 -m 20 https://www.aapanel.com/api/common/getClientIP)
fi
ipv4_regex="^([0-9]{1,3}\.){3}[0-9]{1,3}$"
if [[ ${IPV4_ADDRESS} =~ ${ipv4_regex} ]]; then
echo "${IPV4_ADDRESS}" >/dev/null 2>&1
elif [ -z "${IPV4_ADDRESS}" ]; then
IPV4_ADDRESS="YOUR_SERVER_IPV4_ADDRESS"
fi
echo -e ""
echo -e "\e[31mPlease add the following record to your domain name\e[0m"
echo -e "==========================================================="
echo -e " Type | Host record | IPv4 address |"
echo -e " \e[1;33mA\e[0m | \e[1;33mmail.${BILLIONMAIL_HOSTNAME}\e[0m | \e[1;33m${IPV4_ADDRESS}\e[0m |"
echo -e "==========================================================="
echo -e " Type | Host record | MX priority | Record value "
echo -e " \e[1;33mMX\e[0m | \e[1;33m@\e[0m | \e[1;33m10\e[0m | \e[1;33mmail.${BILLIONMAIL_HOSTNAME}\e[0m "
echo -e "==========================================================="
if [ "${IPV4_ADDRESS}" ]; then
echo -e " Type | Host record | Record value |"
echo -e " \e[1;33mTXT\e[0m | \e[1;33m@\e[0m | \e[1;33mv=spf1 +a +mx +ip4:${IPV4_ADDRESS} -all\e[0m |"
else
echo -e " Type | Host record | Record value |"
echo -e " \e[1;33mTXT\e[0m | \e[1;33m@\e[0m | \e[1;33mv=spf1 +a +mx -all\e[0m |"
fi
echo -e "==========================================================="
echo -e " Type | Host record | Record value |"
echo -e " \e[1;33mTXT\e[0m | \e[1;33m_dmarc\e[0m | \e[1;33mv=DMARC1;p=quarantine;rua=mailto:admin@${BILLIONMAIL_HOSTNAME}\e[0m |"
echo -e "==========================================================="
Domain_DKIM_record
if [ "${DKIM_RECORD}" ]; then
DKIM_RECORD=$(echo "${DKIM_RECORD}" | awk -F'"' '{print $2 $4}' | tr -d '[:space:]')
#echo "DKIM RECORD: ${DKIM_RECORD}"
echo -e " Type | Host record | Record value |"
echo -e " \e[1;33mTXT\e[0m | \e[1;33mdefault._domainkey\e[0m | \e[1;33m${DKIM_RECORD}\e[0m |<-- Start from \"v=DKIM1\" end, A single line."
echo -e "==========================================================="
else
echo -e "${BILLIONMAIL_HOSTNAME} DKIM key generation failed!"
fi
}
Init_Billionmail()
{
# SQL file path
SQL_FILE="./init.sql"
if [ ! -f "${SQL_FILE}" ]; then
Red_Error "SQL The file does not exist: ${SQL_FILE}"
fi
if docker ps --format '{{.Names}}' | grep -q "^${PGSQL_CONTAINER_NAME}$"; then
# Test whether it is possible to connect
Check_Connect_PgSql
echo "Importing database..."
docker exec -i -e PGPASSWORD=${DBPASS} ${PGSQL_CONTAINER_NAME} psql -U ${DBUSER} -d ${DBNAME} < ${SQL_FILE}
if [ $? -eq 0 ]; then
echo "Database import was successful!"
else
Red_Error "Database import failed!"
fi
echo "Creating domain..."
BILLIONMAIL_HOSTNAME=$(echo "${BILLIONMAIL_HOSTNAME}" | tr '[:upper:]' '[:lower:]')
Check_domain=$(docker exec -i -e PGPASSWORD=${DBPASS} ${PGSQL_CONTAINER_NAME} psql -U ${DBUSER} -d ${DBNAME} -c "SELECT * FROM domain WHERE domain = '${BILLIONMAIL_HOSTNAME}';" | grep -w "^ ${BILLIONMAIL_HOSTNAME}")
if [ -z "${Check_domain}" ]; then
# Create a domain
docker exec -i -e PGPASSWORD=${DBPASS} ${PGSQL_CONTAINER_NAME} psql -U ${DBUSER} -d ${DBNAME} -c "INSERT INTO domain (domain, a_record, mailboxes, mailbox_quota, quota, rate_limit, create_time, active)
VALUES ('${BILLIONMAIL_HOSTNAME}', 'mail.${BILLIONMAIL_HOSTNAME}', 500, 5368709120, 5368709120, 12, ${create_time}, 1);"
if [ $? -eq 0 ]; then
echo "Domain creation was successful!"
Domain_DKIM_record
else
Red_Error "Domain creation failed!"
fi
else
echo ""${Check_domain}" Domain already exists!"
fi
# Create a mailbox
if [ -z "${mailbox}" ]; then
mailbox=$(LC_ALL=C </dev/urandom tr -dc a-z0-9 2> /dev/null | head -c 6)
echo "Generate mailbox: ${mailbox}"
else
mailbox=$(echo "${mailbox}" | tr '[:upper:]' '[:lower:]')
fi
Generate_mailbox_password=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 16)
#echo "Generate_mailbox_password: ${Generate_mailbox_password}"
Encrypt_mailbox_password=$(docker exec -i ${DOVECOT_CONTAINER_NAME} doveadm pw -s MD5-CRYPT -p "${Generate_mailbox_password}" | sed 's/{MD5-CRYPT}//')
if [ $? -eq 0 ]; then
echo "Generate_mailbox_password: ${Generate_mailbox_password}"
echo "mailbox_password: ${Encrypt_mailbox_password}"
else
# Generate the default password after failure: BILLIONMAIL
Generate_mailbox_password="BILLIONMAIL"
Encrypt_mailbox_password='$1$ELBUCcYE$TbdGKBvLkFbjQguDbi3s01'
echo "Generate_mailbox_password--default: ${Generate_mailbox_password}"
Default_password=1
fi
if [ "${Default_password}" != 1 ]; then
# password_encode
# Base64 encoding of strings
b64_data=$(echo -n "${Generate_mailbox_password}" | base64)
# Convert characters to hexadecimal
password_encode=$(echo -n "${b64_data}" | while IFS= read -r -n1 char; do printf "%02x" "'$char"; done)
echo "password_encode: ${password_encode}"
if [ -z ${password_encode} ]; then
b64_data=$(echo -n "${Generate_mailbox_password}" | base64)
password_encode=$(echo -n "${b64_data}" | od -A n -t x1 | tr -d ' \n')
echo "password_encode: ${password_encode}"
fi
else
password_encode="516b6c4d54456c50546b31425355773d"
fi
Check_mailbox=$(docker exec -i -e PGPASSWORD=${DBPASS} ${PGSQL_CONTAINER_NAME} psql -U ${DBUSER} -d ${DBNAME} -c "SELECT * FROM mailbox WHERE username = '${mailbox}@${BILLIONMAIL_HOSTNAME}';" | grep -w "${mailbox}@${BILLIONMAIL_HOSTNAME}")
if [ -z "${Check_mailbox}" ]; then
INSERT_mailbox='INSERT INTO mailbox (username, password, password_encode, full_name, is_admin, maildir, quota, local_part, domain, create_time, update_time, active)
VALUES (
'\'${mailbox}@${BILLIONMAIL_HOSTNAME}\'',
'\'${Encrypt_mailbox_password}\'',
'\'${password_encode}\'',
'\'${mailbox}\'',
0,
'\'${mailbox}@${BILLIONMAIL_HOSTNAME}/\'',
5368709120,
'\'${mailbox}\'',
'\'${BILLIONMAIL_HOSTNAME}\'',
'${create_time}',
'${create_time}',
1
);'
# echo "$INSERT_mailbox"
docker exec -i -e PGPASSWORD=${DBPASS} ${PGSQL_CONTAINER_NAME} psql -U ${DBUSER} -d ${DBNAME} -c "$INSERT_mailbox"
if [ $? -eq 0 ]; then
echo "Mailbox creation was successful!"
else
Red_Error "Mailbox creation failed!"
fi
#docker exec -i -e PGPASSWORD=${DBPASS} ${PGSQL_CONTAINER_NAME} psql -U ${DBUSER} -d ${DBNAME} -c "SELECT * FROM mailbox WHERE username = '${mailbox}@${BILLIONMAIL_HOSTNAME}';"
else
echo ""${Check_mailbox}" Mailbox already exists!"
fi
else
Red_Error "PgSql container does not exist!"
fi
}
Billionmail(){
Check_Port=$(ss -tlnp | grep -E ":(${HTTP_PORT})\b")
if [ ! -z "${Check_Port}" ]; then
HTTP_PORT=5678
Check_Port=$(ss -tlnp | grep -E ":(${HTTP_PORT})\b")
fi
if [ ! -z "${Check_Port}" ]; then
echo -e "${HTTP_PORT} Already used, random ports are being used"
while true; do
HTTP_PORT=$((RANDOM % 55535 + 10000))
if ! ss -tln | grep -q ":${HTTP_PORT} "; then
echo "${HTTP_PORT}"
break
fi
done
fi
Check_Port22=$(ss -tlnp | grep -E ":(${HTTPS_PORT})\b")
if [ ! -z "${Check_Port22}" ]; then
HTTPS_PORT=5679
Check_Port22=$(ss -tlnp | grep -E ":(${HTTPS_PORT})\b")
fi
if [ ! -z "${Check_Port22}" ]; then
echo -e "${HTTPS_PORT} Already used, random ports are being used"
while true; do
HTTPS_PORT=$((RANDOM % 55535 + 10000))
if ! ss -tln | grep -q ":${HTTPS_PORT} "; then
echo "${HTTPS_PORT}"
break
fi
done
fi
cat << EOF > billionmail.conf
# Default BillionMail Username password
ADMIN_USERNAME=${ADMIN_USERNAME}
ADMIN_PASSWORD=${ADMIN_PASSWORD}
# Manage Safe entrance
SafePath=${SafePath}
# BILLIONMAIL_HOSTNAME configuration, Postfix myhostname configuration
BILLIONMAIL_HOSTNAME=${ADD_MAIL_BILLIONMAIL_HOSTNAME}
# pgsql NAME and USER and PASSWORD configuration
DBNAME=${DBNAME}
DBUSER=${DBUSER}
DBPASS=${DBPASS}
# REDIS PASSWORD configuration
REDISPASS=${REDISPASS}
## MAIL Ports
SMTP_PORT=${SMTP_PORT}
SMTPS_PORT=${SMTPS_PORT}
SUBMISSION_PORT=${SUBMISSION_PORT}
IMAP_PORT=${IMAP_PORT}
IMAPS_PORT=${IMAPS_PORT}
POP_PORT=${POP_PORT}
POPS_PORT=${POPS_PORT}
REDIS_PORT=${REDIS_PORT}
SQL_PORT=${SQL_PORT}
## Manage Ports
HTTP_PORT=${HTTP_PORT}
HTTPS_PORT=${HTTPS_PORT}
# Web deployment base path. Keep empty for root deployment.
# Set to /billionmail when embedding behind aaPanel path proxy.
WEB_BASE_PATH=
# Shared secret used by aaPanel to request trusted BillionMail SSO tokens.
# Keep empty to disable aaPanel SSO.
AAPANEL_SSO_SECRET=
# You can use this script to set the time zone for your container.
# See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones for a list of timezones"
# echo -e "Use a column named "TZ identifier" + note the column named "Notes""
TZ=${BILLIONMAIL_TIME_ZONE}
# Default containers IPV4 intranet segment
IPV4_NETWORK=172.66.1
# Enable fail2ban Access restrictions, specify that the IP exceeds the access limit
FAIL2BAN_INIT=y
# Number of days to keep log backup
RETENTION_DAYS=7
EOF
\cp -rf billionmail.conf .env
if [ ! -f ".env" ]; then
echo -e "Error: Failed to create .env file"
exit 1
fi
SSL_path=ssl-self-signed
if [ ! -d "ssl-self-signed" ]; then
mkdir ssl-self-signed
fi
openssl genrsa -out ${SSL_path}/key.pem 2048
openssl req -x509 -new -nodes -key ${SSL_path}/key.pem -sha256 -days 3650 -out ${SSL_path}/cert.pem \
-subj "/C=US/ST=State/L=City/O=${BILLIONMAIL_HOSTNAME}/OU=${BILLIONMAIL_HOSTNAME}/CN=*.${BILLIONMAIL_HOSTNAME}" -nodes
mkdir ssl
cp -d -n ${SSL_path}/* ssl/
echo -e "Execute ${DOCKER_COMPOSE} up -d"
if [ ! -s "docker-compose.yml" ]; then
ls -al
Red_Error "docker-compose.yml not found."
fi
${DOCKER_COMPOSE} pull
${DOCKER_COMPOSE} up -d
if [ $? -eq 0 ]; then
echo -e "Billionmail installation completed successfully!"
else
echo ""
echo -e "--------------------------------------------------"
Check_Port
echo -e "\e[1;31m Startup error,\e[0m please resolve it according to the prompts, otherwise it will affect the use!"
sleep 5
bash bm.sh status
echo -e "--------------------------------------------------"
echo ""
fi
# echo -e "Initialize the data..."
# sleep 5
# Init_Billionmail
[ ! -d "/opt" ] && mkdir /opt
echo "${PWD_d}" > /opt/PWD-Billion-Mail.txt
ln -sf ${PWD_d}/bm.sh /usr/bin/bm
chmod +x ${PWD_d}/bm.sh
}
Install_Main(){
# Check_Port
LXC_install_tips
Get_Pack_Manager
if [ "$PM" == "yum" ]; then
Install_RPM_Pack
else
Install_Deb_Pack
fi
set +e
Docker_Check
Docker_Compose_Check
if [ "$is_docker" != "1" ]; then
Docker_Download_Url_Check
Docker_Install
Docker_Compose_Check
fi
if [ "$is_docker_compose" != "1" ]; then
Docker_Compose_Install
Docker_Compose_Check
if [ "$is_docker_compose" != "1" ]; then
Red_Error "ERROR: Docker Compose installation failed, Please reinstall Docker Compose!"
fi
fi
Docker_Start
Billionmail
Set_Firewall
}
Install_Main
# Domain_record
IPV4_ADDRESS=$(curl -sSf -4 --connect-timeout 10 -m 20 https://ifconfig.me)
if [ -z "${IPV4_ADDRESS}" ]; then
IPV4_ADDRESS=$(curl -sSfk --connect-timeout 10 -m 20 https://www.aapanel.com/api/common/getClientIP)
fi
ipv4_regex="^([0-9]{1,3}\.){3}[0-9]{1,3}$"
if [[ ${IPV4_ADDRESS} =~ ${ipv4_regex} ]]; then
echo "${IPV4_ADDRESS}" >/dev/null 2>&1
elif [ -z "${IPV4_ADDRESS}" ]; then
IPV4_ADDRESS="YOUR_SERVER_IPV4_ADDRESS"
fi
intenal_ip=$(ip addr | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -E -v "^127\.|^255\.|^0\." | head -n 1)
# echo -e "\e[31mPlease save the following information:\e[0m"
# if [ ${HTTPS_PORT} = "443" ]; then
# echo -e "Webmail address: \e[1;33mhttps://${IPV4_ADDRESS}/roundcube/\e[0m"
# else
# echo -e "Webmail address: \e[1;33mhttps://${IPV4_ADDRESS}:${HTTP_PORT}/roundcube/\e[0m"
# fi
# echo -e "Webmail Username(e-mail): \e[1;33m${mailbox}@${BILLIONMAIL_HOSTNAME}\e[0m Password: \e[1;33m${Generate_mailbox_password}\e[0m"
# echo -e ""
if [ ${HTTPS_PORT} = "443" ]; then
echo -e "BillionMail Internet address: \e[1;33mhttps://${IPV4_ADDRESS}/${SafePath}\e[0m"
echo -e "BillionMail Internal address: \e[1;33mhttps://${intenal_ip}/${SafePath}\e[0m"
else
echo -e "BillionMail Internet address: \e[1;33mhttps://${IPV4_ADDRESS}:${HTTPS_PORT}/${SafePath}\e[0m"
echo -e "BillionMail Internal address: \e[1;33mhttps://${intenal_ip}:${HTTPS_PORT}/${SafePath}\e[0m"
fi
echo -e "Username: \e[1;33m${ADMIN_USERNAME}\e[0m"
echo -e "Password: \e[1;33m${ADMIN_PASSWORD}\e[0m"
echo -e ""
echo -e "Tip: Use \e[33m bm \e[0m or \e[33mbash bm.sh\e[0m to View login info etc."
# Install
curl -o /dev/null -fsSLk --connect-time 10 -X POST "https://www.aapanel.com/api/panel/panel_count_daily?name=billionmail" >/dev/null 2>&1