574 lines
15 KiB
Text
574 lines
15 KiB
Text
# This is not a standalone script. It provides common functions to server-*.sh scripts
|
|
|
|
case "$hostType" in
|
|
centos7)
|
|
hostTypeLabel="CentOS 7"
|
|
redisService=redis
|
|
apacheConf="/etc/httpd/conf.d/mailtrain.conf"
|
|
apacheLogsPath="logs"
|
|
|
|
if hash firewall-cmd 2>/dev/null; then
|
|
firewallCmdExists=yes
|
|
fi
|
|
;;
|
|
|
|
centos8)
|
|
hostTypeLabel="CentOS 8"
|
|
redisService=redis
|
|
apacheConf="/etc/httpd/conf.d/mailtrain.conf"
|
|
apacheLogsPath="logs"
|
|
|
|
if hash firewall-cmd 2>/dev/null; then
|
|
firewallCmdExists=true
|
|
fi
|
|
;;
|
|
|
|
ubuntu1804)
|
|
hostTypeLabel="Ubuntu 18.04 LTS"
|
|
redisService=redis-server
|
|
apacheConf="/etc/apache2/conf-available/mailtrain.conf"
|
|
apacheLogsPath="/var/log/apache2"
|
|
|
|
if hash ufw 2>/dev/null; then
|
|
firewallCmdExists=yes
|
|
fi
|
|
;;
|
|
|
|
debian10)
|
|
hostTypeLabel="Debian 10"
|
|
redisService=redis-server
|
|
apacheConf="/etc/apache2/conf-available/mailtrain.conf"
|
|
apacheLogsPath="/var/log/apache2"
|
|
|
|
if hash ufw 2>/dev/null; then
|
|
firewallCmdExists=yes
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
|
|
|
|
|
|
function performInstallLocal {
|
|
local paramCount="$1"
|
|
|
|
if [ $paramCount -ne 0 ]; then
|
|
echo "Error: incorrect number of parameters."
|
|
|
|
cat <<EOF
|
|
|
|
Basic usage: install-${hostType}-local.sh
|
|
|
|
Installs Mailtrain 2 on ${hostTypeLabel}. This performs installation for local use on HTTP ports 3000, 3003, 3004. If you want
|
|
to make these ports available from outside, setup an HTTPS proxy yourself or use install-${hostType}-https.sh instead.
|
|
|
|
Example: install-${hostType}-local.sh
|
|
EOF
|
|
|
|
exit 1
|
|
fi
|
|
|
|
installPrerequisities
|
|
installMailtrain http://localhost:3000 http://localhost:3003 http://localhost:3004 0.0.0.0 false
|
|
installService
|
|
|
|
echo
|
|
echo "Success!"
|
|
}
|
|
|
|
|
|
function performInstallHttps {
|
|
local paramCount="$1"
|
|
hostTrusted="$2"
|
|
hostSandbox="$3"
|
|
hostPublic="$4"
|
|
email="$5"
|
|
|
|
|
|
if [ $paramCount -ne 4 ]; then
|
|
echo "Error: incorrect number of parameters."
|
|
|
|
cat <<EOF
|
|
|
|
Basic usage: install-${hostType}-https.sh <trusted host> <sandbox host> <public host> <email>
|
|
|
|
Installs Mailtrain 2 on ${hostTypeLabel}. This performs installation for external use. It installs Mailtrain, sets up
|
|
a reverse HTTPS proxy using Apache HTTPD, sets up firewall rules, and obtains a certificate from Letsencrypt.
|
|
|
|
You have to allocate three endpoints for Mailtrain - trusted (admin UI), sandbox (editors for templates), public (subscription forms and archive).
|
|
These endpoints have to differ in hostname. It's fine to host them all from one IP address. The email parameters is needed by certbot.
|
|
|
|
Note, that this will automatically accept the Let's Encrypt's Terms of Service.
|
|
Thus, by running this script below, you agree with the Let's Encrypt's Terms of Service (https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf).
|
|
|
|
Example: install-${hostType}-https.sh mailtrain.example.com sbox.mailtrain.example.com lists.example.com admin@example.com
|
|
EOF
|
|
|
|
exit 1
|
|
fi
|
|
|
|
installPrerequisities
|
|
installHttpd 443 443 443
|
|
createCertificates "${hostTrusted}" "${hostSandbox}" "${hostPublic}" "${email}"
|
|
installHttpsProxy "${hostTrusted}" 443 "${hostSandbox}" 443 "${hostPublic}" 443 "/etc/letsencrypt/live/${hostPublic}/cert.pem" "/etc/letsencrypt/live/${hostPublic}/privkey.pem" "/etc/letsencrypt/live/${hostPublic}/chain.pem"
|
|
installMailtrain "https://${hostTrusted}" "https://${hostSandbox}" "https://${hostPublic}" 127.0.0.1 true
|
|
installService
|
|
|
|
echo
|
|
echo "Success!"
|
|
}
|
|
|
|
|
|
|
|
function installPrerequisities {
|
|
# Run as root!
|
|
if [[ $EUID -ne 0 ]]; then
|
|
echo "This script must be run as root" 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
case "$hostType" in
|
|
centos7)
|
|
yum -y install epel-release
|
|
|
|
curl --silent --location https://rpm.nodesource.com/setup_10.x | bash -
|
|
cat > /etc/yum.repos.d/mongodb-org.repo <<EOT
|
|
[mongodb-org-4.0]
|
|
name=MongoDB Repository
|
|
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/4.0/x86_64/
|
|
gpgcheck=1
|
|
enabled=1
|
|
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
|
|
EOT
|
|
|
|
yum -y install mariadb-server nodejs ImageMagick redis pwgen gcc-c++ make mongodb-org bzip2
|
|
;;
|
|
|
|
|
|
centos8)
|
|
dnf -y install epel-release
|
|
|
|
cat > /etc/yum.repos.d/mongodb-org.repo <<EOT
|
|
[mongodb-org-4.2]
|
|
name=MongoDB Repository
|
|
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/4.2/x86_64/
|
|
gpgcheck=1
|
|
enabled=1
|
|
gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc
|
|
EOT
|
|
|
|
dnf -y module install nodejs/development
|
|
dnf -y module install mariadb/server
|
|
dnf -y module install redis
|
|
dnf -y install ImageMagick pwgen gcc-c++ make mongodb-org bzip2
|
|
;;
|
|
|
|
|
|
ubuntu1804)
|
|
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
|
|
|
|
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
|
|
echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
|
|
apt-get update
|
|
|
|
apt-get install -y mariadb-server nodejs imagemagick redis pwgen g++ make mongodb-org bzip2
|
|
;;
|
|
|
|
debian10)
|
|
apt-get install -y gnupg
|
|
wget -qO - https://www.mongodb.org/static/pgp/server-4.2.asc | apt-key add -
|
|
echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.2 main" | tee /etc/apt/sources.list.d/mongodb-org-4.2.list
|
|
apt-get update
|
|
apt-get install -y mariadb-server nodejs imagemagick redis pwgen g++ make mongodb-org bzip2 npm
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
systemctl start mariadb
|
|
systemctl enable mariadb
|
|
|
|
systemctl start ${redisService}
|
|
systemctl enable ${redisService}
|
|
|
|
systemctl start mongod
|
|
systemctl enable mongod
|
|
}
|
|
|
|
function installMailtrain {
|
|
local urlBaseTrusted="$1"
|
|
local urlBaseSandbox="$2"
|
|
local urlBasePublic="$3"
|
|
local wwwHost="$4"
|
|
local wwwProxy="$5"
|
|
|
|
mysqlPassword=`pwgen 12 -1`
|
|
mysqlRoPassword=`pwgen 12 -1`
|
|
|
|
# Setup MySQL user for Mailtrain
|
|
mysql -u root -e "CREATE USER 'mailtrain'@'localhost' IDENTIFIED BY '$mysqlPassword';"
|
|
mysql -u root -e "GRANT ALL PRIVILEGES ON mailtrain.* TO 'mailtrain'@'localhost';"
|
|
mysql -u root -e "CREATE USER 'mailtrain_ro'@'localhost' IDENTIFIED BY '$mysqlRoPassword';"
|
|
mysql -u root -e "GRANT SELECT ON mailtrain.* TO 'mailtrain_ro'@'localhost';"
|
|
mysql -u mailtrain --password="$mysqlPassword" -e "CREATE database mailtrain;"
|
|
|
|
# Add new user for the mailtrain daemon to run as
|
|
useradd mailtrain || true
|
|
|
|
# Setup installation configuration
|
|
cat > server/config/production.yaml <<EOT
|
|
user: mailtrain
|
|
group: mailtrain
|
|
roUser: nobody
|
|
roGroup: nobody
|
|
|
|
www:
|
|
host: $wwwHost
|
|
proxy: $wwwProxy
|
|
secret: "`pwgen -1`"
|
|
trustedUrlBase: $urlBaseTrusted
|
|
sandboxUrlBase: $urlBaseSandbox
|
|
publicUrlBase: $urlBasePublic
|
|
|
|
|
|
mysql:
|
|
password: "$mysqlPassword"
|
|
|
|
redis:
|
|
enabled: true
|
|
|
|
log:
|
|
level: info
|
|
|
|
builtinZoneMTA:
|
|
log:
|
|
level: warn
|
|
|
|
queue:
|
|
processes: 5
|
|
EOT
|
|
|
|
cat >> server/services/workers/reports/config/production.yaml <<EOT
|
|
log:
|
|
level: warn
|
|
|
|
mysql:
|
|
user: mailtrain_ro
|
|
password: "$mysqlRoPassword"
|
|
EOT
|
|
|
|
reinstallAllModules
|
|
|
|
(cd client && npm run build)
|
|
|
|
chown -R mailtrain:mailtrain .
|
|
chmod o-rwx server/config
|
|
}
|
|
|
|
|
|
function doForAllModules {
|
|
# Install required node packages
|
|
for idx in client shared server zone-mta mvis/client mvis/server mvis/test-embed mvis/ivis-core/client mvis/ivis-core/server mvis/ivis-core/shared mvis/ivis-core/embedding; do
|
|
if [ -d $idx ]; then
|
|
($1 $idx)
|
|
fi
|
|
done
|
|
}
|
|
|
|
function reinstallModules {
|
|
local idx=$1
|
|
echo Reinstalling modules in $idx
|
|
cd $idx && rm -rf node_modules && npm install
|
|
}
|
|
|
|
function reinstallAllModules {
|
|
doForAllModules reinstallModules
|
|
}
|
|
|
|
function installHttpd {
|
|
local portTrusted="$1"
|
|
local portSandbox="$2"
|
|
local portPublic="$3"
|
|
|
|
case "$hostType" in
|
|
centos7)
|
|
yum -y install httpd mod_ssl
|
|
systemctl start httpd
|
|
systemctl enable httpd
|
|
|
|
setsebool -P httpd_can_network_connect 1
|
|
|
|
if [ -n "$firewallCmdExists" ]; then
|
|
# Enable SSL ports on the firewall
|
|
for port in "80/tcp" "${portTrusted}/tcp" "${portSandbox}/tcp" "${portPublic}/tcp"; do
|
|
firewall-cmd --add-port=$port --permanent
|
|
done
|
|
|
|
# Activate the firefall settings
|
|
firewall-cmd --reload
|
|
fi
|
|
;;
|
|
|
|
centos8)
|
|
dnf -y install httpd mod_ssl
|
|
systemctl start httpd
|
|
systemctl enable httpd
|
|
|
|
setsebool -P httpd_can_network_connect 1
|
|
|
|
if [ -n "$firewallCmdExists" ]; then
|
|
# Enable SSL ports on the firewall
|
|
for port in "80/tcp" "${portTrusted}/tcp" "${portSandbox}/tcp" "${portPublic}/tcp"; do
|
|
firewall-cmd --add-port=$port --permanent
|
|
done
|
|
|
|
# Activate the firefall settings
|
|
firewall-cmd --reload
|
|
fi
|
|
;;
|
|
|
|
ubuntu1804|debian10)
|
|
apt-get install -y apache2
|
|
|
|
if [ -n "$firewallCmdExists" ]; then
|
|
# Enable SSL ports on the firewall
|
|
for port in "80/tcp" "${portTrusted}/tcp" "${portSandbox}/tcp" "${portPublic}/tcp"; do
|
|
ufw allow $port
|
|
done
|
|
fi
|
|
;;
|
|
|
|
esac
|
|
}
|
|
|
|
|
|
function installHttpsProxy {
|
|
local hostTrusted="$1"
|
|
local portTrusted="$2"
|
|
local hostSandbox="$3"
|
|
local portSandbox="$4"
|
|
local hostPublic="$5"
|
|
local portPublic="$6"
|
|
local certificateFile="$7"
|
|
local certificateKey="$8"
|
|
local caChainFile="$9"
|
|
|
|
|
|
> $apacheConf
|
|
|
|
cat >> $apacheConf <<EOT
|
|
<VirtualHost *:80>
|
|
ServerName ${hostTrusted}
|
|
|
|
ServerSignature Off
|
|
|
|
RewriteEngine On
|
|
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
|
|
|
|
ErrorLog ${apacheLogsPath}/${hostTrusted}_redirect_error.log
|
|
LogLevel warn
|
|
</VirtualHost>
|
|
|
|
<VirtualHost *:80>
|
|
ServerName ${hostSandbox}
|
|
|
|
ServerSignature Off
|
|
|
|
RewriteEngine On
|
|
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
|
|
|
|
ErrorLog ${apacheLogsPath}/${hostSandbox}_redirect_error.log
|
|
LogLevel warn
|
|
</VirtualHost>
|
|
|
|
<VirtualHost *:80>
|
|
ServerName ${hostPublic}
|
|
|
|
ServerSignature Off
|
|
|
|
RewriteEngine On
|
|
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
|
|
|
|
ErrorLog ${apacheLogsPath}/${hostPublic}_redirect_error.log
|
|
LogLevel warn
|
|
</VirtualHost>
|
|
|
|
<VirtualHost *:${portTrusted}>
|
|
ServerName ${hostTrusted}:${portTrusted}
|
|
|
|
ErrorLog ${apacheLogsPath}/${hostTrusted}_ssl_error.log
|
|
TransferLog ${apacheLogsPath}/${hostTrusted}_ssl_access.log
|
|
LogLevel warn
|
|
|
|
SSLEngine on
|
|
SSLCertificateFile ${certificateFile}
|
|
SSLCertificateKeyFile ${certificateKey}
|
|
SSLCertificateChainFile ${caChainFile}
|
|
|
|
ProxyPreserveHost On
|
|
ProxyPass "/" "http://127.0.0.1:3000/"
|
|
ProxyPassReverse "/" "http://127.0.0.1:3000/"
|
|
</VirtualHost>
|
|
|
|
<VirtualHost *:${portSandbox}>
|
|
ServerName ${hostSandbox}:${portSandbox}
|
|
|
|
ErrorLog ${apacheLogsPath}/${hostSandbox}_ssl_error.log
|
|
TransferLog ${apacheLogsPath}/${hostSandbox}_ssl_access.log
|
|
LogLevel warn
|
|
|
|
SSLEngine on
|
|
SSLCertificateFile ${certificateFile}
|
|
SSLCertificateKeyFile ${certificateKey}
|
|
SSLCertificateChainFile ${caChainFile}
|
|
|
|
ProxyPreserveHost On
|
|
ProxyPass "/" "http://127.0.0.1:3003/"
|
|
ProxyPassReverse "/" "http://127.0.0.1:3003/"
|
|
</VirtualHost>
|
|
|
|
<VirtualHost *:${portPublic}>
|
|
ServerName ${hostPublic}:${portPublic}
|
|
|
|
ErrorLog ${apacheLogsPath}/${hostPublic}_ssl_error.log
|
|
TransferLog ${apacheLogsPath}/${hostPublic}_ssl_access.log
|
|
LogLevel warn
|
|
|
|
SSLEngine on
|
|
SSLCertificateFile ${certificateFile}
|
|
SSLCertificateKeyFile ${certificateKey}
|
|
SSLCertificateChainFile ${caChainFile}
|
|
|
|
ProxyPreserveHost On
|
|
ProxyPass "/" "http://127.0.0.1:3004/"
|
|
ProxyPassReverse "/" "http://127.0.0.1:3004/"
|
|
</VirtualHost>
|
|
EOT
|
|
|
|
|
|
case "$hostType" in
|
|
centos7|centos8)
|
|
systemctl restart httpd
|
|
;;
|
|
|
|
ubuntu1804|debian10)
|
|
a2enmod ssl
|
|
a2enmod rewrite
|
|
a2enmod proxy
|
|
a2enmod proxy_http
|
|
a2enconf mailtrain
|
|
systemctl restart apache2
|
|
;;
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
function createCertificates {
|
|
# This assumes that HTTPD is already running
|
|
|
|
local hostTrusted="$1"
|
|
local hostSandbox="$2"
|
|
local hostPublic="$3"
|
|
local email="$4"
|
|
|
|
case "$hostType" in
|
|
centos7)
|
|
yum install -y certbot python2-certbot-apache
|
|
;;
|
|
|
|
centos8)
|
|
dnf install -y certbot
|
|
;;
|
|
|
|
ubuntu1804|debian10)
|
|
apt-get install -y certbot python3-certbot-apache
|
|
;;
|
|
esac
|
|
|
|
certbot certonly --agree-tos --email "${email}" --webroot --webroot-path /var/www/html -n -d "${hostPublic}" -d "${hostTrusted}" -d "${hostSandbox}"
|
|
|
|
# Install cron
|
|
echo "0 3 * * * /usr/bin/certbot certonly --apache -n -d \"${hostPublic}\" -d \"${hostTrusted}\" -d \"${hostSandbox}\"" > crontab
|
|
crontab crontab
|
|
rm -rf crontab
|
|
}
|
|
|
|
|
|
|
|
function installService {
|
|
cat > /etc/systemd/system/mailtrain.service <<EOT
|
|
[Unit]
|
|
Description=Mailtrain server
|
|
After=syslog.target network.target mariadb.service ${redisService}.service mongod.service
|
|
|
|
[Service]
|
|
Environment="NODE_ENV=production"
|
|
WorkingDirectory=/opt/mailtrain/server
|
|
ExecStart=/usr/bin/node index.js
|
|
Type=simple
|
|
Restart=always
|
|
RestartSec=10
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOT
|
|
|
|
systemctl daemon-reload
|
|
}
|
|
|
|
|
|
|
|
function deleteModules {
|
|
local idx=$1
|
|
echo Deleting modules in $idx
|
|
cd $idx && rm -rf node_modules
|
|
}
|
|
|
|
function deleteAllModules {
|
|
doForAllModules deleteModules
|
|
}
|
|
|
|
|
|
function setupTest {
|
|
mysqlPassword=`pwgen 12 -1`
|
|
|
|
# Setup MySQL user for Mailtrain
|
|
mysql -u root -e "CREATE USER 'mailtrain_test'@'localhost' IDENTIFIED BY '$mysqlPassword';"
|
|
mysql -u root -e "GRANT ALL PRIVILEGES ON mailtrain_test.* TO 'mailtrain_test'@'localhost';"
|
|
mysql -u mailtrain_test --password="$mysqlPassword" -e "CREATE database mailtrain_test;"
|
|
|
|
# Setup installation configuration
|
|
cat > server/config/test.yaml <<EOT
|
|
mysql:
|
|
user: mailtrain_test
|
|
password: "$mysqlPassword"
|
|
database: mailtrain_test
|
|
|
|
redis:
|
|
enabled: true
|
|
|
|
log:
|
|
level: info
|
|
|
|
builtinZoneMTA:
|
|
log:
|
|
level: warn
|
|
|
|
queue:
|
|
processes: 5
|
|
|
|
testServer:
|
|
enabled: true
|
|
EOT
|
|
|
|
cat >> server/services/workers/reports/config/test.yaml <<EOT
|
|
log:
|
|
level: warn
|
|
|
|
mysql:
|
|
user: mailtrain_test
|
|
password: "$mysqlPassword"
|
|
database: mailtrain_test
|
|
EOT
|
|
}
|