2018-12-25 08:32:14 +00:00
# This is not a standalone script. It provides common functions to server-*.sh scripts
2018-12-25 11:29:26 +00:00
case "$hostType" in
centos7)
hostTypeLabel="CentOS 7"
redisService=redis
apacheConf="/etc/httpd/conf.d/mailtrain.conf"
if hash firewall-cmd 2>/dev/null; then
firewallCmdExists=yes
fi
;;
ubuntu1804)
hostTypeLabel="Ubuntu 18.04 LTS"
redisService=redis-server
apacheConf="/etc/apache2/conf-available/mailtrain.conf"
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
}
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
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
}
2018-12-25 08:32:14 +00:00
2018-12-25 09:02:30 +00:00
function installPrerequisities {
2018-12-25 11:29:26 +00:00
# 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
2018-12-25 09:02:30 +00:00
2018-12-25 11:29:26 +00:00
curl --silent --location https://rpm.nodesource.com/setup_10.x | bash -
cat > /etc/yum.repos.d/mongodb-org.repo <<EOT
2018-12-25 08:32:14 +00:00
[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
2018-12-25 09:02:30 +00:00
2018-12-25 11:29:26 +00:00
yum -y install mariadb-server nodejs ImageMagick redis 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
;;
esac
2018-12-25 09:02:30 +00:00
2018-12-25 08:32:14 +00:00
systemctl start mariadb
systemctl enable mariadb
2018-12-25 09:02:30 +00:00
2018-12-25 11:29:26 +00:00
systemctl start ${redisService}
systemctl enable ${redisService}
2018-12-25 09:02:30 +00:00
2018-12-25 08:32:14 +00:00
systemctl start mongod
systemctl enable mongod
2018-12-25 09:02:30 +00:00
}
function installMailtrain {
local urlBaseTrusted="$1"
local urlBaseSandbox="$2"
local urlBasePublic="$3"
local wwwHost="$4"
2018-12-25 11:29:26 +00:00
local wwwProxy="$5"
2018-12-25 09:02:30 +00:00
2018-12-25 08:32:14 +00:00
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:
2018-12-25 09:02:30 +00:00
host: $wwwHost
2018-12-25 11:29:26 +00:00
proxy: $wwwProxy
2018-12-25 08:32:14 +00:00
secret: "`pwgen -1`"
trustedUrlBase: $urlBaseTrusted
sandboxUrlBase: $urlBaseSandbox
publicUrlBase: $urlBasePublic
mysql:
password: "$mysqlPassword"
redis:
enabled: true
log:
2018-12-25 09:02:30 +00:00
level: info
2018-12-25 08:32:14 +00:00
builtinZoneMTA:
log:
2018-12-25 09:02:30 +00:00
level: warn
2018-12-25 08:32:14 +00:00
queue:
processes: 5
EOT
cat >> server/services/workers/reports/config/production.yaml <<EOT
log:
level: warn
mysql:
user: mailtrain_ro
password: "$mysqlRoPassword"
EOT
# Install required node packages
for idx in client shared server zone-mta; do
(cd $idx && npm install)
done
(cd client && npm run build)
chown -R mailtrain:mailtrain .
chmod o-rwx server/config
}
2018-12-25 09:02:30 +00:00
2018-12-25 08:32:14 +00:00
2018-12-25 11:29:26 +00:00
function installHttpd {
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
;;
ubuntu1804)
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
ufw --force enable
fi
;;
esac
2018-12-25 08:32:14 +00:00
}
2018-12-25 11:29:26 +00:00
function installHttpsProxy {
2018-12-25 08:32:14 +00:00
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"
2018-12-25 11:29:26 +00:00
> $apacheConf
2018-12-25 08:32:14 +00:00
2018-12-25 11:29:26 +00:00
cat >> $apacheConf <<EOT
2018-12-25 09:02:30 +00:00
<VirtualHost *:80>
2018-12-25 08:32:14 +00:00
ServerName ${hostTrusted}
ServerSignature Off
RewriteEngine On
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
ErrorLog logs/${hostTrusted}_redirect_error.log
LogLevel warn
</VirtualHost>
2018-12-25 09:02:30 +00:00
<VirtualHost *:80>
2018-12-25 08:32:14 +00:00
ServerName ${hostSandbox}
ServerSignature Off
RewriteEngine On
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
ErrorLog logs/${hostSandbox}_redirect_error.log
LogLevel warn
</VirtualHost>
2018-12-25 09:02:30 +00:00
<VirtualHost *:80>
2018-12-25 08:32:14 +00:00
ServerName ${hostPublic}
ServerSignature Off
RewriteEngine On
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
ErrorLog logs/${hostPublic}_redirect_error.log
LogLevel warn
</VirtualHost>
2018-12-25 09:02:30 +00:00
<VirtualHost *:${portTrusted}>
2018-12-25 08:32:14 +00:00
ServerName ${hostTrusted}:${portTrusted}
ErrorLog logs/${hostTrusted}_ssl_error.log
TransferLog logs/${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>
2018-12-25 09:02:30 +00:00
<VirtualHost *:${portSandbox}>
2018-12-25 08:32:14 +00:00
ServerName ${hostSandbox}:${portSandbox}
ErrorLog logs/${hostSandbox}_ssl_error.log
TransferLog logs/${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>
2018-12-25 09:02:30 +00:00
<VirtualHost *:${portPublic}>
2018-12-25 09:11:47 +00:00
ServerName ${hostPublic}:${portPublic}
2018-12-25 08:32:14 +00:00
ErrorLog logs/${hostPublic}_ssl_error.log
TransferLog logs/${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
2018-12-25 11:29:26 +00:00
case "$hostType" in
centos7)
systemctl restart httpd
;;
2018-12-25 08:32:14 +00:00
2018-12-25 11:29:26 +00:00
ubuntu1804)
2018-12-25 12:32:53 +00:00
a2enmod ssl
2018-12-25 11:29:26 +00:00
a2enconf mailtrain
systemctl restart apache2
;;
esac
2018-12-25 08:32:14 +00:00
}
function createCertificates {
2018-12-25 11:29:26 +00:00
# This assumes that HTTPD is already running
2018-12-25 09:02:30 +00:00
2018-12-25 08:32:14 +00:00
local hostTrusted="$1"
local hostSandbox="$2"
local hostPublic="$3"
local email="$4"
2018-12-25 11:29:26 +00:00
case "$hostType" in
centos7)
2018-12-25 12:03:06 +00:00
yum install -y certbot python2-certbot-apache
2018-12-25 11:29:26 +00:00
;;
2018-12-25 08:32:14 +00:00
2018-12-25 11:29:26 +00:00
ubuntu1804)
2018-12-25 12:03:06 +00:00
apt-get install -y certbot python3-certbot-apache
2018-12-25 11:29:26 +00:00
;;
esac
2018-12-25 08:32:14 +00:00
2018-12-25 12:10:25 +00:00
certbot certonly --agree-tos --email "${email}" --webroot --webroot-path /var/www/html -n -d "${hostPublic}" -d "${hostTrusted}" -d "${hostSandbox}"
2018-12-25 08:32:14 +00:00
2018-12-25 09:02:30 +00:00
# Install cron
echo "0 3 * * * /usr/bin/certbot certonly --apache -n -d \"${hostPublic}\" -d \"${hostTrusted}\" -d \"${hostSandbox}\"" > crontab
crontab crontab
rm -rf crontab
2018-12-25 08:32:14 +00:00
}
2018-12-25 09:02:30 +00:00
2018-12-25 11:29:26 +00:00
2018-12-25 09:02:30 +00:00
function installService {
cat > /etc/systemd/system/mailtrain.service <<EOT
[Unit]
Description=Mailtrain server
2018-12-25 11:29:26 +00:00
After=syslog.target network.target mariadb.service ${redisService}.service mongod.service
2018-12-25 09:02:30 +00:00
[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
}