Difference between revisions of "Linux Mail Server: Exim4"

From RHS Wiki
Jump to navigation Jump to search
Tag: visualeditor
Line 1: Line 1:
= Whispers Mail Server =
+
=Whispers Mail Server=
== Stack ==
+
==Stack==
* Web server (Apache)
 
* Database server (MySQL)
 
* Email server (MTA) (Exim4)
 
* IMAP server (Dovecot)
 
* Webmail server (Roundcube)
 
  
== Install ==
+
*Web server (Apache)
* apt-get install apache2-mpm-prefork
+
*Database server (MySQL)
** (Some of these email servers require PHP; PHP is crappy and requires mpm-prefork (the ‘slow’ version of Apache))  
+
*Email server (MTA) (Exim4)
* apt-get install mysql-client
+
*IMAP server (Dovecot)
** (should auto-install something like: mysql-common + mysql-client-5.5)
+
*Webmail server (Roundcube)
* apt-get install mysql-server
 
** (should auto-install something like: mysql-server-5.5 + mysql-server-core-5.5)
 
* apt-get install exim4
 
* apt-get install exim4-base
 
* apt-get install exim4-config
 
* apt-get install exim4-daemon-heavy
 
** (there’s an “exim4-mysql” that might be sufficient to replace this, but I gave up: there are way too many exim4 packages, and no help for installing the “correct” set, so … just pick this and get the lot!)
 
* apt-get install dovecot-core
 
* apt-get install dovecot-imapd
 
* apt-get install dovecot-mysql
 
* apt-get install roundcube
 
* apt-get install roundcube-core
 
* apt-get install roundcube-mysql
 
* apt-get install roundcube-plugins
 
  
== Setup ==
+
==Install==
=== DNS ===
+
 
 +
*apt-get install apache2-mpm-prefork
 +
**(Some of these email servers require PHP; PHP is crappy and requires mpm-prefork (the ‘slow’ version of Apache))
 +
*apt-get install mysql-client
 +
**(should auto-install something like: mysql-common + mysql-client-5.5)
 +
*apt-get install mysql-server
 +
**(should auto-install something like: mysql-server-5.5 + mysql-server-core-5.5)
 +
*apt-get install exim4
 +
*apt-get install exim4-base
 +
*apt-get install exim4-config
 +
*apt-get install exim4-daemon-heavy
 +
**(there’s an “exim4-mysql” that might be sufficient to replace this, but I gave up: there are way too many exim4 packages, and no help for installing the “correct” set, so … just pick this and get the lot!)
 +
*apt-get install dovecot-core
 +
*apt-get install dovecot-imapd
 +
*apt-get install dovecot-mysql
 +
*apt-get install roundcube
 +
*apt-get install roundcube-core
 +
*apt-get install roundcube-mysql
 +
*apt-get install roundcube-plugins
 +
 
 +
==Setup==
 +
====DNS====
 
You should know about this already: you need an “MX” record on your DNS server, and it needs to point to your main server where you’ll run your email, web, etc.
 
You should know about this already: you need an “MX” record on your DNS server, and it needs to point to your main server where you’ll run your email, web, etc.
  
Line 49: Line 51:
 
Host: @; Apunta a:mailstore1.secureserver.net; Prioridad:50; TTL:1h
 
Host: @; Apunta a:mailstore1.secureserver.net; Prioridad:50; TTL:1h
  
=== Apache ===
+
<br />
/etc/apache2/sites-available/webmail.conf
+
 
<nowiki><VirtualHost *:80>
+
==== SPF ====
    ServerAdmin rafael@herrerosolis.com
+
TXT
    Redirect permanent / https://webmail.herrerosolis.com/
 
#    DocumentRoot /var/www/rafael
 
    ServerName webmail.herrerosolis.com
 
    ServerAlias webmail.herrerosolis.com
 
    ErrorLog /var/log/apache2/webmail/error.log
 
  
    # Posible values include: debug, info, notice, warn, error, crit.
+
Host: @; Valor TXT: v=spf1 mx ip4:54.154.227.190 ~all
    # alert, emerg.
 
  
    CustomLog /var/log/apache2/webmail/access.log combined
+
==== DMARC ====
</virtualHost>
+
TXT
  
<VirtualHost *:443>
+
Host: _dmarc
    ServerAdmin rafael@herrerosolis.com
 
    DocumentRoot /var/lib/roundcube
 
    ServerName webmail.herrerosolis.com
 
    ServerAlias webmail.herrerosolis.com
 
  
    ErrorLog /var/log/apache2/webmail/error.log
+
Valor TXT: v=DMARC1; p=none  Verification details:      mail-tester.com; dmarc=none header.from=herrerosolis.com     From Domain: herrerosolis.com     DKIM Domain:MIIBIjANBg[...]qCwPwIDAQAB
  
    # Posible values include: debug, info, notice, warn, error, crit.
+
===Apache===
    # alert, emerg.
+
/etc/apache2/sites-available/webmail.conf
    CustomLog /var/log/apache2/webmail/access.log combined
+
<nowiki><VirtualHost *:80>
    SSLEngine on
+
    ServerAdmin rafael@herrerosolis.com
    SSLCertificateFile /etc/ssl/certs/herrerosolis.crt
+
    Redirect permanent / https://webmail.herrerosolis.com/
    SSLCertificateKeyFile /etc/ssl/private/herrerosolis.key
+
#    DocumentRoot /var/www/rafael
</virtualHost>
+
    ServerName webmail.herrerosolis.com
</nowiki>
+
    ServerAlias webmail.herrerosolis.com
 +
    ErrorLog /var/log/apache2/webmail/error.log
 +
 +
    # Posible values include: debug, info, notice, warn, error, crit.
 +
    # alert, emerg.
 +
 +
    CustomLog /var/log/apache2/webmail/access.log combined
 +
</virtualHost>
 +
 +
<VirtualHost *:443>
 +
    ServerAdmin rafael@herrerosolis.com
 +
    DocumentRoot /var/lib/roundcube
 +
    ServerName webmail.herrerosolis.com
 +
    ServerAlias webmail.herrerosolis.com
 +
 +
    ErrorLog /var/log/apache2/webmail/error.log
 +
 +
    # Posible values include: debug, info, notice, warn, error, crit.
 +
    # alert, emerg.
 +
    CustomLog /var/log/apache2/webmail/access.log combined
 +
    SSLEngine on
 +
    SSLCertificateFile /etc/ssl/certs/herrerosolis.crt
 +
    SSLCertificateKeyFile /etc/ssl/private/herrerosolis.key
 +
</virtualHost>
 +
</nowiki>
  
=== OPTIONAL: Remove TinyMCE ===
+
===OPTIONAL: Remove TinyMCE===
 
TinyMCE is a WYSIWYG text-editor for HTML emails. I hate it. It had a long history of being insecure, buggy, slow, and hard to use. So I disable it:
 
TinyMCE is a WYSIWYG text-editor for HTML emails. I hate it. It had a long history of being insecure, buggy, slow, and hard to use. So I disable it:
  
Line 88: Line 104:
  
 
  <nowiki>Comment out these lines:
 
  <nowiki>Comment out these lines:
#<Directory "/usr/share/tinymce/www/">
+
#<Directory "/usr/share/tinymce/www/">
#      Options Indexes MultiViews FollowSymLinks
+
#      Options Indexes MultiViews FollowSymLinks
#      AllowOverride None
+
#      AllowOverride None
#      Order allow,deny
+
#      Order allow,deny
#      allow from all
+
#      allow from all
#</Directory>
+
#</Directory>
</nowiki>
+
</nowiki>
  
=== Create Databases ===
+
===Create Databases===
 
  mysql -u root -p
 
  mysql -u root -p
  
Line 104: Line 120:
  
 
  <nowiki>CREATE TABLE mailboxes (
 
  <nowiki>CREATE TABLE mailboxes (
    id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+
    id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    domain_id INT(10) NOT NULL,
+
    domain_id INT(10) NOT NULL,
    local_part VARCHAR(250) NOT NULL,
+
    local_part VARCHAR(250) NOT NULL,
    password VARCHAR(100) NULL,
+
    password VARCHAR(100) NULL,
    description VARCHAR(250) NULL,
+
    description VARCHAR(250) NULL,
    active TINYINT(1) NOT NULL DEFAULT 0,
+
    active TINYINT(1) NOT NULL DEFAULT 0,
    created TIMESTAMP NOT NULL DEFAULT NOW(),
+
    created TIMESTAMP NOT NULL DEFAULT NOW(),
    modified TIMESTAMP NULL
+
    modified TIMESTAMP NULL
);
+
);
CREATE TABLE aliases (
+
CREATE TABLE aliases (
    id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+
    id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    domain_id INT(10) NOT NULL,
+
    domain_id INT(10) NOT NULL,
    local_part VARCHAR(250) NOT NULL,
+
    local_part VARCHAR(250) NOT NULL,
    goto VARCHAR(250) NOT NULL,
+
    goto VARCHAR(250) NOT NULL,
    description VARCHAR(250) NULL,
+
    description VARCHAR(250) NULL,
    active TINYINT(1) NOT NULL DEFAULT 0,
+
    active TINYINT(1) NOT NULL DEFAULT 0,
    created TIMESTAMP NOT NULL DEFAULT NOW(),
+
    created TIMESTAMP NOT NULL DEFAULT NOW(),
    modified TIMESTAMP NULL
+
    modified TIMESTAMP NULL
);
+
);
CREATE TABLE vacations (
+
CREATE TABLE vacations (
    id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+
    id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    mailbox_id INT(10) NOT NULL,
+
    mailbox_id INT(10) NOT NULL,
    subject VARCHAR(250) NOT NULL,
+
    subject VARCHAR(250) NOT NULL,
    body TEXT NOT NULL,
+
    body TEXT NOT NULL,
    description VARCHAR(250) NULL,
+
    description VARCHAR(250) NULL,
    active TINYINT(1) NOT NULL DEFAULT 0,
+
    active TINYINT(1) NOT NULL DEFAULT 0,
    created TIMESTAMP NOT NULL DEFAULT NOW(),
+
    created TIMESTAMP NOT NULL DEFAULT NOW(),
    modified TIMESTAMP NULL
+
    modified TIMESTAMP NULL
);
+
);
 
+
CREATE TABLE domains (
+
CREATE TABLE domains (
    id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+
    id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    fqdn VARCHAR(250) NOT NULL,
+
    fqdn VARCHAR(250) NOT NULL,
    type ENUM('local','relay') NOT NULL DEFAULT 'local',
+
    type ENUM('local','relay') NOT NULL DEFAULT 'local',
    description VARCHAR(250) NULL,
+
    description VARCHAR(250) NULL,
    active TINYINT(1) NOT NULL DEFAULT 0,
+
    active TINYINT(1) NOT NULL DEFAULT 0,
    created TIMESTAMP NOT NULL DEFAULT NOW(),
+
    created TIMESTAMP NOT NULL DEFAULT NOW(),
    modified TIMESTAMP NULL
+
    modified TIMESTAMP NULL
);
+
);
</nowiki>
+
</nowiki>
  
=== Create your first email account and domain ===
+
===Create your first email account and domain===
==== Domain ====
+
====Domain====
 
  <nowiki>INSERT INTO domains VALUES(NULL,'herrerosolis.com','local','My personal domain',1,NOW(),NOW());</nowiki>
 
  <nowiki>INSERT INTO domains VALUES(NULL,'herrerosolis.com','local','My personal domain',1,NOW(),NOW());</nowiki>
  
==== User ====
+
====User====
 
  <nowiki>INSERT INTO mailboxes VALUES(NULL,1,'joe',MD5('password - choose a good one'),'My account for joe@herrerosolis.com',1,NOW(),NOW());</nowiki>
 
  <nowiki>INSERT INTO mailboxes VALUES(NULL,1,'joe',MD5('password - choose a good one'),'My account for joe@herrerosolis.com',1,NOW(),NOW());</nowiki>
  
==== Alias ====
+
====Alias====
 
  <nowiki>insert into aliases values (null, 1, 'rafa', 'rafael@herrerosolis.com', 'Redirect to me', 1, NOW(), NOW() );</nowiki>
 
  <nowiki>insert into aliases values (null, 1, 'rafa', 'rafael@herrerosolis.com', 'Redirect to me', 1, NOW(), NOW() );</nowiki>
  
=== Create a database-account to access the database ===
+
===Create a database-account to access the database===
 
  <nowiki>grant ALL on email_accounts.* to 'email'@'localhost' identified by 'password';
 
  <nowiki>grant ALL on email_accounts.* to 'email'@'localhost' identified by 'password';
flush privileges;
+
flush privileges;
</nowiki>
+
</nowiki>
 
http://bradthemad.org/tech/notes/exim_cheatsheet.php
 
http://bradthemad.org/tech/notes/exim_cheatsheet.php
  
=== Exim Configuration ===  
+
===Exim Configuration===  
* TODO: review daemon ports @/etc/exim4/conf.d/main/9_exim4-config_daemon
+
 
 +
*TODO: review daemon ports @/etc/exim4/conf.d/main/9_exim4-config_daemon
  
  
Line 171: Line 188:
  
 
  <nowiki># /etc/exim4/update-exim4.conf.conf
 
  <nowiki># /etc/exim4/update-exim4.conf.conf
#
+
#
# Edit this file and /etc/mailname by hand and execute update-exim4.conf
+
# Edit this file and /etc/mailname by hand and execute update-exim4.conf
# yourself or use 'dpkg-reconfigure exim4-config'
+
# yourself or use 'dpkg-reconfigure exim4-config'
#
+
#
# Please note that this is _not_ a dpkg-conffile and that automatic changes
+
# Please note that this is _not_ a dpkg-conffile and that automatic changes
# to this file might happen. The code handling this will honor your local
+
# to this file might happen. The code handling this will honor your local
# changes, so this is usually fine, but will break local schemes that mess
+
# changes, so this is usually fine, but will break local schemes that mess
# around with multiple versions of the file.
+
# around with multiple versions of the file.
#
+
#
# update-exim4.conf uses this file to determine variable values to generate
+
# update-exim4.conf uses this file to determine variable values to generate
# exim configuration macros for the configuration file.
+
# exim configuration macros for the configuration file.
#
+
#
# Most settings found in here do have corresponding questions in the
+
# Most settings found in here do have corresponding questions in the
# Debconf configuration, but not all of them.
+
# Debconf configuration, but not all of them.
#
+
#
# This is a Debian specific file
+
# This is a Debian specific file
 
+
dc_eximconfig_configtype='internet'
+
dc_eximconfig_configtype='internet'
dc_other_hostnames='[YOUR DOMAIN 1];[YOUR DOMAIN 2]'
+
dc_other_hostnames='[YOUR DOMAIN 1];[YOUR DOMAIN 2]'
dc_local_interfaces='127.0.0.1;[PUT YOUR SERVER's IP ADDRESS HERE]'
+
dc_local_interfaces='127.0.0.1;[PUT YOUR SERVER's IP ADDRESS HERE]'
dc_readhost=''
+
dc_readhost=''
dc_relay_domains=''
+
dc_relay_domains=''
dc_minimaldns='false'
+
dc_minimaldns='false'
dc_relay_nets=''
+
dc_relay_nets=''
dc_smarthost=''
+
dc_smarthost=''
CFILEMODE='644'
+
CFILEMODE='644'
dc_use_split_config='true'
+
dc_use_split_config='true'
dc_hide_mailname=''
+
dc_hide_mailname=''
dc_mailname_in_oh='true'
+
dc_mailname_in_oh='true'
dc_localdelivery='maildir_home'</nowiki>
+
dc_localdelivery='maildir_home'</nowiki>
  
==== Macros ====
+
====Macros====
 
ADD the following to /etc/exim4/conf.d/main/000_localmacros
 
ADD the following to /etc/exim4/conf.d/main/000_localmacros
 
  <nowiki>MAIN_LOCAL_DOMAINS = @:localhost:dsearch;/etc/exim4/virtual:${lookup mysql{SELECT fqdn AS domain FROM domains WHERE fqdn='${quote_mysql:$domain}' AND type='local' AND active=1}}</nowiki>
 
  <nowiki>MAIN_LOCAL_DOMAINS = @:localhost:dsearch;/etc/exim4/virtual:${lookup mysql{SELECT fqdn AS domain FROM domains WHERE fqdn='${quote_mysql:$domain}' AND type='local' AND active=1}}</nowiki>
Line 208: Line 225:
 
ADD the following to /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs
 
ADD the following to /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs
 
  <nowiki># List of domains considered local for exim. Domains not listed here
 
  <nowiki># List of domains considered local for exim. Domains not listed here
# need to be deliverable remotely.
+
# need to be deliverable remotely.
domainlist local_domains = MAIN_LOCAL_DOMAINS
+
domainlist local_domains = MAIN_LOCAL_DOMAINS
 
+
# MySQL because exim4 on Debian doesn't always add this:
+
# MySQL because exim4 on Debian doesn't always add this:
 +
 +
MYSQL_SERVER=127.0.0.1
 +
MYSQL_DB=email_accounts
 +
MYSQL_USER=email
 +
MYSQL_PASSWORD=password
 +
hide mysql_servers = MYSQL_SERVER/MYSQL_DB/MYSQL_USER/MYSQL_PASSWORD</nowiki>
  
MYSQL_SERVER=127.0.0.1
+
====Routers====
MYSQL_DB=email_accounts
 
MYSQL_USER=email
 
MYSQL_PASSWORD=password
 
hide mysql_servers = MYSQL_SERVER/MYSQL_DB/MYSQL_USER/MYSQL_PASSWORD</nowiki>
 
 
 
==== Routers ====
 
 
CREATE the file /etc/exim4/conf.d/router/360_exim4-config_mysqlusers
 
CREATE the file /etc/exim4/conf.d/router/360_exim4-config_mysqlusers
  
 
  <nowiki>dovecot_user:
 
  <nowiki>dovecot_user:
      driver = accept
+
      driver = accept
        condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) AS goto FROM domains,mailboxes WHERE \
+
        condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) AS goto FROM domains,mailboxes WHERE \
                  mailboxes.local_part='${quote_mysql:$local_part}' AND \
+
                    mailboxes.local_part='${quote_mysql:$local_part}' AND \
                  mailboxes.active=1 AND \
+
                    mailboxes.active=1 AND \
                  mailboxes.domain_id=domains.id AND \
+
                    mailboxes.domain_id=domains.id AND \
                  domains.fqdn='${quote_mysql:$domain}' AND \
+
                    domains.fqdn='${quote_mysql:$domain}' AND \
                  domains.active=1}{yes}{no}}
+
                    domains.active=1}{yes}{no}}
    transport = dovecot_delivery</nowiki>
+
      transport = dovecot_delivery</nowiki>
  
 
Either DELETE this file, or comment-out all lines /etc/exim4/conf.d/router/400_exim4-config_system_aliases<br />
 
Either DELETE this file, or comment-out all lines /etc/exim4/conf.d/router/400_exim4-config_system_aliases<br />
Line 237: Line 254:
  
 
  <nowiki>### router/401_exim4-config_mysql_aliases
 
  <nowiki>### router/401_exim4-config_mysql_aliases
#################################
+
#################################
 +
 +
# ADAM: This router handles aliasing using the proprietary mysql setup
 +
#
 +
# c.f. http://alex.mamchenkov.net/2010/06/24/exim-dovecot-and-mysql/
 +
#
 +
 +
system_aliases:
 +
      driver = redirect
 +
      allow_fail
 +
      allow_defer
 +
      data = ${lookup mysql{SELECT aliases.goto AS goto FROM domains,aliases WHERE \
 +
                    (aliases.local_part='${quote_mysql:$local_part}' OR aliases.local_part='@') AND \
 +
                    aliases.active=1 AND \
 +
                    aliases.domain_id=domains.id AND \
 +
                    domains.fqdn='${quote_mysql:$domain}' AND \
 +
                    domains.active=1}}
 +
</nowiki>
  
# ADAM: This router handles aliasing using the proprietary mysql setup
+
====Transports====
#
 
# c.f. http://alex.mamchenkov.net/2010/06/24/exim-dovecot-and-mysql/
 
#
 
 
 
system_aliases:
 
    driver = redirect
 
    allow_fail
 
    allow_defer
 
    data = ${lookup mysql{SELECT aliases.goto AS goto FROM domains,aliases WHERE \
 
                  (aliases.local_part='${quote_mysql:$local_part}' OR aliases.local_part='@') AND \
 
                  aliases.active=1 AND \
 
                  aliases.domain_id=domains.id AND \
 
                  domains.fqdn='${quote_mysql:$domain}' AND \
 
                  domains.active=1}}
 
</nowiki>
 
 
 
==== Transports ====
 
 
CREATE / OVERWRITE the file /etc/exim4/conf.d/transport/30_exim4-config_dovecot
 
CREATE / OVERWRITE the file /etc/exim4/conf.d/transport/30_exim4-config_dovecot
  
 
  <nowiki>### transport/30_exim4-config_dovecot
 
  <nowiki>### transport/30_exim4-config_dovecot
#################################
+
#################################
 
+
#
+
#
 
+
dovecot_delivery:
+
dovecot_delivery:
    driver = appendfile
+
      driver = appendfile
    maildir_format = true
+
      maildir_format = true
    directory = /var/spool/mail/$domain/$local_part
+
      directory = /var/spool/mail/$domain/$local_part
    create_directory = true
+
      create_directory = true
    directory_mode = 0770
+
      directory_mode = 0770
    mode_fail_narrower = false
+
      mode_fail_narrower = false
    message_prefix =
+
      message_prefix =
    message_suffix =
+
      message_suffix =
    delivery_date_add
+
      delivery_date_add
    envelope_to_add
+
      envelope_to_add
    return_path_add
+
      return_path_add
    user = mail
+
      user = mail
    group = mail
+
      group = mail
    mode = 0660
+
      mode = 0660
</nowiki>
+
</nowiki>
  
==== Auth ====
+
====Auth====
 
CREATE the file /etc/exim4/conf.d/auth/20_exim4-config_mysql-authenticator
 
CREATE the file /etc/exim4/conf.d/auth/20_exim4-config_mysql-authenticator
  
 
  <nowiki>### AUTHENTICATIOR SECTION
 
  <nowiki>### AUTHENTICATIOR SECTION
 
+
auth_plain:
+
auth_plain:
    driver = plaintext
+
      driver = plaintext
    public_name = PLAIN
+
      public_name = PLAIN
    server_condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) FROM mailboxes,domains WHERE \
+
      server_condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) FROM mailboxes,domains WHERE \
                      mailboxes.local_part=SUBSTRING_INDEX('${quote_mysql:$auth2}','@',1) AND \
+
                        mailboxes.local_part=SUBSTRING_INDEX('${quote_mysql:$auth2}','@',1) AND \
                      mailboxes.password=MD5('${quote_mysql:$auth3}') AND \
+
                        mailboxes.password=MD5('${quote_mysql:$auth3}') AND \
                      mailboxes.active=1 AND \
+
                        mailboxes.active=1 AND \
                      mailboxes.domain_id=domains.id AND \
+
                        mailboxes.domain_id=domains.id AND \
                      domains.fqdn=SUBSTRING_INDEX('${quote_mysql:$auth2}','@',-1) AND \
+
                        domains.fqdn=SUBSTRING_INDEX('${quote_mysql:$auth2}','@',-1) AND \
                      domains.active=1}{yes}{no}}
+
                        domains.active=1}{yes}{no}}
    server_prompts = :
+
      server_prompts = :
    server_set_id = $auth2
+
      server_set_id = $auth2
 
+
auth_login:
+
auth_login:
    driver = plaintext
+
      driver = plaintext
    public_name = LOGIN
+
      public_name = LOGIN
    server_condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) FROM mailboxes,domains WHERE \
+
      server_condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) FROM mailboxes,domains WHERE \
                      mailboxes.local_part=SUBSTRING_INDEX('${quote_mysql:$auth1}','@',1) AND \
+
                        mailboxes.local_part=SUBSTRING_INDEX('${quote_mysql:$auth1}','@',1) AND \
                      mailboxes.password=MD5('${quote_mysql:$auth2}') AND \
+
                        mailboxes.password=MD5('${quote_mysql:$auth2}') AND \
                      mailboxes.active=1 AND \
+
                        mailboxes.active=1 AND \
                      mailboxes.domain_id=domains.id AND \
+
                        mailboxes.domain_id=domains.id AND \
                      domains.fqdn=SUBSTRING_INDEX('${quote_mysql:$auth1}','@',-1) AND \
+
                        domains.fqdn=SUBSTRING_INDEX('${quote_mysql:$auth1}','@',-1) AND \
                      domains.active=1}{yes}{no}}
+
                        domains.active=1}{yes}{no}}
    server_prompts = Username:: : Password::
+
      server_prompts = Username:: : Password::
    server_set_id = $auth1</nowiki>
+
      server_set_id = $auth1</nowiki>
  
  
==== Ports ====
+
====Ports====
 
CREATE the file /etc/exim4/conf.d/main/9_exim4-config_daemon
 
CREATE the file /etc/exim4/conf.d/main/9_exim4-config_daemon
 
  <nowiki>daemon_smtp_ports = 25 : 465 : 587</nowiki>
 
  <nowiki>daemon_smtp_ports = 25 : 465 : 587</nowiki>
Line 320: Line 337:
 
https://aws.amazon.com/forms/ec2-email-limit-rdns-request?catalog=true&isauthcode=true
 
https://aws.amazon.com/forms/ec2-email-limit-rdns-request?catalog=true&isauthcode=true
  
=== Dovecot ===
+
===Dovecot===
 
Make sure you choose split files, can be fixed with:
 
Make sure you choose split files, can be fixed with:
 
  dpkg-reconfigure dovecot-core
 
  dpkg-reconfigure dovecot-core
Line 329: Line 346:
 
ADD to the file /etc/dovecot/dovecot.conf
 
ADD to the file /etc/dovecot/dovecot.conf
 
  <nowiki>protocols = imap
 
  <nowiki>protocols = imap
listen = *, ::</nowiki>
+
listen = *, ::</nowiki>
  
 
Add to the file /etc/dovecot/conf.d/10-mail.conf
 
Add to the file /etc/dovecot/conf.d/10-mail.conf
Line 339: Line 356:
 
ADD to the file /etc/dovecot/dovecot-sql.conf.ext
 
ADD to the file /etc/dovecot/dovecot-sql.conf.ext
 
  <nowiki>driver = mysql
 
  <nowiki>driver = mysql
connect = host=127.0.0.1 dbname=email_accounts user=email password=password
+
connect = host=127.0.0.1 dbname=email_accounts user=email password=password
default_pass_scheme = MD5
+
default_pass_scheme = MD5
 
+
password_query = SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) as `user`, mailboxes.password AS `password`,'/var/spool/mail/%d/%n' AS `userdb_home`, [YOUR UID] AS `userdb_uid`, [YOUR GID] AS `userdb_gid` FROM `mailboxes`, `domains` WHERE mailboxes.local_part = '%n' AND mailboxes.active = 1 AND mailboxes.domain_id = domains.id AND domains.fqdn = '%d' AND domains.active = 1
+
password_query = SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) as `user`, mailboxes.password AS `password`,'/var/spool/mail/%d/%n' AS `userdb_home`, [YOUR UID] AS `userdb_uid`, [YOUR GID] AS `userdb_gid` FROM `mailboxes`, `domains` WHERE mailboxes.local_part = '%n' AND mailboxes.active = 1 AND mailboxes.domain_id = domains.id AND domains.fqdn = '%d' AND domains.active = 1
 +
 +
user_query = SELECT '/var/spool/mail/%d/%n' AS `home`, [YOUR UID] AS `uid`, [YOUR GID] AS `gid`</nowiki>
  
user_query = SELECT '/var/spool/mail/%d/%n' AS `home`, [YOUR UID] AS `uid`, [YOUR GID] AS `gid`</nowiki>
+
====SSL====
 
 
==== SSL ====
 
 
- Get certificates ej: Lets Encrypt
 
- Get certificates ej: Lets Encrypt
 
Edit: /etc/dovecot/conf.d/10-ssl.conf
 
Edit: /etc/dovecot/conf.d/10-ssl.conf
 
  <nowiki>ssl = required
 
  <nowiki>ssl = required
# Preferred permissions: root:root 0444
+
# Preferred permissions: root:root 0444
ssl_cert = </etc/ssl/certs/dovecot.pem
+
ssl_cert = </etc/ssl/certs/dovecot.pem
# Preferred permissions: root:root 0400
+
# Preferred permissions: root:root 0400
ssl_key = </etc/ssl/private/dovecot.pem</nowiki>
+
ssl_key = </etc/ssl/private/dovecot.pem</nowiki>
  
==== Ports ====
+
====Ports====
 
Open ports: IMAP 143 & SSL IMAP 993
 
Open ports: IMAP 143 & SSL IMAP 993
  
=== Roundcube ===
+
===Roundcube===
 
EDIT the file /etc/roundcube/main.inc.php
 
EDIT the file /etc/roundcube/main.inc.php
 
  $rcmail_config['default_host'] = '[YOUR MX RECORD]';
 
  $rcmail_config['default_host'] = '[YOUR MX RECORD]';
Line 365: Line 382:
  
 
In that file, there are instructions on how to make it automatically calculate the address using %n, %d, etc. If your MX records for your different domains follow the same pattern (e.g. they are all “mail.my-domain.com”), and your webmail login addresses all follow the same pattern (e.g. “wemail.my-domain.com”), you can put one string here and it will automatically log people into the right server in every case, based on the URL they visited.
 
In that file, there are instructions on how to make it automatically calculate the address using %n, %d, etc. If your MX records for your different domains follow the same pattern (e.g. they are all “mail.my-domain.com”), and your webmail login addresses all follow the same pattern (e.g. “wemail.my-domain.com”), you can put one string here and it will automatically log people into the right server in every case, based on the URL they visited.
==== TLS ====
+
====TLS====
 
@/etc/roundcube/config.inc.php
 
@/etc/roundcube/config.inc.php
 
  $config['default_host'] = "tls://webmail.herrerosolis.com";
 
  $config['default_host'] = "tls://webmail.herrerosolis.com";
==== Allow dovecot self-signed certificate ====
+
====Allow dovecot self-signed certificate====
 
TODO: Lets Encrypt Certificate CA
 
TODO: Lets Encrypt Certificate CA
 
Add to /etc/roundcube/config.inc.php
 
Add to /etc/roundcube/config.inc.php
 
  <nowiki>$config['imap_conn_options'] = array(
 
  <nowiki>$config['imap_conn_options'] = array(
  'ssl'        => array(
+
  'ssl'        => array(
    'verify_peer'  => false,
+
      'verify_peer'  => false,
    'verify_peer_name'  => false,
+
      'verify_peer_name'  => false,
    'allow_self_signed' => true,
+
      'allow_self_signed' => true,
  ),
+
    ),
);
+
  );
</nowiki>
+
</nowiki>
 +
 
 +
====Enable Password Plugin====
 +
 
 +
*TODO: SQL / password plugin options
  
==== Enable Password Plugin ====
 
* TODO: SQL / password plugin options
 
 
@/etc/roundcube/config.inc.php
 
@/etc/roundcube/config.inc.php
 
  $config['plugins'] = array('xskin', 'password');
 
  $config['plugins'] = array('xskin', 'password');
==== Maximum size for attached documents =====
+
====Maximum size for attached documents =====
* TODO: Maximum size for attached documents
 
  
==== Fix zipdownload plugin ====
+
*TODO: Maximum size for attached documents
 +
 
 +
====Fix zipdownload plugin====
 
  sudo apt-get install php7.0-zip
 
  sudo apt-get install php7.0-zip
 
  sudo apt-get install php7.0-gd
 
  sudo apt-get install php7.0-gd
  
==== Spamassasin ====
+
====Spamassasin====
* TODO: Spamassasin
 
  
==== Roundcube Plugin Installer ====
+
*TODO: Spamassasin
 +
 
 +
====Roundcube Plugin Installer====
 
  cd <roundcube-project-root>
 
  cd <roundcube-project-root>
 
  curl -s https://getcomposer.org/installer | php
 
  curl -s https://getcomposer.org/installer | php
Line 400: Line 421:
 
composer.json-dist to composer.json in your Roundcube root directory
 
composer.json-dist to composer.json in your Roundcube root directory
  
===== Installing Plugins =====
+
=====Installing Plugins=====
 
https://plugins.roundcube.net/explore/<br />
 
https://plugins.roundcube.net/explore/<br />
 
Then edit your local composer.json file and add the "vendor/plugin" names to the "require" section of the JSON structure. Don't forget to specify the version constraint:
 
Then edit your local composer.json file and add the "vendor/plugin" names to the "require" section of the JSON structure. Don't forget to specify the version constraint:
 
  <nowiki>"require" : {
 
  <nowiki>"require" : {
    ...,
+
    ...,
    "roundcube/rcsample": ">=0.2.0"
+
    "roundcube/rcsample": ">=0.2.0"
}</nowiki>
+
}</nowiki>
  
 
After every change to composer.json run
 
After every change to composer.json run
 
  php composer.phar install
 
  php composer.phar install
  
== Restart Everithing ==  
+
==Restart Everithing==  
 
  <nowiki>/etc/init.d/apache2 restart
 
  <nowiki>/etc/init.d/apache2 restart
/etc/init.d/exim4 restart
+
/etc/init.d/exim4 restart
/etc/init.d/dovecot restart</nowiki>
+
/etc/init.d/dovecot restart</nowiki>
  
 
Exim may output a “paniclog”. If so, read it, fix it – and then manually delete the paniclog file, or else you’ll keep getting fake warnings every time you restart exim.
 
Exim may output a “paniclog”. If so, read it, fix it – and then manually delete the paniclog file, or else you’ll keep getting fake warnings every time you restart exim.
Line 423: Line 444:
  
  
=== STARTTLS ===
+
===STARTTLS===
 
https://wiki.debian.org/Exim
 
https://wiki.debian.org/Exim
  
= Troubleshooting =
+
=Troubleshooting=
 
https://mediatemple.net/community/products/dv/204404634/troubleshooting-common-issues-with-email
 
https://mediatemple.net/community/products/dv/204404634/troubleshooting-common-issues-with-email
=== Exim ===
+
===Exim===
 
  exim4 -bP | grep tls_
 
  exim4 -bP | grep tls_
 
test with:
 
test with:
Line 434: Line 455:
 
  swaks -a -tls -q HELO -s gollum.redactate.com -au test -ap '<>'
 
  swaks -a -tls -q HELO -s gollum.redactate.com -au test -ap '<>'
  
==== Receiving emails ====  
+
====Receiving emails====  
 
Pick an email address that you added to the “email_accounts” database, and try sending email to it while logged-in to server command-line:
 
Pick an email address that you added to the “email_accounts” database, and try sending email to it while logged-in to server command-line:
 
  exim -d -bt testname@yourdomain.com
 
  exim -d -bt testname@yourdomain.com
 
…this will give a COMPLETE list of what exim is doing, and it will tell you every decision it made along the way. It should eventually decide the address is “routeable” and OK it.
 
…this will give a COMPLETE list of what exim is doing, and it will tell you every decision it made along the way. It should eventually decide the address is “routeable” and OK it.
  
* TODO: SOLVED --> bind SMTP to eth0 but not to elastic_ip https://forums.aws.amazon.com/thread.jspa?messageID=776527&#776527
+
*TODO: SOLVED --> bind SMTP to eth0 but not to elastic_ip https://forums.aws.amazon.com/thread.jspa?messageID=776527&#776527
 +
 
 
If that looks OK, try sending an email from your normal email account (e.g. your Hotmail / Gmail / Yahoo.com address). Wait a minute, then check the server to see if it crashed trying to receive the email, by checking the logfiles.
 
If that looks OK, try sending an email from your normal email account (e.g. your Hotmail / Gmail / Yahoo.com address). Wait a minute, then check the server to see if it crashed trying to receive the email, by checking the logfiles.
  
Line 454: Line 476:
 
https://www.wormly.com
 
https://www.wormly.com
  
==== Sending emails ====
+
====Sending emails====
 
sending emails
 
sending emails
  
Line 468: Line 490:
 
Here is a list of commands to help: http://bradthemad.org/tech/notes/exim_cheatsheet.php
 
Here is a list of commands to help: http://bradthemad.org/tech/notes/exim_cheatsheet.php
  
=== Test Dovecot ===
+
===Test Dovecot===
 
https://wiki2.dovecot.org/TestInstallation
 
https://wiki2.dovecot.org/TestInstallation
  
=== Roundcube ===
+
===Roundcube===
 
http://www.iredmail.org/docs/debug.roundcubemail.html
 
http://www.iredmail.org/docs/debug.roundcubemail.html
  
=== DNS ===
+
===DNS===
 
https://mxtoolbox.com/diagnostic.aspx
 
https://mxtoolbox.com/diagnostic.aspx
  
Line 481: Line 503:
 
[https://www.dropbox.com/s/8w55kys0yirfmv9/Exim4.69%20configuration%20%2B%20exploitation%20review-j1osx__Q0PE.mp4?dl=0|exim4 configuration (mp4)]
 
[https://www.dropbox.com/s/8w55kys0yirfmv9/Exim4.69%20configuration%20%2B%20exploitation%20review-j1osx__Q0PE.mp4?dl=0|exim4 configuration (mp4)]
  
= Resources =
+
=Resources=
 
http://t-machine.org/index.php/2014/06/27/webmail-on-your-debian-server-exim4-dovecot-roundcube/<br />
 
http://t-machine.org/index.php/2014/06/27/webmail-on-your-debian-server-exim4-dovecot-roundcube/<br />
 
https://intodns.com/herrerosolis.com<br />
 
https://intodns.com/herrerosolis.com<br />
Line 489: Line 511:
 
1. In the file /etc/dovecot/conf.d/auth-sql-conf.ext uncomment driver and set it to mysql
 
1. In the file /etc/dovecot/conf.d/auth-sql-conf.ext uncomment driver and set it to mysql
 
2. /etc/dovecot/conf.d/10-mail.conf uncomment first_valid_uid and set it to [your_uid] (ie. 8). If you need to do the same for first_valid_gid
 
2. /etc/dovecot/conf.d/10-mail.conf uncomment first_valid_uid and set it to [your_uid] (ie. 8). If you need to do the same for first_valid_gid
= Adding new Domains =
+
=Adding new Domains=
# Add the new domain to to MySQL email_accounts.domains
+
 
# Start creating accounts with the new domain id
+
#Add the new domain to to MySQL email_accounts.domains
 +
#Start creating accounts with the new domain id

Revision as of 10:12, 20 August 2019

Whispers Mail Server

Stack

  • Web server (Apache)
  • Database server (MySQL)
  • Email server (MTA) (Exim4)
  • IMAP server (Dovecot)
  • Webmail server (Roundcube)

Install

  • apt-get install apache2-mpm-prefork
    • (Some of these email servers require PHP; PHP is crappy and requires mpm-prefork (the ‘slow’ version of Apache))
  • apt-get install mysql-client
    • (should auto-install something like: mysql-common + mysql-client-5.5)
  • apt-get install mysql-server
    • (should auto-install something like: mysql-server-5.5 + mysql-server-core-5.5)
  • apt-get install exim4
  • apt-get install exim4-base
  • apt-get install exim4-config
  • apt-get install exim4-daemon-heavy
    • (there’s an “exim4-mysql” that might be sufficient to replace this, but I gave up: there are way too many exim4 packages, and no help for installing the “correct” set, so … just pick this and get the lot!)
  • apt-get install dovecot-core
  • apt-get install dovecot-imapd
  • apt-get install dovecot-mysql
  • apt-get install roundcube
  • apt-get install roundcube-core
  • apt-get install roundcube-mysql
  • apt-get install roundcube-plugins

Setup

DNS

You should know about this already: you need an “MX” record on your DNS server, and it needs to point to your main server where you’ll run your email, web, etc.

@Goddady: Removed:

A
Host: @; Apunta a: $ELASTIC_IP; TTL:1h

CNAME
Host: webmail; Apunta a: @; TTL:1h

MX
host: @; Apunta a: webmail.herrerosolis.com; Prioridad: 10; TTL: 1h

TODO: Remove MX registries from godaddy email forwarder:
MX:

Host: @; Apunta a:smtp.secureserver.net; Prioridad:30; TTL:1h
Host: @; Apunta a:mailstore1.secureserver.net; Prioridad:50; TTL:1h


SPF

TXT

Host: @; Valor TXT: v=spf1 mx ip4:54.154.227.190 ~all

DMARC

TXT

Host: _dmarc

Valor TXT: v=DMARC1; p=none  Verification details:      mail-tester.com; dmarc=none header.from=herrerosolis.com     From Domain: herrerosolis.com     DKIM Domain:MIIBIjANBg[...]qCwPwIDAQAB

Apache

/etc/apache2/sites-available/webmail.conf

<VirtualHost *:80>
     ServerAdmin rafael@herrerosolis.com
     Redirect permanent / https://webmail.herrerosolis.com/
 #    DocumentRoot /var/www/rafael
     ServerName webmail.herrerosolis.com
     ServerAlias webmail.herrerosolis.com
     ErrorLog /var/log/apache2/webmail/error.log
 
     # Posible values include: debug, info, notice, warn, error, crit.
     # alert, emerg.
 
     CustomLog /var/log/apache2/webmail/access.log combined
 </virtualHost>
 
 <VirtualHost *:443>
     ServerAdmin rafael@herrerosolis.com
     DocumentRoot /var/lib/roundcube
     ServerName webmail.herrerosolis.com
     ServerAlias webmail.herrerosolis.com
 
     ErrorLog /var/log/apache2/webmail/error.log
 
     # Posible values include: debug, info, notice, warn, error, crit.
     # alert, emerg.
     CustomLog /var/log/apache2/webmail/access.log combined
     SSLEngine on
     SSLCertificateFile /etc/ssl/certs/herrerosolis.crt
     SSLCertificateKeyFile /etc/ssl/private/herrerosolis.key
 </virtualHost>
 

OPTIONAL: Remove TinyMCE

TinyMCE is a WYSIWYG text-editor for HTML emails. I hate it. It had a long history of being insecure, buggy, slow, and hard to use. So I disable it:

Edit /etc/roundcube/apache.conf:

Comment out these lines:
 	#<Directory "/usr/share/tinymce/www/">
 	#      Options Indexes MultiViews FollowSymLinks
 	#      AllowOverride None
 	#      Order allow,deny
 	#      allow from all
 	#</Directory>
 

Create Databases

mysql -u root -p
CREATE DATABASE email_accounts;
USE email_accounts;
CREATE TABLE mailboxes (
     id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
     domain_id INT(10) NOT NULL,
     local_part VARCHAR(250) NOT NULL,
     password VARCHAR(100) NULL,
     description VARCHAR(250) NULL,
     active TINYINT(1) NOT NULL DEFAULT 0,
     created TIMESTAMP NOT NULL DEFAULT NOW(),
     modified TIMESTAMP NULL
 );
 CREATE TABLE aliases (
     id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
     domain_id INT(10) NOT NULL,
     local_part VARCHAR(250) NOT NULL,
     goto VARCHAR(250) NOT NULL,
     description VARCHAR(250) NULL,
     active TINYINT(1) NOT NULL DEFAULT 0,
     created TIMESTAMP NOT NULL DEFAULT NOW(),
     modified TIMESTAMP NULL
 );
 CREATE TABLE vacations (
     id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
     mailbox_id INT(10) NOT NULL,
     subject VARCHAR(250) NOT NULL,
     body TEXT NOT NULL,
     description VARCHAR(250) NULL,
     active TINYINT(1) NOT NULL DEFAULT 0,
     created TIMESTAMP NOT NULL DEFAULT NOW(),
     modified TIMESTAMP NULL
 );
 
 CREATE TABLE domains (
     id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
     fqdn VARCHAR(250) NOT NULL,
     type ENUM('local','relay') NOT NULL DEFAULT 'local',
     description VARCHAR(250) NULL,
     active TINYINT(1) NOT NULL DEFAULT 0,
     created TIMESTAMP NOT NULL DEFAULT NOW(),
     modified TIMESTAMP NULL
 );
 

Create your first email account and domain

Domain

INSERT INTO domains VALUES(NULL,'herrerosolis.com','local','My personal domain',1,NOW(),NOW());

User

INSERT INTO mailboxes VALUES(NULL,1,'joe',MD5('password - choose a good one'),'My account for joe@herrerosolis.com',1,NOW(),NOW());

Alias

insert into aliases values (null, 1, 'rafa', 'rafael@herrerosolis.com', 'Redirect to me', 1, NOW(), NOW() );

Create a database-account to access the database

grant ALL on email_accounts.* to 'email'@'localhost' identified by 'password';
 flush privileges;
 

http://bradthemad.org/tech/notes/exim_cheatsheet.php

Exim Configuration

  • TODO: review daemon ports @/etc/exim4/conf.d/main/9_exim4-config_daemon


dpkg-reconfigure exim4-config

Creates the file: /etc/exim4/update-exim4.conf.conf
Should look like:

# /etc/exim4/update-exim4.conf.conf
 #
 # Edit this file and /etc/mailname by hand and execute update-exim4.conf
 # yourself or use 'dpkg-reconfigure exim4-config'
 #
 # Please note that this is _not_ a dpkg-conffile and that automatic changes
 # to this file might happen. The code handling this will honor your local
 # changes, so this is usually fine, but will break local schemes that mess
 # around with multiple versions of the file.
 #
 # update-exim4.conf uses this file to determine variable values to generate
 # exim configuration macros for the configuration file.
 #
 # Most settings found in here do have corresponding questions in the
 # Debconf configuration, but not all of them.
 #
 # This is a Debian specific file
 
 dc_eximconfig_configtype='internet'
 dc_other_hostnames='[YOUR DOMAIN 1];[YOUR DOMAIN 2]'
 dc_local_interfaces='127.0.0.1;[PUT YOUR SERVER's IP ADDRESS HERE]'
 dc_readhost=''
 dc_relay_domains=''
 dc_minimaldns='false'
 dc_relay_nets=''
 dc_smarthost=''
 CFILEMODE='644'
 dc_use_split_config='true'
 dc_hide_mailname=''
 dc_mailname_in_oh='true'
 dc_localdelivery='maildir_home'

Macros

ADD the following to /etc/exim4/conf.d/main/000_localmacros

MAIN_LOCAL_DOMAINS = @:localhost:dsearch;/etc/exim4/virtual:${lookup mysql{SELECT fqdn AS domain FROM domains WHERE fqdn='${quote_mysql:$domain}' AND type='local' AND active=1}}

ADD the following to /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs

# List of domains considered local for exim. Domains not listed here
 # need to be deliverable remotely.
 domainlist local_domains = MAIN_LOCAL_DOMAINS
 
 # MySQL because exim4 on Debian doesn't always add this:
 
 MYSQL_SERVER=127.0.0.1
 MYSQL_DB=email_accounts
 MYSQL_USER=email
 MYSQL_PASSWORD=password
 hide mysql_servers = MYSQL_SERVER/MYSQL_DB/MYSQL_USER/MYSQL_PASSWORD

Routers

CREATE the file /etc/exim4/conf.d/router/360_exim4-config_mysqlusers

dovecot_user:
       driver = accept
         condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) AS goto FROM domains,mailboxes WHERE \
                    mailboxes.local_part='${quote_mysql:$local_part}' AND \
                    mailboxes.active=1 AND \
                    mailboxes.domain_id=domains.id AND \
                    domains.fqdn='${quote_mysql:$domain}' AND \
                    domains.active=1}{yes}{no}}
      transport = dovecot_delivery

Either DELETE this file, or comment-out all lines /etc/exim4/conf.d/router/400_exim4-config_system_aliases

CREATE this file /etc/exim4/conf.d/router/401_exim4-config_mysql_aliases

### router/401_exim4-config_mysql_aliases
 #################################
 
 # ADAM: This router handles aliasing using the proprietary mysql setup
 #
 # c.f. http://alex.mamchenkov.net/2010/06/24/exim-dovecot-and-mysql/
 #
 
 system_aliases:
      driver = redirect
      allow_fail 
      allow_defer
      data = ${lookup mysql{SELECT aliases.goto AS goto FROM domains,aliases WHERE \
                    (aliases.local_part='${quote_mysql:$local_part}' OR aliases.local_part='@') AND \
                    aliases.active=1 AND \
                    aliases.domain_id=domains.id AND \
                    domains.fqdn='${quote_mysql:$domain}' AND \
                    domains.active=1}}
 

Transports

CREATE / OVERWRITE the file /etc/exim4/conf.d/transport/30_exim4-config_dovecot

### transport/30_exim4-config_dovecot
 #################################
 
 #
 
 dovecot_delivery:
      driver = appendfile
      maildir_format = true
      directory = /var/spool/mail/$domain/$local_part
      create_directory = true
      directory_mode = 0770
      mode_fail_narrower = false
      message_prefix =
      message_suffix =
      delivery_date_add
      envelope_to_add
      return_path_add
      user = mail
      group = mail
      mode = 0660
 

Auth

CREATE the file /etc/exim4/conf.d/auth/20_exim4-config_mysql-authenticator

### AUTHENTICATIOR SECTION
 
 auth_plain:
      driver = plaintext
      public_name = PLAIN
      server_condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) FROM mailboxes,domains WHERE \
                        mailboxes.local_part=SUBSTRING_INDEX('${quote_mysql:$auth2}','@',1) AND \
                        mailboxes.password=MD5('${quote_mysql:$auth3}') AND \
                        mailboxes.active=1 AND \
                        mailboxes.domain_id=domains.id AND \
                        domains.fqdn=SUBSTRING_INDEX('${quote_mysql:$auth2}','@',-1) AND \
                        domains.active=1}{yes}{no}}
      server_prompts = :
      server_set_id = $auth2
 
 auth_login:
      driver = plaintext
      public_name = LOGIN
      server_condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) FROM mailboxes,domains WHERE \
                        mailboxes.local_part=SUBSTRING_INDEX('${quote_mysql:$auth1}','@',1) AND \
                        mailboxes.password=MD5('${quote_mysql:$auth2}') AND \
                        mailboxes.active=1 AND \
                        mailboxes.domain_id=domains.id AND \
                        domains.fqdn=SUBSTRING_INDEX('${quote_mysql:$auth1}','@',-1) AND \
                        domains.active=1}{yes}{no}}
      server_prompts = Username:: : Password::
      server_set_id = $auth1


Ports

CREATE the file /etc/exim4/conf.d/main/9_exim4-config_daemon

daemon_smtp_ports = 25 : 465 : 587

http://www.exim.org/exim-html-current/doc/html/spec_html/ch-main_configuration.html
On amazon AWS port 25 might be blocked: https://aws.amazon.com/forms/ec2-email-limit-rdns-request?catalog=true&isauthcode=true

Dovecot

Make sure you choose split files, can be fixed with:

dpkg-reconfigure dovecot-core

Find mail user uid & gid:

cat /etc/passwd | grep mail

ADD to the file /etc/dovecot/dovecot.conf

protocols = imap
 listen = *, ::

Add to the file /etc/dovecot/conf.d/10-mail.conf

mail_location = maildir:~

ADD to the file /etc/dovecot/conf.d/10-auth.conf

!include auth-sql.conf.ext

ADD to the file /etc/dovecot/dovecot-sql.conf.ext

driver = mysql
 connect = host=127.0.0.1 dbname=email_accounts user=email password=password
 default_pass_scheme = MD5
 
 password_query = SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) as `user`, mailboxes.password AS `password`,'/var/spool/mail/%d/%n' AS `userdb_home`, [YOUR UID] AS `userdb_uid`, [YOUR GID] AS `userdb_gid` FROM `mailboxes`, `domains` WHERE mailboxes.local_part = '%n' AND mailboxes.active = 1 AND mailboxes.domain_id = domains.id AND domains.fqdn = '%d' AND domains.active = 1
 
 user_query = SELECT '/var/spool/mail/%d/%n' AS `home`, [YOUR UID] AS `uid`, [YOUR GID] AS `gid`

SSL

- Get certificates ej: Lets Encrypt Edit: /etc/dovecot/conf.d/10-ssl.conf

ssl = required
 # Preferred permissions: root:root 0444
 ssl_cert = </etc/ssl/certs/dovecot.pem
 # Preferred permissions: root:root 0400
 ssl_key = </etc/ssl/private/dovecot.pem

Ports

Open ports: IMAP 143 & SSL IMAP 993

Roundcube

EDIT the file /etc/roundcube/main.inc.php

$rcmail_config['default_host'] = '[YOUR MX RECORD]';

Note: replace “[YOUR MX RECORD]” with the MX address you put on your DNS server at the very start. e.g. “mail.my-domain.com”.

In that file, there are instructions on how to make it automatically calculate the address using %n, %d, etc. If your MX records for your different domains follow the same pattern (e.g. they are all “mail.my-domain.com”), and your webmail login addresses all follow the same pattern (e.g. “wemail.my-domain.com”), you can put one string here and it will automatically log people into the right server in every case, based on the URL they visited.

TLS

@/etc/roundcube/config.inc.php

$config['default_host'] = "tls://webmail.herrerosolis.com";

Allow dovecot self-signed certificate

TODO: Lets Encrypt Certificate CA Add to /etc/roundcube/config.inc.php

$config['imap_conn_options'] = array(
   'ssl'         => array(
      'verify_peer'  => false,
      'verify_peer_name'  => false,
      'allow_self_signed' => true,
    ),
  );
 

Enable Password Plugin

  • TODO: SQL / password plugin options

@/etc/roundcube/config.inc.php

$config['plugins'] = array('xskin', 'password');

Maximum size for attached documents =

  • TODO: Maximum size for attached documents

Fix zipdownload plugin

sudo apt-get install php7.0-zip
sudo apt-get install php7.0-gd

Spamassasin

  • TODO: Spamassasin

Roundcube Plugin Installer

cd <roundcube-project-root>
curl -s https://getcomposer.org/installer | php

composer.json-dist to composer.json in your Roundcube root directory

Installing Plugins

https://plugins.roundcube.net/explore/
Then edit your local composer.json file and add the "vendor/plugin" names to the "require" section of the JSON structure. Don't forget to specify the version constraint:

"require" : {
     ...,
     "roundcube/rcsample": ">=0.2.0"
 }

After every change to composer.json run

php composer.phar install

Restart Everithing

/etc/init.d/apache2 restart
 /etc/init.d/exim4 restart
 /etc/init.d/dovecot restart

Exim may output a “paniclog”. If so, read it, fix it – and then manually delete the paniclog file, or else you’ll keep getting fake warnings every time you restart exim.




STARTTLS

https://wiki.debian.org/Exim

Troubleshooting

https://mediatemple.net/community/products/dv/204404634/troubleshooting-common-issues-with-email

Exim

exim4 -bP | grep tls_

test with:

sudo apt-get install swaks
swaks -a -tls -q HELO -s gollum.redactate.com -au test -ap '<>'

Receiving emails

Pick an email address that you added to the “email_accounts” database, and try sending email to it while logged-in to server command-line:

exim -d -bt testname@yourdomain.com

…this will give a COMPLETE list of what exim is doing, and it will tell you every decision it made along the way. It should eventually decide the address is “routeable” and OK it.

If that looks OK, try sending an email from your normal email account (e.g. your Hotmail / Gmail / Yahoo.com address). Wait a minute, then check the server to see if it crashed trying to receive the email, by checking the logfiles.

Check exim’s logfiles

Exim will put its logfiles in /var/log/exim4. Check for errors using: tail /var/log/exim4/mainlog

(if there’s a lot of errors, you’ll have to cat the whole thing)

If it rejected the email, it will send a bounce-back to your email provider (yahoo/gmail/etc), and it will ALSO put some info into: tail /var/log/exim4/rejectlog test:
https://www.wormly.com

Sending emails

sending emails

…I waited until I had webmail (Roundcube) working before trying this… Any other Exim problems?

If exim is working, but its blocking/rejecting/losing emails, it will “freeze” them after the first failure. You need to “unfreeze” (i.e. retry) each email to see if you’ve fixed the problem. To process all **frozen** messages in the Exim queue use this command:

mailq | grep frozen | awk '{print $3}' | xargs exim -v -M


Here is a list of commands to help: http://bradthemad.org/tech/notes/exim_cheatsheet.php

Test Dovecot

https://wiki2.dovecot.org/TestInstallation

Roundcube

http://www.iredmail.org/docs/debug.roundcubemail.html

DNS

https://mxtoolbox.com/diagnostic.aspx


configuration (mp4)

Resources

http://t-machine.org/index.php/2014/06/27/webmail-on-your-debian-server-exim4-dovecot-roundcube/
https://intodns.com/herrerosolis.com
Another option would be: https://avix.co/blog/creating-your-own-mail-server-amazon-ec2-postfix-dovecot-postgresql-amavis-spamassassin-apache-and-squirrelmail-part-1/

Only two things I might add: 1. In the file /etc/dovecot/conf.d/auth-sql-conf.ext uncomment driver and set it to mysql 2. /etc/dovecot/conf.d/10-mail.conf uncomment first_valid_uid and set it to [your_uid] (ie. 8). If you need to do the same for first_valid_gid

Adding new Domains

  1. Add the new domain to to MySQL email_accounts.domains
  2. Start creating accounts with the new domain id