Updated install script to bundle ZoneMTA

This commit is contained in:
Andris Reinman 2016-09-08 11:20:33 +03:00
parent 0c0942cf64
commit d2f0d16980
4 changed files with 164 additions and 9 deletions

View file

@ -33,7 +33,7 @@ Subscribe to Mailtrain Newsletter [here](http://mailtrain.org/subscription/EysIv
## Installation
### Automatic install (Ubuntu)
### Simple install (Ubuntu)
You can download and run [install.sh](setup/install.sh) in your blank Ubuntu VPS to set up
Mailtrain and all required dependencies (including MySQL). The installation script assumes a somewhat blank server, so if this is a machine you are already using for something else, you might want to skip the automatic install and proceed manually.
@ -50,13 +50,51 @@ Install script installs and sets up the following:
* **MySQL** (platform default)
* **Mailtrain** (from the master branch) on port 80
* **UFW** firewall that blocks everything besides ports 22, 25, 80, 443
* **[ZoneMTA](https://github.com/zone-eu/zone-mta)** to queue and deliver messages
* **Redis** server for session cache
* **logrotate** to rotate Mailtrain log files
* **upstart** or **systemd** init script to automatically start and manage Mailtrain process
If you are using DigitalOcean then you can copy the contents of the [installation script](setup/install.sh) to the User Data textarea field when creating a new VPS (select Ubuntu 14.04 as the droplet Distribution image). After your droplet is created it should already have Mailtrain up and running. Navigate to http://droplet-hostname-or-ip/ and authenticate as `admin`:`test`. Do not forget to update your account information and set up SMTP settings.
After the install script has finished and you see a success message then you should have a Mailtrain instance running at http://yourdomain.com
### Manual (any OS that supports Node.js)
#### Next steps after installation
##### 1. Change admin password
Navigate to http://yourdomain.com where yourdomain.com is the address of your server. Click on the Sign In link in the right top corner of the page. Authenticate with the following credentials:
* Username: **admin**
* Password: **test**
Once authenticated, click on your username in the right top corner of the page and select "Account". Now you should be able to change your default password.
##### 2. Update page configuration
If signed in navigate to http://yourdomain.com/settings and check that all email addresses and domain names are correct. Mailtrain default installation comes bundled with [ZoneMTA](https://github.com/zone-eu/zone-mta), so you should be able to send out messages right away. ZoneMTA even handles a lot of bounces (not all kind of bounces though) automatically so you do not have to change anything in the SMTP settings to get going.
##### 3. Set up SPF
If you are using the bundled ZoneMTA then you need to add your Mailtrain host to the SPF DNS record of your sending domain. So if you are sending messages as "info@example.com" then the domain "example.com" should have a SPF DNS record that points to the IP address or hostname of your Mailtrain host. Everything should work without the SPF record but setting it up correctly improves the deliverability a lot.
##### 4. Set up DKIM
If you are using the bundled ZoneMTA then you can provide a DKIM key to sign all outgoing messages. If you have a DKIM key set for domain "example.com" with selector "mailtrain", then store the private key to folder /opt/zone-mta/keys as "example.com.mailtrain.pem" (thats sending hostname + "." + seclector + ".pem"). Everything should work without the DKIM signatures but setting it up correctly improves the deliverability a lot.
##### 4. Set up VERP
The bundled ZoneMTA can already handle a large amount of bounces if you use it to deliver messages but not all - namely such bounces that happen *after* the recipient MX accepts the message for local delivery. This might happen for example when a user exists, so the MX accepts the message but the quota for that user is checked only when actually storing the message to users' mailbox. Then a bounce message is generated and sent to the original sender which in your case is the mail address you are sending your list messages from. You can catch these messages and mark such recipients manually as bounced but alternatively you can set up a VERP based bounce handler that does this automatically. In this case the sender on the message envelope would not be your actual address but a rewritten bounce address that points to your Mailtrain installation.
To set it up you need to create an additonal DNS MX entry for a bounce domain, eg "bounces.example.com" if you are sending from "example.com". This entry should point to your Mailtrain server IP address. Next you should enable the VERP handling in Mailtrain Settings page.
> As ZoneMTA uses envelope sender as the default for DKIM addresses, then if using VERP you need to set up DKIM to your bounce domain instead of sender domain and also store the DKIM key as "bouncedomain.selector.pem" in the ZoneMTA key folder.
If you do not use VERP with ZoneMTA then you should get notified most of the bounces so everything should mostly work without it
##### 4. Set up proper PTR record
If you are using the bundled ZoneMTA then you should make sure you are using a proper PTR record for your server. For example if you use DigitalOcean then PTR is set automatically (it's the droplet name, so make sure your droplet name is the same as the domain name you are running Mailtrain from). If you use AWS then you can request setting up PTR records using [this form](https://portal.aws.amazon.com/gp/aws/html-forms-controller/contactus/ec2-email-limit-rdns-request) (requires authentication). Everything should work without the PTR record but setting it up correctly improves the deliverability a lot.
### Manual install (any OS that supports Node.js)
1. Download Mailtrain files using git: `git clone git://github.com/andris9/mailtrain.git` (or download [zipped repo](https://github.com/andris9/mailtrain/archive/master.zip)) and open Mailtrain folder `cd mailtrain`
2. Run `npm install --production` in the Mailtrain folder to install required dependencies

View file

@ -262,7 +262,7 @@ module.exports.add = (url, campaignId, callback) => {
module.exports.updateLinks = (campaign, list, subscription, serviceUrl, message, callback) => {
let re = /(<a[^>]* href\s*=[\s"']*)(http[^"'>\s]+)/gi;
let urls = new Set();
message.replace(re, (match, prefix, url) => {
(message || '').replace(re, (match, prefix, url) => {
urls.add(url);
});

View file

@ -257,4 +257,33 @@ router.post('/mailgun', uploads.any(), (req, res) => {
});
});
router.post('/zone-mta', (req, res, next) => {
if (typeof req.body === 'string') {
try {
req.body = JSON.parse(req.body);
} catch (E) {
return next(new Error('Could not parse input'));
}
}
if (req.body.id) {
campaigns.findMailByResponse(req.body.id, (err, message) => {
if (err || !message) {
return;
}
campaigns.updateMessage(message, 'bounced', true, (err, updated) => {
if (err) {
log.error('ZoneMTA', 'Failed updating message: %s', err.stack);
} else if (updated) {
log.verbose('ZoneMTA', 'Marked message %s as bounced', req.body.id);
}
});
});
}
res.json({
success: true
});
});
module.exports = router;

View file

@ -1,6 +1,12 @@
#!/bin/bash
# This installation script works on Ubuntu 14.04
# This installation script works on Ubuntu 14.04 and 16.04
# Run as root!
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
set -e
@ -9,9 +15,16 @@ export DEBIAN_FRONTEND=noninteractive
apt-add-repository -y ppa:chris-lea/redis-server
curl -sL https://deb.nodesource.com/setup_6.x | bash -
apt-get -q -y install mysql-server pwgen redis-server nodejs git ufw
apt-get -q -y install mariadb-server pwgen redis-server nodejs git ufw build-essential dnsutils
apt-get clean
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`}"
MYSQL_PASSWORD=`pwgen -1`
# Setup MySQL user for Mailtrain
@ -31,7 +44,22 @@ mkdir -p /opt/mailtrain
cd /opt/mailtrain
git clone git://github.com/andris9/mailtrain.git .
# Add new user for the daemon to run as
# Normally we would let Mailtrain itself to import the initial SQL data but in this case
# we need to modify it, before we start Mailtrain
mysql -u mailtrain -p"$MYSQL_PASSWORD" mailtrain < setup/sql/mailtrain.sql
mysql -u mailtrain -p"$MYSQL_PASSWORD" mailtrain <<EOT
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('admin_email','admin@$HOSTNAME') ON DUPLICATE KEY UPDATE \`value\`='admin@$HOSTNAME';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('default_address','admin@$HOSTNAME') ON DUPLICATE KEY UPDATE \`value\`='admin@$HOSTNAME';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('smtp_hostname','localhost') ON DUPLICATE KEY UPDATE \`value\`='localhost';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('smtp_disable_auth','on') ON DUPLICATE KEY UPDATE \`value\`='on';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('smtp_encryption','NONE') ON DUPLICATE KEY UPDATE \`value\`='NONE';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('smtp_port','587') ON DUPLICATE KEY UPDATE \`value\`='587';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('default_homepage','http://$HOSTNAME/') ON DUPLICATE KEY UPDATE \`value\`='http://$HOSTNAME/';
INSERT INTO \`settings\` (\`key\`, \`value\`) VALUES ('service_url','http://$HOSTNAME/') ON DUPLICATE KEY UPDATE \`value\`='http://$HOSTNAME/';
EOT
# Add new user for the mailtrain daemon to run as
useradd mailtrain || true
# Setup installation configuration
@ -48,11 +76,12 @@ password="$MYSQL_PASSWORD"
[redis]
enabled=true
[verp]
enabled=false
enabled=true
EOT
# Install required node packages
npm install --no-progress --production
chown -R mailtrain:mailtrain .
# Setup log rotation to not spend up entire storage on logs
cat <<EOM > /etc/logrotate.d/mailtrain
@ -77,7 +106,66 @@ else
cp setup/mailtrain.conf /etc/init/
fi
# Fetch ZoneMTA files
mkdir -p /opt/zone-mta
cd /opt/zone-mta
git clone git://github.com/zone-eu/zone-mta.git .
# Ensure queue folder
mkdir -p /var/data/mailtrain
# Setup installation configuration
cat >> config/production.json <<EOT
{
"user": "mailtrain",
"group": "mailtrain",
"queue": {
"db": "/var/data/mailtrain"
},
"feeder": {
"port": 587
},
"log": {
"level": "info"
},
"bounces": {
"enabled": false,
"url": "http://localhost/webhooks/zone-mta"
}
}
EOT
# Install required node packages
npm install --no-progress --production
# Setup log rotation to not spend up entire storage on logs
cat <<EOM > /etc/logrotate.d/zone-mta
/var/log/zone-mta.log {
daily
rotate 12
compress
delaycompress
missingok
notifempty
copytruncate
nomail
}
EOM
chown -R mailtrain:mailtrain .
chown -R mailtrain:mailtrain /var/data/mailtrain
if [ -d "/run/systemd/system" ]; then
# Set up systemd service script
cp setup/zone-mta.service /etc/systemd/system/
systemctl enable zone-mta.service
else
# Set up upstart service script
cp setup/zone-mta.conf /etc/init/
fi
# Start the service
service zone-mta start
service mailtrain start
echo "Success!";
echo "Success! Open http://$HOSTNAME/ and log in as admin:test";