Postfix, Dovecot and OpenDKIM

Install Packages
yum install procmail postfix dovecot opendkim

Create a Virtual Email user

groupadd -g 5000 vmail
useradd -u 5000 -g vmail -s /sbin/nologin -d /home/vmail -m vmail
usermod -aG vmail postfix
usermod -aG vmail dovecot

DOMAIN="yourdomain.com"
mkdir -p /var/mail/vhosts/${DOMAIN}
chown -R vmail:vmail /var/mail/vhosts
chmod -R 775 /var/mail/vhosts

Generate SSL Certificate

SSL_DIR="/etc/dovecot/ssl"
mkdir -p ${SSL_DIR}

openssl genrsa -out "${SSL_DIR}/${DOMAIN}.key" 2048

openssl req -new -sha256 -key "${SSL_DIR}/${DOMAIN}.key" -out "${SSL_DIR}/${DOMAIN}.csr"

openssl x509 -req -days 36500 -in "${SSL_DIR}/${DOMAIN}.csr" -signkey "${SSL_DIR}/${DOMAIN}.key" -out "${SSL_DIR}/${DOMAIN}.crt"

Configure OpenDKIM

OPENDKIM_DIR="/etc/opendkim/keys/"

MY_IP=$(ip route get 8.8.8.8 | awk '/8.8.8.8/ {print $NF}')

mkdir -p ${OPENDKIM_DIR}/${DOMAIN}
opendkim-genkey -r -s default -d ${DOMAIN} -D ${OPENDKIM_DIR}/${DOMAIN}
cat > /etc/opendkim.conf <<EOF
AutoRestart Yes
UMask 002
Syslog yes
AutoRestartRate  10/1h
Canonicalization relaxed/simple
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
LogWhy Yes
Mode  sv
PidFile /var/run/opendkim/opendkim.pid
SignatureAlgorithm rsa-sha256
SigningTable refile:/etc/opendkim/SigningTable
Socket inet:8891@localhost
SyslogSuccess Yes
TemporaryDirectory /var/tmp
UserID opendkim:opendkim
EOF

cat > /etc/opendkim/TrustedHosts <<EOF
127.0.0.1
localhost
${DOMAIN}
${MY_IP}
EOF

cat > /etc/opendkim/SigningTable <<EOF
*@${DOMAIN} default._domainkey.${DOMAIN}
EOF

cat > /etc/opendkim/KeyTable <<EOF
default._domainkey.${DOMAIN} ${DOMAIN}:default:/etc/opendkim/keys/${DOMAIN}/default.private
EOF
chown -R opendkim: /etc/opendkim

Configure Postfix

# Configure postfix main.cf
postconf -e "smtpd_banner = \$myhostname ESMTP"
postconf -e "mydomain = ${DOMAIN}"
postconf -e "myorigin = \$mydomain"
postconf -e "inet_interfaces = all"
postconf -e "mydestination = \$myhostname, localhost, localhost.localdomain, $(hostname -f)"
postconf -e "virtual_mailbox_domains = /etc/postfix/virtual_domains"
postconf -e "virtual_mailbox_base = /var/mail/vhosts"
postconf -e "virtual_mailbox_maps = hash:/etc/postfix/vmailbox"
postconf -e "virtual_alias_maps = hash:/etc/postfix/virtual_alias"
postconf -e "virtual_minimum_uid = 100"
postconf -e "virtual_uid_maps = static:5000"
postconf -e "virtual_gid_maps = static:5000"
postconf -e "virtual_transport = virtual"
postconf -e "dovecot_destination_recipient_limit = 1"
postconf -e "smtpd_sasl_auth_enable = yes"
postconf -e "smtpd_sasl_type = dovecot"
postconf -e "smtpd_sasl_path = private/auth"
postconf -e "smtpd_sasl_security_options = noanonymous"
postconf -e "smtpd_sasl_local_domain = \$mydomain"
postconf -e "broken_sasl_auth_clients = yes"
postconf -e "smtpd_tls_security_level = may"
postconf -e "smtpd_tls_auth_only = no"
postconf -e "smtpd_tls_cert_file=${SSL_DIR}/${DOMAIN}.crt"
postconf -e "smtpd_tls_key_file=${SSL_DIR}/${DOMAIN}.key"
postconf -e "smtpd_tls_received_header = yes"
postconf -e "tls_random_source = dev:/dev/urandom"
postconf -e "smtpd_tls_security_level = may"
postconf -e "smtp_tls_security_level = may"
postconf -e "smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_hostname, reject_unknown_client, reject_rbl_client sbl-xbl.spamhaus.org"
postconf -e "smtpd_sender_restrictions = permit_mynetworks, reject_unknown_address, reject_unknown_sender_domain, reject_non_fqdn_sender"
postconf -e "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination"
postconf -e "smtpd_recipient_limit = 250"
postconf -e "milter_default_action = accept"
postconf -e "milter_protocol = 6"
postconf -e "smtpd_milters =  inet:127.0.0.1:8891"
postconf -e "non_smtpd_milters =  inet:127.0.0.1:8891"

# Configure postfix master.cf
sed -i '/^#smtpd.*/ s/^#//' /etc/postfix/master.cf

vi /etc/postfix/master.cf
# Add the following lines at the end:
dovecot	unix	-	n	n	-	-	pipe	flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}


cat > /etc/postfix/virtual_alias <  /etc/postfix/virtual_domains <

Configure Dovecot

cat > /etc/dovecot/dovecot.conf <

Restart all services
service dovecot restart
service postfix restart
service opendkim restart

Adding new email accounts
You can use the following script to add a new email account.  Save the script as ‘add_new_account’, use chmod to make it executable and then run it passing two parameters:

./add_new_account <email@account> #!/bin/bash

vi /home/vmail/add_new_account

# sudo ./add_new_account <email@account>
# Functions
ok() { echo -e '\e[32m'${1}'\e[m'; } # Green
die() { echo -e '\e[1;31m'${1}'\e[m'; exit 1; } # Red

# Sanity check
[ $(id -g) != "0" ] && die "Script must be run as root."
[ $# != "2" ] && die "Usage: $(basename $0) email@account password"
[ ! -f /usr/sbin/postfix ] && die "Postfix is not installed"
[ ! -f /usr/bin/doveadm ] && die "Dovecot is not installed"

# Variables
VMAIL=vmail
VMAIL_UID=5000
VMAIL_GUID=5000
ADDRESS=${1}
PASSWD=${2}
USERNAME=${ADDRESS%@*}
DOMAIN=${ADDRESS##*@}

# Get the Mailbox Base Directory
BASEDIR=$(postconf virtual_mailbox_base)
BASEDIR=${BASEDIR#*= }

# Get the Mailbox Maps File
MAPSFILE=$(postconf virtual_mailbox_maps)
MAPSFILE=${MAPSFILE#*:}

# Check if account exist
if grep -wq "^${ADDRESS}" ${MAPSFILE}
then
die "The mail address ${ADDRESS} already exist"
fi

if [[ ( -f ${MAPSFILE} && -d ${BASEDIR} ) ]]; then

echo "$ADDRESS $DOMAIN/$USERNAME/" >> ${MAPSFILE}
postmap ${MAPSFILE}
if [[ $? -eq 0 ]]; then
echo ${ADDRESS}::${VMAIL_UID}:${VMAIL_GUID}::${BASEDIR}/${DOMAIN}/${ADDRESS} >> ${BASEDIR}/${DOMAIN}/passwd
echo ${ADDRESS}":"$(doveadm pw -p $PASSWD) >> ${BASEDIR}/${DOMAIN}/shadow
chown ${VMAIL}: $BASEDIR/${DOMAIN}/{passwd,shadow}
chmod 775 ${BASEDIR}/${DOMAIN}/{passwd,shadow}
service postfix reload
ok "The email account has been addedd"
fi
else
die "Mailbox maps file or mailbox base directory doesn't exist"
fi

Be the first to comment

Leave a Reply

Your email address will not be published.


*