Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save henno/c4dc7da7eca7900e52eda458de8b477b to your computer and use it in GitHub Desktop.
Save henno/c4dc7da7eca7900e52eda458de8b477b to your computer and use it in GitHub Desktop.
#!/bin/sh
# ABOUT THIS SCRIPT
# This script automates the setup of an email server on Alpine Linux using Postfix, OpenDKIM, and PostSRSd.
# It configures all necessary components to send and receive emails securely and handles virtual mailing lists.
#
# USAGE
# 1. Modify the configuration variables below to match your domain and server settings.
# 2. Run the script as root.
# 3. After running the script, ensure that you see the master process, the postsrsd process and the opendkim process in the
# netstat output that is shown after the script completes.
# 4. Run the following command to get the value of your DKIM record:
# echo -n 'v=DKIM1; k=rsa; '; grep -o 'p=.*' /etc/opendkim/keys/YOURDKIMSELECTOR.txt | sed 's/.*p="//;s/"[^"]*$//'
# 5. Go to your DNS panel and add new TXT record YOURDKIMSELECTOR._domainkey with the previous command's output as its value.
# 6. Install Swaks from https://jetmore.org/john/code/swaks/installation.html and send a test mail to your Gmail address.
# Then observe /var/log/mail.log and if the message reaches your Gmail then open the message and choose Show original from
# the three dots menu and check if DMARC, SPF and DKIM all are PASS.
# Before running, ensure you have set up DNS records as described below:
#
# DNS REQUIREMENTS
# 1. Ensure that the hostname (e.g., mail.example.com) has a correct PTR record, pointing back to the A record of the IP address.
# 2. Add a TXT record for DKIM in your DNS with the name 'example._domainkey.example.com' where example is your DKIM_SELECTOR
# and the value provided by the OpenDKIM key generation (this script will generate this value).
# 3. Ensure SPF and DMARC records are set up to enhance email deliverability and security.
#
# Ensure you modify the configuration variables below as per your domain and server settings.
# Configuration variables
MYHOSTNAME="mail.example.com" # must match the reverse DNS of the IP address that is used to send emails
MYDOMAIN="example.com" # the domain that is used to send emails from the server
DKIM_SELECTOR="example" # the DKIM selector that is listed in the DNS records of the domain
MYDESTINATION="localhost, ${MYHOSTNAME}, ${MYDOMAIN}, ${MYDOMAIN}.localdomain" # the destinations that the server will accept emails for
MAILING_LIST="list@${MYDOMAIN}" # a mailing list that will be used to send emails to multiple recipients
MAILING_LIST_MEMBERS="user1@example.net, user2@example.org" # mailing list members who will receive emails sent to the list
# Check for root privileges
if [ "$(id -u)" -ne 0 ]; then
echo "This script must be run as root." 1>&2
exit 1
fi
# Define the version of Alpine to check for the community repository
ALPINE_VERSION=$(cut -d'.' -f1-2 /etc/alpine-release)
COMMUNITY_REPO="http://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/community"
# Check and ensure the community repository is in the repositories file
if ! grep -Fq "$COMMUNITY_REPO" /etc/apk/repositories; then
echo "$COMMUNITY_REPO" >> /etc/apk/repositories
echo "Community repository added."
else
# Ensure it's not commented out if already present
COMMUNITY_REPO_ESCAPED=$(echo "$COMMUNITY_REPO" | sed 's/\//\\\//g')
sed -i -e "/^#.*$COMMUNITY_REPO_ESCAPED/s/^#//" /etc/apk/repositories
fi
# Update and install necessary packages
apk update
apk add postfix postfix-pcre postsrsd opendkim opendkim-utils
# Configure Postfix
postconf -e "myhostname = $MYHOSTNAME"
postconf -e "mydestination = $MYDESTINATION"
postconf -e "myorigin = $MYDOMAIN"
postconf -e "virtual_alias_maps = lmdb:/etc/postfix/virtual"
postconf -e "milter_default_action = accept"
postconf -e "milter_protocol = 2"
postconf -e "smtpd_milters = inet:localhost:8891"
postconf -e "non_smtpd_milters = inet:localhost:8891"
postconf -e "relay_domains = $MYHOSTNAME"
postconf -e "relayhost = "
postconf -e "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination"
postconf -e "mynetworks = 127.0.0.0/8, 10.0.0.0/8"
echo "$MAILING_LIST $MAILING_LIST_MEMBERS" > /etc/postfix/virtual
postmap /etc/postfix/virtual
# Configure OpenDKIM
mkdir -p /etc/opendkim/keys
chown opendkim:opendkim /etc/opendkim /etc/opendkim/keys
# Update OpenDKIM configuration to use the right paths
cat > /etc/opendkim/opendkim.conf << EOF
BaseDirectory /run/opendkim
LogWhy yes
Syslog yes
SyslogSuccess yes
Canonicalization relaxed/simple
Domain $MYDESTINATION
ReportAddress postmaster@$MYDOMAIN
SendReports yes
InternalHosts 127.0.0.1, 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12
PidFile /var/run/opendkim/opendkim.pid
UserID opendkim:opendkim
Socket inet:8891@localhost
Selector $DKIM_SELECTOR
KeyFile /etc/opendkim/keys/${DKIM_SELECTOR}.private
EOF
opendkim-genkey -D /etc/opendkim/keys/ -d $MYHOSTNAME -s $DKIM_SELECTOR
chown opendkim:opendkim /etc/opendkim/keys/$DKIM_SELECTOR.private
# Configure PostSRSd v2
cat > /etc/postsrsd/postsrsd.conf << EOF
# PostSRSd configuration file
domains = { "$MYDOMAIN" }
syslog = on
debug = on
socketmap = inet:localhost:10003
keep-alive = 30
original-envelope = embedded
secrets-file = "/etc/postsrsd/postsrsd.secret"
separator = "="
hash-length = 4
hash-minimum = 4
always-rewrite = off
unprivileged-user = "postsrsd"
chroot-dir = "/var/lib/postsrsd"
EOF
# Create the chroot directory for PostSRSd
mkdir -p /etc/postsrsd/root
# Postfix configuration to use PostSRSd
postconf -e 'sender_canonical_maps = socketmap:inet:localhost:10003:forward'
postconf -e 'sender_canonical_classes = envelope_sender'
postconf -e 'recipient_canonical_maps = socketmap:inet:localhost:10003:reverse'
postconf -e 'recipient_canonical_classes = envelope_recipient, header_recipient'
# Check and set correct permissions
chmod 755 /var/spool/postfix
chmod 640 /etc/postfix/main.cf /etc/postfix/master.cf
chmod 700 /etc/opendkim/keys
chmod 600 /etc/opendkim/keys/$DKIM_SELECTOR.private
# Log mail and subject
postconf -e 'maillog_file = /var/log/mail.log'
echo '/^subject:/ WARN' >> /etc/postfix/header_checks
postconf -e 'header_checks = pcre:/etc/postfix/header_checks'
# Reload and restart services
rc-service opendkim start
rc-service postsrsd start
rc-service postfix restart
rc-update add postfix default
rc-update add opendkim default
rc-update add postsrsd default
netstat -plant
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment