RQ : change the 3 usernames and their passwords, the mail domain and the server hostname
# for postfixadmin export PFADBNAME="db_pfadmin" export PFADBUSER="pfadmin" export PFADBPW="PASS1_CHANGEME" export PFARODBNAME="db_pfadmin" export PFARODBUSER="pfa_ro" export PFARODBPW="PASS2_CHANGEME" export PFARWDBNAME="db_pfadmin" export PFARWDBUSER="pfa_rw" export PFARWDBPW="PASS3_CHANGEME" export DEFAULT_MAIL_DOMAIN="<changeme>" export MAIL_SERVER_HOSTNAME="<changeme>" export MAIL_SERVER_FQDN="${MAIL_SERVER_HOSTNAME}.${DEFAULT_MAIL_DOMAIN}"
Server update and resolvconf installation :
apt-get update apt-get upgrade apt-get install resolvconf
vi /etc/network/interfaces
Verify/add : “dns-nameservers 127.0.0.1 <DNS_R_1> <DNS_R_2>”
vi /etc/hosts
127.0.0.1 localhost <IP publique> <FQDN> <HOSTNAME>
apt-get install bind9 cp -a /etc/bind/named.conf.local /etc/bind/named.conf.local_ sed -i "s/\/\/include \"\/etc\/bind\/zones\.rfc1918\"\;/include \"\/etc\/bind\/zones\.rfc1918\"\;/g" /etc/bind/named.conf.local /etc/init.d/bind9 stop /etc/init.d/bind9 start
IF NO IPV6 (RQ bug on jessie : https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=767798)
cp -a /etc/default/bind9 /etc/default/bind9_ sed -i "s/RESOLVCONF=no/RESOLVCONF=yes/g" /etc/default/bind9 sed -i "s/OPTIONS=\"-u bind\"/OPTIONS=\"-4 -u bind\"/g" /etc/default/bind9 /etc/init.d/bind9 stop /etc/init.d/bind9 start sleep 3 rndc flush
/etc/init.d/networking stop ; /etc/init.d/networking start
Rq : if the FQDN was changed, restart the server.
apt-get install mysql-server # New mysql superuser password : enter and keep safely somwhere (ex : keepass) apt-get install dbconfig-common
DBs and users creation for postfixadmin
echo "create database $PFADBNAME;" > /opt/create_db_pfa echo "grant usage on *.* to $PFADBUSER@localhost identified by '$PFADBPW';" >> /opt/create_db_pfa echo "grant all privileges on $PFADBNAME.* to $PFADBUSER@localhost ;" >> /opt/create_db_pfa echo "grant usage on *.* to $PFARODBUSER@localhost identified by '$PFARODBPW';" >> /opt/create_db_pfa echo "GRANT SELECT ON $PFARODBNAME.* TO $PFARODBUSER@localhost;" >> /opt/create_db_pfa echo "grant usage on *.* to $PFARWDBUSER@localhost identified by '$PFARWDBPW';" >> /opt/create_db_pfa echo "GRANT SELECT,UPDATE,INSERT ON $PFARWDBNAME.* TO $PFARWDBUSER@localhost;" >> /opt/create_db_pfa cat /opt/create_db_pfa | mysql --defaults-extra-file=/etc/mysql/debian.cnf rm /opt/create_db_pfa
dbconfig preconfiguration for postfixadmin :
cat << 'EOF' > /etc/dbconfig-common/postfixadmin.conf dbc_install='true' dbc_upgrade='true' dbc_remove='' dbc_dbtype='mysql' dbc_dbuser='' dbc_dbpass='' dbc_dbserver='' dbc_dbport='' dbc_dbname='' dbc_dbadmin='root' dbc_basepath='' dbc_ssl='' dbc_authmethod_admin='' dbc_authmethod_user='' EOF sed -i "s/dbc_dbname='.*$/dbc_dbname='$PFADBNAME'/g" /etc/dbconfig-common/postfixadmin.conf sed -i "s/dbc_dbuser='.*$/dbc_dbuser='$PFADBUSER'/g" /etc/dbconfig-common/postfixadmin.conf sed -i "s/dbc_dbpass='.*$/dbc_dbpass='$PFADBPW'/g" /etc/dbconfig-common/postfixadmin.conf
apt-get install postfixadmin # auto reconfigure : apache2 # reconfigure postfixadmin with dbconfig-common ? yes # DB server to use with postfixadmin : mysql # DB admin password : enter mysql superadmin password # choose to install the package maintainer configuration file
if [ -e /var/log/exim4/paniclog ]; then rm /var/log/exim4/paniclog; fi apt-get install postfix postfix-mysql dovecot-common # mail server conf type : internet site # mailserver name : entrer the public FQDN of the mailserver apt-get remove --purge exim4 exim4-base exim4-config exim4-daemon-heavy exim4-daemon-light exim4-config-2 exim4-localscanapi-1.0 exim4-localscanapi-1.1 rm -rf /etc/exim4
apt-get install dovecot-mysql dovecot-sieve dovecot-imapd dovecot-lmtpd dovecot-managesieved
see corresponding howto
cp -a /etc/apache2/conf-available/postfixadmin.conf /etc/apache2/conf-available/postfixadmin.conf_ sed -i "s/Alias \/postfixadmin .*$/Alias \/admin_pfa \/usr\/share\/postfixadmin/g" /etc/apache2/conf-available/postfixadmin.conf cp -a /etc/postfixadmin/dbconfig.inc.php /etc/postfixadmin/dbconfig.inc.php_ sed -i "s|\$dbtype=.*|\$dbtype='mysqli';|g" /etc/postfixadmin/dbconfig.inc.php /etc/init.d/apache2 stop /etc/init.d/apache2 start # verify that the webserver is responding : http://fqdn/admin_pfa vi /etc/postfixadmin/config.inc.php # change these fields : XXX #$CONF['postfix_admin_url'] = '/postfixadmin'; $CONF['postfix_admin_url'] = '/admin_pfa'; $CONF['default_language'] = 'fr'; $CONF['admin_email'] = 'postmaster@<domain_changeme>'; $CONF['default_aliases'] = array ( 'abuse' => 'admin@<domain_changeme>', 'hostmaster' => 'admin@<domain_changeme>', 'postmaster' => 'admin@<domain_changeme>', 'webmaster' => 'admin@<domain_changeme>', 'admin' => 'admin@<domain_changeme>' ); $CONF['aliases'] = '0'; $CONF['mailboxes'] = '0'; $CONF['maxquota'] = '1000'; $CONF['domain_path'] = 'YES'; $CONF['domain_in_mailbox'] = 'NO';
Todo by hand :
service postfix stop
# initial backup cd /etc/postfix mkdir origin cp -ar ./* origin # postfixadmin compatible mysql queries for postfix # RQ : we need exported variables we created before for mysql configuration mkdir /etc/postfix/sql export PFXSQLCONFDIR=/etc/postfix/sql echo "# mysql_virtual_alias_maps user = $PFARODBUSER password = $PFARODBPW hosts = localhost dbname = $PFARODBNAME query = SELECT goto FROM alias WHERE address='%s' AND active = '1' #expansion_limit = 100 " > $PFXSQLCONFDIR/mysql_virtual_alias_maps.cf echo "# mysql_virtual_alias_domain_maps user = $PFARODBUSER password = $PFARODBPW hosts = localhost dbname = $PFARODBNAME query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1' " > $PFXSQLCONFDIR/mysql_virtual_alias_domain_maps.cf echo "# mysql_virtual_alias_domain_catchall_maps # handles catch-all settings of target-domain user = $PFARODBUSER password = $PFARODBPW hosts = localhost dbname = $PFARODBNAME query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1' " > $PFXSQLCONFDIR/mysql_virtual_alias_domain_catchall_maps.cf echo "# mysql_virtual_domains_maps user = $PFARODBUSER password = $PFARODBPW hosts = localhost dbname = $PFARODBNAME query = SELECT domain FROM domain WHERE domain='%s' AND active = '1' #query = SELECT domain FROM domain WHERE domain='%s' #optional query to use when relaying for backup MX #query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1' #expansion_limit = 100 " > $PFXSQLCONFDIR/mysql_virtual_domains_maps.cf echo "# mysql_virtual_mailbox_maps user = $PFARODBUSER password = $PFARODBPW hosts = localhost dbname = $PFARODBNAME query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1' #expansion_limit = 100 " > $PFXSQLCONFDIR/mysql_virtual_mailbox_maps.cf echo "# mysql_virtual_alias_domain_mailbox_maps user = $PFARODBUSER password = $PFARODBPW hosts = localhost dbname = $PFARODBNAME query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1' " > $PFXSQLCONFDIR/mysql_virtual_alias_domain_mailbox_maps.cf echo "# mysql_virtual_mailbox_limit_maps user = $PFARODBUSER password = $PFARODBPW hosts = localhost dbname = $PFARODBNAME query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1' " > $PFXSQLCONFDIR/mysql_virtual_mailbox_limit_maps.cf echo "# mysql_virtual_sasl-sender-check user = $PFARODBUSER password = $PFARODBPW hosts = localhost dbname = $PFARODBNAME query = SELECT goto FROM alias WHERE address='%s' AND active="1" " > $PFXSQLCONFDIR/mysql_virtual_sasl-sender-check.cf chown -R root:postfix /etc/postfix/sql chmod -R 640 /etc/postfix/sql chmod 750 /etc/postfix/sql
cat << '__EOF__' >> /etc/postfix/postfix_header-checks.cf /^received: / IGNORE /^X-Sender: / IGNORE __EOF__ chown root:postfix /etc/postfix/sql chmod 640 /etc/postfix/postfix_header-checks.cf
cat << '__EOF__' >> /etc/postfix/bounce.cf.fr # The failure template is used when mail is returned to the sender; # either the destination rejected the message, or the destination # could not be reached before the message expired in the queue. failure_template = <<EOF Charset: utf-8 From: MAILER-DAEMON (Messagerie auf.org) Subject: Erreur lors de l'acheminement d'un message Postmaster-Subject: Postmaster Copy: Undelivered Mail -- Version française : Information envoyée par le serveur $myhostname : Le message électronique attaché ci-dessous n'a pu être acheminé à l'ensemble de ses destinataires. Vous trouverez plus bas un rapport d'erreur. -- English version : This is the mail system at host $myhostname. Your message could not be delivered to one or more recipients. It's attached below. -- Rapport d'erreur / Problem report : EOF # The delay template is used when mail is delayed. Note a neat trick: # the default template displays the delay_warning_time value as hours # by appending the _hours suffix to the parameter name; it displays # the maximal_queue_lifetime value as days by appending the _days # suffix. # # Other suffixes are: _seconds, _minutes, _weeks. There are no other # main.cf parameters that have this special behavior. # # You need to adjust these suffixes (and the surrounding text) if # you have very different settings for these time parameters. delay_template = <<EOF Charset: utf-8 From: MAILER-DAEMON (Messagerie auf.org) Subject: Retard lors de l'acheminement d'un message Postmaster-Subject: Postmaster Warning: Delayed Mail -- Version française : Information envoyée par le serveur $myhostname : Le système n'est pas parvenu à acheminer le message ci-dessous depuis plus de $delay_warning_time_hours heures. L'envoi va être tenté à nouveau pendant $maximal_queue_lifetime_days jours. ** NB : ceci est seulement un message d'information, vous n'avez pas besoin ** de renvoyer votre message. -- English version : This is the mail system at host $myhostname. Your message could not be delivered for more than $delay_warning_time_hours hour(s). It will be retried until it is $maximal_queue_lifetime_days day(s) old. ** This is a warning only, you do not need to resend your message. -- Rapport d'erreur / Problem report : EOF # # The success template is used when mail is delivered to mailbox, # when an alias or list is expanded, or when mail is delivered to a # system that does not announce DSN support. It is an error to specify # a Postmaster-Subject: here. # success_template = <<EOF Charset: utf-8 From: MAILER-DAEMON (Messagerie auf.org) Subject: Message delivre avec succes -- Version française : Information envoyée par le serveur $myhostname : Votre message a été acheminé avec succès aux destinations indiquées ci-dessous. Si le message est arrivé dans la boîte aux lettres finale vous ne recevrez pas d'autres informations, sinon d'autres d'erreurs peuvent survenir et vous serons éventuellement signalées par d'autres systèmes. -- English version : This is the mail system at host $myhostname. Your message was successfully delivered to the destination(s) listed below. If the message was delivered to mailbox you will receive no further notifications. Otherwise you may still receive notifications of mail delivery errors from other systems. EOF # The verify template is used for address verification (sendmail -bv # address...). or for verbose mail delivery (sendmail -v address...). # It is an error to specify a Postmaster-Subject: here. verify_template = <<EOF Charset: utf-8 From: MAILER-DAEMON (Messagerie auf.org) Subject: Mail Delivery Status Report -- Version française : Information envoyée par le serveur $myhostname : Ci-dessous le rapport d'acheminement que vous avez demandé. -- English version : This is the mail system at host $myhostname. Enclosed is the mail delivery report that you requested. EOF __EOF__ chown root:root /etc/postfix/bounce.cf.fr chmod 644 /etc/postfix/bounce.cf.fr
Cleanup the safe run postfix environment :
rm /var/lib/postfix/*
vi /etc/postfix/main.cf
# See /usr/share/postfix/main.cf.dist for a commented, more complete version ################################################# # Main domain & conf # myhostname = _MAIL_SERVER_FQDN_ mydomain = _DEFAULT_MAIL_DOMAIN_ myorigin = /etc/mailname mydestination = _MAIL_SERVER_FQDN_, localhost._DEFAULT_MAIL_DOMAIN_, localhost relayhost = inet_interfaces = all mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases # Recipient delimiter : + is often refused, _ is more accepted recipient_delimiter = _ # Strict address format in addresses strict_rfc821_envelopes = yes # Maximum postmaster notifications notify_classes = bounce, 2bounce, delay, policy, protocol, resource, software # Mail maximum size in Bytes message_size_limit = 67108864 mailbox_size_limit = 0 ################################################################################ # SSL/TLS # TLS parameters smtpd_tls_cert_file=/etc/ssl/certs/<changeme> smtpd_tls_key_file=/etc/ssl/private/<changeme> smtpd_use_tls=yes smtpd_tls_auth_only = yes ################################################################################ # Sender restrictions # Only registered users can send emails smtpd_sender_login_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_sasl-sender-check.cf smtpd_reject_unlisted_sender = yes # Have a look : http://www.postfix.org/SMTPD_ACCESS_README.html smtpd_client_restrictions = smtpd_sender_restrictions = permit_sasl_authenticated smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_unverified_recipient reject_non_fqdn_recipient ## reject_non_fqdn_sender reject_non_fqdn_helo_hostname reject_invalid_helo_hostname ## reject_unknown_sender_domain reject_unknown_recipient_domain reject_unlisted_recipient reject_unlisted_sender reject_unauth_destination reject_unlisted_sender reject_unauth_destination reject_rbl_client bl.spamcop.net reject_rbl_client zen.spamhaus.org permit smtpd_data_restrictions = reject_unauth_pipelining reject_multi_recipient_bounce permit # hide the sender IP header_checks = regexp:/etc/postfix/postfix_header-checks.cf ################################################################################ # SASL Auth smtpd_sasl_auth_enable = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_sasl_security_options = noanonymous smtpd_sasl_local_domain = smtpd_sasl_authenticated_header = yes broken_sasl_auth_clients = yes ################################################################################ # mail delivery #mailbox_transport = dovecot #mailbox_command = procmail -a "$EXTENSION" #mailbox_command = /usr/lib/dovecot/deliver -n -m "$EXTENSION" #mailbox_size_limit = 0 #dovecot_destination_recipient_limit = 1 virtual_transport = lmtp:unix:private/dovecot-lmtp ################################################ # Virtual mailboxes virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf virtual_alias_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf, proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf ################################################################################ # misc config # No local user, no need to notify them. biff = no # Appending .domain is the MUA's job. append_dot_mydomain = no # messages d'erreur (bounces) en français : bounce_template_file = /etc/postfix/bounce.cf.fr # warn the user of non distributed mail after 24h of tries (but keep trying during 5 days) delay_warning_time = 24h # No need for documentation readme_directory = no # HELO Stuff smtpd_banner = $myhostname ESMTP $mail_name smtpd_helo_required = yes ################################################ # Proxy # Proxy service feeding (important because of the chrooted environment in Debian) proxy_read_maps = $local_recipient_maps $mydestination $mynetworks $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $smtpd_sender_login_maps proxy_write_maps = $smtp_sasl_auth_cache_name $smtp_tls_session_cache_database $smtpd_tls_session_cache_database $lmtp_sasl_auth_cache_name $address_verify_map $postscreen_cache_map smtp_sasl_auth_cache_name = proxy:btree:${data_directory}/smtp_sasl_auth_cache_name smtp_tls_session_cache_database = proxy:btree:${data_directory}/smtp_tls_session_cache_database smtpd_tls_session_cache_database = proxy:btree:${data_directory}/smtpd_tls_session_cache_database lmtp_sasl_auth_cache_name = proxy:btree:${data_directory}/lmtp_sasl_auth_cache_name address_verify_map = proxy:btree:${data_directory}/address_verify_map postscreen_cache_map = proxy:btree:${data_directory}/postscreen_cache_map
sed -i "s/_DEFAULT_MAIL_DOMAIN_/${DEFAULT_MAIL_DOMAIN}/g" /etc/postfix/main.cf sed -i "s/_MAIL_SERVER_HOSTNAME_/${MAIL_SERVER_HOSTNAME}/g" /etc/postfix/main.cf sed -i "s/_MAIL_SERVER_FQDN_/${MAIL_SERVER_FQDN}/g" /etc/postfix/main.cf
vi /etc/postfix/master.cf
add :
submission inet n - n - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_sasl_type=dovecot -o smtpd_sasl_path=private/auth -o smtpd_sasl_security_options=noanonymous -o smtpd_sasl_local_domain=$myhostname -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o smtpd_sender_restrictions=reject_sender_login_mismatch -o smtpd_recipient_restrictions=reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_sasl_authenticated,reject
cd /etc/dovecot mkdir origin cp -aR ./* origin echo " # postfixadmin database queries driver = mysql connect = host=localhost dbname=$PFARODBNAME user=$PFARODBUSER password=$PFARODBPW default_pass_scheme = MD5-CRYPT user_query = SELECT concat('/data/vmail/', maildir) AS home, 500 AS uid, 500 AS gid FROM mailbox WHERE username = '%u' password_query = SELECT username as user, password, concat('/data/vmail/', maildir) as userdb_home, 500 as userdb_uid, 500 as userdb_gid, CONCAT('dirsize:storage=', ROUND(quota / 1024) ) AS quota FROM mailbox WHERE username = '%u' AND active=1 " >> /etc/dovecot/dovecot-sql.conf.ext sed -i "s/#disable_plaintext_auth = yes/disable_plaintext_auth = yes/g" /etc/dovecot/conf.d/10-auth.conf sed -i "s/\!include auth-system.conf.ext/#\!include auth-system.conf.ext/g" /etc/dovecot/conf.d/10-auth.conf sed -i "s/#\!include auth-sql.conf.ext/\!include auth-sql.conf.ext/g" /etc/dovecot/conf.d/10-auth.conf sed -i "s/mail_location =.*$/mail_location = maildir:%h/g" /etc/dovecot/conf.d/10-mail.conf sed -i "s/#mail_privileged_group =/mail_privileged_group = mail/g" /etc/dovecot/conf.d/10-mail.conf #sed -i "s/#port = 993/port = 993/g" /etc/dovecot/conf.d/10-master.conf sed -i "s/unix_listener lmtp {/unix_listener \/var\/spool\/postfix\/private\/dovecot-lmtp {\n user = postfix\n group = postfix\n mode = 0600/g" /etc/dovecot/conf.d/10-master.conf sed -i "s/unix_listener auth-userdb {/unix_listener auth-userdb {\n user = vmail/g" /etc/dovecot/conf.d/10-master.conf sed -i "s/# Postfix smtp-auth/# Postfix smtp-auth\n unix_listener \/var\/spool\/postfix\/private\/auth {\n mode = 0666\n }/g" /etc/dovecot/conf.d/10-master.conf sed -i "s/service auth-worker {/service auth-worker {\n user = \$default_internal_user/g" /etc/dovecot/conf.d/10-master.conf sed -i "s/ssl = no/ssl=required/g" /etc/dovecot/conf.d/10-ssl.conf sed -i 's/#ssl_protocols = !SSLv2/ssl_protocols = !SSLv2/g' /etc/dovecot/conf.d/10-ssl.conf sed -i 's/#ssl_cipher_list = ALL:!LOW:!SSLv2:!EXP:!aNULL/ssl_cipher_list = ALL:!LOW:!SSLv2:!EXP:!aNULL/g' /etc/dovecot/conf.d/10-ssl.conf #sed -i "s/#postmaster_address =/postmaster_address = postmaster@<changeme>/g" /etc/dovecot/conf.d/15-lda.conf #sed -i "s/#recipient_delimiter = +/#recipient_delimiter = +\nrecipient_delimiter = _/g" /etc/dovecot/conf.d/15-lda.conf sed -i "s/protocol lmtp {/protocol lmtp {\n postmaster_address = postmaster@<changeme>\n mail_plugins = \$mail_plugins quota sieve /g" /etc/dovecot/conf.d/20-lmtp.conf sed -i "s/#recipient_delimiter = +/#recipient_delimiter = +\n recipient_delimiter = _/g" /etc/dovecot/conf.d/90-sieve.conf mkdir -p /data/vmail chmod 770 /data/vmail groupadd --gid 500 vmail useradd --system --uid 500 --gid 500 --home-dir /data/vmail --shell /sbin/nologin --comment "Virtual mailbox" vmail chown vmail:vmail /data/vmail
Do by hand :
# (re)start services
tail -f /var/log/syslog & service dovecot stop service dovecot start service postfix start fg
Add www-data alias
echo "www-data: root" >> /etc/aliases echo "root: admin_<MAIL_SERVER_FQDN>@<DEFAULT_MAIL_DOMAIN>" >> /etc/aliases newaliases
Final verification (all the chain)
# stop mail services for SERVICE_ in postfix dovecot ; do service $SERVICE_ stop; done # start mail services for SERVICE_ in dovecot postfix; do service $SERVICE_ start; done