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