Thanks for picking the Virtual Exim package, for your virtual mail hosting needs! :-)
This document provides a basic guide on how to get Virtual Exim working on your system. In this guide, I assume that you have a little knowledge of both MySQL and Exim.
Before we go into any details, I'd like to thanks Philip Hazel and the Exim developers for a fine product. I would also like to thanks the postmasters at various domains for letting me play havoc with their mail while I set this up :-) Finally, a special note of thanks to Dan Bernstein for his Qmail MTA. Dan, thank you for educating me how mail delivery really shouldn't be done, on the Internet.
The Virtual Exim project currently lives on GitHub: https://github.com/vexim/vexim2 And its mailing list/Google group is available at: https://groups.google.com/group/vexim
If you are upgrading from a previous version of Virtual Exim, you'll find additional notes marked 'UPGRADING' in some sections. If and when you do, follow these notes.
Some sections may contain distribution or OS-specific notes. You'll find them after an appropriate prefix, such as 'DEBIAN' or 'FREEBSD' where appropriate.
- Prerequisites
- System user
- Databases and authentication
- Files and Apache
- Mailman
- Exim configuration
- Site Admin
- Virtual Domains
- Mail storage and Delivery
- POP3 and IMAP daemons (separate to this software)
The following packages must be installed on your system, for Virtual Exim to work. If you don't have any of these packages already installed, please refer to the documentation provided with your operating system on how to install each package:
- Exim v4 with MariaDb, MySQL or PostgreSQL support (tested on v4.1x/4.2x/4.7x)
- MariaDb (tested on v11.8.6-MariaDB), MySQL or PostgreSQL
- Apache or other HTTP server (Tested with Apache v2.2.x and Nginx)
- Redis (if using the new web interface)
- PHP 8.x with at least the following extensions:
- PDO
- pdo_mysql or pdo_pgsql
- imap
- gettext
- iconv
- filter
The following packages provide optional functionality:
- Mailman – to have mailing lists
- ClamAV – for scanning e-mail for viruses
- SpamAssassin – for scanning e-mail from spam
VExim might work with older (or newer) versions of these packages, but you may have to perform some adaptation work to achieve that. In any case, you are welcome to file bugs and/or provide patches on GitHub.
DEBIAN: The following command line installs all the packages mentioned above (last four are optional), if you're going with MySQL setup:
# apt-get install apache2 exim4-daemon-heavy mysql-server libapache2-mod-php php-mysql php-imap clamav-daemon clamav-freshclam spamassassin mailman
You should create a new user account to whom the virtual mailboxes will belong. Since you do not want anyone to be able to login using that account, you should also disable logging in for that user. Here are the command lines to do that. This manual assumes you want to have your virtual mailboxes in /var/vmail. If you want them elsewhere, adjust the commands. After the user and group are created, find their uid and gid using the last command and memorize these values:
# useradd -r -m -U -s /bin/false -d /var/vmail vexim
# id vexim
FREEBSD: Instead of the commands above, you should probably use the following (change 90 to another value if this user or group id is already used on your system):
# pw groupadd vexim -g 90
# pw useradd vexim -u 90 -g vexim -d /usr/local/mail -m -s /nonexistant
DEBIAN: Use the following command instead:
# adduser --system --home /var/vmail --disabled-password --disabled-login --group vexim
This distribution contains a file "vexim2/setup/mysql.sql". This file provides the database schema used by vexim. You will have to import it into MySQL, like this:
# mysql -u root -D YOUR_DATABASE_NAME -p < vexim2/setup/mysql.sql
Where YOUR_DATABASE_NAME is the name of an empty database you have created for vexim. If you want the script to create the database for you and set up access to it, this is also doable: just open it in a text editor, and find a commented out block which begins with -- CREATE DATABASE near the top of the file. This block is documented just above it, so you may uncomment it, apply the changes you want and save the file. With the necessary changes made, you should run the following command line to initialize the database:
# mysql -u root -p < vexim2/setup/mysql.sql
Or this is a fresh install you can run bash setup-web.sh in the vexim2 root directory and it will install all the tables for you (MariaDb/MySQL only).
The code has been tested by several users to work with Virtual Exim, and we try our best to make sure it always will. Unfortunately I don't have much PostgreSQL knowledge to support it fully. A database schema for it is included however, as setup/pgsql.sql to help you set up the database. Make sure to adjust it similarly as per MySQL instructions above.
UPGRADING: If you are upgrading your installation, we have prepared MySQL migration scripts for you, which you will find under vexim2/setup/migrations/. Find out the version of Vexim that you have and apply the necessary scripts in a sequential manner, like this:
# mysql -u root -D YOUR_DATABASE_NAME -p < vexim2/setup/migrations/SCRIPT_FILENAME.sql
In this distribution is a directory called 'vexim_web'. You have two options:
- Copy this directory into your current DocumentRoot for your domain, and optionally rename the directory.
- Set up a new VirtualHost and point the DocumentRoot to the vexim directory.
Both should work equally well.
After copying the 'vexim_web' directory, you need to copy .env.example to .env and make the changes, The important bits are:
- APP_NAME (what do you want to call it? - also used in system emails)
- APP_URL (the url of the website)
- DB_CONNECTION
- DB_HOST
- DB_PORT
- DB_DATABASE
- DB_USERNAME
- DB_PASSWORD
- REDIS_CLIENT
- REDIS_HOST
- REDIS_PASSWORD
- REDIS_PORT
- MAIL_MAILER (change to smtp)
- MAIL_HOST (Your smtp host)
- MAIL_PORT (your smtp port)
- MAIL_USERNAME (login)
- MAIL_PASSWORD (password)
- MAIL_FROM_ADDRESS (email address system emails are sent from)
- MAIL_FROM_NAME (can be left as is and will use APP_NAME variable)
- MAIL_FROM_SUPPORT_ADDRESS (your support email address)
- MAIL_FROM_SUPPORT_NAME (name that shows when system emails are sent via the support address
- VEXIM_UID (UID that vexim runs under)
- VEXIM_GID (GID that vexim runs under)
- VEXIM_CRYPT_SCHEME (your current password crypt scheme, website only supports sha512 or bcrypt)
you will find a file called setup-web.sh in the vexim2 folder (not in the web folder). You need to run this to install the extra database tables (and current table modifications). It will also sets up a system admin account and seeds the new database tables (important!). It adds some extra fields to the original vexim2 tables but that is purely for the web interface (updated times etc) and doesn't affect how Exim handles anything.
The new tables created after running that script are:
- activity_log (used for logging)
- cache (laravel cache)
- cache_locks (laravel_cache)
- email_templates (allows for editing of email templates)
- email_template_settings (email template settings)
- email_template_versions (versioning for email templates)
- email_themes (email template themes)
- failed_jobs (laravel job monitoring)
- jobs (laravel job monitoring)
- job_batches (laravel job monitoring)
- migrations (database migrations)
- model_has_permissions (for user permissions (Spatie package))
- model_has_roles (for user permissions)
- passkeys (passkey login support)
- password_reset_tokens (as it sounds)
- permissions (for user permissions (Spatie package))
- roles (for user permissions (Spatie package))
- role_has_permissions (for user permissions (Spatie package))
- sent_emails (unused atm)
- sessions (laravel sessions)
- settings (vexim web settings)
- users_web (vexim we users)
- whitelist_senders (exim whitelist sends table)
The web interface runs off roles and permissions, there are 3 new roles created
- system-admin
- domain-admin
- domain-user
system-admin This account mimics the old siteadmin account, it can do and see everything, give these away carefully and we highly recommend setting up passkey login or at the very least 2FA. You can change the settings for vexim and it's users using this account. This is a website only account, they cannot login to their email using these details.
domain-admin These accounts can control everything about their domains, they can have more than 1 domain in the system and can pretty much do the same as the system-admin account (but only on their domains). Again, passkey and 2FA are recommended. This is also a website only account, they cannot login to their email using these details.
domain-user This is an account that is solely for the purpose of updating their own email information, their login is the same as their email account details.
Now there's some manual admin work to do, log in to your new web interface using the newly created the system-admin account. You need to add some domain-admins who can manage the domain accounts (domain-user accounts are automatically synched). All other accounts can login via their email login details.
Some things to note: *You need to make sure your Exim and Dovecot (or whatever IMAP/POP you are using) supports bcrypt. Support for SHA-256 has been removed in this web app, SHA-512 can be used but whenever a user resets their password it will encrypt the new one using bcrypt. Why? Because bcrypt is just better for passwords, it takes longer to brute force a bcrypt password than it does an SHA-512 or 256 encrypted password. *Pipes are currently disabled, they're a security risk. Am looking into sieve filtering instead.
Mailman needs to be installed if you want to use mailing lists. Edit the default configuration file (/etc/mailman/mm_cfg.py):
DEFAULT_URL_PATTERN = 'https://%s/mailman/'
DEFAULT_SERVER_LANGUAGE = 'en'
DEFAULT_EMAIL_HOST = 'mail.example.tld'
DEFAULT_URL_HOST = 'mail.example.tld'
Debian will already create a default configuration for your webserver that you can enable with a2ensite mailman. Create your master password: `mmsitepass MY_PASSWORD``. Restart mailman and apache.
NOTE: the configuration files supplied here have been revised. You should use them carefully and report problems!
An example Exim 'configure' file, has been included with this distribution as 'docs/configure'. Copy this to the location Exim expects its configuration file to be on your installation. You will also need to copy docs/vexim* to /usr/local/etc/exim/ (or /etc/exim4 if on Debian). The following lines are important and will have to be edited if you are using this configure, or copied to your own configure file:
An important thing to take notice of, in this package there is now a new acl called 20_vexim_whitelist, you don't have to run this but if you choose to you need to remove the default exim file 20_exim4-config_local_deny_exceptions or your Exim will stop working!
Edit these if your mailman is in a different location (in Debian: /var/lib/mailman):
MAILMAN_HOME=/usr/local/mailman
MAILMAN_WRAP=MAILMAN_HOME/mail/mailman
These need to match the username and group under which exim runs (in Debian: list/daemon):
MAILMAN_USER=mailnull
MAILMAN_GROUP=mail
Change this to the name of your server:
primary_hostname=mail.example.org
In general, it is required that your reverse DNS entry of your IP points to this hostname.
If you are using MySQL, uncomment the following two lines:
#VIRTUAL_DOMAINS = SELECT DISTINCT CONCAT(domain, ' : ') FROM domains type = 'local'
#RELAY_DOMAINS = SELECT DISTINCT CONCAT(domain, ' : ') FROM domains type = 'relay'
If you are using PGSQL, uncomment the following four lines:
#VIRTUAL_DOMAINS = SELECT DISTINCT domain || ' : ' FROM domains WHERE type = 'local'
#RELAY_DOMAINS = SELECT DISTINCT domain || ' : ' FROM domains WHERE type = 'relay'
Depending on the database type you are using, you will need to uncomment the appropriate lines in the config, to enable lookups.
These control which domains you accept mail for and deliver locally (local_domains), which domains you accept mail for and deliver remotely (relay_to_domains), which IP addresses are allowed to send mail to any domain (relay_from_hosts) and which system users are considered trusted (trusted_users). More on these options – in Exim documentation.
domainlist local_domains = @ : example.org : ${lookup mysql{VIRTUAL_DOMAINS}} : ${lookup mysql{ALIAS_DOMAINS}}
domainlist relay_to_domains = ${lookup mysql{RELAY_DOMAINS}}
hostlist relay_from_hosts = localhost : @ : 192.168.0.0/24
#trusted_users = www-data
These lines configure database connectivity. You need to uncomment one of them (depending on the database type you have chosen) and adjust it to match your setup. You at least have to change the word 'CHANGE' to the password you used for the 'vexim' database user, which you have created before. The socket path depends on your system, for Debian it is:
#hide mysql_servers = localhost::(/var/run/mysqld/mysqld.sock)/db/user/password
#hide pgsql_servers = (/var/run/postgresql/.s.PGSQL.5432)/db/user/password
If you want to use either Anti-Virus scanning, or SpamAssassin, you will need to uncomment the appropriate line here.
# av_scanner = clamd:/tmp/clamd
# spamd_address = 127.0.0.1 783
in Debian use:
# av_scanner = clamd:/var/run/clamav/clamd.ctl
# spamd_address = /var/run/spamd.sock
Specify here, the username and group under which Exim runs (Debian: Debian-exim). This combination is also that under which mailman must run in order to work:
exim_user = mailnull
exim_group = mail
Also it is assumed that the mysql domain socket is /tmp/mysql.sock, which is where the FreeBSD port puts it. Other installations put it in /var/tmp, /usr/lib, or any number of other places. If yours isn't /tmp/mysql.sock, you will need to set this.
TLS is activated by default. We suppose that you already created a SSL key and certificate.
tls_certificate = /etc/exim4/exim.crt
tls_privatekey = /etc/exim4/exim.key
The creation of SSL-keys is the same like for webservers, e.g. https://www.digitalocean.com/community/tutorials/how-to-set-up-apache-with-a-free-signed-ssl-certificate-on-a-vps . You can use the same certificate your the webserver of this host (if you use webmail).
tls_dhparam = /etc/exim4/dhparam.pem
The Diffie-Hellman group should have at least 1024 bit and can be created with this command (it can take some time):
# openssl dhparam -out /etc/exim4/dhparam.pem 2048
In tls_require_ciphers, currently (2016) secure ciphers are selected. It works by default on GnuTLS setups (Debian/Ubuntu). If your distribution uses OpenSSL (e.g. FreeBSD, CentOS), comment the block tls_require_ciphers = ... and uncomment the line openssl_options = .... If you are not sure, the output of exim -bV will show either GnuTLS or OpenSSL.
We have split all of the ACL's into separate files, to make managing them easier. Please review the ACL section of the configure file. If there are ACL's you would rather not have executed, please comment out the '.include' line that references them, or edit the ACL file directly and comment them out.
Typically, Debian setups use split Exim configuration with some Debconf magic. This manual will assume that you are familiar with it. If not, you should refer to the Debian documentation on Exim. To get the virtual mailboxes to work, copy the contents of docs/debian-conf.d/ to /etc/exim4/conf.d/ and change the MySQL password in .../main/00_vexim_listmacrosdefs. You may also want to review the ACL's in docs/vexim-acl-*.conf and selectively copy and paste their contents to the files provided by Debian in conf.d. By the way, some of these ACL's are already implemented by Debian, so you might just need to enable them by defining certain macros as described in Debian manual. This manual does not cover enabling ClamAV and SpamAssassin in Exin in Debian. Please look this up elsewhere. By the way, the author of this part never bothered to set up Vexim in such a way that Debian would take into account the status of the various user flag (on_av, on_spamassassin etc) for each user. In his setup, these flags have no effect, and all messages are checked for spam and viruses.
Stefan Tomanek has a nice writeup about using Vexim in Debian, but that article does not cover all aspects, is a bit outdated, and most of if has been incorporated (and improved!) into this document anyway. You can find it at http://stefans.datenbruch.de/rootserver/vexim.shtml.
This is now handled by the web interface install script
Virtual Exim can now control which local domains Exim accepts mail for and which domains it relays mail for. The features are controlled by the siteadmin, and domains can be easily added/removed from the siteadmin pages. Local domains can also be enabled/disabled on the fly, but relay domains are always enabled.
The mysql configuration assumes that mail will be stored in /var/vmail/domain.com/username/Maildir. If you want to change the path from '/var/vmail/', you need to edit the file:
vexim/config/variables.php
and change 'mailroot' to the correct path. Don't forget the / at the end.
There are many POP3 and IMAP daemons available. Some that we have found that work are:
- Courier: docs/clients/courierimap.txt
- Dovecot: docs/clients/dovecot.txt
Dovecot provides more features (server-side sieve filters) and is more performant on larger setups.
UPGRADING: If you are upgrading, you will need to update your configs for your POP/IMAP daemons, as the database layout has changed. You should be able to follow the above instructions without problem.
Removed