diff --git a/docker/mail/Dockerfile b/docker/mail/Dockerfile index 71822a6233..1188019368 100644 --- a/docker/mail/Dockerfile +++ b/docker/mail/Dockerfile @@ -7,7 +7,8 @@ ENV \ POSTMASTER=postmaster@example.com \ SSL_CERT=/etc/ssl/mailserver.crt \ SSL_KEY=/etc/ssl/mailserver.key - + +# Install packages RUN \ apt-get update \ && apt-get upgrade -y \ @@ -22,13 +23,15 @@ RUN \ rsyslog \ opendkim \ opendkim-tools \ + openssl \ && apt-get autoclean \ && apt-get autoremove +# Setup folders and users RUN \ rm /etc/postfix/main.cf /etc/postfix/master.cf /etc/dovecot/dovecot.conf /etc/dovecot/conf.d/* /etc/rsyslog.conf /etc/rsyslog.d/* \ - && groupadd -g 5000 vmail \ - && useradd -d /var/mail -M -s /usr/sbin/nologin -u 5000 -g 5000 vmail \ + && groupadd -g 2222 vmail \ + && useradd -d /var/mail -M -s /usr/sbin/nologin -u 2222 -g 2222 vmail \ && usermod -aG vmail postfix \ && usermod -aG vmail dovecot \ && usermod -aG vmail opendkim\ @@ -42,6 +45,8 @@ RUN \ # Copy config files COPY rootfs/ / +# Expose ports EXPOSE 25 143 587 993 +# Run start script ENTRYPOINT /usr/bin/start.sh diff --git a/docker/mail/rootfs/etc/dovecot/15-lda.conf b/docker/mail/rootfs/etc/dovecot/15-lda.conf new file mode 100644 index 0000000000..e33f180b9d --- /dev/null +++ b/docker/mail/rootfs/etc/dovecot/15-lda.conf @@ -0,0 +1,48 @@ +## +## LDA specific settings (also used by LMTP) +## + +# Address to use when sending rejection mails. +# Default is postmaster@. %d expands to recipient domain. +#postmaster_address = + +# Hostname to use in various parts of sent mails (e.g. in Message-Id) and +# in LMTP replies. Default is the system's real hostname@domain. +#hostname = + +# If user is over quota, return with temporary failure instead of +# bouncing the mail. +#quota_full_tempfail = no + +# Binary to use for sending mails. +#sendmail_path = /usr/sbin/sendmail + +# If non-empty, send mails via this SMTP host[:port] instead of sendmail. +#submission_host = + +# Subject: header to use for rejection mails. You can use the same variables +# as for rejection_reason below. +#rejection_subject = Rejected: %s + +# Human readable error message for rejection mails. You can use variables: +# %n = CRLF, %r = reason, %s = original subject, %t = recipient +#rejection_reason = Your message to <%t> was automatically rejected:%n%r + +# Delimiter character between local-part and detail in email address. +#recipient_delimiter = + + +# Header where the original recipient address (SMTP's RCPT TO: address) is taken +# from if not available elsewhere. With dovecot-lda -a parameter overrides this. +# A commonly used header for this is X-Original-To. +#lda_original_recipient_header = + +# Should saving a mail to a nonexistent mailbox automatically create it? +lda_mailbox_autocreate = yes + +# Should automatically created mailboxes be also automatically subscribed? +#lda_mailbox_autosubscribe = no + +protocol lda { + # Space separated list of plugins to load (default is global mail_plugins). + mail_plugins = $mail_plugins sieve +} diff --git a/docker/mail/rootfs/etc/dovecot/20-managesieve.conf b/docker/mail/rootfs/etc/dovecot/20-managesieve.conf new file mode 100644 index 0000000000..ed3e584a72 --- /dev/null +++ b/docker/mail/rootfs/etc/dovecot/20-managesieve.conf @@ -0,0 +1,76 @@ +## +## ManageSieve specific settings +## + +# Uncomment to enable managesieve protocol: +protocols = $protocols sieve + +# Service definitions + +service managesieve-login { + inet_listener sieve { + port = 4190 + } + + #inet_listener sieve_deprecated { + # port = 2000 + #} + + # Number of connections to handle before starting a new process. Typically + # the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0 + # is faster. + service_count = 1 + + # Number of processes to always keep waiting for more connections. + #process_min_avail = 0 + + # If you set service_count=0, you probably need to grow this. + #vsz_limit = 64M +} + +service managesieve { + # Max. number of ManageSieve processes (connections) + process_limit = 1024 +} + +# Service configuration + +protocol sieve { + # Maximum ManageSieve command line length in bytes. ManageSieve usually does + # not involve overly long command lines, so this setting will not normally + # need adjustment + #managesieve_max_line_length = 65536 + + # Maximum number of ManageSieve connections allowed for a user from each IP + # address. + # NOTE: The username is compared case-sensitively. + #mail_max_userip_connections = 10 + + # Space separated list of plugins to load (none known to be useful so far). + # Do NOT try to load IMAP plugins here. + #mail_plugins = + + # MANAGESIEVE logout format string: + # %i - total number of bytes read from client + # %o - total number of bytes sent to client + #managesieve_logout_format = bytes=%i/%o + + # To fool ManageSieve clients that are focused on CMU's timesieved you can + # specify the IMPLEMENTATION capability that Dovecot reports to clients. + # For example: 'Cyrus timsieved v2.2.13' + #managesieve_implementation_string = Dovecot Pigeonhole + + # Explicitly specify the SIEVE and NOTIFY capability reported by the server + # before login. If left unassigned these will be reported dynamically + # according to what the Sieve interpreter supports by default (after login + # this may differ depending on the user). + #managesieve_sieve_capability = + #managesieve_notify_capability = + + # The maximum number of compile errors that are returned to the client upon + # script upload or script verification. + #managesieve_max_compile_errors = 5 + + # Refer to 90-sieve.conf for script quota configuration and configuration of + # Sieve execution limits. +} diff --git a/docker/mail/rootfs/etc/dovecot/90-sieve-extprograms.conf b/docker/mail/rootfs/etc/dovecot/90-sieve-extprograms.conf new file mode 100644 index 0000000000..17dcb77d51 --- /dev/null +++ b/docker/mail/rootfs/etc/dovecot/90-sieve-extprograms.conf @@ -0,0 +1,44 @@ +# Sieve Extprograms plugin configuration + +# Don't forget to add the sieve_extprograms plugin to the sieve_plugins setting. +# Also enable the extensions you need (one or more of vnd.dovecot.pipe, +# vnd.dovecot.filter and vnd.dovecot.execute) by adding these to the +# sieve_extensions or sieve_global_extensions settings. Restricting these +# extensions to a global context using sieve_global_extensions is recommended. + +plugin { + + # The directory where the program sockets are located for the + # vnd.dovecot.pipe, vnd.dovecot.filter and vnd.dovecot.execute extension + # respectively. The name of each unix socket contained in that directory + # directly maps to a program-name referenced from the Sieve script. + #sieve_pipe_socket_dir = sieve-pipe + #sieve_filter_socket_dir = sieve-filter + #sieve_execute_socket_dir = sieve-execute + + # The directory where the scripts are located for direct execution by the + # vnd.dovecot.pipe, vnd.dovecot.filter and vnd.dovecot.execute extension + # respectively. The name of each script contained in that directory + # directly maps to a program-name referenced from the Sieve script. + #sieve_pipe_bin_dir = /usr/lib/dovecot/sieve-pipe + #sieve_filter_bin_dir = /usr/lib/dovecot/sieve-filter + #sieve_execute_bin_dir = /usr/lib/dovecot/sieve-execute +} + +# An example program service called 'do-something' to pipe messages to +#service do-something { + # Define the executed script as parameter to the sieve service + #executable = script /usr/lib/dovecot/sieve-pipe/do-something.sh + + # Use some unprivileged user for executing the program + #user = dovenull + + # The unix socket located in the sieve_pipe_socket_dir (as defined in the + # plugin {} section above) + #unix_listener sieve-pipe/do-something { + # LDA/LMTP must have access + # user = vmail + # mode = 0600 + #} +#} + diff --git a/docker/mail/rootfs/etc/dovecot/90-sieve.conf b/docker/mail/rootfs/etc/dovecot/90-sieve.conf new file mode 100644 index 0000000000..1ebf9f339a --- /dev/null +++ b/docker/mail/rootfs/etc/dovecot/90-sieve.conf @@ -0,0 +1,105 @@ +## +## Settings for the Sieve interpreter +## + +# Do not forget to enable the Sieve plugin in 15-lda.conf and 20-lmtp.conf +# by adding it to the respective mail_plugins= settings. + +plugin { + # The path to the user's main active script. If ManageSieve is used, this the + # location of the symbolic link controlled by ManageSieve. + sieve = ~/.dovecot.sieve + + # The default Sieve script when the user has none. This is a path to a global + # sieve script file, which gets executed ONLY if user's private Sieve script + # doesn't exist. Be sure to pre-compile this script manually using the sievec + # command line tool. + # --> See sieve_before fore executing scripts before the user's personal + # script. + #sieve_default = /var/lib/dovecot/sieve/default.sieve + + # Directory for :personal include scripts for the include extension. This + # is also where the ManageSieve service stores the user's scripts. + sieve_dir = ~/sieve + + # Directory for :global include scripts for the include extension. + #sieve_global_dir = + + # Path to a script file or a directory containing script files that need to be + # executed before the user's script. If the path points to a directory, all + # the Sieve scripts contained therein (with the proper .sieve extension) are + # executed. The order of execution within a directory is determined by the + # file names, using a normal 8bit per-character comparison. Multiple script + # file or directory paths can be specified by appending an increasing number. + #sieve_before = + #sieve_before2 = + #sieve_before3 = (etc...) + + # Identical to sieve_before, only the specified scripts are executed after the + # user's script (only when keep is still in effect!). Multiple script file or + # directory paths can be specified by appending an increasing number. + #sieve_after = + #sieve_after2 = + #sieve_after2 = (etc...) + + # Which Sieve language extensions are available to users. By default, all + # supported extensions are available, except for deprecated extensions or + # those that are still under development. Some system administrators may want + # to disable certain Sieve extensions or enable those that are not available + # by default. This setting can use '+' and '-' to specify differences relative + # to the default. For example `sieve_extensions = +imapflags' will enable the + # deprecated imapflags extension in addition to all extensions were already + # enabled by default. + #sieve_extensions = +notify +imapflags + + # Which Sieve language extensions are ONLY available in global scripts. This + # can be used to restrict the use of certain Sieve extensions to administrator + # control, for instance when these extensions can cause security concerns. + # This setting has higher precedence than the `sieve_extensions' setting + # (above), meaning that the extensions enabled with this setting are never + # available to the user's personal script no matter what is specified for the + # `sieve_extensions' setting. The syntax of this setting is similar to the + # `sieve_extensions' setting, with the difference that extensions are + # enabled or disabled for exclusive use in global scripts. Currently, no + # extensions are marked as such by default. + #sieve_global_extensions = + + # The Pigeonhole Sieve interpreter can have plugins of its own. Using this + # setting, the used plugins can be specified. Check the Dovecot wiki + # (wiki2.dovecot.org) or the pigeonhole website + # (http://pigeonhole.dovecot.org) for available plugins. + # The sieve_extprograms plugin is included in this release. + #sieve_plugins = + + # The separator that is expected between the :user and :detail + # address parts introduced by the subaddress extension. This may + # also be a sequence of characters (e.g. '--'). The current + # implementation looks for the separator from the left of the + # localpart and uses the first one encountered. The :user part is + # left of the separator and the :detail part is right. This setting + # is also used by Dovecot's LMTP service. + #recipient_delimiter = + + + # The maximum size of a Sieve script. The compiler will refuse to compile any + # script larger than this limit. If set to 0, no limit on the script size is + # enforced. + #sieve_max_script_size = 1M + + # The maximum number of actions that can be performed during a single script + # execution. If set to 0, no limit on the total number of actions is enforced. + #sieve_max_actions = 32 + + # The maximum number of redirect actions that can be performed during a single + # script execution. If set to 0, no redirect actions are allowed. + #sieve_max_redirects = 4 + + # The maximum number of personal Sieve scripts a single user can have. If set + # to 0, no limit on the number of scripts is enforced. + # (Currently only relevant for ManageSieve) + #sieve_quota_max_scripts = 0 + + # The maximum amount of disk storage a single user's scripts may occupy. If + # set to 0, no limit on the used amount of disk storage is enforced. + # (Currently only relevant for ManageSieve) + #sieve_quota_max_storage = 0 +} diff --git a/docker/mail/rootfs/etc/dovecot/dovecot.conf b/docker/mail/rootfs/etc/dovecot/dovecot.conf index 023629420f..aad6774a25 100644 --- a/docker/mail/rootfs/etc/dovecot/dovecot.conf +++ b/docker/mail/rootfs/etc/dovecot/dovecot.conf @@ -1,8 +1,8 @@ protocols = imap pop3 lmtp ssl = yes -ssl_cert = + +## Add a DKIM-Filter header field to messages passing through this filter +## to identify messages it has processed. SoftwareHeader yes + +## SIGNING OPTIONS + +## Selects the canonicalization method(s) to be used when signing messages. Canonicalization relaxed/simple + +## Domain(s) whose mail should be signed by this filter. Mail from other domains will +## be verified rather than being signed. Uncomment and use your domain name. +## This parameter is not required if a SigningTable is in use. Domain file:/etc/mail/domains + + +## Defines the name of the selector to be used when signing messages. Selector default + +## Specifies the minimum number of key bits for acceptable keys and signatures. MinimumKeyBits 1024 -KeyFile /etc/opendkim/keys/default.private + +## Gives the location of a private key to be used for signing ALL messages. This +## directive is ignored if KeyTable is enabled. +KeyFile /var/opendkim/keys/default.private + +## Gives the location of a file mapping key names to signing keys. In simple terms, +## this tells OpenDKIM where to find your keys. If present, overrides any KeyFile +## directive in the configuration file. Requires SigningTable be enabled. +# KeyTable /etc/opendkim/KeyTable + +## Defines a table used to select one or more signatures to apply to a message based +## on the address found in the From: header field. In simple terms, this tells +## OpenDKIM how to use your keys. Requires KeyTable be enabled. +# SigningTable refile:/etc/opendkim/SigningTable + +## Identifies a set of "external" hosts that may send mail through the server as one +## of the signing domains without credentials as such. +# ExternalIgnoreList refile:/etc/opendkim/TrustedHosts + +## Identifies a set "internal" hosts whose mail should be signed rather than verified. InternalHosts refile:/etc/opendkim/TrustedHosts + +## Contains a list of IP addresses, CIDR blocks, hostnames or domain names +## whose mail should be neither signed nor verified by this filter. See man +## page for file format. +# PeerList X.X.X.X + +## Always oversign From (sign using actual From and a null From to prevent +## malicious signatures header fields (From and/or others) between the signer +## and the verifier. From is oversigned by default in the Fedora package +## because it is often the identity key used by reputation systems and thus +## somewhat security sensitive. OversignHeaders From diff --git a/docker/mail/rootfs/etc/postfix/main.cf b/docker/mail/rootfs/etc/postfix/main.cf index 681e998adb..90fd5649f8 100644 --- a/docker/mail/rootfs/etc/postfix/main.cf +++ b/docker/mail/rootfs/etc/postfix/main.cf @@ -1,9 +1,8 @@ -smtpd_banner = $myhostname ESMTP -biff = no -append_dot_mydomain = no -compatibility_level=2 +## STANDARD POSTFIX CONFIG PARAMS ### + queue_directory = /var/spool/postfix command_directory = /usr/sbin +daemon_directory = /usr/lib/postfix/sbin data_directory = /var/lib/postfix mail_owner = postfix myhostname = %MAIL_HOSTNAME% @@ -14,8 +13,10 @@ inet_protocols = all mydestination = $myhostname, localhost.$mydomain, localhost unknown_local_recipient_reject_code = 550 mynetworks = 127.0.0.0/8, [::1]/128 +alias_maps = hash:/etc/postfix/aliases +alias_database = $alias_maps -mailbox_command = /usr/libexec/dovecot/deliver +mailbox_command = /usr/lib/dovecot/deliver debug_peer_level = 2 debugger_command = @@ -42,17 +43,17 @@ virtual_mailbox_domains = hash:/etc/mail/domains virtual_mailbox_maps = hash:/etc/mail/mailboxes virtual_mailbox_base = /var/mail -virtual_minimum_uid = 5000 +virtual_minimum_uid = 2222 virtual_transport = dovecot -virtual_uid_maps = static:5000 -virtual_gid_maps = static:5000 +virtual_uid_maps = static:2222 +virtual_gid_maps = static:2222 dovecot_destination_recipient_limit = 1 milter_protocol = 2 milter_default_action = accept smtpd_milters = inet:localhost:8891 -non_smtpd_milters = "inet:localhost:8891" +non_smtpd_milters = inet:localhost:8891 smtpd_sasl_auth_enable = yes smtpd_sasl_type = dovecot @@ -63,8 +64,8 @@ smtpd_sasl_local_domain = $mydomain broken_sasl_auth_clients = yes smtpd_tls_security_level = may -smtpd_tls_key_file = /etc/ssl/mailserver.key -smtpd_tls_cert_file = /etc/ssl/mailserver.crt +smtpd_tls_key_file = /etc/ssl/mailcerts/mail.key +smtpd_tls_cert_file = /etc/ssl/mailcerts/mail_chained.crt smtpd_tls_loglevel = 1 smtpd_tls_session_cache_timeout = 3600s smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_tls_cache @@ -74,4 +75,4 @@ tls_random_exchange_name = /var/lib/postfix/prng_exch smtpd_tls_auth_only = yes smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination -smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination \ No newline at end of file +smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination diff --git a/docker/mail/rootfs/etc/postfix/master.cf b/docker/mail/rootfs/etc/postfix/master.cf index fbf0fb0667..8caedc3fab 100644 --- a/docker/mail/rootfs/etc/postfix/master.cf +++ b/docker/mail/rootfs/etc/postfix/master.cf @@ -1,41 +1,126 @@ -smtp inet n - - - - smtpd -8080 inet n - - - - smtpd -smtps inet n - - - - smtpd +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master"). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== +smtp inet n - n - - smtpd +#smtp inet n - n - 1 postscreen +#smtpd pass - - n - - smtpd +#dnsblog unix - - n - 0 dnsblog +#tlsproxy unix - - n - 0 tlsproxy submission inet n - n - - smtpd -pickup fifo n - - 60 1 pickup -cleanup unix n - - - 0 cleanup -qmgr fifo n - n 300 1 qmgr -tlsmgr unix - - - 1000? 1 tlsmgr -rewrite unix - - - - - trivial-rewrite -bounce unix - - - - 0 bounce -defer unix - - - - 0 bounce -trace unix - - - - 0 bounce -verify unix - - - - 1 verify -flush unix n - - 1000? 0 flush -postlog unix-dgram n - n - 1 postlogd +# -o syslog_name=postfix/submission +# -o smtpd_tls_security_level=encrypt +# -o smtpd_sasl_auth_enable=yes +# -o smtpd_reject_unlisted_recipient=no +# -o smtpd_client_restrictions=$mua_client_restrictions +# -o smtpd_helo_restrictions=$mua_helo_restrictions +# -o smtpd_sender_restrictions=$mua_sender_restrictions +# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING +smtps inet n - n - - smtpd + -o syslog_name=postfix/smtps + -o smtpd_tls_wrappermode=yes + -o smtpd_sasl_auth_enable=yes + -o smtpd_reject_unlisted_recipient=no + -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject + -o milter_macro_daemon_name=ORIGINATING +#628 inet n - n - - qmqpd +pickup unix n - n 60 1 pickup +cleanup unix n - n - 0 cleanup +qmgr unix n - n 300 1 qmgr +#qmgr unix n - n 300 1 oqmgr +tlsmgr unix - - n 1000? 1 tlsmgr +rewrite unix - - n - - trivial-rewrite +bounce unix - - n - 0 bounce +defer unix - - n - 0 bounce +trace unix - - n - 0 bounce +verify unix - - n - 1 verify +flush unix n - n 1000? 0 flush proxymap unix - - n - - proxymap proxywrite unix - - n - 1 proxymap -smtp unix - - - - - smtp -relay unix - - - - - smtp -showq unix n - - - - showq -error unix - - - - - error -retry unix - - - - - error -discard unix - - - - - discard +smtp unix - - n - - smtp +relay unix - - n - - smtp +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - n - - showq +error unix - - n - - error +retry unix - - n - - error +discard unix - - n - - discard local unix - n n - - local virtual unix - n n - - virtual -lmtp unix - - - - - lmtp -anvil unix - - - - 1 anvil -scache unix - - - - 1 scache -uucp unix - n n - - pipe - flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) -ifmail unix - n n - - pipe - flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) -bsmtp unix - n n - - pipe - flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient -scalemail-backend unix - n n - 2 pipe - flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension} -mailman unix - n n - - pipe - flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py - ${nexthop} ${user} +lmtp unix - - n - - lmtp +anvil unix - - n - 1 anvil +scache unix - - n - 1 scache +# +# ==================================================================== +# Interfaces to non-Postfix software. Be sure to examine the manual +# pages of the non-Postfix software to find out what options it wants. +# +# Many of the following services use the Postfix pipe(8) delivery +# agent. See the pipe(8) man page for information about ${recipient} +# and other message envelope options. +# ==================================================================== +# +# maildrop. See the Postfix MAILDROP_README file for details. +# Also specify in main.cf: maildrop_destination_recipient_limit=1 +# +#maildrop unix - n n - - pipe +# flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient} +# +# ==================================================================== +# +# Recent Cyrus versions can use the existing "lmtp" master.cf entry. +# +# Specify in cyrus.conf: +# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 +# +# Specify in main.cf one or more of the following: +# mailbox_transport = lmtp:inet:localhost +# virtual_transport = lmtp:inet:localhost +# +# ==================================================================== +# +# Cyrus 2.1.5 (Amos Gouaux) +# Also specify in main.cf: cyrus_destination_recipient_limit=1 +# +#cyrus unix - n n - - pipe +# user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -r ${sender} -m ${extension} ${user} +# +# ==================================================================== +# +# Old example of delivery via Cyrus. +# +#old-cyrus unix - n n - - pipe +# flags=R user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -m ${extension} ${user} +# +# ==================================================================== +# +# See the Postfix UUCP_README file for configuration details. +# +#uucp unix - n n - - pipe +# flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) +# +# ==================================================================== +# +# Other external delivery methods. +# +#ifmail unix - n n - - pipe +# flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) +# +#bsmtp unix - n n - - pipe +# flags=Fq. user=bsmtp argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient +# +#scalemail-backend unix - n n - 2 pipe +# flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store +# ${nexthop} ${user} ${extension} +# +#mailman unix - n n - - pipe +# flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py +# ${nexthop} ${user} dovecot unix - n n - - pipe - flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient} \ No newline at end of file + flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient} diff --git a/docker/mail/rootfs/etc/rsyslogd/rsyslog.conf b/docker/mail/rootfs/etc/rsyslogd/rsyslog.conf new file mode 100644 index 0000000000..4c6bb8f5c1 --- /dev/null +++ b/docker/mail/rootfs/etc/rsyslogd/rsyslog.conf @@ -0,0 +1,91 @@ +# rsyslog configuration file + +# For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html +# If you experience problems, see http://www.rsyslog.com/doc/troubleshoot.html + +#### MODULES #### + +# The imjournal module bellow is now used as a message source instead of imuxsock. +$ModLoad imuxsock # provides support for local system logging (e.g. via logger command) +#$ModLoad imjournal # provides access to the systemd journal +#$ModLoad imklog # reads kernel messages (the same are read from journald) +#$ModLoad immark # provides --MARK-- message capability + +# Provides UDP syslog reception +#$ModLoad imudp +#$UDPServerRun 514 + +# Provides TCP syslog reception +#$ModLoad imtcp +#$InputTCPServerRun 514 + + +#### GLOBAL DIRECTIVES #### + +# Where to place auxiliary files +#$WorkDirectory /var/lib/rsyslog + +# Use default timestamp format +$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat + +# File syncing capability is disabled by default. This feature is usually not required, +# not useful and an extreme performance hit +#$ActionFileEnableSync on + +# Include all config files in /etc/rsyslog.d/ +$IncludeConfig /etc/rsyslog.d/*.conf + +# Turn off message reception via local log socket; +# local messages are retrieved through imjournal now. +$OmitLocalLogging off + +# File to store the position in the journal +# $IMJournalStateFile imjournal.state + + +#### RULES #### + +# Log all kernel messages to the console. +# Logging much else clutters up the screen. +#kern.* /dev/console + +# Log anything (except mail) of level info or higher. +# Don't log private authentication messages! +*.info;mail.none;authpriv.none;cron.none /var/log/messages + +# The authpriv file has restricted access. +authpriv.* /var/log/secure + +# Log all the mail messages in one place. +mail.* -/var/log/maillog + + +# Log cron stuff +cron.* /var/log/cron + +# Everybody gets emergency messages +*.emerg :omusrmsg:* + +# Save news errors of level crit and higher in a special file. +uucp,news.crit /var/log/spooler + +# Save boot messages also to boot.log +local7.* /var/log/boot.log + + +# ### begin forwarding rule ### +# The statement between the begin ... end define a SINGLE forwarding +# rule. They belong together, do NOT split them. If you create multiple +# forwarding rules, duplicate the whole block! +# Remote Logging (we use TCP for reliable delivery) +# +# An on-disk queue is created for this action. If the remote host is +# down, messages are spooled to disk and sent when it is up again. +#$ActionQueueFileName fwdRule1 # unique name prefix for spool files +#$ActionQueueMaxDiskSpace 1g # 1gb space limit (use as much as possible) +#$ActionQueueSaveOnShutdown on # save messages to disk on shutdown +#$ActionQueueType LinkedList # run asynchronously +#$ActionResumeRetryCount -1 # infinite retries if host is down +# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional +#*.* @@remote-host:514 +# ### end of the forwarding rule ### \ No newline at end of file diff --git a/docker/mail/rootfs/etc/rsyslogd/rsyslogd.conf b/docker/mail/rootfs/etc/rsyslogd/rsyslogd.conf deleted file mode 100644 index b6db00f98d..0000000000 --- a/docker/mail/rootfs/etc/rsyslogd/rsyslogd.conf +++ /dev/null @@ -1,44 +0,0 @@ -#### MODULES #### - -# The imjournal module bellow is now used as a message source instead of imuxsock. -$ModLoad imuxsock # provides support for local system logging (e.g. via logger command) - -#### GLOBAL DIRECTIVES #### - -# Where to place auxiliary files -#$WorkDirectory /var/lib/rsyslog - -# Use default timestamp format -$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat - -# Include all config files in /etc/rsyslog.d/ -$IncludeConfig /etc/rsyslog.d/*.conf - -# Turn off message reception via local log socket; -# local messages are retrieved through imjournal now. -$OmitLocalLogging off - -#### RULES #### - -# Log anything (except mail) of level info or higher. -# Don't log private authentication messages! -*.info;mail.none;authpriv.none;cron.none /var/log/messages - -# The authpriv file has restricted access. -authpriv.* /var/log/secure - -# Log all the mail messages in one place. -mail.* -/var/log/maillog - - -# Log cron stuff -cron.* /var/log/cron - -# Everybody gets emergency messages -*.emerg :omusrmsg:* - -# Save news errors of level crit and higher in a special file. -uucp,news.crit /var/log/spooler - -# Save boot messages also to boot.log -local7.* /var/log/boot.log \ No newline at end of file diff --git a/docker/mail/rootfs/usr/bin/new-alias.sh b/docker/mail/rootfs/usr/bin/new-alias.sh index 8912fb73b8..597430c29f 100644 --- a/docker/mail/rootfs/usr/bin/new-alias.sh +++ b/docker/mail/rootfs/usr/bin/new-alias.sh @@ -9,12 +9,13 @@ fi DOMAINPART=$(echo $1 | sed -e "s/^.*\@//") -if ! grep "^$DOMAINPART\s" /etc/mail/domains &> /dev/null; then +if ! grep -q "^$DOMAINPART" /etc/mail/domains +then echo "This server is not responsible for the domain of this alias." exit 1 fi -echo -e "$1\t\t$2" >> /etc/mail/aliases +echo "$1 $2" >> /etc/mail/aliases postmap /etc/mail/aliases postfix reload diff --git a/docker/mail/rootfs/usr/bin/new-domain.sh b/docker/mail/rootfs/usr/bin/new-domain.sh index 534938be38..4d1a31aada 100644 --- a/docker/mail/rootfs/usr/bin/new-domain.sh +++ b/docker/mail/rootfs/usr/bin/new-domain.sh @@ -7,7 +7,7 @@ then exit 1; fi -echo -e "$1" >> /etc/mail/domains +echo "$1 #OK" >> /etc/mail/domains postmap /etc/mail/domains mkdir "/var/mail/$1" chown vmail:vmail "/var/mail/$1" diff --git a/docker/mail/rootfs/usr/bin/new-user.sh b/docker/mail/rootfs/usr/bin/new-user.sh index d8e8c9708f..1cd93292d2 100644 --- a/docker/mail/rootfs/usr/bin/new-user.sh +++ b/docker/mail/rootfs/usr/bin/new-user.sh @@ -18,7 +18,7 @@ fi PASSHASH=$(doveadm pw -s SHA512-CRYPT) -new-alias.sh $1 $1 +/usr/bin/new-alias.sh "$1" "$1" echo "$1 $DOMAINPART/$USERPART/" >> /etc/mail/mailboxes postmap /etc/mail/mailboxes echo "$1:$PASSHASH" >> /etc/mail/passwd diff --git a/docker/mail/rootfs/usr/bin/start.sh b/docker/mail/rootfs/usr/bin/start.sh index 05f43d723b..34381fa455 100644 --- a/docker/mail/rootfs/usr/bin/start.sh +++ b/docker/mail/rootfs/usr/bin/start.sh @@ -1,35 +1,50 @@ #!/bin/sh +# Config postfix postconf -e myhostname="$MAILNAME" postconf -e mydomain="$DOMAINNAME" postconf -e smtpd_tls_cert_file="$SSL_CERT" postconf -e smtpd_tls_key_file="$SSL_KEY" -touch /etc/mail/aliases /etc/mail/domains /etc/mail/mailbox /etc/mail/passwd -if [ ! -d "/var/mail/$DOMAINNAME" ] -then - echo "$DOMAINNAME #OK" >> /etc/mail/domains - mkdir "/var/mail/$DOMAINNAME" - chown vmail:vmail "/var/mail/$DOMAINNAME" -fi -postmap /etc/mail/aliases && postmap /etc/mail/domains && postmap /etc/mail/mailbox - +# Config dovecot sed -i -e "s#^\s*ssl_cert\s*=.*#ssl_cert = $SSL_CERT#" /etc/dovecot/dovecot.conf sed -i -e "s#^\s*ssl_key\s*=.*#ssl_key = $SSL_KEY#" /etc/dovecot/dovecot.conf sed -i -e "s#^\s*hostname\s*=.*#hostname = $MAILNAME#" /etc/dovecot/dovecot.conf sed -i -e "s#^\s*postmaster_address\s*=.*#postmaster_address = $POSTMASTER#" /etc/dovecot/dovecot.conf +# Config dkim sed -i -e "s/#HOSTNAME/$MAILNAME/" /etc/opendkim/TrustedHosts -if [ ! -e "/etc/opendkim/keys/default.private" ] +# Run openssl +if [ ! -e /etc/ssl/.ssl-generated ] then - opendkim-genkey -d "$DOMAINNAME" -D "/etc/opendkim/keys" + openssl genrsa -des3 -passout pass:asdf -out /etc/ssl/mail.pass.key 2048 && \ + openssl rsa -passin pass:asdf -in /etc/ssl/mail.pass.key -out /etc/ssl/mail.key + rm /etc/ssl/mail.pass.key + openssl req -new -key /etc/ssl/mail.key -out /etc/ssl/mail.csr \ + -subj "/C=UK/ST=England/L=London/O=OrgName/OU=IT Department/CN=$MAIL_HOSTNAME_FQDN" + openssl x509 -req -days 365 -in /etc/ssl/mail.csr -signkey /etc/ssl/mail.key -out /etc/ssl/mail.crt + echo "Do not remove this file." >> /etc/ssl/.ssl-generated fi -# Start services +# Run opendkim +if [ ! -e "/var/opendkim/keys/default.private" ] +then + mkdir -p /var/opendkim/keys + opendkim-genkey -d "$DOMAINNAME" -D "/var/opendkim/keys" +fi -rsyslogd -f /etc/rsyslogd/rsyslogd.conf -/usr/sbin/opendkim #-x /etc/opendkim/opendkim.conf -dovecot -c /etc/dovecot/dovecot.conf -postfix start -c /etc/postfix -supervisord -c /etc/supervisord/supervisord.conf +if [ ! -d "/var/mail/$DOMAINNAME" ] +then + touch /etc/mail/aliases /etc/mail/domains /etc/mail/mailboxes /etc/mail/passwd + postmap /etc/mail/aliases && postmap /etc/mail/domains && postmap /etc/mail/mailboxes + /usr/bin/new-domain.sh "$DOMAINNAME" +fi + + +# Start services +rsyslogd -f /etc/rsyslogd/rsyslog.conf +/usr/sbin/opendkim -x /etc/opendkim/opendkim.conf +/usr/sbin/dovecot -c /etc/dovecot/dovecot.conf +/usr/sbin/postfix start -c /etc/postfix +supervisord -c /etc/supervisord/supervisord.conf