mirror of
https://github.com/nodemailer/wildduck.git
synced 2025-03-01 18:35:09 +08:00
Merge pull request #84 from bunyevacz/install.sh2
Breaking up install.sh into chapters
This commit is contained in:
commit
33ecb657c0
19 changed files with 1256 additions and 736 deletions
255
setup/00_install_variables.sh
Normal file
255
setup/00_install_variables.sh
Normal file
|
@ -0,0 +1,255 @@
|
|||
#! /bin/bash
|
||||
|
||||
# These are all the common global variables and global functions.
|
||||
|
||||
AUT_HOSTNAME=`hostname`
|
||||
export AUT_SAFETY=true
|
||||
|
||||
export AUT_HOME="${HOME}" # maybe a more robust way?
|
||||
|
||||
# COLOR VARIABLES
|
||||
export RED='\033[0;31m'
|
||||
export GREEN='\033[0;32m'
|
||||
export ORANGE='\033[0;33m'
|
||||
export YELLOW='\033[1;33m'
|
||||
export BLUE='\033[0;34m'
|
||||
export NC='\033[0m' # No Color
|
||||
|
||||
# GLOBAL FUNCTIONS
|
||||
|
||||
fun_get_password(){
|
||||
# If we are not root, we should aquire the sudo password
|
||||
if [ `whoami` == 'root' ]
|
||||
then
|
||||
PASSWORD=''
|
||||
else
|
||||
echo -n "GIMME your password! ($OURNAME):"
|
||||
read -s PASSWORD
|
||||
echo -e "\n"
|
||||
fi
|
||||
}
|
||||
export -f fun_get_password
|
||||
|
||||
fun_check_password_boolean(){
|
||||
# Check if the $PASSWORD is good or not
|
||||
|
||||
# TODO: if hostname can not be resolved (/etc/hosts misses 127.0.0.1)
|
||||
# then sudo outputs 'cannot resolve hostname', so this check
|
||||
# "obviously" fails.
|
||||
|
||||
sudo -k #disable sudo timeout
|
||||
|
||||
#prime it
|
||||
echo $PASSWORD | sudo -S echo hello &> /dev/null
|
||||
|
||||
local RESULT=$(echo $PASSWORD | sudo -S sudo -n echo hello 2>&1)
|
||||
if [ "$RESULT" == "hello" ]; then
|
||||
echo 'Correct password.'
|
||||
return 0
|
||||
else
|
||||
echo 'Wrong password.'
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
||||
export -f fun_check_password_boolean
|
||||
|
||||
fun_check_password(){
|
||||
if ! fun_check_password_boolean; then
|
||||
echo -e "${RED}ERROR:${NC} Wrong password, we should quit now."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
export -f fun_check_password
|
||||
|
||||
|
||||
fun_get_user_variables_no_default(){
|
||||
# get REMOTE_SERVER_EMAIL, if not supplied, quit. No default.
|
||||
|
||||
local VARIABLES=("${!1}")
|
||||
local TMP_DEFAULT
|
||||
local TMP_USER
|
||||
local TMP_READ
|
||||
|
||||
echo "Automatic timeout is 120 sec"
|
||||
|
||||
for i in ${VARIABLES[@]}; do
|
||||
TMP_DEFAULT=DEFAULT_$i
|
||||
echo -n "GIMMME the $i (username, eg: ${!TMP_DEFAULT}), no default value:"
|
||||
read -t 120 TMP_READ
|
||||
echo ""
|
||||
declare -g USER_$i=$TMP_READ
|
||||
TMP_USER=USER_$i
|
||||
|
||||
if [ "${!TMP_USER}" == "" ]; then
|
||||
echo -n "${TMP_USER} can not be empty. Please give it again:"
|
||||
read -t 130 TMP_READ
|
||||
declare -g USER_$i=$TMP_READ
|
||||
TMP_USER=USER_$i
|
||||
if [ "${!TMP_USER}" == "" ]; then
|
||||
echo "Second try failed. Quitting..."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
}
|
||||
export -f fun_get_user_variables_no_default
|
||||
|
||||
fun_get_user_variables_password(){
|
||||
# get REMOTE_SERVER_PASSWORD, no default, suppress echoing back
|
||||
|
||||
local VARIABLES=("${!1}")
|
||||
local TMP_DEFAULT
|
||||
local TMP_USER
|
||||
local TMP_READ
|
||||
|
||||
echo "Automatic timeout is 120 sec"
|
||||
|
||||
for i in ${VARIABLES[@]}; do
|
||||
TMP_DEFAULT=DEFAULT_$i
|
||||
echo -n "GIMMME the $i (password, eg: ${!TMP_DEFAULT}), no default value:"
|
||||
read -t 120 -s TMP_READ
|
||||
echo ""
|
||||
declare -g USER_$i=$TMP_READ
|
||||
TMP_USER=USER_$i
|
||||
|
||||
if [ "${!TMP_USER}" == "" ]; then
|
||||
echo -n "${TMP_USER} can not be empty. Please give it again:"
|
||||
read -t 130 -s TMP_READ
|
||||
declare -g USER_$i=$TMP_READ
|
||||
TMP_USER=USER_$i
|
||||
if [ "${!TMP_USER}" == "" ]; then
|
||||
echo "Second try failed. Quitting..."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
export -f fun_get_user_variables_password
|
||||
|
||||
fun_get_user_variables(){
|
||||
# get USER_HOST_PORT, if not supplied, autofill with DEFAULT_HOST_PORT, etc
|
||||
|
||||
local VARIABLES=("${!1}")
|
||||
local TMP_DEFAULT
|
||||
local TMP_USER
|
||||
local TMP_READ
|
||||
|
||||
echo "Automatic timeout is 30 sec"
|
||||
|
||||
for i in ${VARIABLES[@]}; do
|
||||
TMP_DEFAULT=DEFAULT_$i
|
||||
echo -n "GIMMME the $i (default: ${!TMP_DEFAULT}):"
|
||||
read -t 30 TMP_READ
|
||||
echo ""
|
||||
declare -g USER_$i=$TMP_READ
|
||||
TMP_USER=USER_$i
|
||||
|
||||
if [ "${!TMP_USER}" == "" ]; then
|
||||
declare -g USER_$i=${!TMP_DEFAULT}
|
||||
fi
|
||||
done
|
||||
}
|
||||
export -f fun_get_user_variables
|
||||
|
||||
|
||||
fun_prepare_run_command(){
|
||||
# prepare the runcommand variable.
|
||||
# Must be called before fun_echo_command and fun_run_command
|
||||
|
||||
TEMPLATE=$(cat <<EOF
|
||||
-e "ORIGINAL_COMMAND=RUNCOMMAND_TEMPLATE" \
|
||||
$USER_IMAGE
|
||||
EOF
|
||||
)
|
||||
|
||||
RUNCOMMAND_ADDED_ENV=${RUNCOMMAND_ORIG//$USER_IMAGE/$TEMPLATE}
|
||||
RUNCOMMAND_NOPASSWD=${RUNCOMMAND_ADDED_ENV//$PASSWORD/PASSWORD}
|
||||
RUNCOMMAND=${RUNCOMMAND_ADDED_ENV//RUNCOMMAND_TEMPLATE/$RUNCOMMAND_NOPASSWD}
|
||||
|
||||
}
|
||||
export -f fun_prepare_run_command
|
||||
|
||||
fun_echo_command(){
|
||||
# echo the command which will be launched (fun_run_command())
|
||||
|
||||
echo ${RUNCOMMAND//$PASSWORD/PASSWORD}
|
||||
|
||||
}
|
||||
export -f fun_echo_command
|
||||
|
||||
fun_run_command(){
|
||||
# execute the final command
|
||||
|
||||
echo `eval $RUNCOMMAND`
|
||||
}
|
||||
export -f fun_run_command
|
||||
|
||||
fun_print_help(){
|
||||
USAGE=$(cat <<EOF
|
||||
|
||||
# Manual
|
||||
# The main installation script is:
|
||||
./install.sh domainname [hostname]
|
||||
eg. ${GREEN}./install.sh amazeme.com mail.amazeme.com${NC}
|
||||
|
||||
There is a slight difference between domainname and hostname.
|
||||
|
||||
${ORANGE}Simplest case${NC}:
|
||||
One server serves everything: company website, emails, webmails.
|
||||
One ip address, and domainname is the same az hostname.
|
||||
Eg. amazme.com
|
||||
|
||||
${GREEN}More general case${NC}:
|
||||
The domainname is part of the email address:
|
||||
username@domainname
|
||||
|
||||
The hostname is the actual machine name, eg. this machine
|
||||
name is: `hostname`
|
||||
|
||||
On larger organizations, the company homepage is independent from
|
||||
the mail servers. Or the webmail servers.
|
||||
Eg. the company homepage is amazme.com [11.22.33.44],
|
||||
the mail server is mail.amazme.com [11.22.33.43]
|
||||
|
||||
So domainname = amazme.com
|
||||
hostname = mail.amazme.com
|
||||
|
||||
${RED}IP address${NC} case:
|
||||
You can call this script with ip address instead of domain name:
|
||||
./install.sh 11.22.33.44
|
||||
(with the server's public IP address)
|
||||
In that case both domainname and hostname becomes the IP address.
|
||||
Dunno why anyone wanna that...
|
||||
|
||||
EOF
|
||||
)
|
||||
|
||||
# echo -e for the colored output, "quotes" for the newline preserves
|
||||
echo -e "$USAGE"
|
||||
}
|
||||
export -f fun_print_help
|
||||
|
||||
function hook_script {
|
||||
echo "#!/bin/bash
|
||||
git --git-dir=/var/opt/$1.git --work-tree=\"/opt/$1\" checkout "\$3" -f
|
||||
cd \"/opt/$1\"
|
||||
rm -rf package-lock.json
|
||||
npm install --production --progress=false
|
||||
sudo $SYSTEMCTL_PATH restart $1 || echo \"Failed restarting service\"" > "/var/opt/$1.git/hooks/update"
|
||||
chmod +x "/var/opt/$1.git/hooks/update"
|
||||
}
|
||||
export -f hook_script
|
||||
|
||||
function hook_script_bower {
|
||||
echo "#!/bin/bash
|
||||
git --git-dir=/var/opt/$1.git --work-tree=\"/opt/$1\" checkout "\$3" -f
|
||||
cd \"/opt/$1\"
|
||||
rm -rf package-lock.json
|
||||
npm install --progress=false
|
||||
npm run bowerdeps
|
||||
sudo $SYSTEMCTL_PATH restart $1 || echo \"Failed restarting service\"" > "/var/opt/$1.git/hooks/update"
|
||||
chmod +x "/var/opt/$1.git/hooks/update"
|
||||
}
|
||||
export -f hook_script_bower
|
12
setup/01_install_commit_variables.sh
Normal file
12
setup/01_install_commit_variables.sh
Normal file
|
@ -0,0 +1,12 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=01_install_commit_variables.sh
|
||||
|
||||
WILDDUCK_COMMIT="ac053d164bd8e10938d0da813c8295fb0c094437"
|
||||
ZONEMTA_COMMIT="b9915924a8a4488837e5cb1636901631860da1d3" # zone-mta-template
|
||||
WEBMAIL_COMMIT="221783539bd4382917d750989bb2ab425804f80a"
|
||||
WILDDUCK_ZONEMTA_COMMIT="v1.11.2"
|
||||
WILDDUCK_HARAKA_COMMIT="92eba398676dd2418a0830256aa554efd09fb546"
|
||||
HARAKA_VERSION="2.8.17"
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
38
setup/02_install_prerequisites.sh
Normal file
38
setup/02_install_prerequisites.sh
Normal file
|
@ -0,0 +1,38 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=02_install_prerequisites.sh
|
||||
|
||||
# No $AUT_SAFETY variable present, so we have not sourced install_variables.sh yet
|
||||
if [ -z ${AUT_SAFETY+x} ]
|
||||
then
|
||||
echo "this script ${RED}called directly${NC}, and not from the main ./install.sh script"
|
||||
echo "initializing common variables ('install_variables.sh')"
|
||||
source "$INSTALLDIR/install_variables.sh"
|
||||
fi
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
echo -e "Checking ${YELLOW}lsof${NC}"
|
||||
PROGRAM_LSOF=`command -v lsof`
|
||||
|
||||
if ! [ -x "$PROGRAM_LSOF" ]; then
|
||||
echo -e "${RED}ERROR:${NC} lsof is not installed."
|
||||
echo "to know which package contains the particular executable, launch:"
|
||||
echo "dpkg -S lsof |grep lsof$ # on ubuntu/debian variants"
|
||||
echo -e "Launching for you:\n"
|
||||
echo -e "`dpkg -S lsof | grep /lsof$`"
|
||||
echo -e "\nOn ubuntu 16.04 it is: ${GREEN}apt install lsof${NC}"
|
||||
fi
|
||||
|
||||
|
||||
echo -e "Checking ${YELLOW}ps${NC}"
|
||||
PROGRAM_PS=`command -v ps`
|
||||
|
||||
if ! [ -x "$PROGRAM_PS" ]; then
|
||||
echo -e "${RED}ERROR:${NC} ps is not installed."
|
||||
echo "to know which package contains the particular executable, launch:"
|
||||
echo "dpkg -S ps |grep ps$ # on ubuntu/debian variants"
|
||||
echo -e "Launching for you:\n"
|
||||
echo -e "`dpkg -S ps | grep /ps$`"
|
||||
echo -e "\nOn ubuntu 16.04 it is: ${GREEN}apt install procps${NC}"
|
||||
fi
|
138
setup/03_install_check_running_services.sh
Normal file
138
setup/03_install_check_running_services.sh
Normal file
|
@ -0,0 +1,138 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=03_install_check_running_services.sh
|
||||
|
||||
# No $AUT_SAFETY variable present, so we have not sourced install_variables.sh yet
|
||||
# check if $AUT_SAFETY is unset (as opposed to empty "" string)
|
||||
if [ -z ${AUT_SAFETY+x} ]
|
||||
then
|
||||
echo "this script ${RED}called directly${NC}, and not from the main ./install.sh script"
|
||||
echo "initializing common variables ('install_variables.sh')"
|
||||
source "$INSTALLDIR/install_variables.sh"
|
||||
fi
|
||||
|
||||
echo -e "\n\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
echo -e "Checking programs listening on port 25,587,993,995,80,443"
|
||||
PORT25=`lsof -Pi :25 -sTCP:LISTEN -t`
|
||||
PORT587=`lsof -Pi :587 -sTCP:LISTEN -t`
|
||||
PORT993=`lsof -Pi :993 -sTCP:LISTEN -t`
|
||||
PORT995=`lsof -Pi :995 -sTCP:LISTEN -t`
|
||||
PORT80=`lsof -Pi :80 -sTCP:LISTEN -t`
|
||||
PORT443=`lsof -Pi :443 -sTCP:LISTEN -t`
|
||||
|
||||
|
||||
# check if $PORT25 is empty "" string (as opposed to unset)
|
||||
if ! [ -z $PORT25 ] ; then
|
||||
echo -e "${RED}Error:${NC} SMTP server already running on port 25"
|
||||
echo -e "PID: ${YELLOW}$PORT25${NC}"
|
||||
BINARY=`ps -p $PORT25 -o comm=`
|
||||
echo -e "binary: ${YELLOW}$BINARY${NC}"
|
||||
echo -e "full command with arguments: ${YELLOW}`ps -p $PORT25 -o command=`${NC}"
|
||||
echo -e "possible packages (dpkg -S $BINARY | grep /${BINARY}$):"
|
||||
echo -e "`dpkg -S $BINARY | grep /${BINARY}$`"
|
||||
echo -e "If it is launched by systemd, finding the service with"
|
||||
echo -e "Executing ${YELLOW}systemctl status $PORT25${NC}"
|
||||
echo -e "`systemctl status $PORT25`"
|
||||
echo -e "\nList all enabled services:"
|
||||
echo -e "systemctl list-unit-files | grep enabled"
|
||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||
exit 1
|
||||
else
|
||||
echo -e 'OK: port 25 (SMTP) is free'
|
||||
fi
|
||||
|
||||
if ! [ -z $PORT587 ] ; then
|
||||
echo -e "${RED}Error:${NC} SMTP server already running on port 587"
|
||||
echo -e "PID: ${YELLOW}$PORT587${NC}"
|
||||
BINARY=`ps -p $PORT587 -o comm=`
|
||||
echo -e "binary: ${YELLOW}$BINARY${NC}"
|
||||
echo -e "full command with arguments: ${YELLOW}`ps -p $PORT587 -o command=`${NC}"
|
||||
echo -e "possible packages (dpkg -S $BINARY | grep /${BINARY}$):"
|
||||
echo -e "`dpkg -S $BINARY | grep /${BINARY}$`"
|
||||
echo -e "If it is launched by systemd, finding the service with"
|
||||
echo -e "Executing ${YELLOW}systemctl status $PORT587${NC}"
|
||||
echo -e "`systemctl status $PORT587`"
|
||||
echo -e "\nList all enabled services:"
|
||||
echo -e "systemctl list-unit-files | grep enabled"
|
||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||
exit 1
|
||||
else
|
||||
echo -e 'OK: port 587 (SMTP TLS) is free'
|
||||
fi
|
||||
|
||||
if ! [ -z $PORT993 ] ; then
|
||||
echo -e "${RED}Error:${NC} IMAP server already running on port 993"
|
||||
echo -e "PID: ${YELLOW}$PORT993${NC}"
|
||||
BINARY=`ps -p $PORT993 -o comm=`
|
||||
echo -e "binary: ${YELLOW}$BINARY${NC}"
|
||||
echo -e "full command with arguments: ${YELLOW}`ps -p $PORT993 -o command=`${NC}"
|
||||
echo -e "possible packages (dpkg -S $BINARY | grep /${BINARY}$):"
|
||||
echo -e "`dpkg -S $BINARY | grep /${BINARY}$`"
|
||||
echo -e "If it is launched by systemd, finding the service with"
|
||||
echo -e "Executing ${YELLOW}systemctl status $PORT993${NC}"
|
||||
echo -e "`systemctl status $PORT993`"
|
||||
echo -e "\nList all enabled services:"
|
||||
echo -e "systemctl list-unit-files | grep enabled"
|
||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||
exit 1
|
||||
else
|
||||
echo -e 'OK: port 993 (IMAP SSL/TLS) is free'
|
||||
fi
|
||||
|
||||
if ! [ -z $PORT995 ] ; then
|
||||
echo -e "${RED}Error:${NC} POP3 server already running on port 995"
|
||||
echo -e "PID: ${YELLOW}$PORT995${NC}"
|
||||
BINARY=`ps -p $PORT995 -o comm=`
|
||||
echo -e "binary: ${YELLOW}$BINARY${NC}"
|
||||
echo -e "full command with arguments: ${YELLOW}`ps -p $PORT995 -o command=`${NC}"
|
||||
echo -e "possible packages (dpkg -S $BINARY | grep /${BINARY}$):"
|
||||
echo -e "`dpkg -S $BINARY | grep /${BINARY}$`"
|
||||
echo -e "If it is launched by systemd, finding the service with"
|
||||
echo -e "Executing ${YELLOW}systemctl status $PORT995${NC}"
|
||||
echo -e "`systemctl status $PORT995`"
|
||||
echo -e "\nList all enabled services:"
|
||||
echo -e "systemctl list-unit-files | grep enabled"
|
||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||
exit 1
|
||||
else
|
||||
echo -e 'OK: port 995 (POP3 SSL/TLS) is free'
|
||||
fi
|
||||
|
||||
if ! [ -z $PORT80 ] ; then
|
||||
echo -e "${RED}Error:${NC} HTTP server already running on port 80"
|
||||
echo -e "PID: ${YELLOW}$PORT80${NC}"
|
||||
BINARY=`ps -p $PORT80 -o comm=`
|
||||
echo -e "binary: ${YELLOW}$BINARY${NC}"
|
||||
echo -e "full command with arguments: ${YELLOW}`ps -p $PORT80 -o command=`${NC}"
|
||||
echo -e "possible packages (dpkg -S $BINARY | grep /${BINARY}$):"
|
||||
echo -e "`dpkg -S $BINARY | grep /${BINARY}$`"
|
||||
echo -e "If it is launched by systemd, finding the service with"
|
||||
echo -e "Executing ${YELLOW}systemctl status $PORT80${NC}"
|
||||
echo -e "`systemctl status $PORT80`"
|
||||
echo -e "\nList all enabled services:"
|
||||
echo -e "systemctl list-unit-files | grep enabled"
|
||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||
exit 1
|
||||
else
|
||||
echo -e 'OK: port 80 (HTTP) is free'
|
||||
fi
|
||||
|
||||
if ! [ -z $PORT443 ] ; then
|
||||
echo -e "${RED}Error:${NC} HTTPS server already running on port 443"
|
||||
echo -e "PID: ${YELLOW}$PORT443${NC}"
|
||||
BINARY=`ps -p $PORT443 -o comm=`
|
||||
echo -e "binary: ${YELLOW}$BINARY${NC}"
|
||||
echo -e "full command with arguments: ${YELLOW}`ps -p $PORT443 -o command=`${NC}"
|
||||
echo -e "possible packages (dpkg -S $BINARY | grep /${BINARY}$):"
|
||||
echo -e "`dpkg -S $BINARY | grep /${BINARY}$`"
|
||||
echo -e "If it is launched by systemd, finding the service with"
|
||||
echo -e "Executing ${YELLOW}systemctl status $PORT443${NC}"
|
||||
echo -e "`systemctl status $PORT443`"
|
||||
echo -e "\nList all enabled services:"
|
||||
echo -e "systemctl list-unit-files | grep enabled"
|
||||
echo -e "${RED}QUITTING... (please stop the service and launch again)${NC}"
|
||||
exit 1
|
||||
else
|
||||
echo -e 'OK: port 443 (HTTPS) is free'
|
||||
fi
|
50
setup/04_install_import_keys.sh
Normal file
50
setup/04_install_import_keys.sh
Normal file
|
@ -0,0 +1,50 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=04_install_import_keys.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
# create user for running applications
|
||||
useradd wildduck || echo "User wildduck already exists"
|
||||
|
||||
# remove old sudoers file
|
||||
rm -rf /etc/sudoers.d/wildduck
|
||||
|
||||
# create user for deploying code
|
||||
useradd deploy || echo "User deploy already exists"
|
||||
|
||||
mkdir -p /home/deploy/.ssh
|
||||
# add your own key to the authorized_keys file
|
||||
echo "# Add your public key here
|
||||
" >> /home/deploy/.ssh/authorized_keys
|
||||
chown -R deploy:deploy /home/deploy
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# mongo keys
|
||||
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
|
||||
gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58712A2291FA4AD5
|
||||
gpg --armor --export 58712A2291FA4AD5 | apt-key add -
|
||||
echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list
|
||||
|
||||
|
||||
# tor keys
|
||||
# Setup tor to be able to send emails to .onion network.
|
||||
# Receiving from onion is not automatically set up, you would have to
|
||||
# create a hidden servcie first and then bridge port 25
|
||||
echo 'deb http://deb.torproject.org/torproject.org xenial main
|
||||
deb-src http://deb.torproject.org/torproject.org xenial main' > /etc/apt/sources.list.d/tor.list
|
||||
gpg --keyserver keys.gnupg.net --recv A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89
|
||||
gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | sudo apt-key add -
|
||||
|
||||
# rspamd
|
||||
CODENAME=`lsb_release -c -s`
|
||||
wget -O- https://rspamd.com/apt-stable/gpg.key | apt-key add -
|
||||
echo "deb http://rspamd.com/apt-stable/ $CODENAME main" > /etc/apt/sources.list.d/rspamd.list
|
||||
echo "deb-src http://rspamd.com/apt-stable/ $CODENAME main" >> /etc/apt/sources.list.d/rspamd.list
|
||||
apt-get update
|
||||
|
||||
apt-get -q -y install redis-server clamav clamav-daemon
|
||||
apt-get -q -y --no-install-recommends install rspamd
|
||||
|
||||
apt-get clean
|
25
setup/05_install_packages.sh
Normal file
25
setup/05_install_packages.sh
Normal file
|
@ -0,0 +1,25 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=05_install_packages.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
# install nginx
|
||||
apt-get update
|
||||
apt-get -q -y install pwgen git ufw build-essential libssl-dev dnsutils python software-properties-common nginx lsb-release wget
|
||||
|
||||
# install node 8
|
||||
curl -sL https://deb.nodesource.com/setup_8.x | bash -
|
||||
|
||||
# install tor
|
||||
apt-get update
|
||||
|
||||
apt-get -q -y install mongodb-org nodejs tor deb.torproject.org-keyring
|
||||
|
||||
# redis
|
||||
apt-add-repository -y ppa:chris-lea/redis-server
|
||||
|
||||
# rspamd
|
||||
apt-get -q -y install redis-server clamav clamav-daemon
|
||||
apt-get -q -y --no-install-recommends install rspamd
|
||||
apt-get clean
|
25
setup/06_install_enable_services.sh
Normal file
25
setup/06_install_enable_services.sh
Normal file
|
@ -0,0 +1,25 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=06_install_enable_services.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
NODE_PATH=`command -v node`
|
||||
SYSTEMCTL_PATH=`command -v systemctl`
|
||||
|
||||
SRS_SECRET=`pwgen 12 -1`
|
||||
DKIM_SECRET=`pwgen 12 -1`
|
||||
ZONEMTA_SECRET=`pwgen 12 -1`
|
||||
DKIM_SELECTOR=`$NODE_PATH -e 'console.log(Date().toString().substr(4, 3).toLowerCase() + new Date().getFullYear())'`
|
||||
|
||||
$SYSTEMCTL_PATH enable mongod.service
|
||||
|
||||
echo -e "\n-- These are the installed and required programs:"
|
||||
node -v
|
||||
redis-server -v
|
||||
mongod --version
|
||||
echo "HOSTNAME: $HOSTNAME"
|
||||
|
||||
echo -e "-- Installing ${RED}npm globally${NC} (workaround)"
|
||||
# See issue https://github.com/nodemailer/wildduck/issues/82
|
||||
npm install npm -g
|
80
setup/07_install_wildduck.sh
Normal file
80
setup/07_install_wildduck.sh
Normal file
|
@ -0,0 +1,80 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=06_install_wildduck.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
####### WILD DUCK #######
|
||||
|
||||
# clear previous install
|
||||
if [ -f "/etc/systemd/system/wildduck.service" ]
|
||||
then
|
||||
$SYSTEMCTL_PATH stop wildduck || true
|
||||
$SYSTEMCTL_PATH disable wildduck || true
|
||||
rm -rf /etc/systemd/system/wildduck.service
|
||||
fi
|
||||
rm -rf /var/opt/wildduck.git
|
||||
rm -rf /opt/wildduck
|
||||
rm -rf /etc/wildduck
|
||||
|
||||
# fresh install
|
||||
cd /var/opt
|
||||
git clone --bare git://github.com/nodemailer/wildduck.git
|
||||
|
||||
# create update hook so we can later deploy to this location
|
||||
hook_script wildduck
|
||||
|
||||
# allow deploy user to restart wildduck service
|
||||
echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart wildduck" >> /etc/sudoers.d/wildduck
|
||||
|
||||
# checkout files from git to working directory
|
||||
mkdir -p /opt/wildduck
|
||||
git --git-dir=/var/opt/wildduck.git --work-tree=/opt/wildduck checkout "$WILDDUCK_COMMIT"
|
||||
cp -r /opt/wildduck/config /etc/wildduck
|
||||
mv /etc/wildduck/default.toml /etc/wildduck/wildduck.toml
|
||||
|
||||
# enable example message
|
||||
sed -i -e 's/"disabled": true/"disabled": false/g' /opt/wildduck/emails/00-example.json
|
||||
|
||||
# update ports
|
||||
sed -i -e "s/999/99/g;s/localhost/$HOSTNAME/g" /etc/wildduck/imap.toml
|
||||
sed -i -e "s/999/99/g;s/localhost/$HOSTNAME/g" /etc/wildduck/pop3.toml
|
||||
|
||||
echo "enabled=true
|
||||
port=24
|
||||
disableSTARTTLS=true" > /etc/wildduck/lmtp.toml
|
||||
|
||||
# make sure that DKIM keys are not stored to database as cleartext
|
||||
#echo "secret=\"$DKIM_SECRET\"
|
||||
#cipher=\"aes192\"" >> /etc/wildduck/dkim.toml
|
||||
|
||||
echo "user=\"wildduck\"
|
||||
group=\"wildduck\"
|
||||
emailDomain=\"$MAILDOMAIN\"" | cat - /etc/wildduck/wildduck.toml > temp && mv temp /etc/wildduck/wildduck.toml
|
||||
|
||||
sed -i -e "s/localhost:3000/$HOSTNAME/g;s/localhost/$HOSTNAME/g;s/2587/587/g" /etc/wildduck/wildduck.toml
|
||||
|
||||
cd /opt/wildduck
|
||||
npm install --unsafe-perm --production
|
||||
|
||||
chown -R deploy:deploy /var/opt/wildduck.git
|
||||
chown -R deploy:deploy /opt/wildduck
|
||||
|
||||
echo "[Unit]
|
||||
Description=WildDuck Mail Server
|
||||
Conflicts=cyrus.service dovecot.service
|
||||
After=mongod.service redis.service
|
||||
|
||||
[Service]
|
||||
Environment=\"NODE_ENV=production\"
|
||||
WorkingDirectory=/opt/wildduck
|
||||
ExecStart=$NODE_PATH server.js --config=\"/etc/wildduck/wildduck.toml\"
|
||||
ExecReload=/bin/kill -HUP \$MAINPID
|
||||
Type=simple
|
||||
Restart=always
|
||||
SyslogIdentifier=wildduck-server
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target" > /etc/systemd/system/wildduck.service
|
||||
|
||||
$SYSTEMCTL_PATH enable wildduck.service
|
129
setup/08_install_haraka.sh
Normal file
129
setup/08_install_haraka.sh
Normal file
|
@ -0,0 +1,129 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=08_install_haraka.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
|
||||
|
||||
####### HARAKA #######
|
||||
|
||||
# clear previous install
|
||||
if [ -f "/etc/systemd/system/haraka.service" ]
|
||||
then
|
||||
$SYSTEMCTL_PATH stop haraka || true
|
||||
$SYSTEMCTL_PATH disable haraka || true
|
||||
rm -rf /etc/systemd/system/haraka.service
|
||||
fi
|
||||
rm -rf /var/opt/haraka-plugin-wildduck.git
|
||||
rm -rf /opt/haraka
|
||||
|
||||
# fresh install
|
||||
cd /var/opt
|
||||
git clone --bare git://github.com/nodemailer/haraka-plugin-wildduck.git
|
||||
echo "#!/bin/bash
|
||||
git --git-dir=/var/opt/haraka-plugin-wildduck.git --work-tree=/opt/haraka/plugins/wildduck checkout "\$3" -f
|
||||
cd /opt/haraka/plugins/wildduck
|
||||
rm -rf package-lock.json
|
||||
npm install --production --progress=false
|
||||
sudo $SYSTEMCTL_PATH restart haraka || echo \"Failed restarting service\"" > "/var/opt/haraka-plugin-wildduck.git/hooks/update"
|
||||
chmod +x "/var/opt/haraka-plugin-wildduck.git/hooks/update"
|
||||
|
||||
# allow deploy user to restart wildduck service
|
||||
echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart haraka" >> /etc/sudoers.d/wildduck
|
||||
|
||||
cd
|
||||
npm install --unsafe-perm -g Haraka@$HARAKA_VERSION
|
||||
haraka -i /opt/haraka
|
||||
cd /opt/haraka
|
||||
npm install --unsafe-perm --save haraka-plugin-rspamd Haraka@$HARAKA_VERSION
|
||||
|
||||
# Haraka WIldDuck plugin. Install as separate repo as it can be edited more easily later
|
||||
mkdir -p plugins/wildduck
|
||||
git --git-dir=/var/opt/haraka-plugin-wildduck.git --work-tree=/opt/haraka/plugins/wildduck checkout "$WILDDUCK_HARAKA_COMMIT"
|
||||
|
||||
cd plugins/wildduck
|
||||
npm install --unsafe-perm --production --progress=false
|
||||
|
||||
cd /opt/haraka
|
||||
mv config/plugins config/plugins.bak
|
||||
|
||||
echo "26214400" > config/databytes
|
||||
echo "$HOSTNAME" > config/me
|
||||
echo "WildDuck MX" > config/smtpgreeting
|
||||
|
||||
echo "spf
|
||||
|
||||
## ClamAV is disabled by default. Make sure freshclam has updated all
|
||||
## virus definitions and clamav-daemon has successfully started before
|
||||
## enabling it.
|
||||
#clamd
|
||||
|
||||
rspamd
|
||||
tls
|
||||
#dkim_verify
|
||||
|
||||
# WildDuck plugin handles recipient checking and queueing
|
||||
wildduck" > config/plugins
|
||||
|
||||
echo "key=/etc/wildduck/certs/privkey.pem
|
||||
cert=/etc/wildduck/certs/fullchain.pem" > config/tls.ini
|
||||
|
||||
echo 'host = localhost
|
||||
port = 11333
|
||||
add_headers = always
|
||||
[dkim]
|
||||
enabled = true
|
||||
[header]
|
||||
bar = X-Rspamd-Bar
|
||||
report = X-Rspamd-Report
|
||||
score = X-Rspamd-Score
|
||||
spam = X-Rspamd-Spam
|
||||
[check]
|
||||
authenticated=true
|
||||
private_ip=true
|
||||
[reject]
|
||||
spam = false
|
||||
[soft_reject]
|
||||
enabled = true
|
||||
[rmilter_headers]
|
||||
enabled = true
|
||||
[spambar]
|
||||
positive = +
|
||||
negative = -
|
||||
neutral = /' > config/rspamd.ini
|
||||
|
||||
echo 'clamd_socket = /var/run/clamav/clamd.ctl
|
||||
[reject]
|
||||
virus=true
|
||||
error=false' > config/clamd.ini
|
||||
|
||||
cp plugins/wildduck/config/wildduck.yaml config/wildduck.yaml
|
||||
sed -i -e "s/secret value/$SRS_SECRET/g" config/wildduck.yaml
|
||||
|
||||
echo '[Unit]
|
||||
Description=Haraka MX Server
|
||||
After=mongod.service redis.service
|
||||
|
||||
[Service]
|
||||
Environment="NODE_ENV=production"
|
||||
WorkingDirectory=/opt/haraka
|
||||
ExecStart=/usr/bin/node ./node_modules/.bin/haraka -c .
|
||||
Type=simple
|
||||
Restart=always
|
||||
SyslogIdentifier=haraka
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target' > /etc/systemd/system/haraka.service
|
||||
|
||||
echo 'user=wildduck
|
||||
group=wildduck' >> config/smtp.ini
|
||||
|
||||
chown -R deploy:deploy /opt/haraka
|
||||
chown -R deploy:deploy /var/opt/haraka-plugin-wildduck.git
|
||||
|
||||
# ensure queue folder for Haraka
|
||||
mkdir -p /opt/haraka/queue
|
||||
chown -R wildduck:wildduck /opt/haraka/queue
|
||||
|
||||
$SYSTEMCTL_PATH enable haraka.service
|
138
setup/09_install_zone_mta.sh
Normal file
138
setup/09_install_zone_mta.sh
Normal file
|
@ -0,0 +1,138 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=08_install_zone_mta.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
|
||||
#### ZoneMTA ####
|
||||
|
||||
# clear previous install
|
||||
if [ -f "/etc/systemd/system/zone-mta.service" ]
|
||||
then
|
||||
$SYSTEMCTL_PATH stop zone-mta || true
|
||||
$SYSTEMCTL_PATH disable zone-mta || true
|
||||
rm -rf /etc/systemd/system/zone-mta.service
|
||||
fi
|
||||
rm -rf /var/opt/zone-mta.git
|
||||
rm -rf /var/opt/zonemta-wildduck.git
|
||||
rm -rf /opt/zone-mta
|
||||
rm -rf /etc/zone-mta
|
||||
|
||||
# fresh install
|
||||
cd /var/opt
|
||||
git clone --bare git://github.com/zone-eu/zone-mta-template.git zone-mta.git
|
||||
git clone --bare git://github.com/nodemailer/zonemta-wildduck.git
|
||||
|
||||
# create update hooks so we can later deploy to this location
|
||||
hook_script zone-mta
|
||||
echo "#!/bin/bash
|
||||
git --git-dir=/var/opt/zonemta-wildduck.git --work-tree=/opt/zone-mta/plugins/wildduck checkout "\$3" -f
|
||||
cd /opt/zone-mta/plugins/wildduck
|
||||
rm -rf package-lock.json
|
||||
npm install --production --progress=false
|
||||
sudo $SYSTEMCTL_PATH restart zone-mta || echo \"Failed restarting service\"" > "/var/opt/zonemta-wildduck.git/hooks/update"
|
||||
chmod +x "/var/opt/zonemta-wildduck.git/hooks/update"
|
||||
|
||||
# allow deploy user to restart zone-mta service
|
||||
echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart zone-mta" >> /etc/sudoers.d/zone-mta
|
||||
|
||||
# checkout files from git to working directory
|
||||
mkdir -p /opt/zone-mta
|
||||
git --git-dir=/var/opt/zone-mta.git --work-tree=/opt/zone-mta checkout "$ZONEMTA_COMMIT"
|
||||
|
||||
mkdir -p /opt/zone-mta/plugins/wildduck
|
||||
git --git-dir=/var/opt/zonemta-wildduck.git --work-tree=/opt/zone-mta/plugins/wildduck checkout "$WILDDUCK_ZONEMTA_COMMIT"
|
||||
|
||||
cp -r /opt/zone-mta/config /etc/zone-mta
|
||||
sed -i -e 's/port=2525/port=587/g;s/host="127.0.0.1"/host="0.0.0.0"/g;s/authentication=false/authentication=true/g' /etc/zone-mta/interfaces/feeder.toml
|
||||
rm -rf /etc/zone-mta/plugins/dkim.toml
|
||||
echo '# @include "/etc/wildduck/dbs.toml"' > /etc/zone-mta/dbs-production.toml
|
||||
echo 'user="wildduck"
|
||||
group="wildduck"' | cat - /etc/zone-mta/zonemta.toml > temp && mv temp /etc/zone-mta/zonemta.toml
|
||||
|
||||
echo "[[default]]
|
||||
address=\"0.0.0.0\"
|
||||
name=\"$HOSTNAME\"" > /etc/zone-mta/pools.toml
|
||||
|
||||
echo "[\"modules/zonemta-loop-breaker\"]
|
||||
enabled=\"sender\"
|
||||
secret=\"$ZONEMTA_SECRET\"
|
||||
algo=\"md5\"" > /etc/zone-mta/plugins/loop-breaker.toml
|
||||
|
||||
echo '["modules/zonemta-onion"]
|
||||
enabled=["sender"]
|
||||
["modules/zonemta-onion".proxy]
|
||||
host="127.0.0.1"
|
||||
port=9050' > /etc/zone-mta/plugins/onion.toml
|
||||
|
||||
echo "[\"wildduck\"]
|
||||
enabled=[\"receiver\", \"sender\"]
|
||||
|
||||
# which interfaces this plugin applies to
|
||||
interfaces=[\"feeder\"]
|
||||
|
||||
# optional hostname to be used in headers
|
||||
# defaults to os.hostname()
|
||||
hostname=\"$HOSTNAME\"
|
||||
|
||||
# How long to keep auth records in log
|
||||
authlogExpireDays=30
|
||||
|
||||
# SRS settings for forwarded emails
|
||||
|
||||
[srs]
|
||||
# Handle rewriting of forwarded emails
|
||||
enabled=true
|
||||
# SRS secret value. Must be the same as in the MX side
|
||||
secret=\"$SRS_SECRET\"
|
||||
# SRS domain, must resolve back to MX
|
||||
rewriteDomain=\"$MAILDOMAIN\"
|
||||
|
||||
[dkim]
|
||||
# share config with WildDuck installation
|
||||
# @include \"/etc/wildduck/dkim.toml\"
|
||||
" > /etc/zone-mta/plugins/wildduck.toml
|
||||
|
||||
cd /opt/zone-mta/keys
|
||||
openssl genrsa -out "$MAILDOMAIN-dkim.pem" 2048
|
||||
chmod 400 "$MAILDOMAIN-dkim.pem"
|
||||
openssl rsa -in "$MAILDOMAIN-dkim.pem" -out "$MAILDOMAIN-dkim.cert" -pubout
|
||||
DNS_ADDRESS="v=DKIM1;p=$(grep -v -e '^-' $MAILDOMAIN-dkim.cert | tr -d "\n")"
|
||||
|
||||
DKIM_JSON=`DOMAIN="$MAILDOMAIN" SELECTOR="$DKIM_SELECTOR" node -e 'console.log(JSON.stringify({
|
||||
domain: process.env.DOMAIN,
|
||||
selector: process.env.SELECTOR,
|
||||
description: "Default DKIM key for "+process.env.DOMAIN,
|
||||
privateKey: fs.readFileSync("/opt/zone-mta/keys/"+process.env.DOMAIN+"-dkim.pem", "UTF-8")
|
||||
}))'`
|
||||
|
||||
cd /opt/zone-mta
|
||||
npm install --unsafe-perm --production
|
||||
npm install zonemta-onion --save
|
||||
|
||||
cd /opt/zone-mta/plugins/wildduck
|
||||
npm install --unsafe-perm --production
|
||||
|
||||
chown -R deploy:deploy /var/opt/zone-mta.git
|
||||
chown -R deploy:deploy /var/opt/zonemta-wildduck.git
|
||||
chown -R deploy:deploy /opt/zone-mta
|
||||
|
||||
echo '[Unit]
|
||||
Description=Zone Mail Transport Agent
|
||||
Conflicts=sendmail.service exim.service postfix.service
|
||||
After=mongod.service redis.service
|
||||
|
||||
[Service]
|
||||
Environment="NODE_ENV=production"
|
||||
WorkingDirectory=/opt/zone-mta
|
||||
ExecStart=/usr/bin/node index.js --config="/etc/zone-mta/zonemta.toml"
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Type=simple
|
||||
Restart=always
|
||||
SyslogIdentifier=zone-mta
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target' > /etc/systemd/system/zone-mta.service
|
||||
|
||||
$SYSTEMCTL_PATH enable zone-mta.service
|
62
setup/10_install_wildduck_webmail.sh
Normal file
62
setup/10_install_wildduck_webmail.sh
Normal file
|
@ -0,0 +1,62 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=10_install_wildduck_webmail.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
#### WWW ####
|
||||
####
|
||||
# clear previous install
|
||||
if [ -f "/etc/systemd/system/wildduck-webmail.service" ]
|
||||
then
|
||||
$SYSTEMCTL_PATH stop wildduck-webmail || true
|
||||
$SYSTEMCTL_PATH disable wildduck-webmail || true
|
||||
rm -rf /etc/systemd/system/wildduck-webmail.service
|
||||
fi
|
||||
rm -rf /var/opt/wildduck-webmail.git
|
||||
rm -rf /opt/wildduck-webmail
|
||||
|
||||
# fresh install
|
||||
cd /var/opt
|
||||
git clone --bare git://github.com/nodemailer/wildduck-webmail.git
|
||||
|
||||
# create update hook so we can later deploy to this location
|
||||
hook_script_bower wildduck-webmail
|
||||
chmod +x /var/opt/wildduck-webmail.git/hooks/update
|
||||
|
||||
# allow deploy user to restart zone-mta service
|
||||
echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart wildduck-webmail" >> /etc/sudoers.d/wildduck-webmail
|
||||
|
||||
# checkout files from git to working directory
|
||||
mkdir -p /opt/wildduck-webmail
|
||||
git --git-dir=/var/opt/wildduck-webmail.git --work-tree=/opt/wildduck-webmail checkout "$WEBMAIL_COMMIT"
|
||||
cp /opt/wildduck-webmail/config/default.toml /etc/wildduck/wildduck-webmail.toml
|
||||
|
||||
sed -i -e "s/localhost/$HOSTNAME/g;s/999/99/g;s/2587/587/g;s/proxy=false/proxy=true/g" /etc/wildduck/wildduck-webmail.toml
|
||||
|
||||
cd /opt/wildduck-webmail
|
||||
|
||||
chown -R deploy:deploy /var/opt/wildduck-webmail.git
|
||||
chown -R deploy:deploy /opt/wildduck-webmail
|
||||
|
||||
# we need to run bower which reject root
|
||||
HOME=/home/deploy sudo -u deploy npm install
|
||||
HOME=/home/deploy sudo -u deploy npm run bowerdeps
|
||||
|
||||
echo '[Unit]
|
||||
Description=Wildduck Webmail
|
||||
After=wildduck.service
|
||||
|
||||
[Service]
|
||||
Environment="NODE_ENV=production"
|
||||
WorkingDirectory=/opt/wildduck-webmail
|
||||
ExecStart=/usr/bin/node server.js --config="/etc/wildduck/wildduck-webmail.toml"
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Type=simple
|
||||
Restart=always
|
||||
SyslogIdentifier=wildduck-www
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target' > /etc/systemd/system/wildduck-webmail.service
|
||||
|
||||
$SYSTEMCTL_PATH enable wildduck-webmail.service
|
62
setup/11_install_nginx.sh
Normal file
62
setup/11_install_nginx.sh
Normal file
|
@ -0,0 +1,62 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=11_install_nginx.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
#### NGINX ####
|
||||
|
||||
# Create initial certs. These will be overwritten later by Let's Encrypt certs
|
||||
mkdir -p /etc/wildduck/certs
|
||||
cd /etc/wildduck/certs
|
||||
openssl req -subj "/CN=$HOSTNAME/O=My Company Name LTD./C=US" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout privkey.pem -out fullchain.pem
|
||||
|
||||
chown -R wildduck:wildduck /etc/wildduck/certs
|
||||
chmod 0700 /etc/wildduck/certs/privkey.pem
|
||||
|
||||
# Setup domain without SSL at first, otherwise acme.sh will fail
|
||||
echo "server {
|
||||
listen 80;
|
||||
|
||||
server_name $HOSTNAME;
|
||||
|
||||
ssl_certificate /etc/wildduck/certs/fullchain.pem;
|
||||
ssl_certificate_key /etc/wildduck/certs/privkey.pem;
|
||||
|
||||
# special config for EventSource to disable gzip
|
||||
location /api/events {
|
||||
proxy_http_version 1.1;
|
||||
gzip off;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header HOST \$http_host;
|
||||
proxy_set_header X-NginX-Proxy true;
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
# special config for uploads
|
||||
location /webmail/send {
|
||||
client_max_body_size 15M;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header HOST \$http_host;
|
||||
proxy_set_header X-NginX-Proxy true;
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header HOST \$http_host;
|
||||
proxy_set_header X-NginX-Proxy true;
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}" > "/etc/nginx/sites-available/$HOSTNAME"
|
||||
rm -rf "/etc/nginx/sites-enabled/$HOSTNAME"
|
||||
ln -s "/etc/nginx/sites-available/$HOSTNAME" "/etc/nginx/sites-enabled/$HOSTNAME"
|
||||
$SYSTEMCTL_PATH reload nginx
|
16
setup/12_install_ufw_rules.sh
Normal file
16
setup/12_install_ufw_rules.sh
Normal file
|
@ -0,0 +1,16 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=12_install_ufw_rules.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
#### UFW ####
|
||||
|
||||
ufw allow 22/tcp
|
||||
ufw allow 80/tcp
|
||||
ufw allow 443/tcp
|
||||
ufw allow 25/tcp
|
||||
ufw allow 587/tcp
|
||||
ufw allow 993/tcp
|
||||
ufw allow 995/tcp
|
||||
ufw --force enable
|
53
setup/13_install_ssl_certs.sh
Normal file
53
setup/13_install_ssl_certs.sh
Normal file
|
@ -0,0 +1,53 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=13_install_ssl_certs.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
#### SSL CERTS ####
|
||||
|
||||
curl https://get.acme.sh | sh
|
||||
|
||||
echo 'cert="/etc/wildduck/certs/fullchain.pem"
|
||||
key="/etc/wildduck/certs/privkey.pem"' > /etc/wildduck/tls.toml
|
||||
|
||||
sed -i -e "s/key=/#key=/g;s/cert=/#cert=/g" /etc/zone-mta/interfaces/feeder.toml
|
||||
echo '# @include "../../wildduck/tls.toml"' >> /etc/zone-mta/interfaces/feeder.toml
|
||||
|
||||
# vanity script as first run should not restart anything
|
||||
echo '#!/bin/bash
|
||||
echo "OK"' > /usr/local/bin/reload-services.sh
|
||||
chmod +x /usr/local/bin/reload-services.sh
|
||||
|
||||
/root/.acme.sh/acme.sh --issue --nginx \
|
||||
-d "$HOSTNAME" \
|
||||
--key-file /etc/wildduck/certs/privkey.pem \
|
||||
--fullchain-file /etc/wildduck/certs/fullchain.pem \
|
||||
--reloadcmd "/usr/local/bin/reload-services.sh" \
|
||||
--force || echo "Warning: Failed to generate certificates, using self-signed certs"
|
||||
|
||||
# Update site config, make sure ssl is enabled
|
||||
echo "server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name $HOSTNAME;
|
||||
|
||||
ssl_certificate /etc/wildduck/certs/fullchain.pem;
|
||||
ssl_certificate_key /etc/wildduck/certs/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header HOST \$http_host;
|
||||
proxy_set_header X-NginX-Proxy true;
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}" > "/etc/nginx/sites-available/$HOSTNAME"
|
||||
|
||||
#See issue https://github.com/nodemailer/wildduck/issues/83
|
||||
$SYSTEMCTL_PATH start nginx
|
||||
$SYSTEMCTL_PATH reload nginx
|
23
setup/14_install_start_services.sh
Normal file
23
setup/14_install_start_services.sh
Normal file
|
@ -0,0 +1,23 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=14_install_start_services.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
# update reload script for future updates
|
||||
echo "#!/bin/bash
|
||||
$SYSTEMCTL_PATH reload nginx
|
||||
$SYSTEMCTL_PATH reload wildduck
|
||||
$SYSTEMCTL_PATH restart zone-mta
|
||||
$SYSTEMCTL_PATH restart haraka
|
||||
$SYSTEMCTL_PATH restart wildduck-webmail" > /usr/local/bin/reload-services.sh
|
||||
chmod +x /usr/local/bin/reload-services.sh
|
||||
|
||||
### start services ####
|
||||
|
||||
$SYSTEMCTL_PATH start mongod
|
||||
$SYSTEMCTL_PATH start wildduck
|
||||
$SYSTEMCTL_PATH start haraka
|
||||
$SYSTEMCTL_PATH start zone-mta
|
||||
$SYSTEMCTL_PATH start wildduck-webmail
|
||||
$SYSTEMCTL_PATH reload nginx
|
73
setup/15_install_deploy.sh
Normal file
73
setup/15_install_deploy.sh
Normal file
|
@ -0,0 +1,73 @@
|
|||
#! /bin/bash
|
||||
|
||||
OURNAME=15_install_deploy.sh
|
||||
|
||||
echo -e "\n-- Executing ${ORANGE}${OURNAME}${NC} subscript --"
|
||||
|
||||
cd "$INSTALLDIR"
|
||||
|
||||
echo "DEPLOY SETUP
|
||||
|
||||
1. Add your ssh key to /home/deploy/.ssh/authorized_keys
|
||||
|
||||
2. Clone application code
|
||||
\$ git clone deploy@$HOSTNAME:/var/opt/wildduck.git
|
||||
\$ git clone deploy@$HOSTNAME:/var/opt/zone-mta.git
|
||||
\$ git clone deploy@$HOSTNAME:/var/opt/wildduck-webmail.git
|
||||
\$ git clone deploy@$HOSTNAME:/var/opt/haraka-plugin-wildduck.git
|
||||
\$ git clone deploy@$HOSTNAME:/var/opt/zonemta-wildduck.git
|
||||
|
||||
3. After making a change in local copy deploy to server
|
||||
\$ git push origin master
|
||||
(you might need to use -f when pushing first time)
|
||||
|
||||
NAMESERVER SETUP
|
||||
================
|
||||
|
||||
MX
|
||||
--
|
||||
Add this MX record to the $MAILDOMAIN DNS zone:
|
||||
|
||||
$MAILDOMAIN. IN MX 5 $HOSTNAME.
|
||||
|
||||
SPF
|
||||
---
|
||||
Add this TXT record to the $MAILDOMAIN DNS zone:
|
||||
|
||||
$MAILDOMAIN. IN TXT \"v=spf1 a:$HOSTNAME ~all\"
|
||||
|
||||
DKIM
|
||||
----
|
||||
Add this TXT record to the $MAILDOMAIN DNS zone:
|
||||
|
||||
$DKIM_SELECTOR._domainkey.$MAILDOMAIN. IN TXT \"$DNS_ADDRESS\"
|
||||
|
||||
PTR
|
||||
---
|
||||
Make sure that your public IP has a PTR record set to $HOSTNAME.
|
||||
If your hosting provider does not allow you to set PTR records but has
|
||||
assigned their own hostname, then edit /etc/zone-mta/pools.toml and replace
|
||||
the hostname $HOSTNAME with the actual hostname of this server.
|
||||
|
||||
(this text is also stored to $INSTALLDIR/$MAILDOMAIN-nameserver.txt)" > "$INSTALLDIR/$MAILDOMAIN-nameserver.txt"
|
||||
|
||||
printf "Waiting for the server to start up.."
|
||||
|
||||
until $(curl --output /dev/null --silent --fail http://localhost:8080/users); do
|
||||
printf '.'
|
||||
sleep 2
|
||||
done
|
||||
echo "."
|
||||
|
||||
# Ensure DKIM key
|
||||
echo "Registering DKIM key for $MAILDOMAIN"
|
||||
echo $DKIM_JSON
|
||||
|
||||
curl -i -XPOST http://localhost:8080/dkim \
|
||||
-H 'Content-type: application/json' \
|
||||
-d "$DKIM_JSON"
|
||||
|
||||
echo ""
|
||||
cat "$INSTALLDIR/$MAILDOMAIN-nameserver.txt"
|
||||
echo ""
|
||||
echo "All done, open https://$HOSTNAME/ in your browser"
|
|
@ -31,9 +31,7 @@ All components use TLS/HTTPS with Let's Encrypt certificates by default. Webmail
|
|||
|
||||
Run the following commands as root user. Before actually starting _install.sh_ you could inspect it to see what it exactly does.
|
||||
|
||||
$ wget https://raw.githubusercontent.com/nodemailer/wildduck/master/setup/install.sh
|
||||
$ chmod +x install.sh
|
||||
$ ./install.sh mydomain.com
|
||||
$ wget -O - https://raw.githubusercontent.com/nodemailer/wildduck/master/setup/get_install.sh | bash
|
||||
|
||||
Where mydomain.com is the domain name of your server.
|
||||
|
||||
|
|
33
setup/get_install.sh
Normal file
33
setup/get_install.sh
Normal file
|
@ -0,0 +1,33 @@
|
|||
#! /bin/bash
|
||||
|
||||
# This script downloads all the installation files.
|
||||
BASEURL="https://raw.githubusercontent.com/bunyevacz/wildduck/install.sh/setup/"
|
||||
|
||||
## declare an array
|
||||
declare -a arr=(
|
||||
"00_install_variables.sh"
|
||||
"01_install_commit_variables.sh"
|
||||
"02_install_prerequisites.sh"
|
||||
"03_install_check_running_services.sh"
|
||||
"04_install_import_keys.sh"
|
||||
"05_install_packages.sh"
|
||||
"06_install_enable_services.sh"
|
||||
"07_install_wildduck.sh"
|
||||
"08_install_haraka.sh"
|
||||
"09_install_zone_mta.sh"
|
||||
"10_install_wildduck_webmail.sh"
|
||||
"11_install_nginx.sh"
|
||||
"12_install_ufw_rules.sh"
|
||||
"13_install_ssl_certs.sh"
|
||||
"14_install_start_services.sh"
|
||||
"15_install_deploy.sh"
|
||||
"install.sh"
|
||||
)
|
||||
|
||||
for i in "${arr[@]}"
|
||||
do
|
||||
wget -O $i ${BASEURL}$i
|
||||
done
|
||||
|
||||
chmod +x install.sh
|
||||
./install.sh
|
776
setup/install.sh
776
setup/install.sh
|
@ -1,742 +1,52 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Run as root:
|
||||
# sudo ./install.sh [maildomain.com]
|
||||
#! /bin/bash
|
||||
|
||||
# make sure the install script is started here
|
||||
OURNAME=install.sh
|
||||
INSTALLDIR=`pwd`
|
||||
source "$INSTALLDIR/00_install_variables.sh"
|
||||
|
||||
args=("$@")
|
||||
# echo $# arguments passed
|
||||
# echo ${args[0]} ${args[1]} ${args[2]}
|
||||
|
||||
if [ "$#" -gt "0" ]
|
||||
then
|
||||
# foo/bar -> bar
|
||||
MAILDOMAIN=${args[0]}
|
||||
HOSTNAME=${args[1]:-$MAILDOMAIN}
|
||||
echo -e "DOMAINNAME: ${GREEN}$MAILDOMAIN${NC}, HOSTNAME: ${GREEN}$HOSTNAME${NC}"
|
||||
else
|
||||
echo -e "we got ${RED}ZERO${NC} arguments, so here is the manual:"
|
||||
fun_print_help
|
||||
exit
|
||||
fi
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "This script must be run as root" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HOSTNAME="$1"
|
||||
|
||||
if [ -z "$HOSTNAME" ]
|
||||
then
|
||||
PUBLIC_IP=`curl -s https://api.ipify.org`
|
||||
if [ ! -z "$PUBLIC_IP" ]; then
|
||||
HOSTNAME=`dig +short -x $PUBLIC_IP | sed 's/\.$//'`
|
||||
HOSTNAME="${HOSTNAME:-$PUBLIC_IP}"
|
||||
fi
|
||||
HOSTNAME="${HOSTNAME:-`hostname`}"
|
||||
fi
|
||||
|
||||
MAILDOMAIN="${2:-$HOSTNAME}"
|
||||
|
||||
if lsof -Pi :25 -sTCP:LISTEN -t >/dev/null ; then
|
||||
echo "Error: SMTP server already running on port 25"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if lsof -Pi :587 -sTCP:LISTEN -t >/dev/null ; then
|
||||
echo "Error: SMTP server already running on port 587"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if lsof -Pi :993 -sTCP:LISTEN -t >/dev/null ; then
|
||||
echo "Error: IMAP server already running on port 993"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if lsof -Pi :995 -sTCP:LISTEN -t >/dev/null ; then
|
||||
echo "Error: POP3 server already running on port 995"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if lsof -Pi :80 -sTCP:LISTEN -t >/dev/null ; then
|
||||
echo "Error: HTTP server already running on port 80"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if lsof -Pi :443 -sTCP:LISTEN -t >/dev/null ; then
|
||||
echo "Error: HTTPS server already running on port 443"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
WILDDUCK_COMMIT="ac053d164bd8e10938d0da813c8295fb0c094437"
|
||||
ZONEMTA_COMMIT="b9915924a8a4488837e5cb1636901631860da1d3" # zone-mta-template
|
||||
WEBMAIL_COMMIT="221783539bd4382917d750989bb2ab425804f80a"
|
||||
WILDDUCK_ZONEMTA_COMMIT="v1.11.2"
|
||||
WILDDUCK_HARAKA_COMMIT="92eba398676dd2418a0830256aa554efd09fb546"
|
||||
HARAKA_VERSION="2.8.17"
|
||||
|
||||
# stop on first error
|
||||
set -e
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
function hook_script {
|
||||
echo "#!/bin/bash
|
||||
git --git-dir=/var/opt/$1.git --work-tree=\"/opt/$1\" checkout "\$3" -f
|
||||
cd \"/opt/$1\"
|
||||
rm -rf package-lock.json
|
||||
npm install --production --progress=false
|
||||
sudo $SYSTEMCTL_PATH restart $1 || echo \"Failed restarting service\"" > "/var/opt/$1.git/hooks/update"
|
||||
chmod +x "/var/opt/$1.git/hooks/update"
|
||||
}
|
||||
|
||||
function hook_script_bower {
|
||||
echo "#!/bin/bash
|
||||
git --git-dir=/var/opt/$1.git --work-tree=\"/opt/$1\" checkout "\$3" -f
|
||||
cd \"/opt/$1\"
|
||||
rm -rf package-lock.json
|
||||
npm install --progress=false
|
||||
npm run bowerdeps
|
||||
sudo $SYSTEMCTL_PATH restart $1 || echo \"Failed restarting service\"" > "/var/opt/$1.git/hooks/update"
|
||||
chmod +x "/var/opt/$1.git/hooks/update"
|
||||
}
|
||||
|
||||
# create user for running applications
|
||||
useradd wildduck || echo "User wildduck already exists"
|
||||
|
||||
# create user for deploying code
|
||||
useradd deploy || echo "User deploy already exists"
|
||||
|
||||
mkdir -p /home/deploy/.ssh
|
||||
# add your own key to the authorized_keys file
|
||||
echo "# Add your public key here
|
||||
" >> /home/deploy/.ssh/authorized_keys
|
||||
chown -R deploy:deploy /home/deploy
|
||||
|
||||
# mongo
|
||||
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
|
||||
gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58712A2291FA4AD5
|
||||
gpg --armor --export 58712A2291FA4AD5 | apt-key add -
|
||||
echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list
|
||||
|
||||
apt-get update
|
||||
apt-get -q -y install pwgen git ufw build-essential libssl-dev dnsutils python software-properties-common nginx lsb-release wget
|
||||
|
||||
# node
|
||||
curl -sL https://deb.nodesource.com/setup_8.x | bash -
|
||||
|
||||
# Setup tor to be able to send emails to .onion network.
|
||||
# Receiving from onion is not automatically set up, you would have to
|
||||
# create a hidden servcie first and then bridge port 25
|
||||
echo 'deb http://deb.torproject.org/torproject.org xenial main
|
||||
deb-src http://deb.torproject.org/torproject.org xenial main' > /etc/apt/sources.list.d/tor.list
|
||||
gpg --keyserver keys.gnupg.net --recv A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89
|
||||
gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | sudo apt-key add -
|
||||
|
||||
apt-get update
|
||||
|
||||
apt-get -q -y install mongodb-org nodejs tor deb.torproject.org-keyring
|
||||
|
||||
NODE_PATH=`which node`
|
||||
SYSTEMCTL_PATH=`which systemctl`
|
||||
|
||||
SRS_SECRET=`pwgen 12 -1`
|
||||
DKIM_SECRET=`pwgen 12 -1`
|
||||
ZONEMTA_SECRET=`pwgen 12 -1`
|
||||
DKIM_SELECTOR=`$NODE_PATH -e 'console.log(Date().toString().substr(4, 3).toLowerCase() + new Date().getFullYear())'`
|
||||
|
||||
$SYSTEMCTL_PATH enable mongod.service
|
||||
|
||||
# redis
|
||||
apt-add-repository -y ppa:chris-lea/redis-server
|
||||
|
||||
# rspamd
|
||||
CODENAME=`lsb_release -c -s`
|
||||
wget -O- https://rspamd.com/apt-stable/gpg.key | apt-key add -
|
||||
echo "deb http://rspamd.com/apt-stable/ $CODENAME main" > /etc/apt/sources.list.d/rspamd.list
|
||||
echo "deb-src http://rspamd.com/apt-stable/ $CODENAME main" >> /etc/apt/sources.list.d/rspamd.list
|
||||
apt-get update
|
||||
|
||||
apt-get -q -y install redis-server clamav clamav-daemon
|
||||
apt-get -q -y --no-install-recommends install rspamd
|
||||
|
||||
apt-get clean
|
||||
|
||||
node -v
|
||||
redis-server -v
|
||||
mongod --version
|
||||
echo "HOSTNAME: $HOSTNAME"
|
||||
|
||||
# remove old sudoers file
|
||||
rm -rf /etc/sudoers.d/wildduck
|
||||
|
||||
####### WILD DUCK #######
|
||||
|
||||
# clear previous install
|
||||
if [ -f "/etc/systemd/system/wildduck.service" ]
|
||||
then
|
||||
$SYSTEMCTL_PATH stop wildduck || true
|
||||
$SYSTEMCTL_PATH disable wildduck || true
|
||||
rm -rf /etc/systemd/system/wildduck.service
|
||||
fi
|
||||
rm -rf /var/opt/wildduck.git
|
||||
rm -rf /opt/wildduck
|
||||
rm -rf /etc/wildduck
|
||||
|
||||
# fresh install
|
||||
cd /var/opt
|
||||
git clone --bare git://github.com/nodemailer/wildduck.git
|
||||
|
||||
# create update hook so we can later deploy to this location
|
||||
hook_script wildduck
|
||||
|
||||
# allow deploy user to restart wildduck service
|
||||
echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart wildduck" >> /etc/sudoers.d/wildduck
|
||||
|
||||
# checkout files from git to working directory
|
||||
mkdir -p /opt/wildduck
|
||||
git --git-dir=/var/opt/wildduck.git --work-tree=/opt/wildduck checkout "$WILDDUCK_COMMIT"
|
||||
cp -r /opt/wildduck/config /etc/wildduck
|
||||
mv /etc/wildduck/default.toml /etc/wildduck/wildduck.toml
|
||||
|
||||
# enable example message
|
||||
sed -i -e 's/"disabled": true/"disabled": false/g' /opt/wildduck/emails/00-example.json
|
||||
|
||||
# update ports
|
||||
sed -i -e "s/999/99/g;s/localhost/$HOSTNAME/g" /etc/wildduck/imap.toml
|
||||
sed -i -e "s/999/99/g;s/localhost/$HOSTNAME/g" /etc/wildduck/pop3.toml
|
||||
|
||||
echo "enabled=true
|
||||
port=24
|
||||
disableSTARTTLS=true" > /etc/wildduck/lmtp.toml
|
||||
|
||||
# make sure that DKIM keys are not stored to database as cleartext
|
||||
#echo "secret=\"$DKIM_SECRET\"
|
||||
#cipher=\"aes192\"" >> /etc/wildduck/dkim.toml
|
||||
|
||||
echo "user=\"wildduck\"
|
||||
group=\"wildduck\"
|
||||
emailDomain=\"$MAILDOMAIN\"" | cat - /etc/wildduck/wildduck.toml > temp && mv temp /etc/wildduck/wildduck.toml
|
||||
|
||||
sed -i -e "s/localhost:3000/$HOSTNAME/g;s/localhost/$HOSTNAME/g;s/2587/587/g" /etc/wildduck/wildduck.toml
|
||||
|
||||
cd /opt/wildduck
|
||||
npm install --unsafe-perm --production
|
||||
|
||||
chown -R deploy:deploy /var/opt/wildduck.git
|
||||
chown -R deploy:deploy /opt/wildduck
|
||||
|
||||
echo "[Unit]
|
||||
Description=WildDuck Mail Server
|
||||
Conflicts=cyrus.service dovecot.service
|
||||
After=mongod.service redis.service
|
||||
|
||||
[Service]
|
||||
Environment=\"NODE_ENV=production\"
|
||||
WorkingDirectory=/opt/wildduck
|
||||
ExecStart=$NODE_PATH server.js --config=\"/etc/wildduck/wildduck.toml\"
|
||||
ExecReload=/bin/kill -HUP \$MAINPID
|
||||
Type=simple
|
||||
Restart=always
|
||||
SyslogIdentifier=wildduck-server
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target" > /etc/systemd/system/wildduck.service
|
||||
|
||||
$SYSTEMCTL_PATH enable wildduck.service
|
||||
|
||||
####### HARAKA #######
|
||||
|
||||
# clear previous install
|
||||
if [ -f "/etc/systemd/system/haraka.service" ]
|
||||
then
|
||||
$SYSTEMCTL_PATH stop haraka || true
|
||||
$SYSTEMCTL_PATH disable haraka || true
|
||||
rm -rf /etc/systemd/system/haraka.service
|
||||
fi
|
||||
rm -rf /var/opt/haraka-plugin-wildduck.git
|
||||
rm -rf /opt/haraka
|
||||
|
||||
# fresh install
|
||||
cd /var/opt
|
||||
git clone --bare git://github.com/nodemailer/haraka-plugin-wildduck.git
|
||||
echo "#!/bin/bash
|
||||
git --git-dir=/var/opt/haraka-plugin-wildduck.git --work-tree=/opt/haraka/plugins/wildduck checkout "\$3" -f
|
||||
cd /opt/haraka/plugins/wildduck
|
||||
rm -rf package-lock.json
|
||||
npm install --production --progress=false
|
||||
sudo $SYSTEMCTL_PATH restart haraka || echo \"Failed restarting service\"" > "/var/opt/haraka-plugin-wildduck.git/hooks/update"
|
||||
chmod +x "/var/opt/haraka-plugin-wildduck.git/hooks/update"
|
||||
|
||||
# allow deploy user to restart wildduck service
|
||||
echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart haraka" >> /etc/sudoers.d/wildduck
|
||||
|
||||
cd
|
||||
npm install --unsafe-perm -g Haraka@$HARAKA_VERSION
|
||||
haraka -i /opt/haraka
|
||||
cd /opt/haraka
|
||||
npm install --unsafe-perm --save haraka-plugin-rspamd Haraka@$HARAKA_VERSION
|
||||
|
||||
# Haraka WIldDuck plugin. Install as separate repo as it can be edited more easily later
|
||||
mkdir -p plugins/wildduck
|
||||
git --git-dir=/var/opt/haraka-plugin-wildduck.git --work-tree=/opt/haraka/plugins/wildduck checkout "$WILDDUCK_HARAKA_COMMIT"
|
||||
|
||||
cd plugins/wildduck
|
||||
npm install --unsafe-perm --production --progress=false
|
||||
|
||||
cd /opt/haraka
|
||||
mv config/plugins config/plugins.bak
|
||||
|
||||
echo "26214400" > config/databytes
|
||||
echo "$HOSTNAME" > config/me
|
||||
echo "WildDuck MX" > config/smtpgreeting
|
||||
|
||||
echo "spf
|
||||
|
||||
## ClamAV is disabled by default. Make sure freshclam has updated all
|
||||
## virus definitions and clamav-daemon has successfully started before
|
||||
## enabling it.
|
||||
#clamd
|
||||
|
||||
rspamd
|
||||
tls
|
||||
#dkim_verify
|
||||
|
||||
# WildDuck plugin handles recipient checking and queueing
|
||||
wildduck" > config/plugins
|
||||
|
||||
echo "key=/etc/wildduck/certs/privkey.pem
|
||||
cert=/etc/wildduck/certs/fullchain.pem" > config/tls.ini
|
||||
|
||||
echo 'host = localhost
|
||||
port = 11333
|
||||
add_headers = always
|
||||
[dkim]
|
||||
enabled = true
|
||||
[header]
|
||||
bar = X-Rspamd-Bar
|
||||
report = X-Rspamd-Report
|
||||
score = X-Rspamd-Score
|
||||
spam = X-Rspamd-Spam
|
||||
[check]
|
||||
authenticated=true
|
||||
private_ip=true
|
||||
[reject]
|
||||
spam = false
|
||||
[soft_reject]
|
||||
enabled = true
|
||||
[rmilter_headers]
|
||||
enabled = true
|
||||
[spambar]
|
||||
positive = +
|
||||
negative = -
|
||||
neutral = /' > config/rspamd.ini
|
||||
|
||||
echo 'clamd_socket = /var/run/clamav/clamd.ctl
|
||||
[reject]
|
||||
virus=true
|
||||
error=false' > config/clamd.ini
|
||||
|
||||
cp plugins/wildduck/config/wildduck.yaml config/wildduck.yaml
|
||||
sed -i -e "s/secret value/$SRS_SECRET/g" config/wildduck.yaml
|
||||
|
||||
echo '[Unit]
|
||||
Description=Haraka MX Server
|
||||
After=mongod.service redis.service
|
||||
|
||||
[Service]
|
||||
Environment="NODE_ENV=production"
|
||||
WorkingDirectory=/opt/haraka
|
||||
ExecStart=/usr/bin/node ./node_modules/.bin/haraka -c .
|
||||
Type=simple
|
||||
Restart=always
|
||||
SyslogIdentifier=haraka
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target' > /etc/systemd/system/haraka.service
|
||||
|
||||
echo 'user=wildduck
|
||||
group=wildduck' >> config/smtp.ini
|
||||
|
||||
chown -R deploy:deploy /opt/haraka
|
||||
chown -R deploy:deploy /var/opt/haraka-plugin-wildduck.git
|
||||
|
||||
# ensure queue folder for Haraka
|
||||
mkdir -p /opt/haraka/queue
|
||||
chown -R wildduck:wildduck /opt/haraka/queue
|
||||
|
||||
$SYSTEMCTL_PATH enable haraka.service
|
||||
|
||||
#### ZoneMTA ####
|
||||
|
||||
# clear previous install
|
||||
if [ -f "/etc/systemd/system/zone-mta.service" ]
|
||||
then
|
||||
$SYSTEMCTL_PATH stop zone-mta || true
|
||||
$SYSTEMCTL_PATH disable zone-mta || true
|
||||
rm -rf /etc/systemd/system/zone-mta.service
|
||||
fi
|
||||
rm -rf /var/opt/zone-mta.git
|
||||
rm -rf /var/opt/zonemta-wildduck.git
|
||||
rm -rf /opt/zone-mta
|
||||
rm -rf /etc/zone-mta
|
||||
|
||||
# fresh install
|
||||
cd /var/opt
|
||||
git clone --bare git://github.com/zone-eu/zone-mta-template.git zone-mta.git
|
||||
git clone --bare git://github.com/nodemailer/zonemta-wildduck.git
|
||||
|
||||
# create update hooks so we can later deploy to this location
|
||||
hook_script zone-mta
|
||||
echo "#!/bin/bash
|
||||
git --git-dir=/var/opt/zonemta-wildduck.git --work-tree=/opt/zone-mta/plugins/wildduck checkout "\$3" -f
|
||||
cd /opt/zone-mta/plugins/wildduck
|
||||
rm -rf package-lock.json
|
||||
npm install --production --progress=false
|
||||
sudo $SYSTEMCTL_PATH restart zone-mta || echo \"Failed restarting service\"" > "/var/opt/zonemta-wildduck.git/hooks/update"
|
||||
chmod +x "/var/opt/zonemta-wildduck.git/hooks/update"
|
||||
|
||||
# allow deploy user to restart zone-mta service
|
||||
echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart zone-mta" >> /etc/sudoers.d/zone-mta
|
||||
|
||||
# checkout files from git to working directory
|
||||
mkdir -p /opt/zone-mta
|
||||
git --git-dir=/var/opt/zone-mta.git --work-tree=/opt/zone-mta checkout "$ZONEMTA_COMMIT"
|
||||
|
||||
mkdir -p /opt/zone-mta/plugins/wildduck
|
||||
git --git-dir=/var/opt/zonemta-wildduck.git --work-tree=/opt/zone-mta/plugins/wildduck checkout "$WILDDUCK_ZONEMTA_COMMIT"
|
||||
|
||||
cp -r /opt/zone-mta/config /etc/zone-mta
|
||||
sed -i -e 's/port=2525/port=587/g;s/host="127.0.0.1"/host="0.0.0.0"/g;s/authentication=false/authentication=true/g' /etc/zone-mta/interfaces/feeder.toml
|
||||
rm -rf /etc/zone-mta/plugins/dkim.toml
|
||||
echo '# @include "/etc/wildduck/dbs.toml"' > /etc/zone-mta/dbs-production.toml
|
||||
echo 'user="wildduck"
|
||||
group="wildduck"' | cat - /etc/zone-mta/zonemta.toml > temp && mv temp /etc/zone-mta/zonemta.toml
|
||||
|
||||
echo "[[default]]
|
||||
address=\"0.0.0.0\"
|
||||
name=\"$HOSTNAME\"" > /etc/zone-mta/pools.toml
|
||||
|
||||
echo "[\"modules/zonemta-loop-breaker\"]
|
||||
enabled=\"sender\"
|
||||
secret=\"$ZONEMTA_SECRET\"
|
||||
algo=\"md5\"" > /etc/zone-mta/plugins/loop-breaker.toml
|
||||
|
||||
echo '["modules/zonemta-onion"]
|
||||
enabled=["sender"]
|
||||
["modules/zonemta-onion".proxy]
|
||||
host="127.0.0.1"
|
||||
port=9050' > /etc/zone-mta/plugins/onion.toml
|
||||
|
||||
echo "[\"wildduck\"]
|
||||
enabled=[\"receiver\", \"sender\"]
|
||||
|
||||
# which interfaces this plugin applies to
|
||||
interfaces=[\"feeder\"]
|
||||
|
||||
# optional hostname to be used in headers
|
||||
# defaults to os.hostname()
|
||||
hostname=\"$HOSTNAME\"
|
||||
|
||||
# How long to keep auth records in log
|
||||
authlogExpireDays=30
|
||||
|
||||
# SRS settings for forwarded emails
|
||||
|
||||
[srs]
|
||||
# Handle rewriting of forwarded emails
|
||||
enabled=true
|
||||
# SRS secret value. Must be the same as in the MX side
|
||||
secret=\"$SRS_SECRET\"
|
||||
# SRS domain, must resolve back to MX
|
||||
rewriteDomain=\"$MAILDOMAIN\"
|
||||
|
||||
[dkim]
|
||||
# share config with WildDuck installation
|
||||
# @include \"/etc/wildduck/dkim.toml\"
|
||||
" > /etc/zone-mta/plugins/wildduck.toml
|
||||
|
||||
cd /opt/zone-mta/keys
|
||||
openssl genrsa -out "$MAILDOMAIN-dkim.pem" 2048
|
||||
chmod 400 "$MAILDOMAIN-dkim.pem"
|
||||
openssl rsa -in "$MAILDOMAIN-dkim.pem" -out "$MAILDOMAIN-dkim.cert" -pubout
|
||||
DNS_ADDRESS="v=DKIM1;p=$(grep -v -e '^-' $MAILDOMAIN-dkim.cert | tr -d "\n")"
|
||||
|
||||
DKIM_JSON=`DOMAIN="$MAILDOMAIN" SELECTOR="$DKIM_SELECTOR" node -e 'console.log(JSON.stringify({
|
||||
domain: process.env.DOMAIN,
|
||||
selector: process.env.SELECTOR,
|
||||
description: "Default DKIM key for "+process.env.DOMAIN,
|
||||
privateKey: fs.readFileSync("/opt/zone-mta/keys/"+process.env.DOMAIN+"-dkim.pem", "UTF-8")
|
||||
}))'`
|
||||
|
||||
cd /opt/zone-mta
|
||||
npm install --unsafe-perm --production
|
||||
npm install zonemta-onion --save
|
||||
|
||||
cd /opt/zone-mta/plugins/wildduck
|
||||
npm install --unsafe-perm --production
|
||||
|
||||
chown -R deploy:deploy /var/opt/zone-mta.git
|
||||
chown -R deploy:deploy /var/opt/zonemta-wildduck.git
|
||||
chown -R deploy:deploy /opt/zone-mta
|
||||
|
||||
echo '[Unit]
|
||||
Description=Zone Mail Transport Agent
|
||||
Conflicts=sendmail.service exim.service postfix.service
|
||||
After=mongod.service redis.service
|
||||
|
||||
[Service]
|
||||
Environment="NODE_ENV=production"
|
||||
WorkingDirectory=/opt/zone-mta
|
||||
ExecStart=/usr/bin/node index.js --config="/etc/zone-mta/zonemta.toml"
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Type=simple
|
||||
Restart=always
|
||||
SyslogIdentifier=zone-mta
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target' > /etc/systemd/system/zone-mta.service
|
||||
|
||||
$SYSTEMCTL_PATH enable zone-mta.service
|
||||
|
||||
#### WWW ####
|
||||
####
|
||||
# clear previous install
|
||||
if [ -f "/etc/systemd/system/wildduck-webmail.service" ]
|
||||
then
|
||||
$SYSTEMCTL_PATH stop wildduck-webmail || true
|
||||
$SYSTEMCTL_PATH disable wildduck-webmail || true
|
||||
rm -rf /etc/systemd/system/wildduck-webmail.service
|
||||
fi
|
||||
rm -rf /var/opt/wildduck-webmail.git
|
||||
rm -rf /opt/wildduck-webmail
|
||||
|
||||
# fresh install
|
||||
cd /var/opt
|
||||
git clone --bare git://github.com/nodemailer/wildduck-webmail.git
|
||||
|
||||
# create update hook so we can later deploy to this location
|
||||
hook_script_bower wildduck-webmail
|
||||
chmod +x /var/opt/wildduck-webmail.git/hooks/update
|
||||
|
||||
# allow deploy user to restart zone-mta service
|
||||
echo "deploy ALL = (root) NOPASSWD: $SYSTEMCTL_PATH restart wildduck-webmail" >> /etc/sudoers.d/wildduck-webmail
|
||||
|
||||
# checkout files from git to working directory
|
||||
mkdir -p /opt/wildduck-webmail
|
||||
git --git-dir=/var/opt/wildduck-webmail.git --work-tree=/opt/wildduck-webmail checkout "$WEBMAIL_COMMIT"
|
||||
cp /opt/wildduck-webmail/config/default.toml /etc/wildduck/wildduck-webmail.toml
|
||||
|
||||
sed -i -e "s/localhost/$HOSTNAME/g;s/999/99/g;s/2587/587/g;s/proxy=false/proxy=true/g" /etc/wildduck/wildduck-webmail.toml
|
||||
|
||||
cd /opt/wildduck-webmail
|
||||
|
||||
chown -R deploy:deploy /var/opt/wildduck-webmail.git
|
||||
chown -R deploy:deploy /opt/wildduck-webmail
|
||||
|
||||
# we need to run bower which reject root
|
||||
HOME=/home/deploy sudo -u deploy npm install
|
||||
HOME=/home/deploy sudo -u deploy npm run bowerdeps
|
||||
|
||||
echo '[Unit]
|
||||
Description=Wildduck Webmail
|
||||
After=wildduck.service
|
||||
|
||||
[Service]
|
||||
Environment="NODE_ENV=production"
|
||||
WorkingDirectory=/opt/wildduck-webmail
|
||||
ExecStart=/usr/bin/node server.js --config="/etc/wildduck/wildduck-webmail.toml"
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Type=simple
|
||||
Restart=always
|
||||
SyslogIdentifier=wildduck-www
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target' > /etc/systemd/system/wildduck-webmail.service
|
||||
|
||||
$SYSTEMCTL_PATH enable wildduck-webmail.service
|
||||
|
||||
#### NGINX ####
|
||||
|
||||
# Create initial certs. These will be overwritten later by Let's Encrypt certs
|
||||
mkdir -p /etc/wildduck/certs
|
||||
cd /etc/wildduck/certs
|
||||
openssl req -subj "/CN=$HOSTNAME/O=My Company Name LTD./C=US" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout privkey.pem -out fullchain.pem
|
||||
|
||||
chown -R wildduck:wildduck /etc/wildduck/certs
|
||||
chmod 0700 /etc/wildduck/certs/privkey.pem
|
||||
|
||||
# Setup domain without SSL at first, otherwise acme.sh will fail
|
||||
echo "server {
|
||||
listen 80;
|
||||
|
||||
server_name $HOSTNAME;
|
||||
|
||||
ssl_certificate /etc/wildduck/certs/fullchain.pem;
|
||||
ssl_certificate_key /etc/wildduck/certs/privkey.pem;
|
||||
|
||||
# special config for EventSource to disable gzip
|
||||
location /api/events {
|
||||
proxy_http_version 1.1;
|
||||
gzip off;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header HOST \$http_host;
|
||||
proxy_set_header X-NginX-Proxy true;
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
# special config for uploads
|
||||
location /webmail/send {
|
||||
client_max_body_size 15M;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header HOST \$http_host;
|
||||
proxy_set_header X-NginX-Proxy true;
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header HOST \$http_host;
|
||||
proxy_set_header X-NginX-Proxy true;
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}" > "/etc/nginx/sites-available/$HOSTNAME"
|
||||
rm -rf "/etc/nginx/sites-enabled/$HOSTNAME"
|
||||
ln -s "/etc/nginx/sites-available/$HOSTNAME" "/etc/nginx/sites-enabled/$HOSTNAME"
|
||||
$SYSTEMCTL_PATH reload nginx
|
||||
|
||||
#### UFW ####
|
||||
|
||||
ufw allow 22/tcp
|
||||
ufw allow 80/tcp
|
||||
ufw allow 443/tcp
|
||||
ufw allow 25/tcp
|
||||
ufw allow 587/tcp
|
||||
ufw allow 993/tcp
|
||||
ufw allow 995/tcp
|
||||
ufw --force enable
|
||||
|
||||
#### SSL CERTS ####
|
||||
|
||||
curl https://get.acme.sh | sh
|
||||
|
||||
echo 'cert="/etc/wildduck/certs/fullchain.pem"
|
||||
key="/etc/wildduck/certs/privkey.pem"' > /etc/wildduck/tls.toml
|
||||
|
||||
sed -i -e "s/key=/#key=/g;s/cert=/#cert=/g" /etc/zone-mta/interfaces/feeder.toml
|
||||
echo '# @include "../../wildduck/tls.toml"' >> /etc/zone-mta/interfaces/feeder.toml
|
||||
|
||||
# vanity script as first run should not restart anything
|
||||
echo '#!/bin/bash
|
||||
echo "OK"' > /usr/local/bin/reload-services.sh
|
||||
chmod +x /usr/local/bin/reload-services.sh
|
||||
|
||||
/root/.acme.sh/acme.sh --issue --nginx \
|
||||
-d "$HOSTNAME" \
|
||||
--key-file /etc/wildduck/certs/privkey.pem \
|
||||
--fullchain-file /etc/wildduck/certs/fullchain.pem \
|
||||
--reloadcmd "/usr/local/bin/reload-services.sh" \
|
||||
--force || echo "Warning: Failed to generate certificates, using self-signed certs"
|
||||
|
||||
# Update site config, make sure ssl is enabled
|
||||
echo "server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name $HOSTNAME;
|
||||
|
||||
ssl_certificate /etc/wildduck/certs/fullchain.pem;
|
||||
ssl_certificate_key /etc/wildduck/certs/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header HOST \$http_host;
|
||||
proxy_set_header X-NginX-Proxy true;
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_redirect off;
|
||||
}
|
||||
}" > "/etc/nginx/sites-available/$HOSTNAME"
|
||||
$SYSTEMCTL_PATH reload nginx
|
||||
|
||||
# update reload script for future updates
|
||||
echo "#!/bin/bash
|
||||
$SYSTEMCTL_PATH reload nginx
|
||||
$SYSTEMCTL_PATH reload wildduck
|
||||
$SYSTEMCTL_PATH restart zone-mta
|
||||
$SYSTEMCTL_PATH restart haraka
|
||||
$SYSTEMCTL_PATH restart wildduck-webmail" > /usr/local/bin/reload-services.sh
|
||||
chmod +x /usr/local/bin/reload-services.sh
|
||||
|
||||
### start services ####
|
||||
|
||||
$SYSTEMCTL_PATH start mongod
|
||||
$SYSTEMCTL_PATH start wildduck
|
||||
$SYSTEMCTL_PATH start haraka
|
||||
$SYSTEMCTL_PATH start zone-mta
|
||||
$SYSTEMCTL_PATH start wildduck-webmail
|
||||
$SYSTEMCTL_PATH reload nginx
|
||||
|
||||
cd "$INSTALLDIR"
|
||||
|
||||
echo "DEPLOY SETUP
|
||||
|
||||
1. Add your ssh key to /home/deploy/.ssh/authorized_keys
|
||||
|
||||
2. Clone application code
|
||||
\$ git clone deploy@$HOSTNAME:/var/opt/wildduck.git
|
||||
\$ git clone deploy@$HOSTNAME:/var/opt/zone-mta.git
|
||||
\$ git clone deploy@$HOSTNAME:/var/opt/wildduck-webmail.git
|
||||
\$ git clone deploy@$HOSTNAME:/var/opt/haraka-plugin-wildduck.git
|
||||
\$ git clone deploy@$HOSTNAME:/var/opt/zonemta-wildduck.git
|
||||
|
||||
3. After making a change in local copy deploy to server
|
||||
\$ git push origin master
|
||||
(you might need to use -f when pushing first time)
|
||||
|
||||
NAMESERVER SETUP
|
||||
================
|
||||
|
||||
MX
|
||||
--
|
||||
Add this MX record to the $MAILDOMAIN DNS zone:
|
||||
|
||||
$MAILDOMAIN. IN MX 5 $HOSTNAME.
|
||||
|
||||
SPF
|
||||
---
|
||||
Add this TXT record to the $MAILDOMAIN DNS zone:
|
||||
|
||||
$MAILDOMAIN. IN TXT \"v=spf1 a:$HOSTNAME ~all\"
|
||||
|
||||
DKIM
|
||||
----
|
||||
Add this TXT record to the $MAILDOMAIN DNS zone:
|
||||
|
||||
$DKIM_SELECTOR._domainkey.$MAILDOMAIN. IN TXT \"$DNS_ADDRESS\"
|
||||
|
||||
PTR
|
||||
---
|
||||
Make sure that your public IP has a PTR record set to $HOSTNAME.
|
||||
If your hosting provider does not allow you to set PTR records but has
|
||||
assigned their own hostname, then edit /etc/zone-mta/pools.toml and replace
|
||||
the hostname $HOSTNAME with the actual hostname of this server.
|
||||
|
||||
(this text is also stored to $INSTALLDIR/$MAILDOMAIN-nameserver.txt)" > "$INSTALLDIR/$MAILDOMAIN-nameserver.txt"
|
||||
|
||||
printf "Waiting for the server to start up.."
|
||||
|
||||
until $(curl --output /dev/null --silent --fail http://localhost:8080/users); do
|
||||
printf '.'
|
||||
sleep 2
|
||||
# source is for executing in the current shell, and not in a subset.
|
||||
# defined variables persists across files
|
||||
declare -a arr=(
|
||||
"01_install_commit_variables.sh"
|
||||
"02_install_prerequisites.sh"
|
||||
"03_install_check_running_services.sh"
|
||||
"04_install_import_keys.sh"
|
||||
"05_install_packages.sh"
|
||||
"06_install_enable_services.sh"
|
||||
"07_install_wildduck.sh"
|
||||
"08_install_haraka.sh"
|
||||
"09_install_zone_mta.sh"
|
||||
"10_install_wildduck_webmail.sh"
|
||||
"11_install_nginx.sh"
|
||||
"12_install_ufw_rules.sh"
|
||||
"13_install_ssl_certs.sh"
|
||||
"14_install_start_services.sh"
|
||||
"15_install_deploy.sh"
|
||||
)
|
||||
|
||||
for i in "${arr[@]}"
|
||||
do
|
||||
source "$INSTALLDIR/$i"
|
||||
done
|
||||
echo "."
|
||||
|
||||
# Ensure DKIM key
|
||||
echo "Registering DKIM key for $MAILDOMAIN"
|
||||
echo $DKIM_JSON
|
||||
|
||||
curl -i -XPOST http://localhost:8080/dkim \
|
||||
-H 'Content-type: application/json' \
|
||||
-d "$DKIM_JSON"
|
||||
|
||||
echo ""
|
||||
cat "$INSTALLDIR/$MAILDOMAIN-nameserver.txt"
|
||||
echo ""
|
||||
echo "All done, open https://$HOSTNAME/ in your browser"
|
||||
|
|
Loading…
Reference in a new issue