Changes

Jump to navigation Jump to search
m
Line 31: Line 31:  
==Setup==
 
==Setup==
 
====DNS====
 
====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.
+
{| class="wikitable"
 +
|+DNS Registries required by Mail Server
 +
!Type
 +
!Host
 +
!Points to
 +
!TTL
 +
|-
 +
|A
 +
|@
 +
|54.154.227.190
 +
|1h
 +
|-
 +
|CNAME
 +
|webmail
 +
|@
 +
|1h
 +
|-
 +
|MX
 +
|@
 +
|webmail.herrerosolis.com
 +
|1h
 +
|}
 +
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 <br />
+
'''Remove''' MX registries from godaddy email forwarder:<br />MX: <br />Host: @; Apunta a:smtp.secureserver.net; Prioridad:30; TTL:1h<br />Host: @; Apunta a:mailstore1.secureserver.net; Prioridad:50; TTL:1h
Host: @; Apunta a: $ELASTIC_IP; TTL:1h
     −
CNAME<br />
+
=====SPF=====
Host: webmail; Apunta a: @; TTL:1h
+
{| class="wikitable"
 +
|+DNS SPF Registry
 +
!Type
 +
!Host
 +
!TXT Value
 +
|-
 +
|TXT
 +
|@
 +
|v=spf1 mx ip4:54.154.227.190 ~all
 +
|}
   −
MX<br />
+
=====DMARC=====
host: @; Apunta a: webmail.herrerosolis.com; Prioridad: 10; TTL: 1h<br />
+
{| class="wikitable"
 +
|+DNS DMARC Registry
 +
!Type
 +
!Host
 +
!TXT Value
 +
|-
 +
|TXT
 +
|_dmarc
 +
|v=DMARC1; p=none  Verification details:      mail-tester.com; dmarc=none header.from=herrerosolis.com     From Domain: herrerosolis.com     DKIM Domain:MIIBIjANBg[...]qCwPwIDAQAB
 +
|}
 +
<br />
   −
TODO: Remove MX registries from godaddy email forwarder:<br />
+
=====DKIM=====
MX: <br />
+
{| class="wikitable"
 +
|+DNS DKIM Registry
 +
!Type
 +
!Host
 +
!TXT Value
 +
|-
 +
|TXT
 +
|webmail._domainkey
 +
|v=DKIM1; k=rsa; p=MIIBIjAN[...]IDAQAB
 +
|}
   −
Host: @; Apunta a:smtp.secureserver.net; Prioridad:30; TTL:1h<br />
+
*Note: DKIM Host must be {selector}._domainkey where {selector} = DKIM_SELECTOR variable from /etc/exim4/conf.d/main/000_localmacros
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
  −
 
  −
====DKIM====
  −
TXT
  −
 
  −
Host: webmail._domainkey
  −
 
  −
Valor TXT: v=DKIM1; k=rsa; p=MIIBIjAN[...]IDAQAB
      
===Apache===
 
===Apache===
 
/etc/apache2/sites-available/webmail.conf
 
/etc/apache2/sites-available/webmail.conf
 
  <nowiki><VirtualHost *:80>
 
  <nowiki><VirtualHost *:80>
        ServerAdmin rafael@herrerosolis.com
+
                                  ServerAdmin rafael@herrerosolis.com
        Redirect permanent / https://webmail.herrerosolis.com/
+
                                  Redirect permanent / https://webmail.herrerosolis.com/
    #    DocumentRoot /var/www/rafael
+
                              #    DocumentRoot /var/www/rafael
        ServerName webmail.herrerosolis.com
+
                                  ServerName webmail.herrerosolis.com
        ServerAlias webmail.herrerosolis.com
+
                                  ServerAlias webmail.herrerosolis.com
        ErrorLog /var/log/apache2/webmail/error.log
+
                                  ErrorLog /var/log/apache2/webmail/error.log
   
+
                             
        # Posible values include: debug, info, notice, warn, error, crit.
+
                                  # Posible values include: debug, info, notice, warn, error, crit.
        # alert, emerg.
+
                                  # alert, emerg.
   
+
                             
        CustomLog /var/log/apache2/webmail/access.log combined
+
                                  CustomLog /var/log/apache2/webmail/access.log combined
    </virtualHost>
+
                              </virtualHost>
   
+
                             
    <VirtualHost *:443>
+
                              <VirtualHost *:443>
        ServerAdmin rafael@herrerosolis.com
+
                                  ServerAdmin rafael@herrerosolis.com
        DocumentRoot /var/lib/roundcube
+
                                  DocumentRoot /var/lib/roundcube
        ServerName webmail.herrerosolis.com
+
                                  ServerName webmail.herrerosolis.com
        ServerAlias webmail.herrerosolis.com
+
                                  ServerAlias webmail.herrerosolis.com
   
+
                             
        ErrorLog /var/log/apache2/webmail/error.log
+
                                  ErrorLog /var/log/apache2/webmail/error.log
   
+
                             
        # Posible values include: debug, info, notice, warn, error, crit.
+
                                  # Posible values include: debug, info, notice, warn, error, crit.
        # alert, emerg.
+
                                  # alert, emerg.
        CustomLog /var/log/apache2/webmail/access.log combined
+
                                  CustomLog /var/log/apache2/webmail/access.log combined
        SSLEngine on
+
                                  SSLEngine on
        SSLCertificateFile /etc/ssl/certs/herrerosolis.crt
+
                                  SSLCertificateFile /etc/ssl/certs/herrerosolis.crt
        SSLCertificateKeyFile /etc/ssl/private/herrerosolis.key
+
                                  SSLCertificateKeyFile /etc/ssl/private/herrerosolis.key
    </virtualHost>
+
                              </virtualHost>
    </nowiki>
+
                              </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 109: Line 136:     
  <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
+
<syntaxhighlight lang="bash">
 +
mysql -u root -p
 +
</syntaxhighlight>
 +
 +
<syntaxhighlight lang="mysql">
 +
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 DATABASE email_accounts;
+
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
 +
);
   −
USE email_accounts;
+
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
 +
);
   −
<nowiki>CREATE TABLE mailboxes (
+
CREATE TABLE domains (
        id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+
  id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
        domain_id INT(10) NOT NULL,
+
  fqdn VARCHAR(250) NOT NULL,
        local_part VARCHAR(250) NOT NULL,
+
  type ENUM('local','relay') NOT NULL DEFAULT 'local',
        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
+
);
    );
+
</syntaxhighlight>
    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
  −
    );
  −
    </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>
+
<syntaxhighlight lang="mysql">
 +
INSERT INTO domains VALUES(NULL,'herrerosolis.com','local','My personal domain',1,NOW(),NOW());
 +
</syntaxhighlight>
 +
    
====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>
+
<syntaxhighlight lang="mysql">
 +
INSERT INTO mailboxes VALUES(NULL,1,'joe',MD5('password - choose a good one'),'My account for joe@herrerosolis.com',1,NOW(),NOW());
 +
</syntaxhighlight>
 +
    
====Alias====
 
====Alias====
<nowiki>insert into aliases values (null, 1, 'rafa', 'rafael@herrerosolis.com', 'Redirect to me', 1, NOW(), NOW() );</nowiki>
+
<syntaxhighlight lang="mysql">
 +
insert into aliases values (null, 1, 'rafa', 'rafael@herrerosolis.com', 'Redirect to me', 1, NOW(), NOW() );
 +
</syntaxhighlight>
 +
    
===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';
+
<syntaxhighlight lang="mysql">
    flush privileges;
+
grant ALL on email_accounts.* to 'cartero'@'localhost' identified by 'password';
    </nowiki>
+
flush privileges;
 +
</syntaxhighlight>
 +
 +
                     
 
http://bradthemad.org/tech/notes/exim_cheatsheet.php
 
http://bradthemad.org/tech/notes/exim_cheatsheet.php
   Line 190: Line 233:     
Creates the file: /etc/exim4/update-exim4.conf.conf<br />
 
Creates the file: /etc/exim4/update-exim4.conf.conf<br />
Should look like:
+
Should look like:<syntaxhighlight lang="text">
 +
# /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
   −
<nowiki># /etc/exim4/update-exim4.conf.conf
+
dc_eximconfig_configtype='internet'
    #
+
dc_other_hostnames='[YOUR DOMAIN 1];[YOUR DOMAIN 2]'
    # Edit this file and /etc/mailname by hand and execute update-exim4.conf
+
dc_local_interfaces='127.0.0.1;[PUT YOUR SERVER's IP ADDRESS HERE]'
    # yourself or use 'dpkg-reconfigure exim4-config'
+
dc_readhost=''
    #
+
dc_relay_domains=''
    # Please note that this is _not_ a dpkg-conffile and that automatic changes
+
dc_minimaldns='false'
    # to this file might happen. The code handling this will honor your local
+
dc_relay_nets=''
    # changes, so this is usually fine, but will break local schemes that mess
+
dc_smarthost=''
    # around with multiple versions of the file.
+
CFILEMODE='644'
    #
+
dc_use_split_config='true'
    # update-exim4.conf uses this file to determine variable values to generate
+
dc_hide_mailname=''
    # exim configuration macros for the configuration file.
+
dc_mailname_in_oh='true'
    #
+
dc_localdelivery='maildir_home'
    # Most settings found in here do have corresponding questions in the
+
</syntaxhighlight>
    # 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'</nowiki>
      
====Macros====
 
====Macros====
Line 228: Line 270:  
  <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>
   −
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<syntaxhighlight lang="text">
<nowiki># List of domains considered local for exim. Domains not listed here
+
# 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_SERVER=127.0.0.1
    MYSQL_USER=email
+
MYSQL_DB=email_accounts
    MYSQL_PASSWORD=password
+
MYSQL_USER=email
    hide mysql_servers = MYSQL_SERVER/MYSQL_DB/MYSQL_USER/MYSQL_PASSWORD</nowiki>
+
MYSQL_PASSWORD=password
 +
hide mysql_servers = MYSQL_SERVER/MYSQL_DB/MYSQL_USER/MYSQL_PASSWORD
 +
</syntaxhighlight>
 +
    
====Routers====
 
====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<syntaxhighlight lang="text">
 +
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
   −
<nowiki>dovecot_user:
+
</syntaxhighlight>
          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</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 />
   −
CREATE this file /etc/exim4/conf.d/router/401_exim4-config_mysql_aliases
+
CREATE this file /etc/exim4/conf.d/router/401_exim4-config_mysql_aliases<syntaxhighlight lang="text">
 +
### 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/
 +
#
   −
<nowiki>### router/401_exim4-config_mysql_aliases
+
system_aliases:
    #################################
+
    driver = redirect
   
+
    allow_fail
    # ADAM: This router handles aliasing using the proprietary mysql setup
+
    allow_defer
    #
+
    data = ${lookup mysql{SELECT aliases.goto AS goto FROM domains,aliases WHERE \
    # c.f. http://alex.mamchenkov.net/2010/06/24/exim-dovecot-and-mysql/
+
                  (aliases.local_part='${quote_mysql:$local_part}' OR aliases.local_part='@') AND \
    #
+
                  aliases.active=1 AND \
   
+
                  aliases.domain_id=domains.id AND \
    system_aliases:
+
                  domains.fqdn='${quote_mysql:$domain}' AND \
        driver = redirect
+
                  domains.active=1}}
        allow_fail  
+
 
        allow_defer
+
</syntaxhighlight>  
        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====
 
====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<syntaxhighlight lang="text">
 +
### transport/30_exim4-config_dovecot
 +
#################################
   −
<nowiki>### transport/30_exim4-config_dovecot
+
dovecot_delivery:
    #################################
+
    driver = appendfile
   
+
    maildir_format = true
    #
+
    directory = /var/spool/mail/$domain/$local_part
   
+
    create_directory = true
    dovecot_delivery:
+
    directory_mode = 0770
        driver = appendfile
+
    mode_fail_narrower = false
        maildir_format = true
+
    message_prefix =
        directory = /var/spool/mail/$domain/$local_part
+
    message_suffix =
        create_directory = true
+
    delivery_date_add
        directory_mode = 0770
+
    envelope_to_add
        mode_fail_narrower = false
+
    return_path_add
        message_prefix =
+
    user = mail
        message_suffix =
+
    group = mail
        delivery_date_add
+
    mode = 0660
        envelope_to_add
+
</syntaxhighlight>  
        return_path_add
+
             
        user = mail
  −
        group = mail
  −
        mode = 0660
  −
    </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<syntaxhighlight lang="text">
 +
### AUTHENTICATIOR SECTION
   −
<nowiki>### AUTHENTICATIOR SECTION
+
auth_plain:
   
+
    driver = plaintext
    auth_plain:
+
    public_name = PLAIN
        driver = plaintext
+
    server_condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) FROM mailboxes,domains WHERE \
        public_name = PLAIN
+
                      mailboxes.local_part=SUBSTRING_INDEX('${quote_mysql:$auth2}','@',1) AND \
        server_condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) FROM mailboxes,domains WHERE \
+
                      mailboxes.password=MD5('${quote_mysql:$auth3}') AND \
                          mailboxes.local_part=SUBSTRING_INDEX('${quote_mysql:$auth2}','@',1) AND \
+
                      mailboxes.active=1 AND \
                          mailboxes.password=MD5('${quote_mysql:$auth3}') AND \
+
                      mailboxes.domain_id=domains.id AND \
                          mailboxes.active=1 AND \
+
                      domains.fqdn=SUBSTRING_INDEX('${quote_mysql:$auth2}','@',-1) AND \
                          mailboxes.domain_id=domains.id AND \
+
                      domains.active=1}{yes}{no}}
                          domains.fqdn=SUBSTRING_INDEX('${quote_mysql:$auth2}','@',-1) AND \
+
    server_prompts = :
                          domains.active=1}{yes}{no}}
+
    server_set_id = $auth2
        server_prompts = :
+
 
        server_set_id = $auth2
+
auth_login:
   
+
    driver = plaintext
    auth_login:
+
    public_name = LOGIN
        driver = plaintext
+
    server_condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) FROM mailboxes,domains WHERE \
        public_name = LOGIN
+
                      mailboxes.local_part=SUBSTRING_INDEX('${quote_mysql:$auth1}','@',1) AND \
        server_condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,'@',domains.fqdn) FROM mailboxes,domains WHERE \
+
                      mailboxes.password=MD5('${quote_mysql:$auth2}') AND \
                          mailboxes.local_part=SUBSTRING_INDEX('${quote_mysql:$auth1}','@',1) AND \
+
                      mailboxes.active=1 AND \
                          mailboxes.password=MD5('${quote_mysql:$auth2}') AND \
+
                      mailboxes.domain_id=domains.id AND \
                          mailboxes.active=1 AND \
+
                      domains.fqdn=SUBSTRING_INDEX('${quote_mysql:$auth1}','@',-1) AND \
                          mailboxes.domain_id=domains.id AND \
+
                      domains.active=1}{yes}{no}}
                          domains.fqdn=SUBSTRING_INDEX('${quote_mysql:$auth1}','@',-1) AND \
+
    server_prompts = Username:: : Password::
                          domains.active=1}{yes}{no}}
+
    server_set_id = $auth1
        server_prompts = Username:: : Password::
+
 
        server_set_id = $auth1</nowiki>
+
</syntaxhighlight>  
      Line 342: Line 389:  
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
   −
===DKIM===
+
====DKIM====
Edit /etc/exim4/conf.d/transport/30_exim4-config_remote_smtp and add at the beggining:<syntaxhighlight lang="text">
+
 
 +
====Generate DKIM private & public keys:====
 +
<syntaxhighlight lang="bash">
 +
sudo mkdir /etc/exim4/dkim && cd /etc/exim4/dkim
 +
sudo openssl genrsa -out webmail.herrerosolis.com.dkim.pem 2048
 +
sudo openssl rsa -in webmail.herrerosolis.com.dkim.pem -pubout |sudo tee webmail.herrerosolis.com.dkim.pub
 +
</syntaxhighlight>
 +
 
 +
====Configure your exim to sign using the DKIM key====
 +
Edit /etc/exim4/conf.d/main/000_localmacros and add at the beggining:<syntaxhighlight lang="text">
 
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
 
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
 
DKIM_KEY_FILE = /etc/exim4/dkim/webmail.herrerosolis.com.dkim.pem
 
DKIM_KEY_FILE = /etc/exim4/dkim/webmail.herrerosolis.com.dkim.pem
 
DKIM_PRIVATE_KEY = ${if exists{DKIM_KEY_FILE}{DKIM_KEY_FILE}{0}}
 
DKIM_PRIVATE_KEY = ${if exists{DKIM_KEY_FILE}{DKIM_KEY_FILE}{0}}
 
DKIM_SELECTOR = webmail
 
DKIM_SELECTOR = webmail
</syntaxhighlight><syntaxhighlight lang="bash">
+
</syntaxhighlight>
 +
 
 +
====DKIM Multiple Domains (TODO)====
 +
TODO: Handle multiple domains: https://debian-administration.org/article/718/DKIM-signing_outgoing_mail_with_exim4<syntaxhighlight lang="text">
 +
DKIM_CANON = relaxed
 +
DKIM_SELECTOR = 20150726
 +
 
 +
# Get the domain from the outgoing mail.
 +
DKIM_DOMAIN = ${sg{${lc:${domain:$h_from:}}}{^www\.}{}}
 +
 
 +
# The file is based on the outgoing domain-name in the from-header.
 +
DKIM_FILE = /etc/exim4/dkim/{DKIM_DOMAIN}.pem
 +
 
 +
# If key exists then use it, if not don't.
 +
DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
Then run:<syntaxhighlight lang="bash">
 
update-exim4.conf
 
update-exim4.conf
 
service exim4 restart
 
service exim4 restart
Line 360: Line 435:  
  cat /etc/passwd | grep mail
 
  cat /etc/passwd | grep mail
   −
ADD to the file /etc/dovecot/dovecot.conf
+
ADD to the file /etc/dovecot/dovecot.conf<syntaxhighlight lang="text">
<nowiki>protocols = imap
+
protocols = imap  
    listen = *, ::</nowiki>
+
listen = *, ::
 +
</syntaxhighlight>
 +
    
Add to the file /etc/dovecot/conf.d/10-mail.conf
 
Add to the file /etc/dovecot/conf.d/10-mail.conf
Line 370: Line 447:  
  <nowiki>!include auth-sql.conf.ext</nowiki>
 
  <nowiki>!include auth-sql.conf.ext</nowiki>
   −
ADD to the file /etc/dovecot/dovecot-sql.conf.ext
+
ADD to the file /etc/dovecot/dovecot-sql.conf.ext<syntaxhighlight lang="text">
<nowiki>driver = mysql
+
driver = mysql
    connect = host=127.0.0.1 dbname=email_accounts user=email password=password
+
 
    default_pass_scheme = MD5
+
connect = host=127.0.0.1 dbname=[MYSQL DATABASE] user=[MYSQL user] password=[MYSQL mailbox PASSWORD plain text]
   
+
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 mail user GID] AS `userdb_uid`, [YOUR mail user 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 mail USER UID] AS `uid`, [YOUR mail user GID] AS `gid`
 +
 
 +
</syntaxhighlight>
 +
    
====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
+
  ssl = required
    # Preferred permissions: root:root 0444
+
    ssl_cert = </etc/ssl/certs/dovecot.pem
+
ssl_key = </etc/letsencrypt/live/webmail.herrerosolis.com/privkey.pem
    # Preferred permissions: root:root 0400
+
ssl_cert = </etc/letsencrypt/live/webmail.herrerosolis.com/fullchain.pem
    ssl_key = </etc/ssl/private/dovecot.pem</nowiki>
      
====Ports====
 
====Ports====
Line 405: Line 485:  
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====
 
====Enable Password Plugin====
Line 441: Line 521:  
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
+
<syntaxhighlight lang="text">
    /etc/init.d/exim4 restart
+
/etc/init.d/apache2 restart  
    /etc/init.d/dovecot restart</nowiki>
+
/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.
+
</syntaxhighlight>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 502: Line 578:     
  mailq | grep frozen | awk '{print $3}' | xargs exim -v -M
 
  mailq | grep frozen | awk '{print $3}' | xargs exim -v -M
 +
 +
====Exim usefull commands====
 +
https://hostpapasupport.com/list-useful-commands-manage-exim-mail-server/
 +
 +
====Spam filters filtering your mails====
 +
https://www.mail-tester.com/
      Line 527: Line 609:  
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
 +
 +
https://pasztor.at/blog/the-big-exim-tutorial
 
=Adding new Domains=
 
=Adding new Domains=
    
#Add the new domain to to MySQL email_accounts.domains
 
#Add the new domain to to MySQL email_accounts.domains
 
#Start creating accounts with the new domain id
 
#Start creating accounts with the new domain id
 +
 +
=Auxiliary Scripts=
 +
 +
===Create email account===
 +
<syntaxhighlight lang="bash">
 +
#!/bin/bash
 +
PASSWORD1="hola"
 +
PASSWORD2="mundo"
 +
DOMAIN="herrerosolis.com"
 +
echo "******************************* MAIL ACCOUNT INFORMATION *****************************************"
 +
 +
read -p "Username (without@herrerosolis.com): " USERNAME
 +
 +
while [[ "$PASSWORD1" != "$PASSWORD2" ]]; do
 +
    read -s -p "Password: " PASSWORD1
 +
    echo
 +
    read -s -p "Confirm password: " PASSWORD2
 +
    if [ "$PASSWORD1" != "$PASSWORD2" ]; then
 +
        echo "Passwords dont match, try again..."
 +
    fi
 +
done
 +
echo
 +
echo
 +
echo "Input MySQL database password for user mail"
 +
 +
mysql -h 127.0.0.1 -u cartero -p -D email_accounts -e "INSERT INTO mailboxes VALUES(NULL,1,'$USERNAME',MD5('$PASSWORD1'),'Mail account for $USERNAME@${DOMAIN}',1,NOW(),NOW());"
 +
</syntaxhighlight>
 +
 +
===Create email alias===
 +
<syntaxhighlight lang="bash">
 +
#!/bin/bash
 +
 +
echo "******************************* MAIL ACCOUNT INFORMATION *****************************************"
 +
 +
read -p "Alias name (without _@redactate.com): " ALIAS
 +
 +
read -p "Destiny account (full email address): " GOTO
 +
 +
echo
 +
echo
 +
echo "Input MySQL database password for user mail"
 +
 +
mysql -h 127.0.0.1 -u cartero -p -D email_accounts -e "INSERT INTO aliases VALUES (null, 2, '$ALIAS', '$GOTO', 'Redirecting $ALIAS@ to $GOTO', 1, NOW(),NOW());"
 +
 +
</syntaxhighlight>

Navigation menu