mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2024-01-19 02:48:50 +00:00
docs(refactor): Convert more content to use admonitions + improvements
This commit is contained in:
parent
463bc967d2
commit
711b4c9d83
|
@ -6,106 +6,107 @@ title: 'Advanced | LDAP Authentication'
|
|||
|
||||
Getting started with ldap and this mailserver we need to take 3 parts in account:
|
||||
|
||||
* POSTFIX
|
||||
* DOVECOT
|
||||
* SASLAUTHD (this can also be handled by dovecot above)
|
||||
- `postfix`
|
||||
- `dovecot`
|
||||
- `saslauthd` (this can also be handled by dovecot)
|
||||
|
||||
## Variables to Control Provisioning by the Container
|
||||
|
||||
__POSTFIX__:
|
||||
Have a look at the [`ENVIRONMENT.md`][github-file-env] for information on the default values.
|
||||
|
||||
* `LDAP_QUERY_FILTER_USER`
|
||||
* `LDAP_QUERY_FILTER_GROUP`
|
||||
* `LDAP_QUERY_FILTER_ALIAS`
|
||||
* `LDAP_QUERY_FILTER_DOMAIN`
|
||||
!!! example "postfix"
|
||||
|
||||
__SASLAUTHD__:
|
||||
- `LDAP_QUERY_FILTER_USER`
|
||||
- `LDAP_QUERY_FILTER_GROUP`
|
||||
- `LDAP_QUERY_FILTER_ALIAS`
|
||||
- `LDAP_QUERY_FILTER_DOMAIN`
|
||||
|
||||
* `SASLAUTHD_LDAP_FILTER`
|
||||
!!! example "saslauthd"
|
||||
|
||||
__DOVECOT__:
|
||||
- `SASLAUTHD_LDAP_FILTER`
|
||||
|
||||
* `DOVECOT_USER_FILTER`
|
||||
* `DOVECOT_PASS_FILTER`
|
||||
!!! example "dovecot"
|
||||
|
||||
!!! note
|
||||
This page will provide several use cases like recipes to show, how this project can be used with it's LDAP Features.
|
||||
- `DOVECOT_USER_FILTER`
|
||||
- `DOVECOT_PASS_FILTER`
|
||||
|
||||
## LDAP Setup - Kopano / Zarafa
|
||||
|
||||
```yaml
|
||||
---
|
||||
version: '2'
|
||||
???+ example "Example Code"
|
||||
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:latest
|
||||
hostname: mail
|
||||
domainname: domain.com
|
||||
container_name: mail
|
||||
```yaml
|
||||
---
|
||||
version: '2'
|
||||
|
||||
ports:
|
||||
- "25:25"
|
||||
- "143:143"
|
||||
- "587:587"
|
||||
- "993:993"
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:latest
|
||||
hostname: mail
|
||||
domainname: domain.com
|
||||
container_name: mail
|
||||
|
||||
ports:
|
||||
- "25:25"
|
||||
- "143:143"
|
||||
- "587:587"
|
||||
- "993:993"
|
||||
|
||||
volumes:
|
||||
- maildata:/var/mail
|
||||
- mailstate:/var/mail-state
|
||||
- ./config/:/tmp/docker-mailserver/
|
||||
|
||||
environment:
|
||||
# We are not using dovecot here
|
||||
- SMTP_ONLY=1
|
||||
- ENABLE_SPAMASSASSIN=1
|
||||
- ENABLE_CLAMAV=1
|
||||
- ENABLE_FAIL2BAN=1
|
||||
- ENABLE_POSTGREY=1
|
||||
- SASLAUTHD_PASSWD=
|
||||
|
||||
# >>> SASL Authentication
|
||||
- ENABLE_SASLAUTHD=1
|
||||
- SASLAUTHD_LDAP_SERVER=<yourLdapContainer/yourLdapServer>
|
||||
- SASLAUTHD_LDAP_PROTO=
|
||||
- SASLAUTHD_LDAP_BIND_DN=cn=Administrator,cn=Users,dc=mydomain,dc=loc
|
||||
- SASLAUTHD_LDAP_PASSWORD=mypassword
|
||||
- SASLAUTHD_LDAP_SEARCH_BASE=dc=mydomain,dc=loc
|
||||
- SASLAUTHD_LDAP_FILTER=(&(sAMAccountName=%U)(objectClass=person))
|
||||
- SASLAUTHD_MECHANISMS=ldap
|
||||
# <<< SASL Authentication
|
||||
|
||||
# >>> Postfix Ldap Integration
|
||||
- ENABLE_LDAP=1
|
||||
- LDAP_SERVER_HOST=<yourLdapContainer/yourLdapServer>
|
||||
- LDAP_SEARCH_BASE=dc=mydomain,dc=loc
|
||||
- LDAP_BIND_DN=cn=Administrator,cn=Users,dc=mydomain,dc=loc
|
||||
- LDAP_BIND_PW=mypassword
|
||||
- LDAP_QUERY_FILTER_USER=(&(objectClass=user)(mail=%s))
|
||||
- LDAP_QUERY_FILTER_GROUP=(&(objectclass=group)(mail=%s))
|
||||
- LDAP_QUERY_FILTER_ALIAS=(&(objectClass=user)(otherMailbox=%s))
|
||||
- LDAP_QUERY_FILTER_DOMAIN=(&(|(mail=*@%s)(mailalias=*@%s)(mailGroupMember=*@%s))(mailEnabled=TRUE))
|
||||
# <<< Postfix Ldap Integration
|
||||
|
||||
# >>> Kopano Integration
|
||||
- ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1
|
||||
- POSTFIX_DAGENT=lmtp:kopano:2003
|
||||
# <<< Kopano Integration
|
||||
|
||||
- ONE_DIR=1
|
||||
- DMS_DEBUG=0
|
||||
- SSL_TYPE=letsencrypt
|
||||
- PERMIT_DOCKER=host
|
||||
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
|
||||
volumes:
|
||||
- maildata:/var/mail
|
||||
- mailstate:/var/mail-state
|
||||
- ./config/:/tmp/docker-mailserver/
|
||||
|
||||
environment:
|
||||
# We are not using dovecot here
|
||||
- SMTP_ONLY=1
|
||||
- ENABLE_SPAMASSASSIN=1
|
||||
- ENABLE_CLAMAV=1
|
||||
- ENABLE_FAIL2BAN=1
|
||||
- ENABLE_POSTGREY=1
|
||||
- SASLAUTHD_PASSWD=
|
||||
|
||||
# >>> SASL Authentication
|
||||
- ENABLE_SASLAUTHD=1
|
||||
- SASLAUTHD_LDAP_SERVER=<yourLdapContainer/yourLdapServer>
|
||||
- SASLAUTHD_LDAP_PROTO=
|
||||
- SASLAUTHD_LDAP_BIND_DN=cn=Administrator,cn=Users,dc=mydomain,dc=loc
|
||||
- SASLAUTHD_LDAP_PASSWORD=mypassword
|
||||
- SASLAUTHD_LDAP_SEARCH_BASE=dc=mydomain,dc=loc
|
||||
- SASLAUTHD_LDAP_FILTER=(&(sAMAccountName=%U)(objectClass=person))
|
||||
- SASLAUTHD_MECHANISMS=ldap
|
||||
# <<< SASL Authentication
|
||||
|
||||
# >>> Postfix Ldap Integration
|
||||
- ENABLE_LDAP=1
|
||||
- LDAP_SERVER_HOST=<yourLdapContainer/yourLdapServer>
|
||||
- LDAP_SEARCH_BASE=dc=mydomain,dc=loc
|
||||
- LDAP_BIND_DN=cn=Administrator,cn=Users,dc=mydomain,dc=loc
|
||||
- LDAP_BIND_PW=mypassword
|
||||
- LDAP_QUERY_FILTER_USER=(&(objectClass=user)(mail=%s))
|
||||
- LDAP_QUERY_FILTER_GROUP=(&(objectclass=group)(mail=%s))
|
||||
- LDAP_QUERY_FILTER_ALIAS=(&(objectClass=user)(otherMailbox=%s))
|
||||
- LDAP_QUERY_FILTER_DOMAIN=(&(|(mail=*@%s)(mailalias=*@%s)(mailGroupMember=*@%s))(mailEnabled=TRUE))
|
||||
# <<< Postfix Ldap Integration
|
||||
|
||||
# >>> Kopano Integration
|
||||
- ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1
|
||||
- POSTFIX_DAGENT=lmtp:kopano:2003
|
||||
# <<< Kopano Integration
|
||||
|
||||
- ONE_DIR=1
|
||||
- DMS_DEBUG=0
|
||||
- SSL_TYPE=letsencrypt
|
||||
- PERMIT_DOCKER=host
|
||||
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
|
||||
volumes:
|
||||
maildata:
|
||||
driver: local
|
||||
mailstate:
|
||||
driver: local
|
||||
```
|
||||
maildata:
|
||||
driver: local
|
||||
mailstate:
|
||||
driver: local
|
||||
```
|
||||
|
||||
If your directory has not the postfix-book schema installed, then you must change the internal attribute handling for dovecot. For this you have to change the `pass_attr` and the `user_attr` mapping, as shown in the example below:
|
||||
|
||||
|
@ -122,3 +123,5 @@ The following example illustrates this for a directory that has the qmail-schema
|
|||
- DOVECOT_PASS_FILTER=(&(objectClass=qmailUser)(uid=%u)(accountStatus=active))
|
||||
- DOVECOT_USER_FILTER=(&(objectClass=qmailUser)(uid=%u)(accountStatus=active))
|
||||
```
|
||||
|
||||
[github-file-env]: https://github.com/docker-mailserver/docker-mailserver/blob/master/ENVIRONMENT.md
|
|
@ -6,231 +6,258 @@ title: 'Advanced | Kubernetes'
|
|||
|
||||
There is nothing much in deploying mailserver to Kubernetes itself. The things are pretty same as in [`docker-compose.yml`][github-file-compose], but with Kubernetes syntax.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: mailserver
|
||||
---
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver.env.config
|
||||
namespace: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
data:
|
||||
OVERRIDE_HOSTNAME: example.com
|
||||
ENABLE_FETCHMAIL: "0"
|
||||
FETCHMAIL_POLL: "120"
|
||||
ENABLE_SPAMASSASSIN: "0"
|
||||
ENABLE_CLAMAV: "0"
|
||||
ENABLE_FAIL2BAN: "0"
|
||||
ENABLE_POSTGREY: "0"
|
||||
ONE_DIR: "1"
|
||||
DMS_DEBUG: "0"
|
||||
??? example "ConfigMap"
|
||||
|
||||
---
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver.config
|
||||
namespace: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
data:
|
||||
postfix-accounts.cf: |
|
||||
user1@example.com|{SHA512-CRYPT}$6$2YpW1nYtPBs2yLYS$z.5PGH1OEzsHHNhl3gJrc3D.YMZkvKw/vp.r5WIiwya6z7P/CQ9GDEJDr2G2V0cAfjDFeAQPUoopsuWPXLk3u1
|
||||
|
||||
postfix-virtual.cf: |
|
||||
alias1@example.com user1@dexample.com
|
||||
|
||||
#dovecot.cf: |
|
||||
# service stats {
|
||||
# unix_listener stats-reader {
|
||||
# group = docker
|
||||
# mode = 0666
|
||||
# }
|
||||
# unix_listener stats-writer {
|
||||
# group = docker
|
||||
# mode = 0666
|
||||
# }
|
||||
# }
|
||||
|
||||
SigningTable: |
|
||||
*@example.com mail._domainkey.example.com
|
||||
|
||||
KeyTable: |
|
||||
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com-mail.key
|
||||
|
||||
TrustedHosts: |
|
||||
127.0.0.1
|
||||
localhost
|
||||
|
||||
#user-patches.sh: |
|
||||
# #!/bin/bash
|
||||
|
||||
#fetchmail.cf: |
|
||||
|
||||
---
|
||||
kind: Secret
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver.opendkim.keys
|
||||
namespace: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
type: Opaque
|
||||
data:
|
||||
example.com-mail.key: 'base64-encoded-DKIM-key'
|
||||
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver
|
||||
namespace: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
spec:
|
||||
selector:
|
||||
app: mailserver
|
||||
ports:
|
||||
- name: smtp
|
||||
port: 25
|
||||
targetPort: smtp
|
||||
- name: smtp-secure
|
||||
port: 465
|
||||
targetPort: smtp-secure
|
||||
- name: smtp-auth
|
||||
port: 587
|
||||
targetPort: smtp-auth
|
||||
- name: imap
|
||||
port: 143
|
||||
targetPort: imap
|
||||
- name: imap-secure
|
||||
port: 993
|
||||
targetPort: imap-secure
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mailserver
|
||||
namespace: mailserver
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mailserver
|
||||
template:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: mailserver
|
||||
---
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver.env.config
|
||||
namespace: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
role: mail
|
||||
tier: backend
|
||||
spec:
|
||||
#nodeSelector:
|
||||
# kubernetes.io/hostname: local.k8s
|
||||
#initContainers:
|
||||
#- name: init-myservice
|
||||
# image: busybox
|
||||
# command: ["/bin/sh", "-c", "cp /tmp/user-patches.sh /tmp/files"]
|
||||
# volumeMounts:
|
||||
# - name: config
|
||||
# subPath: user-patches.sh
|
||||
# mountPath: /tmp/user-patches.sh
|
||||
# readOnly: true
|
||||
# - name: tmp-files
|
||||
# mountPath: /tmp/files
|
||||
containers:
|
||||
- name: docker-mailserver
|
||||
image: mailserver/docker-mailserver:latest
|
||||
imagePullPolicy: Always
|
||||
volumeMounts:
|
||||
- name: config
|
||||
subPath: postfix-accounts.cf
|
||||
mountPath: /tmp/docker-mailserver/postfix-accounts.cf
|
||||
readOnly: true
|
||||
#- name: config
|
||||
# subPath: postfix-main.cf
|
||||
# mountPath: /tmp/docker-mailserver/postfix-main.cf
|
||||
# readOnly: true
|
||||
- name: config
|
||||
subPath: postfix-virtual.cf
|
||||
mountPath: /tmp/docker-mailserver/postfix-virtual.cf
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: fetchmail.cf
|
||||
mountPath: /tmp/docker-mailserver/fetchmail.cf
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: dovecot.cf
|
||||
mountPath: /tmp/docker-mailserver/dovecot.cf
|
||||
readOnly: true
|
||||
#- name: config
|
||||
# subPath: user1.example.com.dovecot.sieve
|
||||
# mountPath: /tmp/docker-mailserver/user1@example.com.dovecot.sieve
|
||||
# readOnly: true
|
||||
#- name: tmp-files
|
||||
# subPath: user-patches.sh
|
||||
# mountPath: /tmp/docker-mailserver/user-patches.sh
|
||||
- name: config
|
||||
subPath: SigningTable
|
||||
mountPath: /tmp/docker-mailserver/opendkim/SigningTable
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: KeyTable
|
||||
mountPath: /tmp/docker-mailserver/opendkim/KeyTable
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: TrustedHosts
|
||||
mountPath: /tmp/docker-mailserver/opendkim/TrustedHosts
|
||||
readOnly: true
|
||||
- name: opendkim-keys
|
||||
mountPath: /tmp/docker-mailserver/opendkim/keys
|
||||
readOnly: true
|
||||
- name: data
|
||||
mountPath: /var/mail
|
||||
subPath: data
|
||||
- name: data
|
||||
mountPath: /var/mail-state
|
||||
subPath: state
|
||||
- name: data
|
||||
mountPath: /var/log/mail
|
||||
subPath: log
|
||||
ports:
|
||||
- name: smtp
|
||||
containerPort: 25
|
||||
protocol: TCP
|
||||
- name: smtp-secure
|
||||
containerPort: 465
|
||||
protocol: TCP
|
||||
- name: smtp-auth
|
||||
containerPort: 587
|
||||
- name: imap
|
||||
containerPort: 143
|
||||
protocol: TCP
|
||||
- name: imap-secure
|
||||
containerPort: 993
|
||||
protocol: TCP
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: mailserver.env.config
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: mailserver.config
|
||||
- name: opendkim-keys
|
||||
secret:
|
||||
secretName: mailserver.opendkim.keys
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: mail-storage
|
||||
- name: tmp-files
|
||||
emptyDir: {}
|
||||
```
|
||||
data:
|
||||
OVERRIDE_HOSTNAME: example.com
|
||||
ENABLE_FETCHMAIL: "0"
|
||||
FETCHMAIL_POLL: "120"
|
||||
ENABLE_SPAMASSASSIN: "0"
|
||||
ENABLE_CLAMAV: "0"
|
||||
ENABLE_FAIL2BAN: "0"
|
||||
ENABLE_POSTGREY: "0"
|
||||
ONE_DIR: "1"
|
||||
DMS_DEBUG: "0"
|
||||
|
||||
!!! note
|
||||
---
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver.config
|
||||
namespace: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
data:
|
||||
postfix-accounts.cf: |
|
||||
user1@example.com|{SHA512-CRYPT}$6$2YpW1nYtPBs2yLYS$z.5PGH1OEzsHHNhl3gJrc3D.YMZkvKw/vp.r5WIiwya6z7P/CQ9GDEJDr2G2V0cAfjDFeAQPUoopsuWPXLk3u1
|
||||
|
||||
postfix-virtual.cf: |
|
||||
alias1@example.com user1@dexample.com
|
||||
|
||||
#dovecot.cf: |
|
||||
# service stats {
|
||||
# unix_listener stats-reader {
|
||||
# group = docker
|
||||
# mode = 0666
|
||||
# }
|
||||
# unix_listener stats-writer {
|
||||
# group = docker
|
||||
# mode = 0666
|
||||
# }
|
||||
# }
|
||||
|
||||
SigningTable: |
|
||||
*@example.com mail._domainkey.example.com
|
||||
|
||||
KeyTable: |
|
||||
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com-mail.key
|
||||
|
||||
TrustedHosts: |
|
||||
127.0.0.1
|
||||
localhost
|
||||
|
||||
#user-patches.sh: |
|
||||
# #!/bin/bash
|
||||
|
||||
#fetchmail.cf: |
|
||||
```
|
||||
|
||||
??? example "Secret"
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: mailserver
|
||||
---
|
||||
kind: Secret
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver.opendkim.keys
|
||||
namespace: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
type: Opaque
|
||||
data:
|
||||
example.com-mail.key: 'base64-encoded-DKIM-key'
|
||||
```
|
||||
|
||||
??? example "Service"
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: mailserver
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver
|
||||
namespace: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
spec:
|
||||
selector:
|
||||
app: mailserver
|
||||
ports:
|
||||
- name: smtp
|
||||
port: 25
|
||||
targetPort: smtp
|
||||
- name: smtp-secure
|
||||
port: 465
|
||||
targetPort: smtp-secure
|
||||
- name: smtp-auth
|
||||
port: 587
|
||||
targetPort: smtp-auth
|
||||
- name: imap
|
||||
port: 143
|
||||
targetPort: imap
|
||||
- name: imap-secure
|
||||
port: 993
|
||||
targetPort: imap-secure
|
||||
```
|
||||
|
||||
??? example "Deployment"
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: mailserver
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mailserver
|
||||
namespace: mailserver
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mailserver
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mailserver
|
||||
role: mail
|
||||
tier: backend
|
||||
spec:
|
||||
#nodeSelector:
|
||||
# kubernetes.io/hostname: local.k8s
|
||||
#initContainers:
|
||||
#- name: init-myservice
|
||||
# image: busybox
|
||||
# command: ["/bin/sh", "-c", "cp /tmp/user-patches.sh /tmp/files"]
|
||||
# volumeMounts:
|
||||
# - name: config
|
||||
# subPath: user-patches.sh
|
||||
# mountPath: /tmp/user-patches.sh
|
||||
# readOnly: true
|
||||
# - name: tmp-files
|
||||
# mountPath: /tmp/files
|
||||
containers:
|
||||
- name: docker-mailserver
|
||||
image: mailserver/docker-mailserver:latest
|
||||
imagePullPolicy: Always
|
||||
volumeMounts:
|
||||
- name: config
|
||||
subPath: postfix-accounts.cf
|
||||
mountPath: /tmp/docker-mailserver/postfix-accounts.cf
|
||||
readOnly: true
|
||||
#- name: config
|
||||
# subPath: postfix-main.cf
|
||||
# mountPath: /tmp/docker-mailserver/postfix-main.cf
|
||||
# readOnly: true
|
||||
- name: config
|
||||
subPath: postfix-virtual.cf
|
||||
mountPath: /tmp/docker-mailserver/postfix-virtual.cf
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: fetchmail.cf
|
||||
mountPath: /tmp/docker-mailserver/fetchmail.cf
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: dovecot.cf
|
||||
mountPath: /tmp/docker-mailserver/dovecot.cf
|
||||
readOnly: true
|
||||
#- name: config
|
||||
# subPath: user1.example.com.dovecot.sieve
|
||||
# mountPath: /tmp/docker-mailserver/user1@example.com.dovecot.sieve
|
||||
# readOnly: true
|
||||
#- name: tmp-files
|
||||
# subPath: user-patches.sh
|
||||
# mountPath: /tmp/docker-mailserver/user-patches.sh
|
||||
- name: config
|
||||
subPath: SigningTable
|
||||
mountPath: /tmp/docker-mailserver/opendkim/SigningTable
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: KeyTable
|
||||
mountPath: /tmp/docker-mailserver/opendkim/KeyTable
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: TrustedHosts
|
||||
mountPath: /tmp/docker-mailserver/opendkim/TrustedHosts
|
||||
readOnly: true
|
||||
- name: opendkim-keys
|
||||
mountPath: /tmp/docker-mailserver/opendkim/keys
|
||||
readOnly: true
|
||||
- name: data
|
||||
mountPath: /var/mail
|
||||
subPath: data
|
||||
- name: data
|
||||
mountPath: /var/mail-state
|
||||
subPath: state
|
||||
- name: data
|
||||
mountPath: /var/log/mail
|
||||
subPath: log
|
||||
ports:
|
||||
- name: smtp
|
||||
containerPort: 25
|
||||
protocol: TCP
|
||||
- name: smtp-secure
|
||||
containerPort: 465
|
||||
protocol: TCP
|
||||
- name: smtp-auth
|
||||
containerPort: 587
|
||||
- name: imap
|
||||
containerPort: 143
|
||||
protocol: TCP
|
||||
- name: imap-secure
|
||||
containerPort: 993
|
||||
protocol: TCP
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: mailserver.env.config
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: mailserver.config
|
||||
- name: opendkim-keys
|
||||
secret:
|
||||
secretName: mailserver.opendkim.keys
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: mail-storage
|
||||
- name: tmp-files
|
||||
emptyDir: {}
|
||||
```
|
||||
|
||||
!!! warning
|
||||
Any sensitive data (keys, etc) should be deployed via [Secrets][k8s-config-secret]. Other configuration just fits well into [ConfigMaps][k8s-config-pod].
|
||||
|
||||
!!! note
|
||||
|
@ -246,54 +273,58 @@ Preserving real client IP is relatively [non-trivial in Kubernetes][k8s-service-
|
|||
|
||||
If you do not require SPF checks for incoming mails you may disable them in [Postfix configuration][docs-postfix] by dropping following line (which removes `check_policy_service unix:private/policyd-spf` option):
|
||||
|
||||
```yaml
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver.config
|
||||
labels:
|
||||
app: mailserver
|
||||
data:
|
||||
postfix-main.cf: |
|
||||
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_unauth_pipelining, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_recipient_domain, reject_rbl_client zen.spamhaus.org, reject_rbl_client bl.spamcop.net
|
||||
# ...
|
||||
!!! example
|
||||
|
||||
---
|
||||
```yaml
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver.config
|
||||
labels:
|
||||
app: mailserver
|
||||
data:
|
||||
postfix-main.cf: |
|
||||
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_unauth_pipelining, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_recipient_domain, reject_rbl_client zen.spamhaus.org, reject_rbl_client bl.spamcop.net
|
||||
# ...
|
||||
|
||||
kind: Deployment
|
||||
apiVersion: extensions/v1beta1
|
||||
metadata:
|
||||
name: mailserver
|
||||
# ...
|
||||
volumeMounts:
|
||||
- name: config
|
||||
subPath: postfix-main.cf
|
||||
mountPath: /tmp/docker-mailserver/postfix-main.cf
|
||||
readOnly: true
|
||||
```
|
||||
---
|
||||
|
||||
kind: Deployment
|
||||
apiVersion: extensions/v1beta1
|
||||
metadata:
|
||||
name: mailserver
|
||||
# ...
|
||||
volumeMounts:
|
||||
- name: config
|
||||
subPath: postfix-main.cf
|
||||
mountPath: /tmp/docker-mailserver/postfix-main.cf
|
||||
readOnly: true
|
||||
```
|
||||
|
||||
### External IPs Service
|
||||
|
||||
The simplest way is to expose mailserver as a [Service][k8s-network-service] with [external IPs][k8s-network-external-ip].
|
||||
|
||||
```yaml
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
spec:
|
||||
selector:
|
||||
app: mailserver
|
||||
ports:
|
||||
- name: smtp
|
||||
port: 25
|
||||
targetPort: smtp
|
||||
# ...
|
||||
externalIPs:
|
||||
- 80.11.12.10
|
||||
```
|
||||
!!! example
|
||||
|
||||
```yaml
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
spec:
|
||||
selector:
|
||||
app: mailserver
|
||||
ports:
|
||||
- name: smtp
|
||||
port: 25
|
||||
targetPort: smtp
|
||||
# ...
|
||||
externalIPs:
|
||||
- 80.11.12.10
|
||||
```
|
||||
|
||||
**Downsides**
|
||||
|
||||
|
@ -313,29 +344,31 @@ The [Proxy Pod][k8s-proxy-service] helps to avoid necessity of specifying extern
|
|||
|
||||
The simplest way to preserve real client IP is to use `hostPort` and `hostNetwork: true` in the mailserver [Pod][k8s-workload-pod]. This comes in price of availability: you can talk to mailserver from outside world only via IPs of [Node][k8s-nodes] where mailserver is deployed.
|
||||
|
||||
```yaml
|
||||
kind: Deployment
|
||||
apiVersion: extensions/v1beta1
|
||||
metadata:
|
||||
name: mailserver
|
||||
# ...
|
||||
spec:
|
||||
hostNetwork: true
|
||||
# ...
|
||||
containers:
|
||||
# ...
|
||||
ports:
|
||||
- name: smtp
|
||||
containerPort: 25
|
||||
hostPort: 25
|
||||
- name: smtp-auth
|
||||
containerPort: 587
|
||||
hostPort: 587
|
||||
- name: imap-secure
|
||||
containerPort: 993
|
||||
hostPort: 993
|
||||
# ...
|
||||
```
|
||||
!!! example
|
||||
|
||||
```yaml
|
||||
kind: Deployment
|
||||
apiVersion: extensions/v1beta1
|
||||
metadata:
|
||||
name: mailserver
|
||||
# ...
|
||||
spec:
|
||||
hostNetwork: true
|
||||
# ...
|
||||
containers:
|
||||
# ...
|
||||
ports:
|
||||
- name: smtp
|
||||
containerPort: 25
|
||||
hostPort: 25
|
||||
- name: smtp-auth
|
||||
containerPort: 587
|
||||
hostPort: 587
|
||||
- name: imap-secure
|
||||
containerPort: 993
|
||||
hostPort: 993
|
||||
# ...
|
||||
```
|
||||
|
||||
**Downsides**
|
||||
|
||||
|
@ -363,53 +396,55 @@ With [HAProxy][dockerhub-haproxy], the configuration should look similar to the
|
|||
|
||||
Then, configure both [Postfix][docs-postfix] and [Dovecot][docs-dovecot] to expect the PROXY protocol:
|
||||
|
||||
```yaml
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver.config
|
||||
labels:
|
||||
app: mailserver
|
||||
data:
|
||||
postfix-main.cf: |
|
||||
postscreen_upstream_proxy_protocol = haproxy
|
||||
postfix-master.cf: |
|
||||
submission/inet/smtpd_upstream_proxy_protocol=haproxy
|
||||
smtps/inet/smtpd_upstream_proxy_protocol=haproxy
|
||||
dovecot.cf: |
|
||||
# Assuming your ingress controller is bound to 10.0.0.0/8
|
||||
haproxy_trusted_networks = 10.0.0.0/8, 127.0.0.0/8
|
||||
service imap-login {
|
||||
inet_listener imaps {
|
||||
haproxy = yes
|
||||
}
|
||||
}
|
||||
# ...
|
||||
---
|
||||
!!! example
|
||||
|
||||
kind: Deployment
|
||||
apiVersion: extensions/v1beta1
|
||||
metadata:
|
||||
name: mailserver
|
||||
spec:
|
||||
template:
|
||||
```yaml
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: mailserver.config
|
||||
labels:
|
||||
app: mailserver
|
||||
data:
|
||||
postfix-main.cf: |
|
||||
postscreen_upstream_proxy_protocol = haproxy
|
||||
postfix-master.cf: |
|
||||
submission/inet/smtpd_upstream_proxy_protocol=haproxy
|
||||
smtps/inet/smtpd_upstream_proxy_protocol=haproxy
|
||||
dovecot.cf: |
|
||||
# Assuming your ingress controller is bound to 10.0.0.0/8
|
||||
haproxy_trusted_networks = 10.0.0.0/8, 127.0.0.0/8
|
||||
service imap-login {
|
||||
inet_listener imaps {
|
||||
haproxy = yes
|
||||
}
|
||||
}
|
||||
# ...
|
||||
---
|
||||
|
||||
kind: Deployment
|
||||
apiVersion: extensions/v1beta1
|
||||
metadata:
|
||||
name: mailserver
|
||||
spec:
|
||||
containers:
|
||||
- name: docker-mailserver
|
||||
volumeMounts:
|
||||
- name: config
|
||||
subPath: postfix-main.cf
|
||||
mountPath: /tmp/docker-mailserver/postfix-main.cf
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: postfix-master.cf
|
||||
mountPath: /tmp/docker-mailserver/postfix-master.cf
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: dovecot.cf
|
||||
mountPath: /tmp/docker-mailserver/dovecot.cf
|
||||
readOnly: true
|
||||
```
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: docker-mailserver
|
||||
volumeMounts:
|
||||
- name: config
|
||||
subPath: postfix-main.cf
|
||||
mountPath: /tmp/docker-mailserver/postfix-main.cf
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: postfix-master.cf
|
||||
mountPath: /tmp/docker-mailserver/postfix-master.cf
|
||||
readOnly: true
|
||||
- name: config
|
||||
subPath: dovecot.cf
|
||||
mountPath: /tmp/docker-mailserver/dovecot.cf
|
||||
readOnly: true
|
||||
```
|
||||
|
||||
**Downsides**
|
||||
|
||||
|
@ -419,52 +454,56 @@ spec:
|
|||
|
||||
[Kube-Lego][kube-lego] may be used for a role of Let's Encrypt client. It works with Kubernetes [Ingress Resources][k8s-network-ingress] and automatically issues/manages certificates/keys for exposed services via Ingresses.
|
||||
|
||||
```yaml
|
||||
kind: Ingress
|
||||
apiVersion: extensions/v1beta1
|
||||
metadata:
|
||||
name: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
annotations:
|
||||
kubernetes.io/tls-acme: 'true'
|
||||
spec:
|
||||
rules:
|
||||
- host: example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: default-backend
|
||||
servicePort: 80
|
||||
tls:
|
||||
- secretName: mailserver.tls
|
||||
hosts:
|
||||
- example.com
|
||||
```
|
||||
!!! example
|
||||
|
||||
```yaml
|
||||
kind: Ingress
|
||||
apiVersion: extensions/v1beta1
|
||||
metadata:
|
||||
name: mailserver
|
||||
labels:
|
||||
app: mailserver
|
||||
annotations:
|
||||
kubernetes.io/tls-acme: 'true'
|
||||
spec:
|
||||
rules:
|
||||
- host: example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: default-backend
|
||||
servicePort: 80
|
||||
tls:
|
||||
- secretName: mailserver.tls
|
||||
hosts:
|
||||
- example.com
|
||||
```
|
||||
|
||||
Now, you can use Let's Encrypt cert and key from `mailserver.tls` [Secret][k8s-config-secret] in your [Pod][k8s-workload-pod] spec:
|
||||
|
||||
```yaml
|
||||
# ...
|
||||
env:
|
||||
- name: SSL_TYPE
|
||||
value: 'manual'
|
||||
- name: SSL_CERT_PATH
|
||||
value: '/etc/ssl/mailserver/tls.crt'
|
||||
- name: SSL_KEY_PATH
|
||||
value: '/etc/ssl/mailserver/tls.key'
|
||||
# ...
|
||||
volumeMounts:
|
||||
- name: tls
|
||||
mountPath: /etc/ssl/mailserver
|
||||
readOnly: true
|
||||
# ...
|
||||
volumes:
|
||||
- name: tls
|
||||
secret:
|
||||
secretName: mailserver.tls
|
||||
```
|
||||
!!! example
|
||||
|
||||
```yaml
|
||||
# ...
|
||||
env:
|
||||
- name: SSL_TYPE
|
||||
value: 'manual'
|
||||
- name: SSL_CERT_PATH
|
||||
value: '/etc/ssl/mailserver/tls.crt'
|
||||
- name: SSL_KEY_PATH
|
||||
value: '/etc/ssl/mailserver/tls.key'
|
||||
# ...
|
||||
volumeMounts:
|
||||
- name: tls
|
||||
mountPath: /etc/ssl/mailserver
|
||||
readOnly: true
|
||||
# ...
|
||||
volumes:
|
||||
- name: tls
|
||||
secret:
|
||||
secretName: mailserver.tls
|
||||
```
|
||||
|
||||
[docs-dovecot]: ./override-defaults/dovecot.md
|
||||
[docs-postfix]: ./override-defaults/postfix.md
|
||||
|
|
|
@ -26,25 +26,29 @@ Generate a file called `fetchmail.cf` and place it in the `config` folder. Your
|
|||
|
||||
A detailed description of the configuration options can be found in the [online version of the manual page][fetchmail-docs].
|
||||
|
||||
### Example IMAP Configuration
|
||||
### IMAP Configuration
|
||||
|
||||
```fetchmailrc
|
||||
poll 'imap.example.com' proto imap
|
||||
user 'username'
|
||||
pass 'secret'
|
||||
is 'user1@domain.tld'
|
||||
ssl
|
||||
```
|
||||
!!! example
|
||||
|
||||
### Example POP3 Configuration
|
||||
```fetchmailrc
|
||||
poll 'imap.example.com' proto imap
|
||||
user 'username'
|
||||
pass 'secret'
|
||||
is 'user1@domain.tld'
|
||||
ssl
|
||||
```
|
||||
|
||||
```fetchmailrc
|
||||
poll 'pop3.example.com' proto pop3
|
||||
user 'username'
|
||||
pass 'secret'
|
||||
is 'user2@domain.tld'
|
||||
ssl
|
||||
```
|
||||
### POP3 Configuration
|
||||
|
||||
!!! example
|
||||
|
||||
```fetchmailrc
|
||||
poll 'pop3.example.com' proto pop3
|
||||
user 'username'
|
||||
pass 'secret'
|
||||
is 'user2@domain.tld'
|
||||
ssl
|
||||
```
|
||||
|
||||
!!! caution
|
||||
Don’t forget the last line: eg: `is 'user1@domain.tld'`. After `is` you have to specify one email address from the configuration file `config/postfix-accounts.cf`.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
title: 'Mail Forwarding | AWS SES'
|
||||
---
|
||||
|
||||
!!! note
|
||||
!!! warning
|
||||
New configuration, see [Configure Relay Hosts][docs-relay]
|
||||
|
||||
Instead of letting postfix deliver mail directly it is possible to configure it to deliver outgoing email via Amazon SES (Simple Email Service). (Receiving inbound email via SES is not implemented.) The configuration follows the guidelines provided by AWS in https://docs.aws.amazon.com/ses/latest/DeveloperGuide/postfix.html, specifically, the `STARTTLS` method.
|
||||
|
|
|
@ -12,14 +12,14 @@ Depending on the domain of the sender, you may want to send via a different rela
|
|||
|
||||
Basic configuration is done via environment variables:
|
||||
|
||||
* **RELAY_HOST** _default host to relay mail through, empty will disable this feature_
|
||||
* **RELAY_PORT** _port on default relay, defaults to port 25_
|
||||
* **RELAY_USER** _username for the default relay_
|
||||
* **RELAY_PASSWORD** _password for the default user_
|
||||
* `RELAY_HOST`: _default host to relay mail through, empty will disable this feature_
|
||||
* `RELAY_PORT`: _port on default relay, defaults to port 25_
|
||||
* `RELAY_USER`: _username for the default relay_
|
||||
* `RELAY_PASSWORD`: _password for the default user_
|
||||
|
||||
Setting these environment variables will cause mail for all sender domains to be routed via the specified host, authenticating with the user/password combination.
|
||||
|
||||
!!! note
|
||||
!!! warning
|
||||
For users of the previous `AWS_SES_*` variables: please update your configuration to use these new variables, no other configuration is required.
|
||||
|
||||
## Advanced Configuration
|
||||
|
|
|
@ -19,32 +19,38 @@ It's even possible to install a user provided Sieve filter at startup during use
|
|||
|
||||
An example of a sieve filter that moves mails to a folder `INBOX/spam` depending on the sender address:
|
||||
|
||||
```sieve
|
||||
require ["fileinto", "reject"];
|
||||
!!! example
|
||||
|
||||
if address :contains ["From"] "spam@spam.com" {
|
||||
fileinto "INBOX.spam";
|
||||
} else {
|
||||
keep;
|
||||
}
|
||||
```
|
||||
```sieve
|
||||
require ["fileinto", "reject"];
|
||||
|
||||
!!! note
|
||||
if address :contains ["From"] "spam@spam.com" {
|
||||
fileinto "INBOX.spam";
|
||||
} else {
|
||||
keep;
|
||||
}
|
||||
```
|
||||
|
||||
!!! warning
|
||||
That folders have to exist beforehand if sieve should move them.
|
||||
|
||||
Another example of a sieve filter that forward mails to a different address:
|
||||
|
||||
```sieve
|
||||
require ["copy"];
|
||||
!!! example
|
||||
|
||||
redirect :copy "user2@otherdomain.tld";
|
||||
```
|
||||
```sieve
|
||||
require ["copy"];
|
||||
|
||||
redirect :copy "user2@otherdomain.tld";
|
||||
```
|
||||
|
||||
Just forward all incoming emails and do not save them locally:
|
||||
|
||||
```sieve
|
||||
redirect "user2@otherdomain.tld";
|
||||
```
|
||||
!!! example
|
||||
|
||||
```sieve
|
||||
redirect "user2@otherdomain.tld";
|
||||
```
|
||||
|
||||
You can also use external programs to filter or pipe (process) messages by adding executable scripts in `config/sieve-pipe` or `config/sieve-filter`. This can be used in lieu of a local alias file, for instance to forward an email to a webservice. These programs can then be referenced by filename, by all users. Note that the process running the scripts run as a privileged user. For further information see [Dovecot's wiki](https://wiki.dovecot.org/Pigeonhole/Sieve/Plugins/Pipe).
|
||||
|
||||
|
@ -59,13 +65,15 @@ For more examples or a detailed description of the Sieve language have a look at
|
|||
|
||||
The [Manage Sieve](https://doc.dovecot.org/admin_manual/pigeonhole_managesieve_server/) extension allows users to modify their Sieve script by themselves. The authentication mechanisms are the same as for the main dovecot service. ManageSieve runs on port `4190` and needs to be enabled using the `ENABLE_MANAGESIEVE=1` environment variable.
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
ports:
|
||||
- "4190:4190"
|
||||
environment:
|
||||
- ENABLE_MANAGESIEVE=1
|
||||
```
|
||||
!!! example
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
ports:
|
||||
- "4190:4190"
|
||||
environment:
|
||||
- ENABLE_MANAGESIEVE=1
|
||||
```
|
||||
|
||||
All user defined sieve scripts that are managed by ManageSieve are stored in the user's home folder in `/var/mail/domain.com/user1/sieve`. Just one sieve script might be active for a user and is sym-linked to `/var/mail/domain.com/user1/.dovecot.sieve` automatically.
|
||||
|
||||
|
@ -73,4 +81,5 @@ All user defined sieve scripts that are managed by ManageSieve are stored in the
|
|||
ManageSieve makes sure to not overwrite an existing `.dovecot.sieve` file. If a user activates a new sieve script the old one is backuped and moved to the `sieve` folder.
|
||||
|
||||
The extension is known to work with the following ManageSieve clients:
|
||||
* **Sieve Editor** a portable standalone application based on the former Thunderbird plugin (https://github.com/thsmi/sieve).
|
||||
|
||||
- **Sieve Editor** a portable standalone application based on the former Thunderbird plugin (https://github.com/thsmi/sieve).
|
||||
|
|
|
@ -48,7 +48,7 @@ To debug your dovecot configuration you can use:
|
|||
- Or: `docker exec -it <your-container-name> doveconf | grep <some-keyword>`
|
||||
|
||||
!!! note
|
||||
[`setup.sh`][github-file-setupsh] is included in the `docker-mailserver` repository.
|
||||
[`setup.sh`][github-file-setupsh] is included in the `docker-mailserver` repository. Make sure to grap the one matching your image version.
|
||||
|
||||
The `config/dovecot.cf` is copied internally to `/etc/dovecot/local.conf`. To check this file run:
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@ message_size_limit = 52428800
|
|||
|
||||
That specific example is now supported and can be handled by setting `POSTFIX_MESSAGE_SIZE_LIMIT`.
|
||||
|
||||
[Postfix documentation](http://www.postfix.org/documentation.html) remains the best place to find configuration options.
|
||||
!!! seealso
|
||||
|
||||
[Postfix documentation](http://www.postfix.org/documentation.html) remains the best place to find configuration options.
|
||||
|
||||
Each line in the provided file will be loaded into postfix.
|
||||
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
title: 'Best Practices | DKIM'
|
||||
---
|
||||
|
||||
DKIM is a security measure targeting email spoofing. It is greatly recommended one activates it. See [the Wikipedia page](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) for more details on DKIM.
|
||||
DKIM is a security measure targeting email spoofing. It is greatly recommended one activates it.
|
||||
|
||||
!!! seealso
|
||||
See [the Wikipedia page](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) for more details on DKIM.
|
||||
|
||||
## Enabling DKIM Signature
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@ hide:
|
|||
- toc # Hide Table of Contents for this page
|
||||
---
|
||||
|
||||
DMARC Guide: https://github.com/internetstandards/toolbox-wiki/blob/master/DMARC-how-to.md
|
||||
!!! seealso
|
||||
DMARC Guide: https://github.com/internetstandards/toolbox-wiki/blob/master/DMARC-how-to.md
|
||||
|
||||
## Enabling DMARC
|
||||
|
||||
|
|
|
@ -6,9 +6,11 @@ hide:
|
|||
|
||||
From [Wikipedia](https://en.wikipedia.org/wiki/Sender_Policy_Framework):
|
||||
|
||||
> Sender Policy Framework (SPF) is a simple email-validation system designed to detect email spoofing by providing a mechanism to allow receiving mail exchangers to check that incoming mail from a domain comes from a host authorized by that domain's administrators. The list of authorized sending hosts for a domain is published in the Domain Name System (DNS) records for that domain in the form of a specially formatted TXT record. Email spam and phishing often use forged "from" addresses, so publishing and checking SPF records can be considered anti-spam techniques.
|
||||
!!! quote
|
||||
Sender Policy Framework (SPF) is a simple email-validation system designed to detect email spoofing by providing a mechanism to allow receiving mail exchangers to check that incoming mail from a domain comes from a host authorized by that domain's administrators. The list of authorized sending hosts for a domain is published in the Domain Name System (DNS) records for that domain in the form of a specially formatted TXT record. Email spam and phishing often use forged "from" addresses, so publishing and checking SPF records can be considered anti-spam techniques.
|
||||
|
||||
For a more technical review: https://github.com/internetstandards/toolbox-wiki/blob/master/SPF-how-to.md
|
||||
!!! seealso
|
||||
For a more technical review: https://github.com/internetstandards/toolbox-wiki/blob/master/SPF-how-to.md
|
||||
|
||||
## Add a SPF Record
|
||||
|
||||
|
|
|
@ -4,10 +4,11 @@ hide:
|
|||
- toc # Hide Table of Contents for this page
|
||||
---
|
||||
|
||||
**We do not recommend using POP. Use IMAP instead.**
|
||||
!!! warning
|
||||
|
||||
If you really want to have POP3 running, add 3 lines to the docker-compose.yml :
|
||||
Add the ports 110 and 995, and add environment variable ENABLE_POP :
|
||||
**We do not recommend using POP3. Use IMAP instead.**
|
||||
|
||||
If you really want to have POP3 running add the ports 110 and 995 and the environment variable `ENABLE_POP3` to your `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
mail:
|
||||
|
|
|
@ -134,98 +134,102 @@ Then: `/path/to/mailserver/docker-compose up -d mail`
|
|||
|
||||
The following `docker-compose.yml` is the basic setup you need for using `letsencrypt-nginx-proxy-companion`. It is mainly derived from its own wiki/documenation.
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
???+ example "Example Code"
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
|
||||
services:
|
||||
nginx:
|
||||
image: nginx
|
||||
container_name: nginx
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
volumes:
|
||||
- /mnt/data/nginx/htpasswd:/etc/nginx/htpasswd
|
||||
- /mnt/data/nginx/conf.d:/etc/nginx/conf.d
|
||||
- /mnt/data/nginx/vhost.d:/etc/nginx/vhost.d
|
||||
- /mnt/data/nginx/html:/usr/share/nginx/html
|
||||
- /mnt/data/nginx/certs:/etc/nginx/certs:ro
|
||||
networks:
|
||||
- proxy-tier
|
||||
restart: always
|
||||
|
||||
nginx-gen:
|
||||
image: jwilder/docker-gen
|
||||
container_name: nginx-gen
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- /mnt/data/nginx/templates/nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro
|
||||
volumes_from:
|
||||
- nginx
|
||||
entrypoint: /usr/local/bin/docker-gen -notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
|
||||
restart: always
|
||||
|
||||
letsencrypt-nginx-proxy-companion:
|
||||
image: jrcs/letsencrypt-nginx-proxy-companion
|
||||
container_name: letsencrypt-companion
|
||||
volumes_from:
|
||||
- nginx
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- /mnt/data/nginx/certs:/etc/nginx/certs:rw
|
||||
environment:
|
||||
- NGINX_DOCKER_GEN_CONTAINER=nginx-gen
|
||||
- DEBUG=false
|
||||
restart: always
|
||||
|
||||
services:
|
||||
nginx:
|
||||
image: nginx
|
||||
container_name: nginx
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
volumes:
|
||||
- /mnt/data/nginx/htpasswd:/etc/nginx/htpasswd
|
||||
- /mnt/data/nginx/conf.d:/etc/nginx/conf.d
|
||||
- /mnt/data/nginx/vhost.d:/etc/nginx/vhost.d
|
||||
- /mnt/data/nginx/html:/usr/share/nginx/html
|
||||
- /mnt/data/nginx/certs:/etc/nginx/certs:ro
|
||||
networks:
|
||||
- proxy-tier
|
||||
restart: always
|
||||
|
||||
nginx-gen:
|
||||
image: jwilder/docker-gen
|
||||
container_name: nginx-gen
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
- /mnt/data/nginx/templates/nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro
|
||||
volumes_from:
|
||||
- nginx
|
||||
entrypoint: /usr/local/bin/docker-gen -notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
|
||||
restart: always
|
||||
|
||||
letsencrypt-nginx-proxy-companion:
|
||||
image: jrcs/letsencrypt-nginx-proxy-companion
|
||||
container_name: letsencrypt-companion
|
||||
volumes_from:
|
||||
- nginx
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- /mnt/data/nginx/certs:/etc/nginx/certs:rw
|
||||
environment:
|
||||
- NGINX_DOCKER_GEN_CONTAINER=nginx-gen
|
||||
- DEBUG=false
|
||||
restart: always
|
||||
|
||||
networks:
|
||||
proxy-tier:
|
||||
external:
|
||||
name: nginx-proxy
|
||||
```
|
||||
proxy-tier:
|
||||
external:
|
||||
name: nginx-proxy
|
||||
```
|
||||
|
||||
The second part of the setup is the actual mail container. So, in another folder, create another `docker-compose.yml` with the following content (Removed all ENV variables for this example):
|
||||
|
||||
```yaml
|
||||
version: '2'
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:latest
|
||||
hostname: ${HOSTNAME}
|
||||
domainname: ${DOMAINNAME}
|
||||
container_name: ${CONTAINER_NAME}
|
||||
ports:
|
||||
- "25:25"
|
||||
- "143:143"
|
||||
- "465:465"
|
||||
- "587:587"
|
||||
- "993:993"
|
||||
volumes:
|
||||
- ./mail:/var/mail
|
||||
- ./mail-state:/var/mail-state
|
||||
- ./config/:/tmp/docker-mailserver/
|
||||
- /mnt/data/nginx/certs/:/etc/letsencrypt/live/:ro
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_PTRACE
|
||||
restart: always
|
||||
???+ example "Example Code"
|
||||
|
||||
```yaml
|
||||
version: '2'
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:latest
|
||||
hostname: ${HOSTNAME}
|
||||
domainname: ${DOMAINNAME}
|
||||
container_name: ${CONTAINER_NAME}
|
||||
ports:
|
||||
- "25:25"
|
||||
- "143:143"
|
||||
- "465:465"
|
||||
- "587:587"
|
||||
- "993:993"
|
||||
volumes:
|
||||
- ./mail:/var/mail
|
||||
- ./mail-state:/var/mail-state
|
||||
- ./config/:/tmp/docker-mailserver/
|
||||
- /mnt/data/nginx/certs/:/etc/letsencrypt/live/:ro
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_PTRACE
|
||||
restart: always
|
||||
|
||||
cert-companion:
|
||||
image: nginx
|
||||
environment:
|
||||
- "VIRTUAL_HOST="
|
||||
- "VIRTUAL_NETWORK=nginx-proxy"
|
||||
- "LETSENCRYPT_HOST="
|
||||
- "LETSENCRYPT_EMAIL="
|
||||
networks:
|
||||
- proxy-tier
|
||||
restart: always
|
||||
|
||||
cert-companion:
|
||||
image: nginx
|
||||
environment:
|
||||
- "VIRTUAL_HOST="
|
||||
- "VIRTUAL_NETWORK=nginx-proxy"
|
||||
- "LETSENCRYPT_HOST="
|
||||
- "LETSENCRYPT_EMAIL="
|
||||
networks:
|
||||
- proxy-tier
|
||||
restart: always
|
||||
|
||||
networks:
|
||||
proxy-tier:
|
||||
external:
|
||||
name: nginx-proxy
|
||||
```
|
||||
proxy-tier:
|
||||
external:
|
||||
name: nginx-proxy
|
||||
```
|
||||
|
||||
The mail container needs to have the letsencrypt certificate folder mounted as a volume. No further changes are needed. The second container is a dummy-sidecar we need, because the mail-container do not expose any web-ports. Set your ENV variables as you need. (`VIRTUAL_HOST` and `LETSENCRYPT_HOST` are mandandory, see documentation)
|
||||
|
||||
|
@ -275,70 +279,72 @@ For Caddy v2 you can specify the `key_type` in your server's global settings, wh
|
|||
|
||||
If you are instead using a json config for Caddy v2, you can set it in your site's TLS automation policies:
|
||||
|
||||
```json
|
||||
{
|
||||
"apps": {
|
||||
"http": {
|
||||
"servers": {
|
||||
"srv0": {
|
||||
"listen": [
|
||||
":443"
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"match": [
|
||||
{
|
||||
"host": [
|
||||
"mail.domain.com",
|
||||
]
|
||||
}
|
||||
???+ example "Example Code"
|
||||
|
||||
```json
|
||||
{
|
||||
"apps": {
|
||||
"http": {
|
||||
"servers": {
|
||||
"srv0": {
|
||||
"listen": [
|
||||
":443"
|
||||
],
|
||||
"handle": [
|
||||
"routes": [
|
||||
{
|
||||
"handler": "subroute",
|
||||
"routes": [
|
||||
"match": [
|
||||
{
|
||||
"handle": [
|
||||
"host": [
|
||||
"mail.domain.com",
|
||||
]
|
||||
}
|
||||
],
|
||||
"handle": [
|
||||
{
|
||||
"handler": "subroute",
|
||||
"routes": [
|
||||
{
|
||||
"body": "",
|
||||
"handler": "static_response"
|
||||
"handle": [
|
||||
{
|
||||
"body": "",
|
||||
"handler": "static_response"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"terminal": true
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"tls": {
|
||||
"automation": {
|
||||
"policies": [
|
||||
{
|
||||
"subjects": [
|
||||
"mail.domain.com",
|
||||
],
|
||||
"key_type": "rsa2048",
|
||||
"issuer": {
|
||||
"email": "email@email.com",
|
||||
"module": "acme"
|
||||
}
|
||||
},
|
||||
{
|
||||
"issuer": {
|
||||
"email": "email@email.com",
|
||||
"module": "acme"
|
||||
],
|
||||
"terminal": true
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tls": {
|
||||
"automation": {
|
||||
"policies": [
|
||||
{
|
||||
"subjects": [
|
||||
"mail.domain.com",
|
||||
],
|
||||
"key_type": "rsa2048",
|
||||
"issuer": {
|
||||
"email": "email@email.com",
|
||||
"module": "acme"
|
||||
}
|
||||
},
|
||||
{
|
||||
"issuer": {
|
||||
"email": "email@email.com",
|
||||
"module": "acme"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
The generated certificates can be mounted:
|
||||
|
||||
|
@ -375,44 +381,46 @@ Traefik's V2 storage format is natively supported if the `acme.json` store is mo
|
|||
|
||||
This allows for support of wild card certificates: `SSL_DOMAIN=*.example.com`. Here is an example setup for [`docker-compose`](https://docs.docker.com/compose/):
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:stable
|
||||
hostname: mail
|
||||
domainname: example.com
|
||||
volumes:
|
||||
- /etc/ssl/acme-v2.json:/etc/letsencrypt/acme.json:ro
|
||||
environment:
|
||||
SSL_TYPE: letsencrypt
|
||||
# SSL_DOMAIN: "*.example.com"
|
||||
traefik:
|
||||
image: traefik:v2.2
|
||||
restart: always
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
command:
|
||||
- --providers.docker
|
||||
- --entrypoints.web.address=:80
|
||||
- --entrypoints.web.http.redirections.entryPoint.to=websecure
|
||||
- --entrypoints.web.http.redirections.entryPoint.scheme=https
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --entrypoints.websecure.http.middlewares=hsts@docker
|
||||
- --entrypoints.websecure.http.tls.certResolver=le
|
||||
- --certificatesresolvers.le.acme.email=admin@example.net
|
||||
- --certificatesresolvers.le.acme.storage=/acme.json
|
||||
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- /etc/ssl/acme-v2.json:/acme.json
|
||||
???+ example "Example Code"
|
||||
|
||||
whoami:
|
||||
image: containous/whoami
|
||||
labels:
|
||||
- "traefik.http.routers.whoami.rule=Host(`mail.example.com`)"
|
||||
```
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:stable
|
||||
hostname: mail
|
||||
domainname: example.com
|
||||
volumes:
|
||||
- /etc/ssl/acme-v2.json:/etc/letsencrypt/acme.json:ro
|
||||
environment:
|
||||
SSL_TYPE: letsencrypt
|
||||
# SSL_DOMAIN: "*.example.com"
|
||||
traefik:
|
||||
image: traefik:v2.2
|
||||
restart: always
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
command:
|
||||
- --providers.docker
|
||||
- --entrypoints.web.address=:80
|
||||
- --entrypoints.web.http.redirections.entryPoint.to=websecure
|
||||
- --entrypoints.web.http.redirections.entryPoint.scheme=https
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --entrypoints.websecure.http.middlewares=hsts@docker
|
||||
- --entrypoints.websecure.http.tls.certResolver=le
|
||||
- --certificatesresolvers.le.acme.email=admin@example.net
|
||||
- --certificatesresolvers.le.acme.storage=/acme.json
|
||||
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- /etc/ssl/acme-v2.json:/acme.json
|
||||
|
||||
whoami:
|
||||
image: containous/whoami
|
||||
labels:
|
||||
- "traefik.http.routers.whoami.rule=Host(`mail.example.com`)"
|
||||
```
|
||||
|
||||
This setup only comes with one caveat: The domain has to be configured on another service for traefik to actually request it from lets-encrypt (`whoami` in this case).
|
||||
|
||||
|
@ -422,9 +430,13 @@ If you are using Traefik v1, you might want to _push_ your Traefik-managed certi
|
|||
|
||||
Depending of your Traefik configuration, certificates may be stored using a file or a KV Store (consul, etcd...) Either way, certificates will be renewed by Traefik, then automatically pushed to the mailserver thanks to the `cert-renewer` service. Finally, dovecot and postfix will be restarted.
|
||||
|
||||
## Self-Signed Certificates (Testing Only)
|
||||
## Self-Signed Certificates
|
||||
|
||||
You can easily generate a self-signed SSL certificate by using the following command:
|
||||
!!! warning
|
||||
|
||||
Use self-signed certificates only for testing purposes!
|
||||
|
||||
You can generate a self-signed SSL certificate by using the following command:
|
||||
|
||||
```sh
|
||||
docker run -it --rm -v "$(pwd)"/config/ssl:/tmp/docker-mailserver/ssl -h mail.my-domain.com -t mailserver/docker-mailserver generate-ssl-certificate
|
||||
|
@ -472,7 +484,7 @@ environment:
|
|||
|
||||
This will mount the path where your ssl certificates reside as read-only under `/tmp/ssl`. Then all you have to do is to specify the location of your private key and the certificate.
|
||||
|
||||
!!! note
|
||||
!!! info
|
||||
You may have to restart your mailserver once the certificates change.
|
||||
|
||||
## Testing a Certificate is Valid
|
||||
|
@ -509,9 +521,11 @@ docker exec mail openssl s_client \
|
|||
|
||||
## Plain-Text Access
|
||||
|
||||
Not recommended for purposes other than testing.
|
||||
!!! warning
|
||||
|
||||
Just add this to `config/dovecot.cf`:
|
||||
Not recommended for purposes other than testing.
|
||||
|
||||
Add this to `config/dovecot.cf`:
|
||||
|
||||
```cf
|
||||
ssl = yes
|
||||
|
|
|
@ -13,6 +13,10 @@ wget https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/maste
|
|||
chmod a+x ./setup.sh
|
||||
```
|
||||
|
||||
!!! info
|
||||
|
||||
Make sure to get the `setup.sh` that comes with the release you're using. Look up the release and the git commit on which this release is based upon by selecting the appropriate tag on GitHub. This can done with the "Switch branches/tags" button on GitHub, choosing the right tag. This is done in order to rule out possible inconsistencies between versions.
|
||||
|
||||
## Usage
|
||||
|
||||
Run `./setup.sh -h` and you'll get some usage information:
|
||||
|
|
|
@ -22,39 +22,41 @@ We are going to use this docker based mailserver:
|
|||
|
||||
- Create the file `docker-compose.yml` with a content like this:
|
||||
|
||||
```yaml
|
||||
version: '2'
|
||||
!!! example
|
||||
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:latest
|
||||
hostname: mail
|
||||
domainname: example.org
|
||||
container_name: mail
|
||||
ports:
|
||||
- "25:25"
|
||||
- "587:587"
|
||||
- "465:465"
|
||||
volumes:
|
||||
- ./data/:/var/mail/
|
||||
- ./state/:/var/mail-state/
|
||||
- ./config/:/tmp/docker-mailserver/
|
||||
- /var/ds/wsproxy/letsencrypt/:/etc/letsencrypt/
|
||||
environment:
|
||||
- PERMIT_DOCKER=network
|
||||
- SSL_TYPE=letsencrypt
|
||||
- ONE_DIR=1
|
||||
- DMS_DEBUG=1
|
||||
- SPOOF_PROTECTION=0
|
||||
- REPORT_RECIPIENT=1
|
||||
- ENABLE_SPAMASSASSIN=0
|
||||
- ENABLE_CLAMAV=0
|
||||
- ENABLE_FAIL2BAN=1
|
||||
- ENABLE_POSTGREY=0
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_PTRACE
|
||||
```
|
||||
```yaml
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:latest
|
||||
hostname: mail
|
||||
domainname: example.org
|
||||
container_name: mail
|
||||
ports:
|
||||
- "25:25"
|
||||
- "587:587"
|
||||
- "465:465"
|
||||
volumes:
|
||||
- ./data/:/var/mail/
|
||||
- ./state/:/var/mail-state/
|
||||
- ./config/:/tmp/docker-mailserver/
|
||||
- /var/ds/wsproxy/letsencrypt/:/etc/letsencrypt/
|
||||
environment:
|
||||
- PERMIT_DOCKER=network
|
||||
- SSL_TYPE=letsencrypt
|
||||
- ONE_DIR=1
|
||||
- DMS_DEBUG=1
|
||||
- SPOOF_PROTECTION=0
|
||||
- REPORT_RECIPIENT=1
|
||||
- ENABLE_SPAMASSASSIN=0
|
||||
- ENABLE_CLAMAV=0
|
||||
- ENABLE_FAIL2BAN=1
|
||||
- ENABLE_POSTGREY=0
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_PTRACE
|
||||
```
|
||||
|
||||
For more details about the environment variables that can be used, and their meaning and possible values, check also these:
|
||||
|
||||
|
|
|
@ -97,9 +97,13 @@ postfix reload
|
|||
|
||||
You see that besides `query_filter`, I had to customize as well `result_attribute` and `result_format`.
|
||||
|
||||
For more details about using LDAP see: [LDAP managed mail server with Postfix and Dovecot for multiple domains](https://www.vennedey.net/resources/2-LDAP-managed-mail-server-with-Postfix-and-Dovecot-for-multiple-domains)
|
||||
!!! sealso
|
||||
|
||||
Another solution that serves as a forward-only mailserver is this: https://gitlab.com/docker-scripts/postfix
|
||||
For more details about using LDAP see: [LDAP managed mail server with Postfix and Dovecot for multiple domains](https://www.vennedey.net/resources/2-LDAP-managed-mail-server-with-Postfix-and-Dovecot-for-multiple-domains)
|
||||
|
||||
!!! seealso
|
||||
|
||||
Another solution that serves as a forward-only mailserver is this: https://gitlab.com/docker-scripts/postfix
|
||||
|
||||
[github-file-readme-patches]: https://github.com/docker-mailserver/docker-mailserver/blob/master/README.md#custom-user-changes--patches
|
||||
[github-issue-1247]: https://github.com/docker-mailserver/docker-mailserver/issues/1247
|
||||
|
|
|
@ -9,11 +9,11 @@ This image is based on config files that can be persisted using Docker volumes,
|
|||
|
||||
### Where are emails stored?
|
||||
|
||||
Mails are stored in `/var/mail/${domain}/${username}`.
|
||||
Mails are stored in `/var/mail/${domain}/${username}`. Since `v9.0.0` it is possible to add custom `user_attributes` for each accounts to have a different mailbox configuration (See [#1792][github-issue-1792]).
|
||||
|
||||
You should use a [data volume container](https://medium.com/@ramangupta/why-docker-data-containers-are-good-589b3c6c749e#.uxyrp7xpu) for `/var/mail` to persist data.
|
||||
!!! warning
|
||||
|
||||
Otherwise, your data may be lost.
|
||||
You should use a [data volume container](https://medium.com/@ramangupta/why-docker-data-containers-are-good-589b3c6c749e#.uxyrp7xpu) for `/var/mail` to persist data. Otherwise, your data may be lost.
|
||||
|
||||
### How to alter the running mailserver instance _without_ relaunching the container?
|
||||
|
||||
|
@ -147,68 +147,70 @@ If you run the server with `docker-compose`, you can leverage on docker configs
|
|||
|
||||
The following configuration works nicely:
|
||||
|
||||
Create a _system_ cron file:
|
||||
??? example
|
||||
|
||||
```sh
|
||||
# in the docker-compose.yml root directory
|
||||
mkdir cron
|
||||
touch cron/sa-learn
|
||||
chown root:root cron/sa-learn
|
||||
chmod 0644 cron/sa-learn
|
||||
```
|
||||
Create a _system_ cron file:
|
||||
|
||||
Edit the system cron file `nano cron/sa-learn`, and set an appropriate configuration:
|
||||
```sh
|
||||
# in the docker-compose.yml root directory
|
||||
mkdir cron
|
||||
touch cron/sa-learn
|
||||
chown root:root cron/sa-learn
|
||||
chmod 0644 cron/sa-learn
|
||||
```
|
||||
|
||||
```conf
|
||||
# This assumes you're having `environment: ONE_DIR=1` in the env-mailserver,
|
||||
# with a consolidated config in `/var/mail-state`
|
||||
#
|
||||
# m h dom mon dow user command
|
||||
#
|
||||
# Everyday 2:00AM, learn spam from a specific user
|
||||
# spam: junk directory
|
||||
0 2 * * * root sa-learn --spam /var/mail/domain.com/username/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
# ham: archive directories
|
||||
15 2 * * * root sa-learn --ham /var/mail/domain.com/username/.Archive* --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
# ham: inbox subdirectories
|
||||
30 2 * * * root sa-learn --ham /var/mail/domain.com/username/cur* --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
#
|
||||
# Everyday 3:00AM, learn spam from all users of a domain
|
||||
# spam: junk directory
|
||||
0 3 * * * root sa-learn --spam /var/mail/otherdomain.com/*/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
# ham: archive directories
|
||||
15 3 * * * root sa-learn --ham /var/mail/otherdomain.com/*/.Archive* --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
# ham: inbox subdirectories
|
||||
30 3 * * * root sa-learn --ham /var/mail/otherdomain.com/*/cur* --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
```
|
||||
Edit the system cron file `nano cron/sa-learn`, and set an appropriate configuration:
|
||||
|
||||
Then with plain `docker-compose`:
|
||||
```conf
|
||||
# This assumes you're having `environment: ONE_DIR=1` in the env-mailserver,
|
||||
# with a consolidated config in `/var/mail-state`
|
||||
#
|
||||
# m h dom mon dow user command
|
||||
#
|
||||
# Everyday 2:00AM, learn spam from a specific user
|
||||
# spam: junk directory
|
||||
0 2 * * * root sa-learn --spam /var/mail/domain.com/username/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
# ham: archive directories
|
||||
15 2 * * * root sa-learn --ham /var/mail/domain.com/username/.Archive* --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
# ham: inbox subdirectories
|
||||
30 2 * * * root sa-learn --ham /var/mail/domain.com/username/cur* --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
#
|
||||
# Everyday 3:00AM, learn spam from all users of a domain
|
||||
# spam: junk directory
|
||||
0 3 * * * root sa-learn --spam /var/mail/otherdomain.com/*/.Junk --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
# ham: archive directories
|
||||
15 3 * * * root sa-learn --ham /var/mail/otherdomain.com/*/.Archive* --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
# ham: inbox subdirectories
|
||||
30 3 * * * root sa-learn --ham /var/mail/otherdomain.com/*/cur* --dbpath /var/mail-state/lib-amavis/.spamassassin
|
||||
```
|
||||
|
||||
```yaml
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:latest
|
||||
volumes:
|
||||
- ./cron/sa-learn:/etc/cron.d/sa-learn
|
||||
```
|
||||
Then with plain `docker-compose`:
|
||||
|
||||
Or with [docker swarm](https://docs.docker.com/engine/swarm/configs/):
|
||||
```yaml
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:latest
|
||||
volumes:
|
||||
- ./cron/sa-learn:/etc/cron.d/sa-learn
|
||||
```
|
||||
|
||||
```yaml
|
||||
version: "3.3"
|
||||
Or with [docker swarm](https://docs.docker.com/engine/swarm/configs/):
|
||||
|
||||
```yaml
|
||||
version: "3.3"
|
||||
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:latest
|
||||
# ...
|
||||
configs:
|
||||
- source: my_sa_crontab
|
||||
target: /etc/cron.d/sa-learn
|
||||
|
||||
services:
|
||||
mail:
|
||||
image: mailserver/docker-mailserver:latest
|
||||
# ...
|
||||
configs:
|
||||
- source: my_sa_crontab
|
||||
target: /etc/cron.d/sa-learn
|
||||
|
||||
configs:
|
||||
my_sa_crontab:
|
||||
file: ./cron/sa-learn
|
||||
```
|
||||
my_sa_crontab:
|
||||
file: ./cron/sa-learn
|
||||
```
|
||||
|
||||
With the default settings, Spamassassin will require 200 mails trained for spam (for example with the method explained above) and 200 mails trained for ham (using the same command as above but using `--ham` and providing it with some ham mails). Until you provided these 200+200 mails, Spamassasin will not take the learned mails into account. For further reference, see the [Spamassassin Wiki](https://wiki.apache.org/spamassassin/BayesNotWorking).
|
||||
|
||||
|
@ -302,7 +304,7 @@ If we're blind, we won't be able to do anything.
|
|||
1 core and 1GB of RAM + swap partition is recommended to run `docker-mailserver` with clamav.
|
||||
Otherwise, it could work with 512M of RAM.
|
||||
|
||||
!!! note
|
||||
!!! warning
|
||||
Clamav can consume a lot of memory, as it reads the entire signature database into RAM.
|
||||
|
||||
Current figure is about 850M and growing. If you get errors about clamav or amavis failing to allocate memory you need more RAM or more swap and of course docker must be allowed to use swap (not always the case). If you can't use swap at all you may need 3G RAM.
|
||||
|
@ -407,4 +409,5 @@ supervisorctl update
|
|||
[github-issue-1247]: https://github.com/docker-mailserver/docker-mailserver/issues/1247
|
||||
[github-issue-1405-comment]: https://github.com/docker-mailserver/docker-mailserver/issues/1405#issuecomment-590106498
|
||||
[github-issue-1639]: https://github.com/docker-mailserver/docker-mailserver/issues/1639
|
||||
[github-issue-1792]: https://github.com/docker-mailserver/docker-mailserver/pull/1792
|
||||
[hanscees-userpatches]: https://github.com/hanscees/dockerscripts/blob/master/scripts/tomav-user-patches.sh
|
||||
|
|
|
@ -51,15 +51,16 @@ Fetching an email: MUA <------------------------------ ┫ MDA ╯ ┃
|
|||
┗━━━━━━━┛
|
||||
```
|
||||
|
||||
> Let's say Alice owns a Gmail account, `alice@gmail.com`; and Bob owns an account on a `docker-mailserver`'s instance, `bob@dms.io`.
|
||||
>
|
||||
> Make sure not to conflate these two very different scenarios:
|
||||
> A) Alice sends an email to `bob@dms.io` => the email is first submitted to MTA `smtp.gmail.com`, then relayed to MTA `smtp.dms.io` where it is then delivered into Bob's mailbox.
|
||||
> B) Bob sends an email to `alice@gmail.com` => the email is first submitted to MTA `smtp.dms.io`, then relayed to MTA `smtp.gmail.com` and eventually delivered into Alice's mailbox.
|
||||
>
|
||||
> In scenario *A* the email leaves Gmail's premises, that email's *initial* submission is _not_ handled by your `docker-mailserver` instance(MTA); it merely receives the email after it has been relayed by Gmail's MTA. In scenario *B*, the `docker-mailserver` instance(MTA) handles the submission, prior to relaying.
|
||||
>
|
||||
> The main takeaway is that when a third-party sends an email to a `docker-mailserver` instance(MTA) (or any MTA for that matter), it does _not_ establish a direct connection with that MTA. Email submission first goes through the sender's MTA, then some relaying between at least two MTAs is required to deliver the email. That will prove very important when it comes to security management.
|
||||
!!! example
|
||||
Let's say Alice owns a Gmail account, `alice@gmail.com`; and Bob owns an account on a `docker-mailserver`'s instance, `bob@dms.io`.
|
||||
|
||||
Make sure not to conflate these two very different scenarios:
|
||||
A) Alice sends an email to `bob@dms.io` => the email is first submitted to MTA `smtp.gmail.com`, then relayed to MTA `smtp.dms.io` where it is then delivered into Bob's mailbox.
|
||||
B) Bob sends an email to `alice@gmail.com` => the email is first submitted to MTA `smtp.dms.io`, then relayed to MTA `smtp.gmail.com` and eventually delivered into Alice's mailbox.
|
||||
|
||||
In scenario *A* the email leaves Gmail's premises, that email's *initial* submission is _not_ handled by your `docker-mailserver` instance(MTA); it merely receives the email after it has been relayed by Gmail's MTA. In scenario *B*, the `docker-mailserver` instance(MTA) handles the submission, prior to relaying.
|
||||
|
||||
The main takeaway is that when a third-party sends an email to a `docker-mailserver` instance(MTA) (or any MTA for that matter), it does _not_ establish a direct connection with that MTA. Email submission first goes through the sender's MTA, then some relaying between at least two MTAs is required to deliver the email. That will prove very important when it comes to security management.
|
||||
|
||||
One important thing to note is that MTA and MDA programs may actually handle _multiple_ tasks (which is the case with `docker-mailserver`'s Postfix and Dovecot).
|
||||
|
||||
|
@ -145,7 +146,7 @@ The best practice as of 2020 when it comes to securing Outward Submission is to
|
|||
- [ESMTP][wikipedia-esmtp] is [SMTP][wikipedia-smtp] + extensions. It's the version of the SMTP protocol that most mail servers speak nowadays. For the purpose of this documentation, ESMTP and SMTP are synonymous.
|
||||
- Port 465 is the reserved TCP port for Implicit TLS Submission (since 2018). There is actually a boisterous history to that ports usage, but let's keep it simple.
|
||||
|
||||
!!! note
|
||||
!!! warning
|
||||
This Submission setup is sometimes refered to as [SMTPS][wikipedia-smtps]. Long story short: this is incorrect and should be avoided.
|
||||
|
||||
Although a very satisfactory setup, Implicit TLS on port 465 is somewhat "cutting edge". There exists another well established mail Submission setup that must be supported as well, SMTP+STARTTLS on port 587. It uses Explicit TLS: the client starts with a cleartext connection, then the server informs a TLS-encrypted "upgraded" connection may be established, and the client _may_ eventually decide to establish it prior to the Submission. Basically it's an opportunistic, opt-in TLS upgrade of the connection between the client and the server, at the client's discretion, using a mechanism known as [STARTTLS][wikipedia-starttls] that both ends need to implement.
|
||||
|
|
Loading…
Reference in a new issue