GithubHelp home page GithubHelp logo

hardware / mailserver Goto Github PK

View Code? Open in Web Editor NEW
1.3K 78.0 320.0 953 KB

:warning: UNMAINTAINED - Simple and full-featured mail server using Docker

Home Page: https://store.docker.com/community/images/hardware/mailserver

License: MIT License

Shell 83.78% Makefile 4.34% Perl 1.16% C++ 0.13% Assembly 0.04% Python 3.10% PLpgSQL 7.11% Dockerfile 0.33% Pawn 0.02%
docker mailserver postfix dovecot clamav sieve fetchmail dkim dmarc debian

mailserver's Introduction

⚠️

This docker image is no longer maintained.

⚠️

hardware/mailserver

Chat & questions

Build

Docker image

hardware/mailserver is a simple and full-featured mail server build as a set of multiple docker images, including:

  • Postfix : a full-set smtp email server
  • Dovecot : secure IMAP and POP3 email server
  • Rspamd : anti-spam filter with SPF, DKIM, DMARC, ARC, ratelimit and greylisting capabilities
  • Clamav : antivirus with automatic updates and third-party signature databases
  • Zeyple : automatic GPG encryption of all your emails
  • Sieve : email filtering (vacation auto-responder, auto-forward, etc...)
  • Fetchmail : fetch emails from external IMAP/POP3 server into local mailbox
  • Rainloop : web based email client
  • Postfixadmin : web-based administration interface
  • Unbound: recursive caching DNS resolver with DNSSEC support
  • NSD : authoritative DNS server with DNSSEC support
  • Træfik : modern HTTP reverse proxy
  • SSL : let's encrypt with auto-renewal (SAN and wildcard certificates), custom and self-signed certificates support
  • OpenLDAP : [BETA] ldap support available (only in 1.1-latest for now)
  • Supporting multiple virtual domains over MySQL/PostgreSQL backend
  • Integration tests with Travis CI
  • Automated builds on DockerHub

Summary

System Requirements

Please check, if your system meets the following minimum requirements :

With MariaDB/PostgreSQL and Redis on the same host

Type Without ClamAV With ClamAV
CPU 1 GHz 1 GHz
RAM 1.5 GiB 2 GiB

With MariaDB/PostgreSQL and Redis hosted on another server

Type Without ClamAV With ClamAV
CPU 1 GHz 1 GHz
RAM 512 MiB 1 GiB

Back to table of contents 🔼

Prerequisites

Cleaning

Please remove any web server and mail services running on your server. I recommend using a clean installation of your prefered distro. If you are using Debian, remember to remove the default MTA Exim4 :

# apt-get purge exim4*

Also make sure that no other application is interfering with mail server configuration :

# netstat -tulpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190'

If this command returns any results please remove or stop the application running on that port.

Ports

If you have a firewall, unblock the following ports, according to your needs :

Service Software Protocol Port
SMTP Postfix TCP 25
HTTP Nginx TCP 80
POP3 Dovecot TCP 110
IMAP Dovecot TCP 143
HTTPS Nginx TCP 443
SMTPS Postfix TCP 465
Submission Postfix TCP 587
IMAPS Dovecot TCP 993
POP3S Dovecot TCP 995
ManageSieve Dovecot TCP 4190

DNS setup

I recommend you to use hardware/nsd-dnssec as an authoritative name server with DNSSEC capabilities. NSD is an authoritative only, high performance, simple and open source name server.

DNS records and reverse PTR

A correct DNS setup is required, this step is very important.

HOSTNAME CLASS TYPE PRIORITY VALUE
mail IN A/AAAA any 1.2.3.4
spam IN CNAME any mail.domain.tld.
webmail IN CNAME any mail.domain.tld.
postfixadmin IN CNAME any mail.domain.tld.
@ IN MX 10 mail.domain.tld.
@ IN TXT any "v=spf1 a mx ip4:SERVER_IPV4 ~all"
mail._domainkey IN TXT any "v=DKIM1; k=rsa; p=YOUR DKIM Public Key"
_dmarc IN TXT any "v=DMARC1; p=reject; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=0; adkim=s; aspf=s; pct=100; rf=afrf; sp=reject"

Notes:

  • Make sure that the PTR record of your IP matches the FQDN (default : mail.domain.tld) of your mailserver host. This record is usually set in your web hosting interface.
  • DKIM, SPF and DMARC records are recommended to build a good reputation score.
  • The DKIM public key will be available on host after the container startup :
/mnt/docker/mail/dkim/domain.tld/public.key

To regenerate your public and private keys, remove the /mnt/docker/mail/dkim/domain.tld folder. By default a 1024-bit key is generated, you can increase this size by setting the OPENDKIM_KEY_LENGTH environment variable with a higher value. Check your domain registrar support to verify that it supports a TXT record long enough for a key larger than 1024 bits.

These DNS record will raise your trust reputation score and reduce abuse of your domain name. You can find more information here :

Testing

You can audit your mailserver with the following assessment services :

Back to table of contents 🔼

Installation

1 - Prepare your environment

💡 The reverse proxy used in this setup is Traefik, but you can use the solution of your choice (Nginx, Apache, Haproxy, Caddy, H2O...etc).

⚠️ This docker image may not work with some hardened Linux distribution using security-enhancing kernel patches like GrSecurity, please use a supported platform.

# Create a new docker network for Traefik (IPv4 only)
docker network create http_network
# If you want to support IPv6, please refer to [IPv6 support]

# Create the required folders and files
mkdir -p /mnt/docker/traefik/acme && cd /mnt/docker \
&& curl https://raw.githubusercontent.com/hardware/mailserver/master/docker-compose.sample.yml -o docker-compose.yml \
&& curl https://raw.githubusercontent.com/hardware/mailserver/master/sample.env -o .env \
&& curl https://raw.githubusercontent.com/hardware/mailserver/master/traefik.sample.toml -o traefik/traefik.toml \
&& touch traefik/acme/acme.json \
&& chmod 600 docker-compose.yml .env traefik/traefik.toml traefik/acme/acme.json

Edit the .env and traefik.toml, adapt to your needs, then start all services :

docker-compose up -d

2 - Postfixadmin installation

PostfixAdmin is a web based interface used to manage mailboxes, virtual domains and aliases.

3 - Rainloop installation (optional)

Rainloop is a simple, modern and fast webmail with Sieve scripts support (filters and vacation message), GPG and a modern user interface.

4 - Done, congratulation ! 🎉

At first launch, the container takes few minutes to generate SSL certificates (if needed), DKIM keypair and update clamav database, all of this takes some time (1/2 minutes). This image comes with a snake-oil self-signed certificate, please use your own trusted certificates. See below for configuration.

List of webservices available:

Service URI
Traefik dashboard https://mail.domain.tld/
Rspamd dashboard https://spam.domain.tld/
Administration https://postfixadmin.domain.tld/
Webmail https://webmail.domain.tld/

Traefik dashboard use a basic authentication (user:admin, password:12345), the password can be encoded in MD5, SHA1 and BCrypt. You can use htpasswd to generate those ones. Users can be specified directly in the traefik.toml file. Rspamd dashboard use the password defined in your docker-compose.yml.

You can check the startup logs with this command :

# docker logs -f mailserver

[INFO] Let's encrypt live directory found
[INFO] Using /etc/letsencrypt/live/mail.domain.tld folder
[INFO] Creating DKIM keys for domain domain.tld
[INFO] Database hostname found in /etc/hosts
[INFO] Fetchmail forwarding is enabled.
[INFO] Automatic GPG encryption is enabled.
[INFO] ManageSieve protocol is enabled.
[INFO] POP3 protocol is enabled.
-------------------------------------------------------------------------------------
2017-08-26T11:06:58.885562+00:00 mail root: s6-supervise : spawning clamd process
2017-08-26T11:06:59.059077+00:00 mail root: s6-supervise : spawning freshclam process
2017-08-26T11:06:59.395214+00:00 mail root: s6-supervise : spawning rspamd process
2017-08-26T11:07:01.615597+00:00 mail root: s6-supervise : spawning unbound process
2017-08-26T11:07:01.870856+00:00 mail root: s6-supervise : spawning postfix process
2017-08-26T11:07:03.303536+00:00 mail root: s6-supervise : spawning dovecot process
...

Back to table of contents 🔼

Rancher Catalog

rancher-logo

https://github.com/hardware/mailserver-rancher

This catalog provides a basic template to easily deploy an email server based on hardware/mailserver very quickly. To use it, just add this repository to your Rancher system as a catalog in Admin > Settings page and follow the readme. This catalog has been initiated by @MichelDiz.

rancher-ui

Back to table of contents 🔼

Ansible Playbooks

logo

If you use Ansible, I recommend you to go to see @ksylvan playbooks here : https://github.com/ksylvan/docker-mail-server

Back to table of contents 🔼

Environment variables

Variable Description Type Default value
VMAILUID vmail user id optional 1024
VMAILGID vmail group id optional 1024
VMAIL_SUBDIR Individual mailbox' subdirectory optional mail
OPENDKIM_KEY_LENGTH Size of your DKIM RSA key pair optional 1024
DEBUG_MODE Enable Postfix, Dovecot, Rspamd and Unbound verbose logging optional false
PASSWORD_SCHEME Passwords encryption scheme optional SHA512-CRYPT
DBDRIVER Database type: mysql, pgsql, ldap optional mysql
DBHOST Database instance ip/hostname optional mariadb
DBPORT Database instance port optional 3306 / 389 (sql/ldap)
DBUSER Database username optional postfix
DBNAME Database name optional postfix
DBPASS Database password or location of a file containing it required *1) null
REDIS_HOST Redis instance ip/hostname optional redis
REDIS_PORT Redis instance port optional 6379
REDIS_PASS Redis database password or location of a file containing it optional null
REDIS_NUMB Redis database number optional 0
RSPAMD_PASSWORD Rspamd WebUI and controller password or location of a file containing it required null
ADD_DOMAINS Add additional domains to the mailserver separated by commas (needed for dkim keys etc.) optional null
RELAY_NETWORKS Additional IPs or networks the mailserver relays without authentication optional null
WHITELIST_SPAM_ADDRESSES List of whitelisted email addresses separated by commas optional null
DISABLE_RSPAMD_MODULE List of disabled modules separated by commas optional null
DISABLE_CLAMAV Disable virus scanning optional false
DISABLE_SIEVE Disable ManageSieve protocol optional false
DISABLE_SIGNING Disable DKIM/ARC signing optional false
DISABLE_GREYLISTING Disable greylisting policy optional false
DISABLE_RATELIMITING Disable ratelimiting policy optional true
DISABLE_DNS_RESOLVER Disable the local DNS resolver optional false
DISABLE_SSL_WATCH Disable watching of acme.json and the Let's Encrypt directory optional false
ENABLE_POP3 Enable POP3 protocol optional false
ENABLE_FETCHMAIL Enable fetchmail forwarding optional false
ENABLE_ENCRYPTION Enable automatic GPG encryption optional false
FETCHMAIL_INTERVAL Fetchmail polling interval optional 10
RECIPIENT_DELIMITER RFC 5233 subaddress extension separator (single character only) optional +

*1) DBPASS is NOT required when using LDAP authentication

  • Use DEBUG_MODE to enable the debug mode. Switch to true to enable verbose logging for postfix, dovecot, rspamd and Unbound. To debug components separately, use this syntax : DEBUG_MODE=postfix,rspamd.
  • VMAIL_SUBDIR is the mail location subdirectory name /var/mail/vhosts/%domain/%user/$subdir. For more information, read this : https://wiki.dovecot.org/VirtualUsers/Home
  • PASSWORD_SCHEME for compatible schemes, read this : https://wiki.dovecot.org/Authentication/PasswordSchemes
  • Currently, only a single RECIPIENT_DELIMITER is supported. Support for multiple delimiters will arrive with Dovecot v2.3.
  • FETCHMAIL_INTERVAL must be a number between 1 and 59 minutes.
  • Use DISABLE_DNS_RESOLVER if you have some DNS troubles and DNSSEC lookup issues with the local DNS resolver.
  • Use DISABLE_RSPAMD_MODULE to disable any module listed here : https://rspamd.com/doc/modules/

When using LDAP authentication the following additional variables become available. All DBUSER, DBNAME and DBPASS variables will not be used in this case:

Variable Description Type Default value
LDAP_TLS_ENABLED Enable TLS on LDAP optional false
LDAP_TLS_CA_FILE The TLS CA File required if LDAP_TLS_ENABLED
LDAP_TLS_FORCE Force TLS connections required if LDAP_TLS_ENABLED false
LDAP_BIND Bind to LDAP Server optional true
LDAP_BIND_DN The DN to bind to required if LDAP_BIND
LDAP_BIND_PW LDAP password or location of a file containing it required if LDAP_BIND
LDAP_DEFAULT_SEARCH_BASE The base DN for all lookus required
LDAP_DEFAULT_SEARCH_SCOPE The default scope for all lookups (sub, base or one) optional sub
LDAP_DOMAIN_SEARCH_BASE The search base for domain lookups optional ${LDAP_DEFAULT_SEARCH_BASE}
LDAP_DOMAIN_SEARCH_SCOPE The search scope for domain lookups optional ${LDAP_DEFAULT_SEARCH_SCOPE}
LDAP_DOMAIN_FILTER The search filter for domain lookups required
LDAP_DOMAIN_ATTRIBUTE The attibutes for domain lookup required
LDAP_DOMAIN_FORMAT The format for domain lookups optional
LDAP_MAILBOX_SEARCH_BASE The search base for mailbox lookups optional ${LDAP_DEFAULT_SEARCH_BASE}
LDAP_MAILBOX_SEARCH_SCOPE The search scope for mailbox lookups optional ${LDAP_DEFAULT_SEARCH_SCOPE}
LDAP_MAILBOX_FILTER The search filter for mailbox lookups required
LDAP_MAILBOX_ATTRIBUTE The attibutes for mailbox lookup required
LDAP_MAILBOX_FORMAT The format for domain mailbox optional
LDAP_ALIAS_SEARCH_BASE The search base for domain lookups optional ${LDAP_DEFAULT_SEARCH_BASE}
LDAP_ALIAS_SEARCH_SCOPE The search scope for domain lookups optional ${LDAP_DEFAULT_SEARCH_SCOPE}
LDAP_ALIAS_FILTER The search filter for domain lookups required
LDAP_ALIAS_ATTRIBUTE The attibutes for domain lookup required
LDAP_ALIAS_FORMAT The format for domain lookups optional
LDAP_FORWARD_SEARCH_BASE The search base for forward lookups optional ${LDAP_DEFAULT_SEARCH_BASE}
LDAP_FORWARD_SEARCH_SCOPE The search scope for forward lookups optional ${LDAP_DEFAULT_SEARCH_SCOPE}
LDAP_FORWARD_FILTER The search filter for forward lookups optional
LDAP_FORWARD_ATTRIBUTE The attibutes for forward lookup optional
LDAP_FORWARD_FORMAT The format for forward lookups optional
LDAP_GROUP_SEARCH_BASE The search base for group lookups optional ${LDAP_DEFAULT_SEARCH_BASE}
LDAP_GROUP_SEARCH_SCOPE The search scope for group lookups optional ${LDAP_DEFAULT_SEARCH_SCOPE}
LDAP_GROUP_FILTER The search filter for group lookups optional
LDAP_GROUP_ATTRIBUTE The attibutes for group lookup optional
LDAP_GROUP_FORMAT The format for group lookups optional
LDAP_SENDER_SEARCH_BASE The search base for sender lookups optional ${LDAP_DEFAULT_SEARCH_BASE}
LDAP_SENDER_SEARCH_SCOPE The search scope for sender lookups optional ${LDAP_DEFAULT_SEARCH_SCOPE}
LDAP_SENDER_FILTER The search filter for sender lookups required
LDAP_SENDER_ATTRIBUTE The attibutes for sender lookup required
LDAP_SENDER_FORMAT The format for sender lookups required
LDAP_DOVECOT_USER_ATTRS Dovecot user attribute mapping required
LDAP_DOVECOT_USER_FILTER Dovecot user search filter required
LDAP_DOVECOT_PASS_ATTRS Dovecot user password attribute mapping required
LDAP_DOVECOT_PASS_FILTER Dovecot user password filter required
LDAP_DOVECOT_ITERATE_ATTRS Dovecot user iterate attributes optional
LDAP_DOVECOT_ITERATE_FILTER Dovecot user iterate filters optional
LDAP_MASTER_USER_ENABLED Enable LDAP master users optional false
LDAP_MASTER_USER_SEPARATOR LDAP master user seperator required if LDAP_MASTER_USER_ENABLED *
LDAP_MASTER_USER_SEARCH_BASE LDAP master user search base required if LDAP_MASTER_USER_ENABLED ${LDAP_DEFAULT_SEARCH_BASE}
LDAP_MASTER_USER_SEARCH_SCOPE LDAP master user scope required if LDAP_MASTER_USER_ENABLED ${LDAP_DEFAULT_SEARCH_SCOPE}
LDAP_DOVECOT_MASTER_USER_ATTRS LDAP master user dovecot attributes required if LDAP_MASTER_USER_ENABLED
LDAP_DOVECOT_MASTER_USER_FILTER LDAP master user dovecot search filter required if LDAP_MASTER_USER_ENABLED

Back to table of contents 🔼

Automatic GPG encryption of all your emails

How does it work ?

Zeyple catches email from the postfix queue, then encrypts it if a corresponding recipient's GPG public key is found. Finally, it puts it back into the queue.

zeyple

Enable automatic GPG encryption

Please enable this option carefully and only if you know what you are doing.

Switch ENABLE_ENCRYPTION environment variable to true. The public keyring will be saved in /var/mail/zeyple/keys. Please don't change the default value of RECIPIENT_DELIMITER (default = "+"). If encryption is enabled with another delimiter, Zeyple could have an unpredictable behavior.

Import your public key

⚠️ Make sure to send your public key on a gpg keyserver before to run the following command.

docker exec -ti mailserver encryption.sh import-key YOUR_KEY_ID

Import all recipients public keys

This command browses all /var/mail/vhosts/* domains directories and users subdirectories to find all the recipients addresses in the mailserver.

docker exec -ti mailserver encryption.sh import-all-keys

Specify another gpg keyserver

docker exec -ti mailserver encryption.sh import-key YOUR_KEY_ID hkp://pgp.mit.edu
docker exec -ti mailserver encryption.sh import-all-keys hkp://keys.gnupg.net

Run other GPG options

You can use all options of gpg command line except an already assigned parameter called --homedir.

docker exec -ti mailserver encryption.sh --list-keys
docker exec -ti mailserver encryption.sh --fingerprint
docker exec -ti mailserver encryption.sh --refresh-keys
docker exec -ti mailserver encryption.sh ...

Documentation : https://www.gnupg.org/documentation/manuals/gnupg/Operational-GPG-Commands.html

Back to table of contents 🔼

Relaying from other networks

The RELAY_NETWORKS is a space separated list of additional IP addresses and subnets (in CIDR notation) which the mailserver relays without authentication. Hostnames are possible, but generally disadvised. IPv6 addresses must be surrounded by square brackets. You can also specify an absolut path to a file with IPs and networks so you can keep it on a mounted volume. Note that the file is not monitored for changes.

You can use this variable to allow other local containers to relay via the mailserver. Typically you would set this to the IP range of the default docker bridge (172.17.0.0/16) or the default network of your compose. If you are unable to determine, you might just add all RFC 1918 addresses 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8

⚠️ A value like 0.0.0.0/0 will turn your mailserver into an open relay!

Back to table of contents 🔼

SSL certificates

Let's Encrypt certificates generated by Traefik

To use Let's Encrypt certificates generated by Traefik, mount a new docker volume like this :

mailserver:
  image: hardware/mailserver
  volumes:
    - /mnt/docker/traefik/acme:/etc/letsencrypt/acme
    ...

The startup script read the acme.json* file generated by Traefik and split into pem files all appropriate certificates (CN = mail.domain.tld).

💡 *Compatible with both Traefik >=1.5.0 and 1.6+ ACME json format, with SAN and wildcard certificates support.

docker logs -f mailserver

[INFO] Search for SSL certificates generated by Traefik
[INFO] acme.json found with ACME v2 format, dumping into pem files
[INFO] Let's encrypt live directory found
[INFO] Using /etc/letsencrypt/live/mail.domain.tld folder

Don't forget to add a new traefik frontend rule somewhere in your docker-compose.yml to generate a certificate for your mailserver FQDN (default : mail.domain.tld) subdomain.

# docker-compose.yml

labels:
  - traefik.frontend.rule=Host:mail.${DOMAIN}

Alternatively, you can specify your domains in the traefik.toml to generate a SAN certificate :

[acme]
onHostRule = false

[[acme.domains]]
main = "domain.tld"
sans = ["mail.domain.tld", "spam.domain.tld", "postfixadmin.domain.tld", "webmail.domain.tld"]

Or a wildcard certificate :

⚠️ ACME wildcard certificates can only be generated thanks to a DNS-01 challenge.

[acme]
onHostRule = false

# https://docs.traefik.io/v1.6/configuration/acme/#dnschallenge
[acme.dnsChallenge]
provider = "your_dns_provider"
delayBeforeCheck = 0

[[acme.domains]]
main = "*.domain.tld"

If the startup script does not find the appropriate SSL certificate and private key, look at Traefik's logs to see what's going on.

docker logs -f mailserver

[INFO] Search for SSL certificates generated by Traefik
[INFO] ...
[INFO] ...
[INFO] acme.json found with ACME v2 format, dumping into pem files
[ERROR] The certificate for mail.domain.tld or the private key was not found !
[INFO] Don't forget to add a new traefik frontend rule to generate a certificate for mail.domain.tld subdomain
[INFO] Look /mnt/docker/traefik/acme/dump.log and 'docker logs traefik' for more information
# traefik.toml

[acme]
acmeLogging = true
docker-compose restart traefik && docker logs -f traefik

Custom certificates

You can use Let's Encrypt or any other certification authority. Setup your docker-compose.yml like this :

mailserver:
  image: hardware/mailserver
  volumes:
    - /mnt/docker/ssl:/etc/letsencrypt
    ...

Request your certificates in /mnt/docker/ssl/live/mail.domain.tld with an ACME client if you use Let's Encrypt, otherwise get your SSL certificates with the method provided by your CA and put everything needed in this directory.

Required files in this folder :

💡 If you only have the fullchain.pem and privkey.pem, the startup script extract automatically the cert.pem and chain.pem from fullchain.pem.

Filename Description
privkey.pem Private key for the certificate
cert.pem Server certificate only
chain.pem Root and intermediate certificates only, excluding server certificate
fullchain.pem All certificates, including server certificate. This is concatenation of cert.pem and chain.pem

Example with acme.sh :

acme.sh --install-cert -d example.com \
--ca-file        ${VOLUMES_ROOT_PATH}/ssl/live/mail.domain.tld/chain.pem  \
--cert-file      ${VOLUMES_ROOT_PATH}/ssl/live/mail.domain.tld/cert.pem  \
--key-file       ${VOLUMES_ROOT_PATH}/ssl/live/mail.domain.tld/privkey.pem  \
--fullchain-file ${VOLUMES_ROOT_PATH}/ssl/live/mail.domain.tld/fullchain.pem \
--reloadcmd      "docker restart mailserver"

Notes :

  • Important : When renewing certificates, you must restart the mailserver container.

  • If you do not use your own trusted certificates or those generated by Traefik, a default self-signed certificate (RSA 4096 bits SHA2) is added here : /mnt/docker/mail/ssl/selfsigned/{cert.pem, privkey.pem}.

  • If you have generated a ECDSA certificate with a curve other than prime256v1 (NIST P-256), you need to change the Postfix TLS configuration because of a change in OpenSSL >= 1.1.0. For example, if you use secp384r1 elliptic curve with your ECDSA certificate, change the tls_eecdh_strong_curve value :

# /mnt/docker/mail/postfix/custom.conf

tls_eecdh_strong_curve = secp384r1

Additional informations about this issue :

Testing

# IMAP STARTTLS - 143 port (IMAP)
openssl s_client -connect mail.domain.tld:143 -starttls imap -tlsextdebug

# SMTP STARTTLS - 587 port (Submission)
openssl s_client -connect mail.domain.tld:587 -starttls smtp -tlsextdebug

# IMAP SSL/TLS - 993 port (IMAPS)
openssl s_client -connect mail.domain.tld:993 -tlsextdebug

Back to table of contents 🔼

MTA-STS

MTA-STS is a new standard that makes it possible to send downgrade-resistant email over SMTP. In that sense, it is like an alternative to DANE but it does this by piggybacking on the browser Certificate Authority model, not DNSSEC.

To enable Strict Transport Security on your mailserver configure the following things :

  1. Add a TLSRPT DNS TXT record at _smtp._tls on your domain, e.g. _smtp._tls.domain.tld, with something like v=TLSRPTv1; rua=mailto:[email protected].
  2. Add a MTA-STS DNS TXT record at _mta-sts on your domain, e.g. _mta-sts.domain.tld, with something like v=STSv1; id=2018072801.
  3. Add a subdomain mta-sts to your domain (note the lack of an underscore) and serve a policy file on https://mta-sts.domain.tld/.well-known/mta-sts.txt.

Here is an example policy file:

version: STSv1
mode: enforce
max_age: 10368000
mx: mail.domain.tld

Test your mail domain using a MTA-STS validator like Hardenize. You can also add your domain name in the STARTTLS Policy List maintained by EFF.

Back to table of contents 🔼

Third-party clamav signature databases

Clamav-unofficial-sigs provides a simple way to download and update third-party signature databases provided by Sanesecurity, FOXHOLE, OITC, Scamnailer, BOFHLAND, CRDF, Porcupine, Securiteinfo, MalwarePatrol, Yara-Rules Project, etc.

Readme : https://github.com/extremeshok/clamav-unofficial-sigs

Required Ports

Software Protocol Port
Rsync TCP 873
Curl TCP 443

Enable clamav-unofficial-sigs

Create your user.conf file under /mnt/docker/mail/clamav-unofficial-sigs directory to configure clamav-unofficial-sigs updater. This file override the default configuration specified in os.conf and master.conf. Don't forget, once you have completed the configuration of this file, set the value of user_configuration_complete to yes otherwise the script will not be able to execute. As Yara rules are broken with clamav ≥ 0.100, we disable Yara rules for now.

# /mnt/docker/mail/clamav-unofficial-sigs/user.conf

# =========================
# MalwarePatrol : https://www.malwarepatrol.net
# MalwarePatrol 2016 (free) clamav signatures
#
# 1. Sign up for an account : https://www.malwarepatrol.net/signup-free.shtml
# 2. You will receive an email containing your password/receipt number
# 3. Login to your account at malwarePatrol
# 4. In My Accountpage, choose the ClamAV list you will download. Free subscribers only get ClamAV Basic, commercial subscribers have access to ClamAV Extended. Do not use the agressive lists.
# 5. In the download URL, you will see 3 parameters: receipt, product and list, enter them in the variables below.
# malwarepatrol_receipt_code="YOUR-RECEIPT-NUMBER"
# malwarepatrol_product_code="8"
# malwarepatrol_list="clamav_basic"
# malwarepatrol_free="yes"

# =========================
# SecuriteInfo : https://www.SecuriteInfo.com
# SecuriteInfo 2015 free clamav signatures
#
# Usage of SecuriteInfo 2015 free clamav signatures : https://www.securiteinfo.com
# - 1. Sign up for a free account : https://www.securiteinfo.com/clients/customers/signup
# - 2. You will receive an email to activate your account and then a followup email with your login name
# - 3. Login and navigate to your customer account : https://www.securiteinfo.com/clients/customers/account
# - 4. Click on the Setup tab
# - 5. You will need to get your unique identifier from one of the download links, they are individual for every user
# - 5.1. The 128 character string is after the http://www.securiteinfo.com/get/signatures/
# - 5.2. Example https://www.securiteinfo.com/get/signatures/your_unique_and_very_long_random_string_of_characters/securiteinfo.hdb
#   Your 128 character authorisation signature would be : your_unique_and_very_long_random_string_of_characters
# - 6. Enter the authorisation signature into the config securiteinfo_authorisation_signature: replacing YOUR-SIGNATURE-NUMBER with your authorisation signature from the link
# securiteinfo_authorisation_signature="YOUR-SIGNATURE-NUMBER"

# We disable Yara rules for now because they are broken with clamav releases > 0.100
yararulesproject_enabled="no"
enable_yararules="no"

# After you have completed the configuration of this file, set the value to "yes"
user_configuration_complete="yes"

If the startup script detects this file, clamav-unofficial-sigs is automatically enabled and third-party databases downloaded under /mnt/docker/mail/clamav after clamav startup. Once the databases are downloaded, a SIGUSR2 signal is sent to clamav to reload the signature databases :

docker logs -f mailserver

[INFO] clamav-unofficial-sigs is enabled (user configuration found)
[...]
s6-supervise : clamav unofficial signature update running
s6-supervise : virus database downloaded, spawning clamd process
[...]
s6-supervise : clamav unofficial signature update done
clamd[xxxxxx]: Reading databases from /var/lib/clamav
clamd[xxxxxx]: Database correctly reloaded (6812263 signatures)

Back to table of contents 🔼

Unbound DNS resolver

Unbound is a validating, recursive, and caching DNS resolver inside the container, you can control it with the remote server control utility.

Some examples :

# Display server status
docker exec -ti mailserver unbound-control status

# Print server statistics
docker exec -ti mailserver unbound-control stats_noreset

# Reload the server. This flushes the cache and reads the config file.
docker exec -ti mailserver unbound-control reload

Documentation : https://www.unbound.net/documentation/unbound-control.html

Back to table of contents 🔼

PostgreSQL support

PostgreSQL can be used instead of MariaDB. You have to make some changes in the original docker-compose.yml file to use this DBMS :

mailserver:
  environment:
    - DBDRIVER=pgsql
    - DBHOST=postgres
    - DBPORT=5432
  depends_on:
    - postgres

postfixadmin:
  environment:
    - DBDRIVER=pgsql
    - DBHOST=postgres
    - DBPORT=5432
  depends_on:
    - postgres

rainloop:
  depends_on:
    - postgres

# Database
# https://github.com/docker-library/postgres
# https://postgresql.org/
postgres:
  image: postgres:10.5-alpine
  container_name: postgres
  restart: ${RESTART_MODE}
  stop_signal: SIGINT                 # Fast Shutdown mode
  # Info : These variables are ignored when the volume already exists (if databases was created before).
  environment:
    - POSTGRES_DB=postfix
    - POSTGRES_USER=postfix
    - POSTGRES_PASSWORD=${DATABASE_USER_PASSWORD}
  volumes:
    - ${VOLUMES_ROOT_PATH}/pgsql/db:/var/lib/postgresql/data
  networks:
    - mail_network

Back to table of contents 🔼

LDAP support

This mailserver supports LDAP now aswell. Please keep in mind that LDAP itself is an already complicated system and using this mailserver with LDAP will require you to already have a deeper understanding on how LDAP, postfix and dovecot works. Due to the nature of LDAP there is no "default" setup you can or is suggested to be used. This means a lot of configuration is required to set this mailserver up with your LDAP system and it will definetly not work out of the box.

To enable LDAP you have to set DBDRIVER to ldap. DBHOST and DBPORT must point to the LDAP server used. DBUSER, DBNAME, DBPASS enviroment variables will not be used in this case.

If you want to use TLS set LDAP_TLS_ENABLED to true and specify a LDAP_TLS_CA_FILE. If you want to require the use of TLS set LDAP_TLS_FORCE to true.

If you want to bind to the LDAP server (default) set LDAP_BIND to true (default) and give your bind user dn (full path) as LDAP_BIND_DN and password as LDAP_BIND_PW. If a path to a existing file is given in LDAP_BIND_PW the content of the file will be used instead.

All lookups will by default use LDAP_DEFAULT_SEARCH_BASE as base and LDAP_DEFAULT_SEARCH_SCOPE as scope. But for any query a specific base and scope can be provided aswell. Valid scopes are: sub for subtree meaning all nodes below the base. one for all direct child nodes of the base and one for only the base node itself.

Unlike with postfixadmin where all tables are fixed, this mailserver is intended to work with existing ldap structures. This requires all lookups to be specified by you.

There are 4 required and 2 optional lookups for postfix that have to be provided by you. Each consists of 5 variables. The loopups are: Domain, Mailbox, Alias and Sender (all 4 required) and Forward and Group (optional). Each has the enviroment variables LDAP_XXX_SEARCH_BASE, LDAP_XXX_SEARCH_SCOPE, LDAP_XXX_FILTER, LDAP_XXX_ATTRIBUTE and LDAP_XXXN_FORMAT (optional) where XXX* must be replaced with DOMAIN, MAILBOX, ALIAS, SENDER, FORWARD or GROUP. E.g. LDAP_DOMAIN_SEARCH_BASE or LDAP_MAILBOX_FILTER

The LDAP_XXX_SEARCH_BASE is the search base dn. It will default to LDAP_DEFAULT_SEARCH_BASE as LDAP_XXX_SEARCH_SCOPE will default to LDAP_DEFAULT_SEARCH_SCOPE (which defaults to sub).

The LDAP_XXX_FILTER must be a valid LDAP query filter. For a documentation of LDAP query filters you can look at https://ldap.com/ldap-filters/. For a list of valid replacement tokens please look at http://www.postfix.org/ldap_table.5.html in the section query_filter. Some examples:

LDAP_DOMAIN_FILTER="(&(mail=*@%s)(objectClass=mailAccount))"

LDAP_MAILBOX_FILTER="(&(mail=%s)(objectClass=mailAccount))"

LDAP_SENDER_FILTER="(&(|(mail=%s)(mailalias=%s))(objectClass=mailAccount))"

The LDAP_XXX_ATTRIBUTE specifies which attribute of the found LDAP objects will be used. Usually these are either mail, uid, mailalias or mailacceptinggeneralid but may be completly different ones depending on your LDAP setup.

LDAP_XXX_FORMAT can be used to reformat the result. E.g. you can use LDAP_MAILBOX_FORMAT="/var/mail/vhosts/%d/%s/mail/" to set a fixed path for the mailbox location if the path is not stored within LDAP.

The optional FORWARD and GROUP lookups are technically identical to the ALIAS lookup and could be used interchangeably but are intended for additional alias/group/forward lookups. So you can use aliases using an alias field in your user objects. Forwards as source and destination mapping fields in forwarding objects and group address and group member emails in group objects. But you can also use them in different ways to suit your system.

Then you also have to provide the lookups for dovecot. These will probably be similar to your postfix lookups but may and will differ in some cases. The variables neccessary are LDAP_DOVECOT_USER_ATTRS, LDAP_DOVECOT_USER_FILTER, LDAP_DOVECOT_PASS_ATTRS, LDAP_DOVECOT_PASS_FILTER, LDAP_DOVECOT_ITERATE_ATTRS, LDAP_DOVECOT_ITERATE_FILTER. They correspond directly to the dovecot variables of the same name. While the user and pass attributes and filters are required, the iterate attributes and filters are not. For more detailed information please look at https://wiki.dovecot.org/AuthDatabase/LDAP/Userdb. Note that multiple attribures may be required per query and must be provided in a different form than for postfix! Here are some examples:

LDAP_DOVECOT_USER_ATTRS="=home=/var/mail/vhosts/%d/%n/,=mail=maildir:/var/mail/vhosts/%d/%n/mail/,mailuserquota=quota=quota_rule=*:bytes=%\$$"
LDAP_DOVECOT_USER_FILTER="(&(mail=%u)(objectClass=mailAccount))"
LDAP_DOVECOT_PASS_ATTRS="mail=user,userPassword=password"
LDAP_DOVECOT_PASS_FILTER="(&(mail=%u)(objectClass=mailAccount))"
LDAP_DOVECOT_ITERATE_ATTRS="mail=user"
LDAP_DOVECOT_ITERATE_FILTER="(objectClass=mailAccount)"

This mailserver also supports the user of master users that are allowed to log into other users mailboxes using their own password. This can be used e.g. for shared mailboxes or external imap services that should be able to connect to all inboxes via imap while not knowing the users passwords. To enable the use of master users set LDAP_MASTER_USER_ENABLED to true. With LDAP_MASTER_USER_SEPARATOR the separator can be specified (default is *). So you can log in with the username [email protected]*[email protected] or normaluser*masteruser if you only use usernames as logins. The password then has to be the password of the master user. LDAP_MASTER_USER_SEARCH_BASE, LDAP_MASTER_USER_SEARCH_SCOPE, LDAP_DOVECOT_MASTER_USER_ATTRS and LDAP_DOVECOT_MASTER_USER_FILTER work analogous to the dovecot user lookups. For more detailed documentation please look at https://wiki.dovecot.org/Authentication/MasterUsers . Note that %u is the master user name in this case and %{login_user} can be used to get the user name of the user to be loged in.

LDAP_MASTER_USER_ENABLED=true
LDAP_DOVECOT_MASTER_PASS_ATTRS="mail=user,userPassword=password"
LDAP_DOVECOT_MASTER_PASS_FILTER="(&(mail=%u)(st=%{login_user})(objectClass=mailAccount))"

Back to table of contents 🔼

IPv6 support

If you want to support inbound IPv6 connections, you need to create a docker network with IPv6 enabled, otherwise, you may have some issues with docker internal networking.

The procedure is quite simple:

  • Remove your old http_network (if you already have created it)
docker network rm http_network
  • Choose a private ipv6 address range (/64)

  • Create a docker network with IPv6 enabled

# Replace subnet mask with your own "Combined/CID"
docker network create http_network --ipv6 --subnet "fd00:0000:0000:0000::/64"
  • Append this to your docker-compose.yml
# IPv6NAT
# https://github.com/robbertkl/docker-ipv6nat
# https://hub.docker.com/r/robbertkl/ipv6nat/
ipv6nat:
  image: robbertkl/ipv6nat
  container_name: ipv6nat
  restart: ${RESTART_MODE}
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock:ro
    - /lib/modules:/lib/modules:ro
  depends_on:
    - mailserver
  cap_add:
    - NET_ADMIN
    - SYS_MODULE
  network_mode: "host"
  • Create a record named mail of type AAAA with your public IPv6 address in your DNS provider.

Done! This is all the configuration needed to enable inbound IPv6 support on this mailserver.

You can read more on how and why robbertkl/docker-ipv6nat container mimics NAT for IPv6 on his page.

Back to table of contents 🔼

Persistent files and folders in /mnt/docker/mail Docker volume

/mnt/docker
└──mail
   ├──postfix
   |     custom.conf
   |     sender_access
   |  ├──spool (Postfix queues directory)
   │  │     defer
   │  │     flush
   │  │     hold
   │  │     maildrop
   │  │     ...
   ├──dovecot
   |     instances
   |     ssl-parameters.dat
   |  ├──conf.d (Custom dovecot configuration)
   ├──clamav (ClamAV databases directory)
   │     bytecode.cvd
   │     daily.cld
   │     main.cvd
   ├──clamav-unofficial-sigs
   │     user.conf
   ├──rspamd (Rspamd databases directory)
   │     rspamd.rrd
   |     stats.ucl
   ├──zeyple
   │  ├──keys (GPG public keyring)
   │  │     pubring.kbx
   │  │     trustdb.gpg
   │  │     ...
   ├──sieve
   │     default.sieve
   │     custom.sieve (custom default sieve rules for all users)
   ├──dkim
   │  ├──domain.tld
   │  │     private.key
   │  │     public.key
   ├──ssl
   │  ├──selfsigned (Auto-generated if no certificate found)
   │  │     cert.pem
   │  │     privkey.pem
   ├──vhosts
   │  ├──domain.tld
   │  │  ├──user
   │  │  │     .dovecot.sieve -> sieve/rainloop.user.sieve
   │  │  │     .dovecot.svbin
   │  │  │  ├──mail
   │  │  │  │  ├──.Archive
   │  │  │  │  ├──.Drafts
   │  │  │  │  ├──.Sent
   │  │  │  │  ├──.Spam
   │  │  │  │  ├──.Trash
   │  │  │  │  ├──cur
   │  │  │  │  ├──new
   │  │  │  │     ...
   │  │  │  ├──sieve
   │  │  │  │     rainloop.user.sieve (if using rainloop webmail)

Back to table of contents 🔼

Override postfix configuration

Postfix default configuration can be overrided providing a custom configuration file at postfix format. This can be used to also add configuration that are not in default configuration. Postfix documentation remains the best place to find configuration options.

Each line in the provided file will be loaded into Postfix. Create a new file here /mnt/docker/mail/postfix/custom.conf and add your custom options inside.

To edit services in master.cf configuration file, SFP prefixes are available to indicate what you want to change.

  • S| = service entry (service/type=value)
  • F| = service field (service/type/field=value)
  • P| = service parameter (service/type/parameter=value)

Example :

# /mnt/docker/mail/postfix/custom.conf

# main.cf parameters
smtpd_banner = $myhostname ESMTP MyGreatMailServer
inet_protocols = ipv4
delay_notice_recipient = [email protected]
delay_warning_time = 2h

# master.cf services
S|submission/inet=submission inet n       -       -       -       -       smtpd
P|submission/inet/syslog_name=postfix/submission-custom
P|submission/inet/smtpd_tls_security_level=may
P|submission/inet/smtpd_tls_ciphers=medium
F|smtp/unix/chroot=n
docker logs -f mailserver

[INFO] Override parameter in main.cf : smtpd_banner = $myhostname ESMTP MyGreatMailServer
[INFO] Override parameter in main.cf : inet_protocols = ipv4
[INFO] Override parameter in main.cf : delay_notice_recipient = [email protected]
[INFO] Override parameter in main.cf : delay_warning_time = 2h
[INFO] Override service entry in master.cf : submission/inet=submission inet n       -       -       -       -       smtpd
[INFO] Override service parameter in master.cf : submission/inet/syslog_name=postfix/submission-custom
[INFO] Override service parameter in master.cf : submission/inet/smtpd_tls_security_level=may
[INFO] Override service parameter in master.cf : submission/inet/smtpd_tls_ciphers=medium
[INFO] Override service field in master.cf : smtp/unix/chroot=n
[INFO] Custom Postfix configuration file loaded

Back to table of contents 🔼

Custom configuration for dovecot

Sometimes you might want to add additional configuration parameters or override the default ones. You can do so by placing configuration files to the persistent folder /mnt/docker/mail/dovecot/conf.d.

Example:

# /mnt/docker/mail/dovecot/conf.d/20-imap.conf

protocol imap {

  mail_max_userip_connections = 100

}

# /mnt/docker/mail/dovecot/conf.d/90-quota.conf

plugin {

  quota_rule2 = Trash:storage=+200M
  quota_exceeded_message = You have exceeded your mailbox quota.

}

Back to table of contents 🔼

Postfix blacklist

To block some senders or an entire domain, create a new file named sender_access in /mnt/docker/mail/postfix.

# /mnt/docker/mail/postfix/sender_access
# Format : <address|domain> <action>

domain.tld REJECT
[email protected] REJECT
docker logs -f mailserver

NOQUEUE: reject: 554 5.7.1 <[email protected]>: Sender address rejected: Access denied

Back to table of contents 🔼

Email client settings

  • IMAP/SMTP username : [email protected]
  • Incoming IMAP server : mail.domain.tld (your FQDN)
  • Outgoing SMTP server : mail.domain.tld (your FQDN)
  • IMAP port : 993
  • SMTP port : 587
  • IMAP Encryption protocol : SSL/TLS
  • SMTP Encryption protocol : STARTTLS

Back to table of contents 🔼

Components

  • Postfix 3.1.8
  • Dovecot 2.2.27
  • Rspamd 1.9.4
  • Fetchmail 6.3.26
  • ClamAV 0.100.3
  • Clamav Unofficial Sigs 5.6.2
  • Zeyple 1.2.2
  • Unbound 1.6.0
  • s6 2.8.0.1
  • Rsyslog 8.24.0
  • ManageSieve server

Back to table of contents 🔼

Migration from 1.0 to 1.1

If you still use 1.0 version (bundled with Spamassassin, Amavisd...etc) which was available with the latest tag, you can follow the migration steps here :

https://github.com/hardware/mailserver/wiki/Migrating-from-1.0-stable-to-1.1-stable

Or stay with 1.0-legacy tag (not recommended).

Back to table of contents 🔼

Community projects

Back to table of contents 🔼

Some useful Thunderbird extensions

Back to table of contents 🔼

mailserver's People

Contributors

amq avatar arckosfr avatar atomtigerzoo avatar brunocascio avatar chrootlogin avatar cweiske avatar denji avatar drmurx avatar eknapp-inst avatar fa-at-pulsit avatar gitter-badger avatar hardware avatar heliflieger avatar jodumont avatar julien1619 avatar ksylvan avatar michael-k avatar mirtouf avatar navossoc avatar nickbusey avatar peerd avatar phires avatar pjeby avatar reyiyo avatar sknight80 avatar snkisuke avatar swoga avatar thezenti avatar vizv avatar zerpex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mailserver's Issues

Invalid query: Table 'postfix.config' doesn't exist

I'm hosting the mailserver on an instance on AWS.
I've had to upgrade the instance, so I created a new image based on the mailserver instance.
After upgrading and running docker-compose up, the following error is printed out when pointing the browser to postfixadmin.mydomain.com:

Invalid query: Table 'postfix.config' doesn't exist

Im a little confused about this error, because all the files (including the databases) is present on the new instance .

Any idea of why this bug is present and how to fix it?

Impossible d'obtenir les filtres

Hello,

Petit problème depuis rainloop lorsque j'accède a la partie "filtres" le message d'erreur suivant : Impossible d'obtenir les filtres

Les filtres déclarés au préalable fonctionne bien
La configuration depuis le panel admin est bien ok

Je ne trouve pas de log pouvant m'éclaircir pour débugué

1480015082-webmail.jpg - envoi d'image avec NoelShack

postgrey doesn't start

Hi,

I would like to start the postgrey but it doesn't start. I exec the following command in docker and get error message. When I didn't set dbdir postgrey works well.

/usr/sbin/postgrey --delay=120 --inet=127.0.0.1:10023 --dbdir=/var/mail/postgrey

2016/09/25-07:22:21 postgrey (type Net::Server::Multiplex) starting! pid(707)
Binding to TCP port 10023 on host 127.0.0.1 with IPv4
Setting gid to "114 114"
Setting uid to "108"
ERROR: can't open lock file: /var/mail/postgrey/postgrey.lock

opendmarc: IgnoreMailFrom should also include all ADD_DOMAINS

/etc/opendmarc/opendmarc.conf contains the IgnoreMailFrom directive. It serves to not check and add headers to mails send from our own domain(s).

While opendkim/spamassassin etc. are configured by the startup script to include the additional domains given by the ADD_DOMAINS env variable, opendmarc is left out. The startup script should probably concatenate DOMAIN and ADD_DOMAINS and put them all into IgnoreMailFrom.

Probleme Installation

Salut,

J'ai suivi l'installation à la lettre mais l'envoi et la réception de mail de fonctionne pas :(

Le log du mailserver : https://paste.mondedie.fr/?85268daf86e77180#0ohLoIIXY6MxVDv8TXF3DJ4Bcn48mAbJtixpcEvdf8M=

Postfixadmin :
image

test IMAP SSL/TLS - 993 port (IMAPS) : https://paste.mondedie.fr/?952a69bbf8d49ae9#nRU3y/K4GUU6At7WUAbZf86sT6ShjcY7dqTCELMc/EE=

Mon DNS Record :

@                  IN MX 10  mail.mondomain.tld.
                       IN TXT    "v=spf1 a mx ip4:ipV4 ~all"
_dmarc                 IN TXT    "v=DMARC1; p=reject; rua=mailto:[email protected]; ruf=mailto:[email protected]; fo=0; adkim=s; aspf=s; pct=100; rf=afrf; sp=reject"
mail                   IN A      ipV4
mail._domainkey        IN TXT    "v=DKIM1; k=rsa;  p=makey"

postfixadmin           IN CNAME  mondomain.tld.
webmail                IN CNAME  mondomain.tld.

J'espère avoir été assez complet :D

Merci

Update container - Temporary lookup failure

Hey after I have updated my container I get this error:

Temporary lookup failure at the client.

When I want to send a mail (can not reseve also). But I can view all my mails as before...

In the console I get the message:

warning: connect to mysql server mariadb: Unknown MySQL server host 'mariadb'

but if I connect to the container and ping the db there is no problem...

My startparameters:
docker run --name=mail --link mariadb:mariadb --restart=always -p 25:25 -p 143:143 -p 465:465 -p 587:587 -p 993:993 -p 4190:4190 -e DBHOST=mariadb -e DBUSER=mailserver -e DBNAME=mailserver -e DBPASS=mypassword -e ADD_DOMAINS=mail.domain.tld -v /home/mailserver:/var/mail -v /home/mailserver/opendkim:/etc/opendkim/keys -h mail.domain.tld -d hardware/mailserver
did not changed it since first start

Any suggestions ? Thanks :)

Unknown MySQL server host 'mariadb'

I can't send or receive mails. When I check logs, I see :

2016-04-08T22:13:30.656856+02:00 mail postfix/smtpd[283]: NOQUEUE: reject: RCPT from unknown[***.***.***.***]: 451 4.3.0 <*****@bounce.twitter.com>: Temporary lookup failure; from=<******@bounce.twitter.com> to=<***@***.net> proto=ESMTP helo=<spring-chicken-af.twitter.com>

But when i look more i see that :

2016-04-08T22:13:30.562427+02:00 mail postfix/trivial-rewrite[287]: warning: connect to mysql server mariadb: Unknown MySQL server host 'mariadb' (2)
2016-04-08T22:13:30.563026+02:00 mail postfix/trivial-rewrite[287]: warning: mysql:/etc/postfix/mysql/mysql-virtual-alias-maps.cf: table lookup problem
2016-04-08T22:13:30.563156+02:00 mail postfix/trivial-rewrite[287]: warning: virtual_alias_domains lookup failure
2016-04-08T22:13:30.655698+02:00 mail postfix/trivial-rewrite[287]: warning: mysql:/etc/postfix/mysql/mysql-virtual-alias-maps.cf: table lookup problem
2016-04-08T22:13:30.656295+02:00 mail postfix/trivial-rewrite[287]: warning: virtual_alias_domains lookup failure

Infortunatly, i can't explain why :/ When i try with telnet (from mailserver container to mariadb container) it's working

root@mail:/# telnet mariadb 3306   
Trying 172.21.0.2...
Connected to mariadb.
Escape character is '^]'.
b
5.5.5-10.1.13-MariaDB-1~jessie�TNlS;n:�?��Ov%OA99Srg/Qmysql_native_passwordConnection closed by foreign host.

Some idea to help me ?
Thanks :-)

add THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA for Dovecot

It will be great if we can add THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA ad default or optional.

for postfix, please consider add discard_ehlo for localhost.

In /etc/postfix/main.cf:

smtpd_discard_ehlo_keyword_address_maps = hash:/etc/postfix/discard_ehlo

and in /etc/postfix/discard_ehlo:

127.0.0.1 starttls,silent-discard 
172.17.0.1 starttls,silent-discard 

Dmarc fail in Authentication Results

Hi,

I think than the problem come from me but I've the dmarc which fail only in Authentication Results and which do my mails directly go to Spam on hotmail/outlook and AOL....

It's very strange because I've 10/10 on mail-tester.com, I think (but not sure) than my DNS are well configured...
The dmarc seems to pass but only at the level of "Authentication-Results" it fails...

Thanks for your help !

I've a trace which can help you :

Delivered-To: [email protected]
Received: by 10.107.6.22 with SMTP id 22csp25501iog;
        Fri, 18 Nov 2016 03:29:31 -0800 (PST)
X-Received: by 10.194.200.69 with SMTP id jq5mr5317402wjc.93.1479468571133;
        Fri, 18 Nov 2016 03:29:31 -0800 (PST)
Return-Path: <[email protected]>
Received: from mail.shuguenot.fr (mail.shuguenot.fr. [163.172.52.11])
        by mx.google.com with ESMTPS id up6si7122038wjc.275.2016.11.18.03.29.30
        for <[email protected]>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Fri, 18 Nov 2016 03:29:31 -0800 (PST)
Received-SPF: pass (google.com: domain of [email protected] designates 163.172.52.11 as permitted sender) client-ip=163.172.52.11;
Authentication-Results: mx.google.com;
       dkim=pass [email protected];
       spf=pass (google.com: domain of [email protected] designates 163.172.52.11 as permitted sender) [email protected];
       dmarc=pass (p=REJECT dis=NONE) header.from=wefluence.fr
Received: from localhost (localhost [127.0.0.1]) by mail.shuguenot.fr (Postfix) with ESMTP id D1600654B for <[email protected]>; Fri, 18 Nov 2016 11:29:30 +0000 (UTC)
X-Virus-Scanned: Debian amavisd-new at mail.shuguenot.fr
Received: from mail.shuguenot.fr ([127.0.0.1]) by localhost (mail.shuguenot.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gy8Ktd1R0q9q for <[email protected]>; Fri, 18 Nov 2016 11:29:30 +0000 (UTC)
Received: from authenticated-user (mail.shuguenot.fr [127.0.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: [email protected]) by mail.shuguenot.fr (Postfix) with ESMTPSA id 944A9653F for <[email protected]>; Fri, 18 Nov 2016 11:29:30 +0000 (UTC)
Authentication-Results: mail.shuguenot.fr; dmarc=fail header.from=wefluence.fr
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wefluence.fr; s=mail; t=1479468570; bh=+TycC/TM72o6KfFzMjbyVsg+WpzsrSyC/3BEXcQaXvs=; h=Date:From:Subject:To:From; b=ao8n/MAptBtsJE2f5s/6rQMalVIHVyMxF6XwpDLLwnKoWdge0eXuwMcipFTtsTSl/
	 rCKs0rT6Cp0SudPr8EXrLHNiVbte0DHw3vak2iW0gYwitDFoNhcirM/PnprtQywz+1
	 ED429zjcZ/GyF/xKRZaJ27Mn5SUN01u5A2nL5rXc=
Mime-Version: 1.0
Date: Fri, 18 Nov 2016 11:29:30 +0000
Content-Type: multipart/alternative; boundary="--=_RainLoop_139_799085972.1479468570"
Message-ID: <e6ccf83311020d4c10ea8cb4c2ff1803@11dfdbab313e>
From: [email protected]
Subject: Hello
To: [email protected]

----=_RainLoop_139_799085972.1479468570
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable

Petit test et voila !

----=_RainLoop_139_799085972.1479468570
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE html><html><head><meta http-equiv=3D"Content-Type" content=3D"tex=
t/html; charset=3Dutf-8" /></head><body><div data-html-editor-font-wrapper=
=3D"true" style=3D"font-family: arial, sans-serif; font-size: 13px;"> <sign=
ature></signature>Petit test et voila !<br> </div></body></html>

----=_RainLoop_139_799085972.1479468570--

Postfixadmin

Bonjour,

J'ai mis en place votre solution, cela fonctionne correctement à défaut d'une erreur sur postfixadmin, en effet lors de la création d'un utilisateur / envoi d'un message depuis l'interface j'ai l'erreur :

Erreur lors de l'envoit du message! ([email protected])

J'ai beau regarder les logs avec des docker logs -f, je ne vois rien.

Une idée ?

Merci beaucoup pour votre fabuleux travail

postfix: adding custom config problem

The startup script allows to use /var/mail/postfix/custom.conf to overwrite the default settings w/ the help of postconf.
When only overriding existing options this works. But when I try to add an option previously undefined in the main.cf like "smtpd_data_restrictions" or "smtpd_delay_reject" it is NOT appended as a new file but instead appended to the last line. Further new options then will be added as new lines.
Result looks like:

non_smtpd_milters = $smtpd_milterssmtpd_delay_reject = yes
smtpd_data_restrictions = reject_unauth_pipelining

So this should be fixed by keeping a trailing linebreak in the /etc/postfix/main.cf

LDAP Support

Hi,

I'm currently organizing a new infrastructure around an OpenLDAP container for my users, and I'd like to manage them from a centralized place.

I was going for a manual Postfix / Dovecot install revolving around my directory and then stumbled upon your packaged docker solution.

Do you know if this is all pluggable to an LDAP instance ? Thank you : )

Increase opendkim key length

Actuellement, la taille de la clé est de 1024 bits.
https://github.com/hardware/mailserver/blob/master/rootfs/usr/local/bin/opendkim#L15

Est-ce qu'il y a une raison qui empêcherait, ou déconseillerait techniquement l'utilisation d'une clé de taille supérieure ? Comme 2048 bits ? Parce qu'aujourd'hui en 2016 les clés RSA de cette taille sont fortement déconseillée d'utilisation. Si c'est juste une question d'enregistrement DNS chez certains services comme celui d'OVH, il y a par exemple le moyen de découper la clé en plusieurs enregistrements TXT. Pour le reste, aucun problème.

Merci de m'éclairer.
Au pire, pourquoi pas laisser le choix ? On en a déjà parlé, ce serait une bonne idée. Il suffit juste de rajouter une variable pour qu'on puisse générer une clé dont on peut préciser la taille avec docker exec -ti mailserver opendkim 2048.

Invalid query: Table 'postfix.domain' doesn't exist

Hello,

Sorry for my English, I use google translation to write.

I followed the instructions for the installation by creating the group and UNIX user. I copy the file docker-compose and I executed.

When I make myself the admin page, I get this error: Invalid query: Table 'postfix.domain' doesn't exist

The attached the log of the starting containers
log.txt

Allow to have multiple domains on opendkim

Could you implement a way to have multiple entry in the KeyTable, SigningTable and TrustedHosts ?
Maybe doing a shared folder and if the files exist then don't reset them.
It can be useful for multiple domains DKIM signing.
Actually on each restart these files are reset to the original values.

Container failed to exit within 10 seconds of signal 15 - using the force

Whenever I stop/restart the container, the following happens in syslog :

Container xxxx failed to exit within 10 seconds of signal 15 - using the force

Nothing critical, but I'd like to know if I'm not the only one who experiences this.
As someone told me : "A Jedi uses the Force for knowledge and defense, never for attack."

[Improvement] Quota support from the Postfix

Postfix VDA — Limiting the size of virtual mailbox for Postfix.

Features

  • Brings per mailbox/maildir quota support to Postfix VDA
  • Support for Courier style maildir format, including maildirsize file
  • Limit either only INBOX or whole maildir
  • Customizable bounce message, used if mails are bounced (it's also an option)
  • Customisable suffix for Maildir support, sometimes needed for Courier IMAP
  • Enhanced patch delivery abilities using vfilter
##############################
## QUOTA SUPPORT PARAMETERS ##
##############################

virtual_create_maildirsize     = yes
virtual_mailbox_extended       = yes
virtual_mailbox_limit_maps     = mysql:/etc/postfix/mysql/mysql-virtual-mailbox-limit-maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message  = "The user you are trying to reach is over quota."
virtual_overquota_bounce       = yes
mysql-virtual-mailbox-limit-maps.cf
#
query = SELECT quota FROM mailbox WHERE username = '%s' AND active'1'

How to initialize database

Hi,

just wanted to use your mailserver image but I wonder how to initialize the database. In the readme you suggest to generate a new password and then UPDATE the admin user. But the database was never filled with any data, neither is there a structure.

How is this image supposed to work?

Problème démarrage Nginx

Hello,

Pb suivant au démarrage de NGINX (version boring)

root@mail:/mnt/docker/nginx/log# tail -f error.log
2016/11/06 10:59:43 [emerg] 8#8: SSL_CTX_set1_curves_list("secp384r1") failed (SSL:)
2016/11/06 10:59:43 [emerg] 8#8: SSL_CTX_set1_curves_list("secp384r1") failed (SSL:)
2016/11/06 10:59:44 [emerg] 8#8: SSL_CTX_set1_curves_list("secp384r1") failed (SSL:)
2016/11/06 10:59:46 [emerg] 7#7: SSL_CTX_set1_curves_list("secp384r1") failed (SSL:)
2016/11/06 10:59:50 [emerg] 7#7: SSL_CTX_set1_curves_list("secp384r1") failed (SSL:)
2016/11/06 10:59:56 [emerg] 8#8: SSL_CTX_set1_curves_list("secp384r1") failed (SSL:)
2016/11/06 11:00:09 [emerg] 7#7: SSL_CTX_set1_curves_list("secp384r1") failed (SSL:)
2016/11/06 11:00:35 [emerg] 8#8: SSL_CTX_set1_curves_list("secp384r1") failed (SSL:)
2016/11/06 11:01:27 [emerg] 7#7: SSL_CTX_set1_curves_list("secp384r1") failed (SSL:)
2016/11/06 11:03:10 [emerg] 8#8: SSL_CTX_set1_curves_list("secp384r1") failed (SSL:
root@mail:/mnt/docker/nginx/log# docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                         PORTS                                                                                                                   NAMES
bbf8f63ef21e        wonderfall/boring-nginx   "run.sh"                 22 minutes ago      Restarting (1) 2 minutes ago   0.0.0.0:443->4430/tcp, 0.0.0.0:80->8000/tcp             

Une idée ?

Merci

[Docker-compose v2] Unknown MySQL server host 'mariadb'

I seem to be getting an issue with name services under rancher, it appears postfixadmin can connect to the db, however postfix cant.... it deployed ok, and heres the docker compose

nginx:
  ports:
  - 443:4430/tcp
  - 80:8000/tcp
  image: wonderfall/nginx
  links:
  - postfixadmin:postfixadmin
  - rainloop:rainloop
  volumes:
  - /mnt/docker/nginx/sites-enabled:/sites-enabled
  - /mnt/docker/nginx/conf:/conf.d
  - /mnt/docker/nginx/log:/var/log/nginx
  - /mnt/docker/nginx/certs:/certs
postfixadmin:
  environment:
    DBPASS: xxxxxxx
  domainname: domain.tld
  hostname: mail
  image: hardware/postfixadmin
  links:
  - mariadb:mariadb
  - mailserver:mailserver
mailserver:
  ports:
  - 143:143/tcp
  - 25:25/tcp
  - 4190:4190/tcp
  - 465:465/tcp
  - 587:587/tcp
  - 993:993/tcp
  environment:
    DBPASS: xxxxxxx
  domainname: domain.tld
  hostname: mail
  image: hardware/mailserver
  links:
  - mariadb:mariadb
  volumes:
  - /mnt/docker/mail:/var/mail
  - /mnt/docker/opendkim:/etc/opendkim/keys
mariadb:
  environment:
    MYSQL_DATABASE: postfix
    MYSQL_PASSWORD: xxxxxxx
    MYSQL_ROOT_PASSWORD: xxxxxxx
    MYSQL_USER: postfix
  image: mariadb:10.1
  volumes:
  - /mnt/docker/mysql/db:/var/lib/mysql
rainloop:
  image: hardware/rainloop
  links:
  - mariadb:mariadb
  - mailserver:mailserver
  volumes:
  - /mnt/docker/rainloop:/rainloop/data
2016-07-04T05:00:57.502262+00:00 mail postfix/trivial-rewrite[448]: warning: connect to mysql server mariadb: Unknown MySQL server host 'mariadb' (2)
2016-07-04T05:00:57.502328+00:00 mail postfix/trivial-rewrite[448]: warning: mysql:/etc/postfix/mysql/mysql-virtual-alias-maps.cf: table lookup problem
2016-07-04T05:00:57.502359+00:00 mail postfix/trivial-rewrite[448]: warning: virtual_alias_domains lookup failure
2016-07-04T05:00:57.503029+00:00 mail postfix/trivial-rewrite[448]: warning: mysql:/etc/postfix/mysql/mysql-virtual-alias-maps.cf: table lookup problem
2016-07-04T05:00:57.503072+00:00 mail postfix/trivial-rewrite[448]: warning: virtual_alias_domains lookup failure

502 Bad Gateway

Yop,

Petit souci ce soir suite a l'upgrade du mailserver, je n'arrive plus a accéder a Rainloop/PostfixAdmin

J'ai bien entendu modifié le proxy_pass sur le port 8888 comme indiqué mais cela ne corrige pas le pb.

Lorsque je fais un docker logs nginx je n'ai absolument rien (noir/vide)

Je vois bien les connexions dans l'access.log

Aurais-tu une idée ?

Security and SSL/TLS MUA/MTA configuration

Actuellement, l'image est taillée pour la compatibilité, parfois au détriment de la sécurité dans l'absolu.
Par exemple pour le MUA on pourrait n'autoriser que TLS 1.2 et AESGCM :

ssl = required
ssl_cert = <<FULLCHAIN>
ssl_key = <<KEYFILE>
ssl_protocols = !SSLv2 !SSLv3 !TLSv1 !TLSv1.1
ssl_cipher_list = AESGCM
ssl_prefer_server_ciphers = yes
ssl_dh_parameters_length = 2048

En plus édulcoré on pourrait faire :

ssl_protocols = !SSLv2 !SSLv3
ssl_cipher_list = AES128+EECDH:AES128+EDH

Ensuite, pour le MTA : https://github.com/hardware/mailserver/blob/master/rootfs/etc/postfix/main.cf#L31-L69
Ne pourrait-on pas être un peu plus exigent quand même ? Déjà que la sécurité offerte par SMTP+STARTTLS est toute relative, autant faire le moins de concessions, toujours dans l'absolu sécuritaire.

Je pense qu'il est quand même utile d'au moins en discuter.

550 5.1.1 <[email protected]> Recipient not found.

Hi,

I'm getting "Recipient not found" for all addresses with different domains than the email server itself. Shouldn't that also work for multiple domains?
Also I can't see this error in any logfile. Could you redirect the logs from all services to stdout/stderr?

ClamAV don't launch

Amavis fail to start :

2016-07-07 08:16:16,105 INFO spawned: 'freshclam' with pid 259
2016-07-07 08:16:16,153 INFO exited: freshclam (exit status 40; not expected)
2016-07-07 08:16:17,158 INFO spawned: 'clamd' with pid 260
2016-07-07 08:16:17,195 INFO exited: clamd (exit status 1; not expected)
2016-07-07 08:16:19,622 INFO exited: freshclam (exit status 40; not expected)
2016-07-07 08:16:19,812 INFO gave up: freshclam entered FATAL state, too many st                              art retries too quickly
2016-07-07 08:16:20,881 INFO exited: clamd (exit status 1; not expected)
2016-07-07 08:16:21,883 INFO gave up: clamd entered FATAL state, too many start                               retries too quickly

That occur debug mail at each sending mail and no sending at all.

Access and Auditing Milter for Postfix

ClueGetter - Access and Auditing Milter

ClueGetter provides a means to have an integrated way to determine if a message
should be accepted by Postfix. All email (metadata) and verdicts are stored in a
database allowing for auditing.

Each message has a verdict of one of the following values:

  • Permit: Accept message.
  • Tempfail: Deny delivery, but expect the delivering MTA to deliver it at a later time.
  • Reject: Reject the message, indicating it will not be accepted a next time either.

Features:

  • Quotas - Limit the number of emails
    (per ip, sasl user, recipient, sender) over an arbitrary amount of time.
  • SpamAssassin - Determine whether an email is SPAM through SpamAssassin.
    Can be used alongside the Rspamd module.
  • Rspamd - Determine whether an email is SPAM through Rspamd.
    Can be used alongside the SpamAssassin module.
  • ClamAV/Clamd - Scan the message for viruses, malware, etc.
  • Greylisting - Ask a server to try again in a bit if it wasn't seen before and the mail looks spammy.
  • Bounce Handling - Keep track of what emails were rejected by remote MTAs and for what reasons.
  • Abusers - Present a list of users in the web interface who had an unusual amount of email rejected.
    Usually these users have been hacked, or are otherwise malicious.
  • MailQueue - Display an aggregate of all mail queues that reside in your ClueGetter cluster.
    Filter based on instance, recipient(/domain), sender(/domain) and delete or requeue selections
    of items in the queue.
  • Contacts - Import address books (e.g. from RoundCube) so these addresses and/or domains can be used to (partially) blacklist messages from those addresses or domains.
  • SRS - Sender Rewriting Scheme
  • DKIM - Sign messages using DKIM
  • Volume Reputation - Detect anomalies in volume, and penalize sudden increases in volume.
Message Details Searching for a message Mail Queue
Message Details Search for a message Mail Queue

Add greylisting support

Do you have any intention to add greylisting to this mail stack? I am currently migrating a production mailserver to a docker-based one using this image and right now the only difference between both servers is the one that is currently used uses greylisting in conjunction with spamassassin for filtering spams.

I don't know, in 2016, if greylisting is still efficient and recommended. What are your thoughts on this?

Thanks.

nginx proxy for a directory

Hello,
something failed when i try to configure the proxy for postfixadmin and rainloop.
i can just see postfixadmin. i can't connect to rainloop.
i tryied to modify the nginx proxy for that postfixadmin be in a specific directory /pf/ ( Webroot (default is /): /pf/ ), it indicates that : WARNING: You might have to add a proxy header to get your custom webroot working.
it request this : "Type the required proxy_set_header (like X-Script-Name):"
what would the good line ?
Is there a little tuto to do that ?
thx

add configure to disable amavis & clamav

With amavis & clamav on small VPS the server will be slow, if we can disable it by configure or ENV var will make hardware/mailserver more useable for small VPS.

Mailserver / Out Of Memory

Bonjour Hardware,
J'utilise ton docker Mailserver, j'ai des boites mail qui sont conséquente.
et j'ai ce genre d'erreur quand on a besoin de consulter nos boîtes mail.

2016-05-09T09:43:12.310028+00:00 lucy dovecot: imap-login: Login: user=<[email protected]>, method=PLAIN, rip=172.17.0.1, lip=172.17.0.5, mpid=4876, TLS, session=<4eUOo2Uy0ACsEQAB>
2016-05-09T09:43:12.374169+00:00 lucy dovecot: imap([email protected]): Fatal: pool_system_realloc(1048576): Out of memory
2016-05-09T09:43:12.375808+00:00 lucy dovecot: imap([email protected]): Fatal: master: service(imap): child 4876 returned error 83 (Out of memory (service imap { vsz_limit=256 MB }, you may need to increase it) - set CORE_OUTOFMEM=1 environment to get core dump)

Question: sometimes Postfix thinks 172.18.0.1 is the client_ip

Sometimes when receiving mail (from an external server) I can see something like this in the logs:

postfix/smtpd[4657]: connect from unknown[172.18.0.1]
postfix/smtpd[4657]: Anonymous TLS connection established from unknown[172.18.0.1]: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
postfix/cleanup[4665]: 78DA3189E7E: milter-reject: END-OF-MESSAGE from unknown[172.18.0.1]: 5.7.1 rejected by DMARC policy for google.com; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<mail-oi0-x249.google.com>

So postfix only sees the IP of the docker host (172.18.0.1) instead of the real client IP. This causes different problems: SPF fails and eventually fails DMARC (as in the log above), or the spam score from spamassassin contains "ALL_TRUSTED=-1" as the mail server thinks the mail came from a trusted network.

Others are having the same problem with Docker & Postfix: http://stackoverflow.com/questions/39517593/postfix-docker-and-inconsistent-ip-addresses-from-host
I'm using docker compose (yaml v2) with no specific network settings (so it uses the default bridged mode) and no other proxies, the ports are directly exposed.

I was wondering if you ran into the same problem / know the reason for this?

POP3 support

Hi,

Could you add pop3/pop3s support to mail server?

Regards,

Zoli

Ajouter le Push

Est-il possible d'ajouter la fonctionnalitée PUSH sur la récéption des mails ?

Rspamd spam filtering system

Rspamd is an advanced spam filtering system that allows evaluation of messages by a number of rules including regular expressions, statistical analysis and custom services such as URL black lists. Each message is analysed by Rspamd and given a spam score.

According to this spam score and the user's settings Rspamd recommends an action for
the MTA to apply to the message, for example, to pass, reject or add a header.
Rspamd is designed to process hundreds of messages per second simultaneously and has a number of features available.

You can watch the following introduction video from the FOSDEM-2016 where I describe the main features of Rspamd and explain why Rspamd runs so fast.

Rspamd is packaged for the major Linux distributions and is also available via FreeBSD ports and NetBSD pkgsrc.

Spam filtering features

Rspamd distribution contains a number of mail processing features, including such techniques as:

  • Regular expressions filtering - allows basic processing of messages, their textual parts, MIME headers and SMTP data received by MTA against a set of expressions that includes both normal regular expressions and message processing functions. Rspamd expressions are the powerful tool that allows to filter messages based on some pre-defined rules. This feature is similar to regular expressions in SpamAssassin spam filter.

  • SPF module that allows to validate a message's sender against the policy defined in the DNS record of sender's domain. You can read about SPF policies here. A number of mail systems includes SPF support, such as Gmail or Yahoo Mail.

  • DKIM module validates a message cryptographic signature against a public key placed in the DNS record of sender's domain. Like SPF, this technique is widely spread and allows to validate that a message is sent from that specific domain.

  • DNS black lists allows to estimate reputation of sender's IP address or network. Rspamd uses a number of DNS lists including such lists as SORBS or Spamhaus. However, Rspamd doesn't trust any specific DNS list and use a conjunction of estimations instead that allows to avoid mistakes and false positives. Rspamd also uses positive and grey DNS lists for checking for trusted senders.

  • URL black lists are rather similar to DNS black lists but uses URLs in a message to make an estimation of sender's reputation.
    This technique is very useful for finding malicious or phished domains and filter such mail.

  • Statistics - Rspamd uses Bayesian classifier based on five-grams of input. This means that the input is estimated not based on individual words, but all input is organized in chains that are further estimated by Bayesian classifier. This approach allows to achieve better results than traditionally used monograms (or words literally speaking), that is described in details in the following paper.

  • Fuzzy hashes - for checking of malicious mail patterns Rspamd uses so called fuzzy hashes. Unlike normal hashes, these structures are targeted to hide
    small differences between text patterns allowing to find similar messages quickly. Rspamd has internal storage of such hashes and allows to block mass spam sendings
    quickly based on user's feedback that specifies messages reputation. Moreover, this allows to feed Rspamd with data from honeypots without polluting the statistical module.

Rspamd uses the conjunction of different techniques to make the final decision about a message. This allows to improve the overall quality of filtering and reduce the number of false positives (e.g. when a innocent message is badly classified as a spam one). I have tried to simplify Rspamd usage by adding the following elements:

  • Web interface - Rspamd is shipped with the fully functional Ajax-based web interface that allows to observe Rspamd statistic, to configure rules, weights and lists, to scan and learn messages and to view the history of scans. The interface is self-hosted, requires zero configuration and follows the recent web applications standards. You don't need a web server or applications server to run WebUI - you just need to run Rspamd itself and a web browser.

  • Integration with MTA - Rspamd can work with the most popular mail transfer systems, such as Postfix, Exim or Sendmail. For Postfix and Sendmail, there is an Rmilter project, whilst for Exim there are several solutions to work with Rspamd. Should you require MTA integration then please consult with the integration guide.

  • Extensive Lua API - Rspamd ships with hundreds of Lua functions that are available to write own rules for efficient and targeted spam filtering.

  • Dynamic tables - Rspamd allows to specify bulk lists as dynamic maps that are checked in runtime with updating data when they are changed. Rspamd supports file, HTTP and HTTPS maps.

Performance

Rspamd is designed to be fast. The core of Rspamd is written in C and uses an event-driven model that allows to process multiple messages simultaneously and without blocking.
Moreover, a set of techniques is used in Rspamd to process messages faster:

  • Finite state machines processing - Rspamd uses specialized finite state machines for the performance critical tasks to process input faster than a set of regular expressions.
    Of course, it is possible to implement these machines by ordinary Perl regular expressions but then they won't be compact or human-readable. On the contrary, Rspamd optimizes such actions as headers processing, received elements extraction, protocol operations by building the concrete automata for an assigned task.

  • Expressions optimizer - allows to optimize expressions by execution of likely false or likely true expressions in order in the branches. That allows to reduce number of expensive expressions calls when scanning a message.

  • Symbols optimizer - Rspamd tries to check first the rules that are frequent or inexpensive in terms of time or CPU resources which allows to block spam before processing of expensive rules (rules with negative weights are always checked before other ones).

  • Event driven model - Rspamd is designed not to block anywhere in the code and knowing that a spam check requires a lot of network operations, Rspamd can process many messages
    simultaneously increasing the efficiency of shared DNS caches and other system resources. Moreover, event-driven system normally scales automatically and you won't need to do any
    tuning in the most of cases.

  • Hyperscan regular expressions engine - Rspamd utilizes Hyperscan engine to match multiple regular expressions at the same time. You can watch the following presentation where the main benefits of Hyperscan are described.

  • Clever choice of data structures - Rspamd tries to use the optimal data structure for each task. For example, it uses very efficient suffix tries for fast matching of a text against a set of multiple patterns. Or it uses radix bit trie for storing IP addresses information that provides O(1) access time complexity.

Extensions

Besides its C core, Rspamd provides an extensive Lua API to access almost all the features available directly from C. Lua is an extremely easy
to learn programming language though it is powerful enough to implement complex mail filters. In fact Rspamd has a significant amount of code written completely in Lua such as
DNS blacklists checks, user's settings or different maps implementation. You can also write your own filters and rules in Lua adopting Rspamd functionality to your needs.
Furthermore, Lua programs are very fast and their performance is rather close to pure C. However, you should mention that for the most
of performance critical tasks you usually use the Rspamd core functionality than Lua code. Anyway, you can also use LuaJIT with Rspamd if your goal is maximum performance.
From the Lua API you can do the following tasks:

  • Reading the configuration parameters - Lua code has the full access to the parsed configuration knobs and you can easily modify your plugins behaviour by means of the main
    Rspamd configuration.

  • Registering custom filters - it is more than simple to add your own filters to Rspamd: just add new index to the global variable rspamd_config:

rspamd_config.MYFILTER = function(task)
-- Do something
end
  • Full access to the content of messages - you can access text parts, headers, SMTP data and so on and so forth by using of task object. The full list of methods could be found
    here.

  • Pre- and post- filters - you can register callbacks that are called before or after messages processing to make results more precise or to make some early decision, for example, to implement a rate limit.

  • Registering functions for Rspamd - you can write your own functions in Lua to extend Rspamd internal expression functions.

  • Managing statistics - Lua scripts can define a set of statistical files to be scanned or learned for a specific message allowing to create more complex statistical systems, e.g. based on an input language. Moreover, you can even learn Rspamd statistic from Lua scripts.

  • Standalone Lua applications - you can even write your own worker based on Rspamd core and performing some asynchronous logic in Lua. Of course, you can use the all features from Rspamd core, including such features as non-blocking IO, HTTP client and server, non-blocking Redis client, asynchronous DNS, UCL configuration and so on
    and so forth.

  • API documentation - Rspamd Lua API has an extensive documentation where you can find examples, references and the guide about how to extend Rspamd with Lua.

References

amavisd-new - Performance Tuning

  • Increase of number of amavisd-new childs/forks
    • Default number of instances 2 => $max_servers=2;
    • 4 Childs/Core *2 Cores => $max_servers=8;
  • Debian HOME of user amavis is /var/lib/amavisd-new
  • mount tmpfs at $TEMPBASE = $HOME/tmp => /var/lib/amavisd-new/tmp/
    • $max_servers(8) * message_size_limit(10MiB) * Reserve(1,5) => size=128m
apt install pigz pxz pbzip2

/etc/amavis/conf.d/50-user

use strict;

#
# Place your configuration directives here.  They will override those in
# earlier files.
#
# See /usr/share/doc/amavisd-new/ for documentation and examples of
# the directives you can use in this file
#

### Maximun number of child processes
$max_servers = 8;

### Parallel de-/compression
$gzip   = 'pgiz';
$bzip2  = 'pbzip2';
$uncompress = ['uncompress', 'pigz -d', 'zcat'];

### Actions to be performed on events
$final_virus_destiny      = D_REJECT;

### Header Encoding
## to be used in RFC 2047-encoded header field bodies, e.g. in Subject:
$hdr_encoding = 'utf8';  # (default: 'iso-8859-1')
## to be used in notification body text: its encoding and Content-type.charset
$bdy_encoding = 'utf8';  # (default: 'iso-8859-1')


#------------ Do not modify anything below this line -------------
1;  # ensure a defined return

Refs:

Automated build fail on docker hub

The automated build fail on docker hub since 2 weeks, i don't know why...

Step 6 : EXPOSE 25 143 465 587 993 4190
 ---> Running in a572810c6807
 ---> 444d7bd2d173
Removing intermediate container a572810c6807
Step 7 : COPY rootfs /
Removing intermediate container a073e4b98b3e
lchown /var/lib/docker/overlay/673a8cc98f9cc7b3c815406edd258b5ec4192a4b74034db5a2d7184e5750b488/merged/etc: no such file or directory

https://hub.docker.com/r/hardware/mailserver/builds/

I have no problem when i build hardware/mailserver manually on my pc :

https://paste.mondedie.fr/?ceff42e030d11b92#/a5NKzfvfIHK1yFyl4tr15+BrNmsyr0hfzV4Sgj90Yo=

Does anyone have an idea to solve this issue ?

EDIT: It's a Docker Hub bug : docker/hub-feedback#811

Improvement for docker-compose.sample.yml

In the docker-compose.sample.yml at the level of the Mariadb container, there are environment and volumes property which are set.
However if the volumes property is set then the environment variables are ignored.
I think it might be a good thing to specify it in the README for example.

Allow to modify php.ini variables in rainloop

These two variables are set by default and cannot be set manually (without exec in the docker and that's not a good solution...)
upload_max_filesize
post_max_size

Is it possible to add something to allow to modify it ?
It's really useful to set the maximum size of an attachment.

Reduce docker containers size

DockerSlim (docker-slim): Optimize and secure your Docker containers

Creating small containers requires a lot of voodoo magic and it can be pretty painful. You shouldn't have to throw away your tools and your workflow to have skinny containers. Using Docker should be easy.

docker-slim is a magic diet pill for your containers :) It will use static and dynamic analysis to create a skinny container for your app.

postifxadmin port 4443 unavailable

I had this all functional until i tried to upgrade rancher/docker... fail.... so i started over from scratch now im running into issues, however i see the postfix db resolution has been resolved.

seems looking at the nginx postfixadmin config it shows postfixadmin container should be listening on 8000 and 4443, however using the docker-compose.yml postfixadmin container is only listening on port 80

I also noted that when i go to https://postifxadmin.optimcloud.com i actually get rainloop webmail
as is the same for https://webmail.optimcloud.com goes to rainloop

How to configure with nginx-proxy image

Hi,

I use docker to serve several websites on my host through the nginx-proxy image.
I would like to know if it's possible to serve the mailserver through that image instead of boring-nginx.
I would have something like:
website1.com and mail.website1.com to serve emails for this domain @website1.com
website2.com and mail.website2.com to serve emails for this domain @website2.com
where mail.domain.com is the webgui for postfix admin.
My db is actually a mysql container.

Machine installed with Debian 8.

crond.d is the wrong directory name?

I think /etc/crond.d/ with the spamassassin conrjobs should be renamed to /etc/cron.d/
I suspected this jobs weren't run, so I added a job that would run every minute which wasn't run. Moving the "spamassassin" file to /etc/cron.d (next to the automatically added "amavisd-new" file) fixed this.

The amavisd-new triggers "sa-sync", this itself seems to trigger "sa-learn --sync", without specifying the "--ham" and "--spam" folders. What will "sa-learn --sync" do here, does it interfere with the ham/spam jobs?

Additionally: If the "spamassassin" file itself is left unchanged the cron will send mails with the output of the jobs to root@$hostname, the output should be redirected to syslog, a logfile or /dev/null.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.