email:install_a_full_mail_server
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
email:install_a_full_mail_server [2016/11/11 17:01] – peter | email:install_a_full_mail_server [2019/11/27 21:53] (current) – removed peter | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Email - Install a full mail server ====== | ||
- | ===== Requirements ===== | ||
- | |||
- | * Multiple domains using this for email (e.g. @company.com, | ||
- | * Webmail on your server (for anyone in the org to access email). | ||
- | * Aliases / redirects for some email addresses (e.g. so you can redirect " | ||
- | * DO NOT create "linux users" for every email user – it’s a huge security hole, and a massive pain in the ass for the sysadmin. | ||
- | * DO NOT do mail-relaying. | ||
- | |||
- | ===== What is needed ===== | ||
- | |||
- | * Web server [Nginx] | ||
- | * Database server (MySQL) | ||
- | * Email server (MTA) (Exim4) | ||
- | * IMAP server (Dovecot) | ||
- | * Webmail server (Roundcube) | ||
- | |||
- | |||
- | The database server will be used to manage ALL logins and usernames/ | ||
- | |||
- | |||
- | ===== Installation ===== | ||
- | |||
- | You need to install ALL of: | ||
- | |||
- | * apt-get install apache2-mpm-prefork\\ (Some of these email servers require PHP; PHP is crappy and requires mpm-prefork (the ' | ||
- | * 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' | ||
- | * 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 | ||
- | |||
- | |||
- | ===== Setup: DNS ===== | ||
- | |||
- | You need an " | ||
- | |||
- | |||
- | ===== Setup: Web server ===== | ||
- | |||
- | Roundcube sets up an over-the-top config: it creates an email server on every single website hosted on your server, and makes them all available at once. | ||
- | |||
- | Following the idea of http:// | ||
- | |||
- | |||
- | ==== Create a web address for your webmail ==== | ||
- | |||
- | If you have multiple websites hosted on your server, you SHOULD have a separate file for each inside / | ||
- | |||
- | * / | ||
- | * / | ||
- | * / | ||
- | |||
- | For each domain that you want to give webmail to, edit the file and ADD the following: | ||
- | |||
- | |||
- | <file apache> | ||
- | < | ||
- | ServerName webmail.[the domain name] | ||
- | DocumentRoot / | ||
- | </ | ||
- | </ | ||
- | |||
- | Note: replace “[the domain name]” with the domain name, e.g. " | ||
- | |||
- | |||
- | ===== Setup: create databases ===== | ||
- | |||
- | Create your databases. From the command-line, | ||
- | |||
- | <code bash> | ||
- | mysql -u root -p | ||
- | </ | ||
- | |||
- | …or use your preferred softare (e.g. phpMyAdmin). | ||
- | |||
- | ==== Create the database ==== | ||
- | |||
- | <code mysql> | ||
- | CREATE DATABASE email_accounts; | ||
- | </ | ||
- | |||
- | ==== Create the tables for email-accounts and config ==== | ||
- | |||
- | <code mysql> | ||
- | 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(' | ||
- | description VARCHAR(250) NULL, | ||
- | active TINYINT(1) NOT NULL DEFAULT 0, | ||
- | created TIMESTAMP NOT NULL DEFAULT NOW(), | ||
- | modified TIMESTAMP NULL | ||
- | ); | ||
- | </ | ||
- | |||
- | ==== Create a database-account to access the database ==== | ||
- | |||
- | <code mysql> | ||
- | grant ALL on email_accounts.* to ' | ||
- | flush privileges; | ||
- | </ | ||
- | |||
- | Note: that is not an email address, it’s a MySQL user account. | ||
- | Note: this account will ONLY be accessible by our software running on the server; you cannot access this account remotely (over the internet). | ||
- | |||
- | |||
- | ==== Create your first email account and domain ==== | ||
- | |||
- | |||
- | <code mysql> | ||
- | INSERT INTO domains VALUES(NULL,' | ||
- | INSERT INTO mailboxes VALUES(NULL, | ||
- | </ | ||
- | |||
- | Note: this password is used over the internet when you login to webmail – so pick a good one! This has to be secure! | ||
- | |||
- | ==== Create a redirector for an email address ==== | ||
- | |||
- | <code mysql> | ||
- | INSERT INTO aliases VALUES (NULL, 1, ' | ||
- | </ | ||
- | |||
- | Note: only set this up if you actually want a redirect. | ||
- | |||
- | |||
- | ===== Setup: Configure Exim4 ===== | ||
- | |||
- | When you install Exim4, make sure you chose the “split” packages. If not, you can fix that now by running: | ||
- | |||
- | <code bash> | ||
- | dpkg-reconfigure exim4-config | ||
- | </ | ||
- | |||
- | |||
- | ==== Debian: set the global / initial Exim config ==== | ||
- | |||
- | NB: these are the settings filled out by “dpkg-reconfigure exim4-config”. Here’s what your file should look like: | ||
- | |||
- | Edit: / | ||
- | |||
- | <file bash / | ||
- | # / | ||
- | # | ||
- | # Edit this file and / | ||
- | # yourself or use ' | ||
- | # | ||
- | # 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, | ||
- | # | ||
- | # This is a Debian specific file | ||
- | |||
- | dc_eximconfig_configtype=' | ||
- | dc_other_hostnames=' | ||
- | dc_local_interfaces=' | ||
- | dc_readhost='' | ||
- | dc_relay_domains='' | ||
- | dc_minimaldns=' | ||
- | dc_relay_nets='' | ||
- | dc_smarthost='' | ||
- | CFILEMODE=' | ||
- | dc_use_split_config=' | ||
- | dc_hide_mailname='' | ||
- | dc_mailname_in_oh=' | ||
- | dc_localdelivery=' | ||
- | </ | ||
- | |||
- | Note: replace “[YOUR DOMAIN 1]” with e.g. “my-company.com”, | ||
- | Note: replace “[PUT YOUR SERVER’s IP ADDRESS HERE]” with e.g. “10.0.0.1” (whatever your public internet address is) | ||
- | |||
- | |||
- | ==== Setup Exim: Macros ==== | ||
- | |||
- | ADD the following to / | ||
- | |||
- | <file bash> | ||
- | MAIN_LOCAL_DOMAINS = @: | ||
- | </ | ||
- | |||
- | ADD the following to / | ||
- | |||
- | <file bash> | ||
- | # 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' | ||
- | |||
- | MYSQL_SERVER=127.0.0.1 | ||
- | MYSQL_DB=email_accounts | ||
- | MYSQL_USER=email | ||
- | MYSQL_PASSWORD=password | ||
- | hide mysql_servers = MYSQL_SERVER/ | ||
- | </ | ||
- | |||
- | Note: “hide mysql_servers” isn’t “hiding” anything – it’s an ESSENTIAL step! It actually means “use this database server”. Terrible config name :(. | ||
- | |||
- | |||
- | ==== Setup Exim: Routers ==== | ||
- | |||
- | CREATE the file / | ||
- | |||
- | <file bash> | ||
- | dovecot_user: | ||
- | driver = accept | ||
- | condition = ${lookup mysql{SELECT CONCAT(mailboxes.local_part,' | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | </ | ||
- | |||
- | Either DELETE this file, or comment-out all lines / | ||
- | |||
- | <file bash> | ||
- | ### router/ | ||
- | ################################# | ||
- | |||
- | # This router handles aliasing using a traditional / | ||
- | # | ||
- | ##### NB You must ensure that / | ||
- | ##### NB that every Unix had that file, because it was the Sendmail default. | ||
- | ##### NB These days, there are systems that don't have it. Your aliases | ||
- | ##### NB file should at least contain an alias for " | ||
- | # | ||
- | # This router handles the local part in a case-insensitive way which | ||
- | # satisfies the RFCs requirement that postmaster be reachable regardless | ||
- | # of case. If you decide to handle / | ||
- | # need to make arrangements for a caseless postmaster. | ||
- | # | ||
- | # Delivery to arbitrary directories, | ||
- | # / | ||
- | # If that is a problem for you, see | ||
- | # / | ||
- | # for explanation and some workarounds. | ||
- | |||
- | # | ||
- | # debug_print = "R: system_aliases for $local_part@$domain" | ||
- | # driver = redirect | ||
- | # domains = +local_domains | ||
- | # allow_fail | ||
- | # allow_defer | ||
- | # data = ${lookup{$local_part}lsearch{/ | ||
- | # .ifdef SYSTEM_ALIASES_USER | ||
- | # user = SYSTEM_ALIASES_USER | ||
- | # .endif | ||
- | # .ifdef SYSTEM_ALIASES_GROUP | ||
- | # group = SYSTEM_ALIASES_GROUP | ||
- | # .endif | ||
- | # .ifdef SYSTEM_ALIASES_FILE_TRANSPORT | ||
- | # file_transport = SYSTEM_ALIASES_FILE_TRANSPORT | ||
- | # .endif | ||
- | # .ifdef SYSTEM_ALIASES_PIPE_TRANSPORT | ||
- | # pipe_transport = SYSTEM_ALIASES_PIPE_TRANSPORT | ||
- | # .endif | ||
- | # .ifdef SYSTEM_ALIASES_DIRECTORY_TRANSPORT | ||
- | # directory_transport = SYSTEM_ALIASES_DIRECTORY_TRANSPORT | ||
- | # .endif | ||
- | </ | ||
- | |||
- | CREATE this file / | ||
- | |||
- | <file bash> | ||
- | ### router/ | ||
- | ################################# | ||
- | |||
- | # ADAM: This router handles aliasing using the proprietary mysql setup | ||
- | # | ||
- | # c.f. http:// | ||
- | # | ||
- | |||
- | system_aliases: | ||
- | | ||
- | | ||
- | | ||
- | data = ${lookup mysql{SELECT aliases.goto AS goto FROM domains, | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | </ | ||
- | |||
- | |||
- | ==== Setup exim: Transports ==== | ||
- | |||
- | CREATE / OVERWRITE the file / | ||
- | |||
- | <file bash> | ||
- | ### transport/ | ||
- | ################################# | ||
- | |||
- | # | ||
- | |||
- | dovecot_delivery: | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | user = mail | ||
- | group = mail | ||
- | mode = 0660 | ||
- | </ | ||
- | |||
- | |||
- | ==== Setup exim: Auth ==== | ||
- | |||
- | CREATE the file / | ||
- | |||
- | <file bash> | ||
- | ### AUTHENTICATIOR SECTION | ||
- | |||
- | auth_plain: | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | |||
- | auth_login: | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | </ | ||
- | |||
- | |||
- | ===== Setup: Configure Dovecot ===== | ||
- | |||
- | When installing the dovecot apts, make sure you chose the “split files” option (exactly as with Exim4). It makes life easier. If you got this wrong, run: | ||
- | |||
- | <code bash> | ||
- | dpkg-reconfigure dovecot-core | ||
- | </ | ||
- | |||
- | Note: Dovecot installs with almost everything " | ||
- | |||
- | ==== Dovecot: find your " | ||
- | |||
- | For security, you want a " | ||
- | |||
- | To find these out do: | ||
- | |||
- | <code bash> | ||
- | cat /etc/passwd | ||
- | </ | ||
- | |||
- | …and find the line something like: | ||
- | |||
- | <file bash / | ||
- | mail: | ||
- | </ | ||
- | |||
- | the first 8 is your uid, the second 8 is your gid (could be different numbers on your server) | ||
- | |||
- | |||
- | |||
- | ==== Dovecot: all config files ==== | ||
- | |||
- | ADD to the file / | ||
- | |||
- | <file bash> | ||
- | protocols = imap | ||
- | listen = *, :: | ||
- | </ | ||
- | |||
- | Add to the file / | ||
- | |||
- | <file bash> | ||
- | mail_location = maildir:~ | ||
- | </ | ||
- | |||
- | ADD to the file / | ||
- | |||
- | <file bash> | ||
- | !include auth-sql.conf.ext | ||
- | </ | ||
- | |||
- | |||
- | ADD to the file / | ||
- | |||
- | <file bash> | ||
- | connect = host=127.0.0.1 dbname=email_accounts user=email password=password | ||
- | default_pass_scheme = MD5 | ||
- | |||
- | password_query = SELECT CONCAT(mailboxes.local_part,' | ||
- | |||
- | user_query = SELECT '/ | ||
- | </ | ||
- | |||
- | Note: replace [YOUR UID] and [YOUR GID] with correct numbers (that you found out using cat / | ||
- | |||
- | |||
- | |||
- | ===== Setup: Configure Roundcube ===== | ||
- | |||
- | EDIT the file / | ||
- | |||
- | <code bash> | ||
- | $rcmail_config[' | ||
- | </ | ||
- | |||
- | Note: replace “[YOUR MX RECORD]” with the MX address you put on your DNS server at the very start. e.g. " | ||
- | |||
- | 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”), | ||
- | |||
- | |||
- | ===== Restart EVERYTHING ===== | ||
- | |||
- | Now you’ve set it up, you MUST restart the web and email servers. | ||
- | |||
- | You must ALSO do this everytime you change any config files! | ||
- | |||
- | <code bash> | ||
- | / | ||
- | / | ||
- | / | ||
- | </ | ||
- | |||
- | |||
- | Exim may output a " | ||
- | |||
- | |||
- | ===== Debugging – making it work! ===== | ||
- | |||
- | You’ve got a lot to test here! | ||
- | |||
- | ==== Test exim ==== | ||
- | |||
- | === receiving emails === | ||
- | |||
- | Pick an email address that you added to the " | ||
- | |||
- | <code bash> | ||
- | 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 / | ||
- | |||
- | <code bash> | ||
- | tail / | ||
- | </ | ||
- | |||
- | (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/ | ||
- | |||
- | <code bash> | ||
- | tail / | ||
- | </ | ||
- | |||
- | |||
- | === sending emails === | ||
- | |||
- | …I waited until I had webmail (Roundcube) working before trying this… | ||
- | |||
- | |||
- | === Any other Exim problems? === | ||
- | |||
- | If exim is working, but its blocking/ | ||
- | |||
- | How? | ||
- | |||
- | Here is a list of commands to help: http:// | ||
- | |||
- | === Test Dovecot === | ||
- | |||
- | Dovecot’s maintainers have written [[http:// | ||
- | |||
- | Note: to make this work, I had to install telnet: “apt-get install telnet-client” | ||
- | |||
- | |||
- | === Test Roundcube === | ||
- | |||
- | Go to the web-address you configured at the very start (e.g. " | ||
- | |||
- | Login using the user-account you crated in MySQL at the start, using the FULL email address, e.g.: | ||
- | |||
- | Username: " | ||
- | Password: " | ||
- | |||
- | If you set things up correctly, following my steps above, it should NOT ask you for an IMAP server. If it does … go back and read this post more carefully. | ||
- | |||
- | You should find yourself in webmail, able to send emails, and receive them. | ||
- | |||
- | |||
- | ==== If it all works … speed it up! ==== | ||
- | |||
- | Out of the box, Roundcube runs very, very, very slowly … because it checks lots of different passwords before asking MySQL to check the password. | ||
- | |||
- | Fortunately there’s a very quick fix here: http:// | ||
- | |||
- | After doing that, I found webmail go from “takes 5 seconds per click” to “most clicks have immediate effect” (on my fast broadband). | ||
- | |||
- | |||
- | ===== What you should do next… ===== | ||
- | |||
- | This setup gets you decent, working, webmail. This is the hardest bit! | ||
- | |||
- | But it’s missing some core features you’ll want to add next: | ||
- | |||
- | - Reduce incoming spam: install SpamAssassin or similar | ||
- | - Secure the webmail connection: buy an SSL certificate, | ||
- | - Secure the IMAP connection: the setup above allows anyone to IMAP to the server from public internet. This allows you to use Outlook etc as a mail client. But if you *only* want to allow Webmail, you can edit your Dovecot configs and change the “listen” setting to only listen on 127.0.0.1 / localhost. This will allow Roundcube to connect (it’s on the same server) but will block internet clients. | ||
- | |||
- | …those should be easy to find separate guides for. Good luck. | ||
- | |||
- | |||
- | ===== 2016 Update ===== | ||
- | |||
- | Changes needed for Ubuntu 15.10 (may be needed for some other Debian' | ||
- | |||
- | Only two things I might add: | ||
- | |||
- | - In the file / | ||
- | - / | ||
- | |||
- | ===== Comments ===== | ||
- | |||
- | - In the file / | ||
- | - / | ||
- | |||
- | Option “CONCAT” unknown. Usually due to incorrect version of exim4. | ||
- | |||
- | |||
- | |||
- | ===== References ===== | ||
- | |||
- | |||
- | http:// | ||
- | |||
- | https:// | ||
- | |||
- | http:// | ||
- | |||
- | http:// |
email/install_a_full_mail_server.1478883670.txt.gz · Last modified: 2020/07/15 09:30 (external edit)