Mail Server Setup With Exim, MySQL, Cyrus-Imapd, Horde Webmail On Centos 5.1 - Page 2

Configuration

Configure Apache

  • Enable virtual hosting and create default virtualhost, edit /etc/httpd/conf/httpd.conf and add at the end
    NameVirtualHost *:80
    <VirtualHost *:80>
        ServerAdmin [email protected]
    </VirtualHost>
    
  • Create the virtual host for horde webmail add this under the above
    <VirtualHost *:80>
            Servername mail.home.topdog-software.com
            DocumentRoot /usr/share/horde
            ErrorLog logs/mail-error_log
            CustomLog logs/mail-access_log common
    </VirtualHost>
    
  • Enable horde security settings edit the file /etc/httpd/conf.d/horde.conf and set as below
    #Alias /horde /usr/share/horde
    <Directory /usr/share/horde>
        Options +FollowSymLinks
        php_admin_flag safe_mode off
        php_admin_flag magic_quotes_runtime off
        php_flag session.use_trans_sid off
        php_flag session.auto_start off
        php_admin_flag file_uploads on
        #php_admin_flag allow_url_fopen on
        php_value post_max_size 20M
        php_value upload_max_filesize 10M
        php_admin_value open_basedir "/usr/share/horde:/usr/share/horde/config:/usr/share/pear:/tmp"
        php_admin_flag register_globals off
    </Directory>
    <Directory /usr/share/horde/config>
        Order Deny,Allow
        Deny from all
    </Directory>
    <DirectoryMatch "^/usr/share/horde/(.*/)?(config|lib|locale|po|scripts|templates)/(.*)?">
        Order Deny,Allow
        Deny from all
    </DirectoryMatch>
    
  • Increase PHP memory limit edit /etc/php.ini and change to below
    memory_limit = 64M
    
  • Enable horde under SSL edit /etc/httpd/conf.d/ssl.conf and add the following to the default virtualhost between the <VirtualHost _default_:443><VirtualHost> tags
    Servername mail.home.topdog-software.com:443
    DocumentRoot /usr/share/horde
    

 

Configure Exim

  • Switch the MTA to exim
 system-switch-mail (select exim)

Anti-virus / Sanesecurity Checks

  • Configure Exim (/etc/exim/exim.conf) to use clamav to scan incoming mail and reject virus infected email and image and pdf spam at smtp time
av_scanner = clamd:/var/run/clamav/clamd.sock

RBL's

  • Configure the RBL's under acl_check_rcpt:
    drop    message       = REJECTED because $sender_host_address is in a black list spamhaus.org
               dnslists      = zen.spamhaus.org
    drop    message       = REJECTED because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
               dnslists      = bl.spamcop.net
    drop    message       = REJECTED because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
               dnslists      = dnsbl.sorbs.net
    

 

Anti Spam

  • If you want to reject messages from servers with no reverse dns add this under acl_check_rcpt:, it does have a exception list to which you can add domains where the acl should not be applied and trys to deliver a test message to sending address to verify if the sender is valid.
    drop  message   = REJECTED - We don't accept messages from hosts without reverse DNS
            log_message = No reverse DNS
            domains = ! lsearch;/etc/exim/checks_exempt_hosts
            !verify = reverse_host_lookup
            !verify = sender/callout=2m,defer_ok
            !condition =  ${if eq{$sender_verify_failure}{}}
    
  • To reject messages from clients that dont provide a HELO/EHLO add this to acl_check_rcpt:
    drop  message  = REFUSED - no HELO/EHLO greeting
            log_message = remote host did not present greeting
            condition = ${if def:sender_helo_name {false}{true}}
    
  • You can rate limit the connections to your server as well add this to acl_check_connect: to do so (read the exim docs on the parameters if you want to fine tune it for your site)
    deny ratelimit = 250 / 15m / strict
           message = You can only send $sender_rate per $sender_rate_period
           log_message = RATE: $sender_rate/$sender_rate_period (max $sender_rate_limit)
    accept
    
  • Stop rogue spam bots from trashing your machine
    smtp_accept_max_nonmail = 30
    smtp_max_unknown_commands = 1
    
  • Don't advertise pipelining
    pipelining_advertise_hosts = 
    
  • Enable Spamassassin checks
    spamd_address = /var/run/spamassassin/spamd.sock
    
  • Reject all messages with score above 6 at smtp time. (acl_check_data)
    accept  condition  = ${if >={$message_size}{100000} {1}}
            add_header = X-Spam-Note: SpamAssassin run bypassed due to message size
      warn    spam       = nobody/defer_ok
            add_header = X-Spam-Flag: YES
      accept  condition  = ${if !def:spam_score_int {1}}
            add_header = X-Spam-Note: SpamAssassin invocation failed
      warn    add_header = X-Spam-Score: $spam_score ($spam_bar)\n\
    #       X-Spam-Report: $spam_report
      drop    condition = ${if >{$spam_score_int}{60} {1}}
            message   = Your message scored $spam_score SpamAssassin point. Report follows:\n\
            $spam_report
    

 

Mail routing

  • Enable access to Mysql database
    hide mysql_servers = localhost/horde/horde/hordepassword
    
  • Modify the local delivery router to deliver to cyrus but verify the email address of user before delivery (in routers section of exim.conf)
    localuser:
      driver = accept
      local_parts = ${lookup mysql {SELECT REPLACE(user_uid,'${quote_mysql:@$domain}','') \
             as user FROM horde_users WHERE user_uid='${quote_mysql:$local_part@$domain}'}{$value}}
      transport = local_delivery
      cannot_route_message = Unknown user
    
  • Create a transport to deliver to cyrus via lmtp socket
    local_delivery:
      driver = lmtp
      socket = /var/lib/imap/socket/lmtp
      batch_max = 50
      user = cyrus
    

 

SMTP Authentication

  • Add the following to the authentication section of /etc/exim/exim.conf
    plain:
      driver = plaintext
      public_name = PLAIN
      server_prompts = :
      server_set_id = $2
      server_condition = ${if saslauthd{{$2}{$3}{pop}}{1}{0}}
      server_advertise_condition = true
    login:
      driver = plaintext
      public_name = LOGIN
      server_prompts = "Username:: : Password::"
      server_condition = ${if saslauthd{{$1}{$2}{pop}}{1}{0}}
      server_set_id = $1
      server_advertise_condition = true
    

 

Full sample configuration

Download the full configuration file here.

 

Configure Mysql

  • Disable TCP networking edit /etc/my.cnf and the following in the mysqld section
    skip-networking
    
  • Set root password

    /usr/bin/mysqladmin -u root password 'new-password'
    /usr/bin/mysqladmin -u root -h your_host_name password 'new-password' -p

 

Configure Horde

  • Edit the sql file and change the mysql password for the horde user

    cp /usr/share/horde/scripts/sql/create.mysql.sql .
    vi create.mysql.sql

    REPLACE INTO user (host, user, password)
        VALUES (
            'localhost',
            'horde',
    -- IMPORTANT: Change this password!
            PASSWORD('hordepassword')
    );
    
  • Create the user and populate the horde database
    mysql -p < create.mysql.sql
  • Create the tables for turba (Address book)
    mysql -p horde < /usr/share/horde/turba/scripts/sql/turba_objects.mysql.sql
  • Create the tables for kronolith (calendering)
    mysql -p horde < /usr/share/horde/kronolith/scripts/sql/kronolith.mysql.sql

 

Horde Configuration

  • Create horde base configuration /usr/share/horde/config/conf.php
    <?php
    $conf['debug_level'] = E_ALL;
    $conf['max_exec_time'] = 0;
    $conf['compress_pages'] = true;
    $conf['umask'] = 077;
    $conf['use_ssl'] = 2;
    $conf['server']['name'] = $_SERVER['SERVER_NAME'];
    $conf['server']['port'] = $_SERVER['SERVER_PORT'];
    $conf['session']['name'] = 'Horde';
    $conf['session']['use_only_cookies'] = true;
    $conf['session']['cache_limiter'] = 'nocache';
    $conf['session']['timeout'] = 0;
    $conf['cookie']['domain'] = $_SERVER['SERVER_NAME'];
    $conf['cookie']['path'] = '/';
    $conf['sql']['username'] = 'horde';
    $conf['sql']['password'] = 'hordepassword';
    $conf['sql']['socket'] = '/var/lib/mysql/mysql.sock';
    $conf['sql']['protocol'] = 'unix';
    $conf['sql']['database'] = 'horde';
    $conf['sql']['charset'] = 'iso-8859-1';
    $conf['sql']['phptype'] = 'mysqli';
    $conf['auth']['admins'] = array('Administrator', '[email protected]');
    $conf['auth']['checkip'] = true;
    $conf['auth']['checkbrowser'] = true;
    $conf['auth']['alternate_login'] = false;
    $conf['auth']['redirect_on_logout'] = false;
    $conf['auth']['params']['driverconfig'] = 'horde';
    $conf['auth']['params']['table'] = 'horde_users';
    $conf['auth']['params']['username_field'] = 'user_uid';
    $conf['auth']['params']['password_field'] = 'user_pass';
    $conf['auth']['params']['encryption'] = 'md5-hex';
    $conf['auth']['params']['show_encryption'] = false;
    $conf['auth']['driver'] = 'sql';
    $conf['signup']['allow'] = false;
    $conf['log']['priority'] = PEAR_LOG_NOTICE;
    $conf['log']['ident'] = 'HORDE';
    $conf['log']['params'] = array();
    $conf['log']['name'] = '/tmp/horde.log';
    $conf['log']['params']['append'] = true;
    $conf['log']['type'] = 'file';
    $conf['log']['enabled'] = true;
    $conf['log_accesskeys'] = false;
    $conf['prefs']['params']['driverconfig'] = 'horde';
    $conf['prefs']['driver'] = 'sql';
    $conf['datatree']['params']['driverconfig'] = 'horde';
    $conf['datatree']['driver'] = 'sql';
    $conf['group']['driver'] = 'datatree';
    $conf['cache']['default_lifetime'] = 1800;
    $conf['cache']['params']['dir'] = Horde::getTempDir();
    $conf['cache']['params']['gc'] = 86400;
    $conf['cache']['driver'] = 'file';
    $conf['token']['driver'] = 'none';
    $conf['mailer']['params']['auth'] = '0';
    $conf['mailer']['type'] = 'smtp';
    $conf['vfs']['params']['driverconfig'] = 'horde';
    $conf['vfs']['type'] = 'sql';
    $conf['sessionhandler']['params']['persistent'] = false;
    $conf['sessionhandler']['params']['rowlocking'] = true;
    $conf['sessionhandler']['params']['socket'] = '/var/lib/mysql/mysql.sock';
    $conf['sessionhandler']['params']['protocol'] = 'unix';
    $conf['sessionhandler']['params']['hostspec'] = 'localhost';
    $conf['sessionhandler']['params']['username'] = 'horde';
    $conf['sessionhandler']['params']['password'] = 'hordepassword';
    $conf['sessionhandler']['params']['database'] = 'horde';
    $conf['sessionhandler']['type'] = 'mysql';
    $conf['problems']['email'] = '[email protected]';
    $conf['problems']['maildomain'] = 'home.topdog-software.com';
    $conf['problems']['tickets'] = false;
    $conf['menu']['apps'] = array();
    $conf['menu']['always'] = true;
    $conf['menu']['links']['help'] = 'authenticated';
    $conf['menu']['links']['help_about'] = true;
    $conf['menu']['links']['options'] = 'authenticated';
    $conf['menu']['links']['problem'] = 'never';
    $conf['menu']['links']['login'] = 'all';
    $conf['menu']['links']['logout'] = 'authenticated';
    $conf['hooks']['permsdenied'] = false;
    $conf['hooks']['username'] = false;
    $conf['hooks']['preauthenticate'] = false;
    $conf['hooks']['postauthenticate'] = false;
    $conf['hooks']['authldap'] = false;
    $conf['portal']['fixed_blocks'] = array();
    $conf['accounts']['driver'] = 'null';
    $conf['imsp']['enabled'] = false;
    $conf['kolab']['enabled'] = false;
    
  • Set horde preferences to make web mail the default application on logging in. Edit the file /usr/share/horde/config/prefs.php and modify $_prefs['initial_application'] to look as below
    $_prefs['initial_application'] = array(
        'value' => 'imp',
        'locked' => true,
        'shared' => true,
        'type' => 'select',
        'desc' => sprintf(_("What application should %s display after login?"), $GLOBALS['registry']->get('name'))
    );
    
  • Make horde work from within the default root of the web servers, edit /usr/share/horde/config/registry.php and modify $this?applications['horde'] as below
    $this->applications['horde'] = array(
        'fileroot' => dirname(__FILE__) . '/..',
        'webroot' => '',
        'initial_page' => 'login.php',
        'name' => _("Horde"),
        'status' => 'active',
        'templates' => dirname(__FILE__) . '/../templates',
        'provides' => 'horde'
    );
    
Share this page:

3 Comment(s)