ISP Mail Server HowTo: Difference between revisions
No edit summary |
|||
Line 165: | Line 165: | ||
== Install Postfix == | == Install Postfix == | ||
Create a user for the virtual mail delivery, and get its uid/gid (you'll need the numeric uid/gid for postfix) | |||
adduser vmail -H -D -s /bin/false | |||
grep vmail /etc/passwd | |||
(In examples below, we use 1006/1006 for the uid/gid) | |||
Create the mail directory, and assign vmail as the owner | |||
mkdir -p /var/mail/domains | |||
chown -R vmail:vmail /var/mail/domains | |||
Install postfix | |||
apk add acf-postfix postfix-pgsql | |||
Edit the /etc/postfix/main.cf file Here's an example: | |||
myhostname=host.example.com | |||
mydomain=example.com | |||
mydestination = $myhostname, localhost.$mydomains, localhost | |||
mynetworks_style = subnet | |||
mynetworks = 127.0.0.0/8 | |||
virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf | |||
virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf, | |||
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf, | |||
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf | |||
virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf, | |||
proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf | |||
virtual_mailbox_base = /var/mail/domains/ | |||
virtual_gid_maps = static:1006 | |||
virtual_uid_maps = static:1006 | |||
virtual_minimum_uid = 100 | |||
virtual_transport = virtual | |||
# This next command means you must create a virtual | |||
# domain for the host itself - ALL mail goes through | |||
# The virtual transport | |||
mailbox_transport = virtual | |||
local_transport = virtual | |||
local_transport_maps = $virtual_mailbox_maps | |||
smtpd_helo_required = yes | |||
disable_vrfy_command = yes | |||
message_size_limit = 10240000 | |||
queue_minfree = 51200000 | |||
smtpd_sender_restrictions = | |||
permit_mynetworks, | |||
reject_non_fqdn_sender, | |||
reject_unknown_sender_domain | |||
smtpd_recipient_restrictions = | |||
reject_non_fqdn_recipient, | |||
reject_unknown_recipient_domain, | |||
permit_mynetworks, | |||
permit_sasl_authenticated, | |||
reject_unauth_destination, | |||
reject_rbl_client dnsbl.sorbs.net, | |||
reject_rbl_client zen.spamhaus.org, | |||
reject_rbl_client bl.spamcop.net | |||
smtpd_data_restrictions = reject_unauth_pipelining | |||
# we will use this later - This prevents cleartext authentication | |||
# for relaying | |||
smtpd_tls_auth_only = yes | |||
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here's a shell script to create the scripts. | |||
cd /etc/postfix | |||
mkdir sql | |||
PGPW="ChangeMe" | |||
cat - <<EOF >sql/pgsql_virtual_alias_domain_catchall_maps.cf | |||
user=postfix | |||
password = $PGPW | |||
hosts = localhost | |||
dbname = postfix | |||
query = Select goto From alias,alias_domain where alias_domain.alias_domain = '%d' and alias.address = '@' || alias_domain.target_domain and alias.active = true and alias_domain.active= true | |||
EOF | |||
cat - <<EOF >sql/pgsql_virtual_alias_domain_mailbox_maps.cf | |||
user=postfix | |||
password = $PGPW | |||
hosts = localhost | |||
dbname = postfix | |||
query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = '%d' and mailbox.username = '%u' || '@' || alias_domain.target_domain and mailbox.active = true and alias_domain.active | |||
EOF | |||
cat - <<EOF >sql/pgsql_virtual_alias_domain_maps.cf | |||
user=postfix | |||
password = $PGPW | |||
hosts = localhost | |||
dbname = postfix | |||
query = select goto from alias,alias_domain where alias_domain.alias_domain='%d' and alias.address = '%u' || '@' || alias_domain.target_domain and alias.active= true and alias_domain.active= true | |||
EOF | |||
cat - <<EOF >sql/pgsql_virtual_alias_maps.cf | |||
user=postfix | |||
password = $PGPW | |||
hosts = localhost | |||
dbname = postfix | |||
query = Select goto From alias Where address='%s' and active ='1' | |||
EOF | |||
cat - <<EOF >sql/pgsql_virtual_domains_maps.cf | |||
user=postfix | |||
password = $PGPW | |||
hosts = localhost | |||
dbname = postfix | |||
query = Select domain from domain where domain='%s' and active='1' | |||
EOF | |||
cat - <<EOF >sql/pgsql_virtual_mailbox_limit_maps.cf | |||
user=postfix | |||
password = $PGPW | |||
hosts = localhost | |||
dbname = postfix | |||
query = Select quota from mailbox where username='%s' and active='1' | |||
EOF | |||
cat - <<EOF >sql/pgsql_virtual_mailbox_maps.cf | |||
user=postfix | |||
password = $PGPW | |||
hosts = localhost | |||
dbname = postfix | |||
query = Select maildir from mailbox where username='%s' and active=true | |||
EOF | |||
=== Spam Filtering === | |||
Add the following line to /etc/postfix/main.cf | |||
#content_filter = scan:[127.0.0.1]:10025 | |||
=== Relay for Authenticated Users === | |||
# TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first | |||
smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem | |||
smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem | |||
smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem | |||
smtpd_tls_security_level = may | |||
# Log info about the negotiated encryption levels | |||
smtpd_tls_received_header = yes | |||
smtpd_tls_loglevel = 1 | |||
# SASL - this allows senders to authenticiate themselves | |||
# This along with "premit_sasl_authenticated" in smtpd_recipient_restrictions above allows relaying | |||
smtpd_sasl_type = dovecot | |||
smtpd_sasl_path = private/dovecot-auth.sock | |||
smtpd_sasl_auth_enable = yes | |||
smtpd_sasl_authenticated_header = yes | |||
smtpd_tls_auth_only = yes | |||
== Install Dovecot == | == Install Dovecot == |
Revision as of 01:01, 18 January 2010
A Full Service Mail Server
The goal of this document is to describe how to set up postfix, dovecot, clamav, dspam, roundecube, and postfixadmin for a full-featured "ISP" level mail server.
The server must provide:
- multiple virtual domains
- admins for each domain (to add/remove virtual accounts)
- Quota support per domain / account
- downloading email via IMAP / IMAPS / POP3 / POP3S
- relaying email for authenticated users with TLS or SSL (Submission / SMTPS protocol)
- Standard filters (virus/spam/rbl/etc)
- Web mail client
- Value Add services
Set up Lighttpd + PHP
PostfixAdmin needs php pgpsql and imap modules, so we do it in this step.
apk add lighttpd php php-pgsql php-imap
Stop and remove mini_httpd, and move ACF to lighttpd; We are setting this up to be a mult-domain virtual web server:
mkdir -p /var/www/domains/host.example.com mv /usr/share/acf/* /var/www/domains/host.example.com
Edit /etc/lighttpd/mod_cgi.conf to serve haserl files by adding a "" => "" cgi handler
$HTTP["url"] =~ "^/cgi-bin/" { # disable directory listings dir-listing.activate = "disable" # only allow cgi's in this directory cgi.assign = ( ".pl" => "/usr/bin/perl", ".cgi" => "/usr/bin/perl", "" => "" ) }
Edit /etc/lighttpd/mod_fastcgi.conf to serve php scripts
server.modules += ("mod_fastcgi") fastcgi.server = ( ".php" => (( "socket" => "/var/run/lighttpd/lighttpd-fastcgi-php-" + PID + ".socket" "bin-path" => "/usr/bin/php-cgi" )) )
Add these lines to /etc/lighttpd/lighttpd.conf to point to the new document root, and set it up to listen on port 443:
simple-vhost.server-root = "/var/www/domains/" simple-vhost.default-host = "/" simple-vhost.document-root = "www/
$SERVER["socket"] == "[ip_address_of_server]" { ssl.engine = "enable" ssl.pemfile = "/etc/lighttpd/server-bundle.pem" ssl.ca-file = "/etc/lighttpd/ca-crt.pem" }
Get a web certificate, and install it. If you want to use a self-signed cert, you can use Generating SSL certs with ACF or Generating SSL certs with ACF 1.9. If you create a certificate with ACF, you can create the "server-bundle.pem" and the "ca-crt.pem" file with these commands:
openssl x509 -nocerts -nokeys -cacert -in certificate.pfx -out /etc/lighttpd/ca-crt.pem openssl x509 -nodes -in certifcate.pfx -out /etc/lighttpd/server-bundle.pem chown root:root /etc/lighttpd/server-bundle.pem chmod 400 /etc/lighttpd/server-bundle.pem
Note: The server certifcate and key are in the server-bundle.pem file, so it is critical that the file be read-only by user "root".
Stop and remove mini_httpd; start lighttpd, test
/etc/init.d/mini_httpd stop rc-update del mini_httpd apk del mini_httpd rc-update add lighttpd /etc/init.d/lighttpd start
At this point you should be able to see ACF being served with lighttpd: https://host.example.com/
Install Postgresql
Add get and configure postgresql
apk add acf-postgresql postgresql-client /etc/init.d/postgresql setup /etc/init.d/postgresql start rc-update add postgresql
At this point any user can connect to the sql server with "trust" mechanism. If you want to enforce password authentication (you probably do) edit /var/lib/postgresql/8.4/data/pg_hba.conf
Editme: What should we recommend?
Create the postfix database:
psql -U postgres create user postfix with password '******'; create database postfix owner postfix; \c postfix create language plpgsql; \q
(Of course, use your selected password where ******* is shown above.)
Install PostfixAdmin
We are going to install the postfix admin web front-end before we install the mail server. This just creates an interface to populate the SQL tables that postfix and dovecot will use.
Download PostfixAdmin from Sourceforge. When these instructions were written, 2.3 was the current release, so:
wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz tar zxvf postfixadmin_2.3.tar.gz mkdir /var/www/domains/host.example.com/postfixadmin mv postfixadmin-2.3/* /var/www/domains/host.example.com/postfixadmin rm -rf postfixadmin*
Edit /var/www/domains/host.example.com/postfixadmin/config.inc.php and modify at least these lines:
$CONF['configured'] = true; $CONF['setup_password'] = ; << Don't change this yet $CONF['database_type'] = 'pgsql'; $CONF['database_host'] = 'localhost'; $CONF['database_user'] = 'postfix'; $CONF['database_password'] = '*****'; << The password you chose above $CONF['database_name'] = 'postfix'; $CONF['database_prefix'] = ; $CONF['database_prefix'] = ; $CONF['database_tables'] = array ( $CONF['admin_email'] = 'you@some.email.com'; << Your email address $CONF['encrypt'] = 'md5crypt'; $CONF['authlib_default_flavor'] = 'md5raw'; $CONF['dovecotpw'] = "/usr/sbin/dovecotpw"; $CONF['domain_path'] = 'YES'; $CONF['domain_in_mailbox'] = 'NO'; $CONF['aliases'] = '10'; $CONF['mailboxes'] = '10'; $CONF['maxquota'] = '10'; $CONF['quota'] = 'YES'; $CONF['quota_multiplier'] = '1024000'; $CONF['alias_control'] = 'YES'; $CONF['alias_control_admin'] = 'YES'; $CONF['special_alias_control'] = 'YES'; $CONF['fetchmail'] = 'NO'; $CONF['user_footer_link'] = "http://host.example.com"; $CONF['footer_link'] = 'http://host.example.com/postfixadmin/main.php'; $CONF['create_mailbox_subdirs_prefix']='INBOX.'; $CONF['used_quotas'] = 'YES'; $CONF['new_quota_table'] = 'YES';
Go to http://host.example.com/postfixadmin/setup.php
Create the password hash, add it to the config.inc.php file
Go back to http://host.example.com/postfixadmin/setup.php
Create superadmin, create a mail domain or other, as desired.
Install Postfix
Create a user for the virtual mail delivery, and get its uid/gid (you'll need the numeric uid/gid for postfix)
adduser vmail -H -D -s /bin/false grep vmail /etc/passwd
(In examples below, we use 1006/1006 for the uid/gid)
Create the mail directory, and assign vmail as the owner
mkdir -p /var/mail/domains chown -R vmail:vmail /var/mail/domains
Install postfix
apk add acf-postfix postfix-pgsql
Edit the /etc/postfix/main.cf file Here's an example:
myhostname=host.example.com mydomain=example.com mydestination = $myhostname, localhost.$mydomains, localhost mynetworks_style = subnet mynetworks = 127.0.0.0/8 virtual_mailbox_domains = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_domains_maps.cf virtual_alias_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_maps.cf, proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_maps.cf, proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_catchall_maps.cf virtual_mailbox_maps = proxy:pgsql:/etc/postfix/sql/pgsql_virtual_mailbox_maps.cf, proxy:pgsql:/etc/postfix/sql/pgsql_virtual_alias_domain_mailbox_maps.cf virtual_mailbox_base = /var/mail/domains/ virtual_gid_maps = static:1006 virtual_uid_maps = static:1006 virtual_minimum_uid = 100 virtual_transport = virtual
# This next command means you must create a virtual # domain for the host itself - ALL mail goes through # The virtual transport
mailbox_transport = virtual local_transport = virtual local_transport_maps = $virtual_mailbox_maps
smtpd_helo_required = yes disable_vrfy_command = yes message_size_limit = 10240000 queue_minfree = 51200000 smtpd_sender_restrictions = permit_mynetworks, reject_non_fqdn_sender, reject_unknown_sender_domain smtpd_recipient_restrictions = reject_non_fqdn_recipient, reject_unknown_recipient_domain, permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_rbl_client dnsbl.sorbs.net, reject_rbl_client zen.spamhaus.org, reject_rbl_client bl.spamcop.net smtpd_data_restrictions = reject_unauth_pipelining
# we will use this later - This prevents cleartext authentication # for relaying smtpd_tls_auth_only = yes
Now we need to create a *bunch* of files so that postfix can get the delivery information out of sql. Here's a shell script to create the scripts.
cd /etc/postfix mkdir sql PGPW="ChangeMe"
cat - <<EOF >sql/pgsql_virtual_alias_domain_catchall_maps.cf
user=postfix password = $PGPW hosts = localhost dbname = postfix query = Select goto From alias,alias_domain where alias_domain.alias_domain = '%d' and alias.address = '@' || alias_domain.target_domain and alias.active = true and alias_domain.active= true EOF cat - <<EOF >sql/pgsql_virtual_alias_domain_mailbox_maps.cf user=postfix password = $PGPW hosts = localhost dbname = postfix query = Select maildir from mailbox,alias_domain where alias_domain.alias_domain = '%d' and mailbox.username = '%u' || '@' || alias_domain.target_domain and mailbox.active = true and alias_domain.active EOF cat - <<EOF >sql/pgsql_virtual_alias_domain_maps.cf user=postfix password = $PGPW hosts = localhost dbname = postfix query = select goto from alias,alias_domain where alias_domain.alias_domain='%d' and alias.address = '%u' || '@' || alias_domain.target_domain and alias.active= true and alias_domain.active= true EOF cat - <<EOF >sql/pgsql_virtual_alias_maps.cf user=postfix password = $PGPW hosts = localhost dbname = postfix query = Select goto From alias Where address='%s' and active ='1' EOF cat - <<EOF >sql/pgsql_virtual_domains_maps.cf user=postfix password = $PGPW hosts = localhost dbname = postfix query = Select domain from domain where domain='%s' and active='1' EOF cat - <<EOF >sql/pgsql_virtual_mailbox_limit_maps.cf user=postfix password = $PGPW hosts = localhost dbname = postfix query = Select quota from mailbox where username='%s' and active='1' EOF cat - <<EOF >sql/pgsql_virtual_mailbox_maps.cf user=postfix password = $PGPW hosts = localhost dbname = postfix query = Select maildir from mailbox where username='%s' and active=true EOF
Spam Filtering
Add the following line to /etc/postfix/main.cf
#content_filter = scan:[127.0.0.1]:10025
Relay for Authenticated Users
# TLS Stuff -- since we allow SASL with tls *only*, we have to set up TLS first
smtpd_tls_cert_file = /etc/lighttpd/server-bundle.pem smtpd_tls_key_file = /etc/lighttpd/server-bundle.pem smtpd_tls_CAfile = /etc/lighttpd/ca-crt.pem smtpd_tls_security_level = may # Log info about the negotiated encryption levels smtpd_tls_received_header = yes smtpd_tls_loglevel = 1 # SASL - this allows senders to authenticiate themselves # This along with "premit_sasl_authenticated" in smtpd_recipient_restrictions above allows relaying smtpd_sasl_type = dovecot smtpd_sasl_path = private/dovecot-auth.sock smtpd_sasl_auth_enable = yes smtpd_sasl_authenticated_header = yes smtpd_tls_auth_only = yes