version 1
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.env
|
||||||
|
private/
|
||||||
|
snappymail/
|
||||||
|
config/opendkim/keys/
|
||||||
108
README.md
Normal file
108
README.md
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
# README.md — Docker Mailserver (DMS) Setup for knusperkerne.de
|
||||||
|
|
||||||
|
This document describes the stable, minimal configuration of your Docker Mailserver (DMS) installation and the daily operational commands required to manage domains and users.
|
||||||
|
|
||||||
|
## 1. Project Structure
|
||||||
|
|
||||||
|
The directory contains:
|
||||||
|
|
||||||
|
- compose.yml
|
||||||
|
- .env
|
||||||
|
- config/postfix-main.cf
|
||||||
|
- config/postfix-master.cf
|
||||||
|
- config/postfix-accounts.cf
|
||||||
|
- config/postfix-virtual.cf
|
||||||
|
- config/opendkim/*
|
||||||
|
- volumes: maildata, mailstate, maillogs
|
||||||
|
- snappymail/ (webmail)
|
||||||
|
|
||||||
|
## 2. Services
|
||||||
|
|
||||||
|
### mail (Docker Mailserver 12.x)
|
||||||
|
- Hostname: mailsystem.knusperkerne.de
|
||||||
|
- Ports: SMTP(25), SUBMISSION(587), IMAPS(993)
|
||||||
|
- Configuration directory mounted to `/tmp/docker-mailserver`
|
||||||
|
- SPF-Checks fully disabled via postfix-main.cf and postfix-master.cf overrides
|
||||||
|
- DKIM enabled via `/config/opendkim`
|
||||||
|
|
||||||
|
### snappymail (Webmail)
|
||||||
|
- Bound to 127.0.0.1:${SNAPPYMAIL_PORT}
|
||||||
|
- Stores data in ./snappymail
|
||||||
|
|
||||||
|
## 3. Essential Admin Commands
|
||||||
|
|
||||||
|
All commands are executed inside the mailserver container:
|
||||||
|
|
||||||
|
### Enter the container
|
||||||
|
docker exec -it mailserver bash
|
||||||
|
|
||||||
|
### 3.1 Add a domain
|
||||||
|
Domains do not require a separate explicit create-command.
|
||||||
|
To ensure DMS recognizes a domain, add a dummy account:
|
||||||
|
setup email add dms-domain-init@yourdomain.de somepassword
|
||||||
|
|
||||||
|
After DNS MX + A records propagate, the domain becomes active.
|
||||||
|
|
||||||
|
### 3.2 Add a real user
|
||||||
|
setup email add USER@DOMAIN.TLD PASSWORD
|
||||||
|
|
||||||
|
### 3.3 Change a user password
|
||||||
|
setup email update USER@DOMAIN.TLD PASSWORD
|
||||||
|
|
||||||
|
### 3.4 Delete a user
|
||||||
|
setup email del USER@DOMAIN.TLD
|
||||||
|
|
||||||
|
### 3.5 List all accounts
|
||||||
|
setup email list
|
||||||
|
|
||||||
|
### 3.6 Show mailbox sizes
|
||||||
|
du -sh /var/mail/vhosts/DOMAIN.TLD/USER/
|
||||||
|
|
||||||
|
### 3.7 Rebuild postfix/dovecot after config changes
|
||||||
|
Supervised automatically at startup; restart the container after modifying any file under config/:
|
||||||
|
docker compose restart mail
|
||||||
|
|
||||||
|
## 4. Config Overrides
|
||||||
|
|
||||||
|
### 4.1 postfix-main.cf
|
||||||
|
- Disables SPF policy checks completely
|
||||||
|
- Keeps only minimal safe recipient checks:
|
||||||
|
|
||||||
|
policyd-spf_time_limit = 0
|
||||||
|
smtpd_recipient_restrictions =
|
||||||
|
permit_mynetworks,
|
||||||
|
permit_sasl_authenticated,
|
||||||
|
reject_unauth_destination
|
||||||
|
|
||||||
|
### 4.2 postfix-master.cf
|
||||||
|
Overrides the policyd-spf service to discard:
|
||||||
|
|
||||||
|
policyd-spf unix - n n - 0 discard
|
||||||
|
|
||||||
|
### 4.3 postfix-accounts.cf
|
||||||
|
Auto-generated by DMS. Contains user → password-hash entries.
|
||||||
|
|
||||||
|
### 4.4 postfix-virtual.cf
|
||||||
|
Virtual alias configuration for mail routing.
|
||||||
|
|
||||||
|
## 5. DNS Requirements
|
||||||
|
|
||||||
|
For each domain:
|
||||||
|
|
||||||
|
MX 10 mailsystem.knusperkerne.de
|
||||||
|
A mailsystem.knusperkerne.de → YOUR.SERVER.IP
|
||||||
|
SPF TXT (liberal): "v=spf1 a mx ~all"
|
||||||
|
DKIM: Add the public key from config/opendkim/keys/DOMAIN/mail.txt
|
||||||
|
|
||||||
|
## 6. Backup
|
||||||
|
|
||||||
|
- Backup volumes: maildata, mailstate
|
||||||
|
- Backup config/: postfix configs and DKIM keys
|
||||||
|
- Logs are in maillogs/
|
||||||
|
|
||||||
|
## 7. Notes
|
||||||
|
|
||||||
|
- SPF checks are intentionally disabled (forwarding-friendly).
|
||||||
|
- DKIM signing remains active and reliable for reputation.
|
||||||
|
- DMS v12 receives security updates and remains stable.
|
||||||
|
- No additional MTA/MDA components are required; Postfix+Dovecot are fully integrated.
|
||||||
111
UPDATE.MD
Normal file
111
UPDATE.MD
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# UPDATE.md — Keeping the Mail Server Up to Date
|
||||||
|
|
||||||
|
This document describes how to keep the mail server setup up to date:
|
||||||
|
|
||||||
|
- docker-mailserver (DMS)
|
||||||
|
- Snappymail
|
||||||
|
- Amavis / SpamAssassin
|
||||||
|
- ClamAV
|
||||||
|
- Postfix / Dovecot
|
||||||
|
- TLS via host-level nginx
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Update Docker Images
|
||||||
|
|
||||||
|
Run regularly (e.g. weekly or monthly):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker pull mailserver/docker-mailserver:12
|
||||||
|
docker pull ghcr.io/the-djmaze/snappymail:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Then restart the stack:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose down
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. ClamAV Signature Updates
|
||||||
|
|
||||||
|
ClamAV updates automatically via `freshclam` inside the container.
|
||||||
|
|
||||||
|
Check status:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec mailserver freshclam --version
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. SpamAssassin / Amavis Updates
|
||||||
|
|
||||||
|
SpamAssassin rules are updated automatically via `sa-update`.
|
||||||
|
|
||||||
|
Verify:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec mailserver sa-update -D
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Restart After Configuration Changes
|
||||||
|
|
||||||
|
If anything under `config/` is modified:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec mailserver setup restart
|
||||||
|
```
|
||||||
|
|
||||||
|
or:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose restart mailserver
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. TLS Certificates
|
||||||
|
|
||||||
|
TLS termination is handled by host-level nginx.
|
||||||
|
ACME renewal is automatic.
|
||||||
|
No action required inside the mailserver container.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Health Check
|
||||||
|
|
||||||
|
Run the custom health checker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./tools/health_check.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
It verifies DNS, TLS, Postfix, Dovecot, Amavis, ClamAV, and queue status.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Full System Upgrade (optional)
|
||||||
|
|
||||||
|
On the host:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt update && apt upgrade
|
||||||
|
reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
Docker containers restart automatically.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
- Pull updated images regularly
|
||||||
|
- Restart after pulling
|
||||||
|
- ClamAV and SpamAssassin update themselves
|
||||||
|
- TLS certificates renew automatically
|
||||||
|
- Use the health checker to verify system status
|
||||||
0
config/dovecot-quotas.cf
Normal file
0
config/dovecot-quotas.cf
Normal file
2
config/opendkim/KeyTable
Normal file
2
config/opendkim/KeyTable
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
mail._domainkey.knusperkerne.de knusperkerne.de:mail:/etc/opendkim/keys/knusperkerne.de/mail.private
|
||||||
|
mail._domainkey.junisthomsen.de junisthomsen.de:mail:/etc/opendkim/keys/junisthomsen.de/mail.private
|
||||||
2
config/opendkim/SigningTable
Normal file
2
config/opendkim/SigningTable
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*@knusperkerne.de mail._domainkey.knusperkerne.de
|
||||||
|
*@junisthomsen.de mail._domainkey.junisthomsen.de
|
||||||
2
config/opendkim/TrustedHosts
Normal file
2
config/opendkim/TrustedHosts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
127.0.0.1
|
||||||
|
localhost
|
||||||
3
config/postfix-accounts.cf
Normal file
3
config/postfix-accounts.cf
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
postmaster@knusperkerne.de|{SHA512-CRYPT}$6$Lm9yhp7vKxI1$yA9iC9JS9AV5RrC0y0Z6B.HS5eKLp41BNxT6TxHGwqR2wvyOpl5gq6l5jHHe2pupHbn2uAIX1rC8RDk9MIrGu1
|
||||||
|
lars@knusperkerne.de|{SHA512-CRYPT}$6$liI0ggXzslHVaETp$duBJIo98rV/uyo6rL8IQBN96DPtkmO5s6DB4q.QnP9sIVaFAqpE/MT6tHUymmq0I72IWoxbayakwdUN8XO9We.
|
||||||
|
dms-domain-init@junisthomsen.de|{SHA512-CRYPT}$6$klU.mosQPqk1c624$MT.EnJomAw7/1J98UcV4LO3wuzZ1mg7qUPl5f.7uXMHTl1UOptujWwnFTx7g.8brNPrwRQ7.8c0jmj4bEbYip/
|
||||||
7
config/postfix-main.cf
Normal file
7
config/postfix-main.cf
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
policyd-spf_time_limit = 0
|
||||||
|
|
||||||
|
# Klassische, simple Recipient-Checks ohne SPF-Policy
|
||||||
|
smtpd_recipient_restrictions =
|
||||||
|
permit_mynetworks,
|
||||||
|
permit_sasl_authenticated,
|
||||||
|
reject_unauth_destination
|
||||||
1
config/postfix-master.cf
Normal file
1
config/postfix-master.cf
Normal file
@@ -0,0 +1 @@
|
|||||||
|
policyd-spf unix - n n - 0 discard
|
||||||
6
config/postfix-virtual.cf
Normal file
6
config/postfix-virtual.cf
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
postmaster@knusperkerne.de postmaster@knusperkerne.de
|
||||||
|
abuse@knusperkerne.de postmaster@knusperkerne.de
|
||||||
|
hostmaster@knusperkerne.de postmaster@knusperkerne.de
|
||||||
|
webmaster@knusperkerne.de postmaster@knusperkerne.de
|
||||||
|
root@knusperkerne.de postmaster@knusperkerne.de
|
||||||
|
admin@knusperkerne.de postmaster@knusperkerne.de
|
||||||
49
config/ssl/fullchain.pem
Normal file
49
config/ssl/fullchain.pem
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDvTCCA0SgAwIBAgISBWnhzHTqDns+KzNZ+mZVlemCMAoGCCqGSM49BAMDMDIx
|
||||||
|
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
|
||||||
|
NzAeFw0yNTExMDgwOTUzNTlaFw0yNjAyMDYwOTUzNThaMCUxIzAhBgNVBAMTGm1h
|
||||||
|
aWxzeXN0ZW0ua251c3Blcmtlcm5lLmRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE
|
||||||
|
af8nqIUs9obIBCvxFdbtacVamdeCZxgr4TuzNIO384+nKzenfGwDVH0m+C+el48J
|
||||||
|
APrJhoewOnhP2KIXITh2MTBWzXcTQuQQchT2OjvzVMLqcmRnz645N4euEU3iJ0iq
|
||||||
|
o4ICKDCCAiQwDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
|
||||||
|
BgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQ+gwR9eRa4HD3GtaNMjYho
|
||||||
|
GOx4HzAfBgNVHSMEGDAWgBSuSJ7chx1EoG/aouVgdAR4wpwAgDAyBggrBgEFBQcB
|
||||||
|
AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly9lNy5pLmxlbmNyLm9yZy8wJQYDVR0R
|
||||||
|
BB4wHIIabWFpbHN5c3RlbS5rbnVzcGVya2VybmUuZGUwEwYDVR0gBAwwCjAIBgZn
|
||||||
|
gQwBAgEwLAYDVR0fBCUwIzAhoB+gHYYbaHR0cDovL2U3LmMubGVuY3Iub3JnLzMu
|
||||||
|
Y3JsMIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDxAHcADleUvPOuqT4zGyyZB7P3kN+b
|
||||||
|
wj1xMiXdIaklrGHFTiEAAAGaYxieagAABAMASDBGAiEAlmf2mLFJMPyZF50BrfZe
|
||||||
|
9bUxS2rTbb2EXwCbiNYYpiUCIQClv0XZKOR472KWltEnBXZe7bkLHjtiwryqDfQK
|
||||||
|
CaODhQB2AEmcm2neHXzs/DbezYdkprhbrwqHgBnRVVL76esp3fjDAAABmmMYpkQA
|
||||||
|
AAQDAEcwRQIgGzyP6dfukv++cixYygLxdfTb/oQpxqyoV1CW+StyMDMCIQCu0DrC
|
||||||
|
90AYbk48zLgFq1VvkMSsMtlGnF6DlQ2n9seCvDAKBggqhkjOPQQDAwNnADBkAjBy
|
||||||
|
uNr6oSkTouTT6I6Z3Mps48OuW4yuCKk6t0ARWvale6oOgrqh8jXKBEE4rj/M0WgC
|
||||||
|
MCWwVLFKzBPKJu2eF1vCvbpolMsz6ymZsXALUFZ/uV9vVF7NDtDl5shYDzW3jP+Z
|
||||||
|
JA==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEVzCCAj+gAwIBAgIRAKp18eYrjwoiCWbTi7/UuqEwDQYJKoZIhvcNAQELBQAw
|
||||||
|
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||||
|
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
|
||||||
|
WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
|
||||||
|
RW5jcnlwdDELMAkGA1UEAxMCRTcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARB6AST
|
||||||
|
CFh/vjcwDMCgQer+VtqEkz7JANurZxLP+U9TCeioL6sp5Z8VRvRbYk4P1INBmbef
|
||||||
|
QHJFHCxcSjKmwtvGBWpl/9ra8HW0QDsUaJW2qOJqceJ0ZVFT3hbUHifBM/2jgfgw
|
||||||
|
gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
|
||||||
|
ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSuSJ7chx1EoG/aouVgdAR4
|
||||||
|
wpwAgDAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
|
||||||
|
AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
|
||||||
|
BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
|
||||||
|
Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAjx66fDdLk5ywFn3CzA1w1qfylHUD
|
||||||
|
aEf0QZpXcJseddJGSfbUUOvbNR9N/QQ16K1lXl4VFyhmGXDT5Kdfcr0RvIIVrNxF
|
||||||
|
h4lqHtRRCP6RBRstqbZ2zURgqakn/Xip0iaQL0IdfHBZr396FgknniRYFckKORPG
|
||||||
|
yM3QKnd66gtMst8I5nkRQlAg/Jb+Gc3egIvuGKWboE1G89NTsN9LTDD3PLj0dUMr
|
||||||
|
OIuqVjLB8pEC6yk9enrlrqjXQgkLEYhXzq7dLafv5Vkig6Gl0nuuqjqfp0Q1bi1o
|
||||||
|
yVNAlXe6aUXw92CcghC9bNsKEO1+M52YY5+ofIXlS/SEQbvVYYBLZ5yeiglV6t3S
|
||||||
|
M6H+vTG0aP9YHzLn/KVOHzGQfXDP7qM5tkf+7diZe7o2fw6O7IvN6fsQXEQQj8TJ
|
||||||
|
UXJxv2/uJhcuy/tSDgXwHM8Uk34WNbRT7zGTGkQRX0gsbjAea/jYAoWv0ZvQRwpq
|
||||||
|
Pe79D/i7Cep8qWnA+7AE/3B3S/3dEEYmc0lpe1366A/6GEgk3ktr9PEoQrLChs6I
|
||||||
|
tu3wnNLB2euC8IKGLQFpGtOO/2/hiAKjyajaBP25w1jF0Wl8Bbqne3uZ2q1GyPFJ
|
||||||
|
YRmT7/OXpmOH/FVLtwS+8ng1cAmpCujPwteJZNcDG0sF2n/sc0+SQf49fdyUK0ty
|
||||||
|
+VUwFj9tmWxyR/M=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
6
config/ssl/privkey.pem
Normal file
6
config/ssl/privkey.pem
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAYKud5Cn+C6I+g57dM
|
||||||
|
ve6+hPENM87YfPkmw+tUJSyBltpyp9LQjJAEbBHwx5jgqsWhZANiAARp/yeohSz2
|
||||||
|
hsgEK/EV1u1pxVqZ14JnGCvhO7M0g7fzj6crN6d8bANUfSb4L56XjwkA+smGh7A6
|
||||||
|
eE/YohchOHYxMFbNdxNC5BByFPY6O/NUwupyZGfPrjk3h64RTeInSKo=
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
38
docker-compose.yml
Normal file
38
docker-compose.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
|
||||||
|
mail:
|
||||||
|
image: mailserver/docker-mailserver:12
|
||||||
|
container_name: mailserver
|
||||||
|
hostname: mailsystem.knusperkerne.de
|
||||||
|
env_file: .env
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "${SMTP_PORT}:25"
|
||||||
|
- "${SUBMISSION_PORT}:587"
|
||||||
|
- "${IMAPS_PORT}:993"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- ./config:/tmp/docker-mailserver
|
||||||
|
- maildata:/var/mail
|
||||||
|
- mailstate:/var/mail-state
|
||||||
|
- maillogs:/var/log/mail
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
- SYS_PTRACE
|
||||||
|
|
||||||
|
snappymail:
|
||||||
|
image: ghcr.io/the-djmaze/snappymail:latest
|
||||||
|
container_name: snappymail
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:${SNAPPYMAIL_PORT}:8888"
|
||||||
|
volumes:
|
||||||
|
- ./snappymail:/var/lib/snappymail
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Berlin
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
maildata:
|
||||||
|
mailstate:
|
||||||
|
maillogs:
|
||||||
35
docker-compose.yml.ok
Normal file
35
docker-compose.yml.ok
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
services:
|
||||||
|
|
||||||
|
mail:
|
||||||
|
image: mailserver/docker-mailserver:12
|
||||||
|
container_name: mailserver
|
||||||
|
hostname: mailsystem.knusperkerne.de
|
||||||
|
env_file: .env
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "${SMTP_PORT}:25"
|
||||||
|
- "${SUBMISSION_PORT}:587"
|
||||||
|
- "${IMAPS_PORT}:993"
|
||||||
|
volumes:
|
||||||
|
- ./config:/tmp/docker-mailserver
|
||||||
|
- maildata:/var/mail
|
||||||
|
- mailstate:/var/mail-state
|
||||||
|
- maillogs:/var/log/mail
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
- SYS_PTRACE
|
||||||
|
|
||||||
|
snappymail:
|
||||||
|
image: ghcr.io/the-djmaze/snappymail:latest
|
||||||
|
container_name: snappymail
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:${SNAPPYMAIL_PORT}:8888"
|
||||||
|
volumes:
|
||||||
|
- ./snappymail:/var/www/snappymail/data
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
maildata:
|
||||||
|
mailstate:
|
||||||
|
maillogs:
|
||||||
64
tools/add_mail_domain.sh
Executable file
64
tools/add_mail_domain.sh
Executable file
@@ -0,0 +1,64 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DOMAIN="$1"
|
||||||
|
|
||||||
|
if [[ -z "$DOMAIN" ]]; then
|
||||||
|
echo "Usage: $0 <domain>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=============================================="
|
||||||
|
echo " ADDING MAIL DOMAIN: $DOMAIN"
|
||||||
|
echo "=============================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
MAILSERVER_CONTAINER="mailserver"
|
||||||
|
|
||||||
|
#
|
||||||
|
# STEP 1: create dummy mailbox — required to register domain internally
|
||||||
|
#
|
||||||
|
echo "[1/3] Creating domain presence via dummy account ..."
|
||||||
|
docker exec "$MAILSERVER_CONTAINER" setup email add "dms-domain-init@$DOMAIN" "Init12345" >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
#
|
||||||
|
# STEP 2: generate DKIM key
|
||||||
|
#
|
||||||
|
echo "[2/3] Generating DKIM key ..."
|
||||||
|
docker exec "$MAILSERVER_CONTAINER" setup config dkim keysize 2048 domain "$DOMAIN"
|
||||||
|
|
||||||
|
#
|
||||||
|
# STEP 3: extract DKIM public key (to show user DNS record)
|
||||||
|
#
|
||||||
|
echo "[3/3] Extracting DKIM public key ..."
|
||||||
|
PUBKEY=$(docker exec "$MAILSERVER_CONTAINER" sh -c \
|
||||||
|
"cat /tmp/docker-mailserver/opendkim/keys/$DOMAIN/mail.txt" 2>/dev/null)
|
||||||
|
|
||||||
|
if [[ -z "$PUBKEY" ]]; then
|
||||||
|
echo "ERROR: Could not read DKIM key!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=============================================="
|
||||||
|
echo " DNS RECORDS TO ADD FOR: $DOMAIN"
|
||||||
|
echo "=============================================="
|
||||||
|
echo ""
|
||||||
|
echo "1) MX record:"
|
||||||
|
echo " $DOMAIN. 50 mail.knusperkerne.de."
|
||||||
|
echo ""
|
||||||
|
echo "2) SPF record:"
|
||||||
|
echo " $DOMAIN. TXT \"v=spf1 mx a:mailsystem.knusperkerne.de ip4:89.58.2.51 -all\""
|
||||||
|
echo ""
|
||||||
|
echo "3) DKIM record (selector: mail):"
|
||||||
|
echo ""
|
||||||
|
echo "$PUBKEY"
|
||||||
|
echo ""
|
||||||
|
echo "4) DMARC record:"
|
||||||
|
echo " _dmarc.$DOMAIN. TXT \"v=DMARC1; p=quarantine; rua=mailto:postmaster@$DOMAIN\""
|
||||||
|
echo ""
|
||||||
|
echo "=============================================="
|
||||||
|
echo " Domain setup completed."
|
||||||
|
echo "=============================================="
|
||||||
|
echo ""
|
||||||
43
tools/add_mailuser.sh
Executable file
43
tools/add_mailuser.sh
Executable file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
MAILSERVER_CONTAINER="mailserver"
|
||||||
|
PWGEN_CMD="pwgen -scn 32"
|
||||||
|
|
||||||
|
if [ $# -ne 1 -o $# -ne 2 ]
|
||||||
|
then
|
||||||
|
echo "Usage: $0 mail_address [password]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
EMAIL="$1"
|
||||||
|
PASSWORD="${2:-}"
|
||||||
|
|
||||||
|
if [ -z "$PASSWORD" ]
|
||||||
|
then
|
||||||
|
# Ensure pwgen exists
|
||||||
|
if ! command -v pwgen >/dev/null 2>&1; then
|
||||||
|
echo "ERROR: pwgen is not installed. Install with: sudo apt install pwgen"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate a secure password
|
||||||
|
PASSWORD="$($PWGEN_CMD)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the mailbox inside Docker-Mailserver (DMS hashes internally)
|
||||||
|
docker exec -i "$MAILSERVER_CONTAINER" setup email add "$EMAIL" "$PASSWORD"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=============================================="
|
||||||
|
echo "User added: $EMAIL"
|
||||||
|
echo
|
||||||
|
echo "Generated password (plaintext):"
|
||||||
|
echo " $PASSWORD"
|
||||||
|
echo
|
||||||
|
echo "This password is NOT stored in plaintext anywhere."
|
||||||
|
echo "Docker-Mailserver stored only a secure hash."
|
||||||
|
echo "=============================================="
|
||||||
|
echo
|
||||||
|
echo "Restart mailserver to apply changes:"
|
||||||
|
echo " docker compose restart mail"
|
||||||
124
tools/check_dns.sh
Executable file
124
tools/check_dns.sh
Executable file
@@ -0,0 +1,124 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
DOMAIN="knusperkerne.de"
|
||||||
|
HOST="mailsystem.knusperkerne.de"
|
||||||
|
IP="89.58.2.51"
|
||||||
|
|
||||||
|
MAILSERVER_CONTAINER="mailserver"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=========================================="
|
||||||
|
echo " MAILSERVER HEALTH CHECK"
|
||||||
|
echo " Domain: $DOMAIN"
|
||||||
|
echo " Host: $HOST ($IP)"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
#
|
||||||
|
# Helper
|
||||||
|
#
|
||||||
|
check_dns_record() {
|
||||||
|
local label="$1"
|
||||||
|
local result="$2"
|
||||||
|
|
||||||
|
if [[ -z "$result" ]]; then
|
||||||
|
echo "$label: [FAIL]"
|
||||||
|
else
|
||||||
|
echo "$label: [OK] $result"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
service_running() {
|
||||||
|
local svc="$1"
|
||||||
|
docker exec "$MAILSERVER_CONTAINER" supervisorctl status "$svc" 2>/dev/null | grep -q "RUNNING"
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Load environment flags
|
||||||
|
#
|
||||||
|
ENVFILE="$(dirname "$0")/../config/dms.env"
|
||||||
|
|
||||||
|
get_env_flag() {
|
||||||
|
local key="$1"
|
||||||
|
grep -E "^$key=" "$ENVFILE" | cut -d '=' -f2
|
||||||
|
}
|
||||||
|
|
||||||
|
ENABLE_AMAVIS=$(get_env_flag ENABLE_AMAVIS)
|
||||||
|
ENABLE_CLAMAV=$(get_env_flag ENABLE_CLAMAV)
|
||||||
|
|
||||||
|
#
|
||||||
|
# DNS CHECK
|
||||||
|
#
|
||||||
|
echo "Checking DNS..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
|
||||||
|
MX=$(dig +short MX $DOMAIN)
|
||||||
|
A=$(dig +short A $HOST)
|
||||||
|
SPF=$(dig +short TXT $DOMAIN | grep spf)
|
||||||
|
DKIM=$(dig +short TXT mail._domainkey.$DOMAIN)
|
||||||
|
DMARC=$(dig +short TXT _dmarc.$DOMAIN)
|
||||||
|
RDNS=$(dig -x $IP +short)
|
||||||
|
|
||||||
|
check_dns_record "MX" "$MX"
|
||||||
|
check_dns_record "A" "$A"
|
||||||
|
check_dns_record "SPF" "$SPF"
|
||||||
|
check_dns_record "DKIM" "$DKIM"
|
||||||
|
check_dns_record "DMARC" "$DMARC"
|
||||||
|
check_dns_record "rDNS" "$RDNS"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
#
|
||||||
|
# TLS Tests
|
||||||
|
#
|
||||||
|
echo "Checking SMTP TLS (Port 587)..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
openssl s_client -connect "$HOST:587" -starttls smtp -brief < /dev/null &>/tmp/tls587
|
||||||
|
grep -q "TLSv" /tmp/tls587 && echo "587/TLS: [OK]" || echo "587/TLS: [FAIL]"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Checking SMTP (Port 25)..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
openssl s_client -connect "$HOST:25" -starttls smtp -brief < /dev/null &>/tmp/tls25
|
||||||
|
grep -q "TLSv" /tmp/tls25 && echo "25/TLS: [OK]" || echo "25/TLS: [FAIL]"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Checking IMAPS TLS (993)..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
openssl s_client -connect "$HOST:993" -brief < /dev/null &>/tmp/tls993
|
||||||
|
grep -q "TLSv" /tmp/tls993 && echo "993/TLS: [OK]" || echo "993/TLS: [FAIL]"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
#
|
||||||
|
# SERVICE CHECK (ONLY ACTIVE SERVICES)
|
||||||
|
#
|
||||||
|
echo "Checking local mail services (inside container)..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
|
||||||
|
# Postfix
|
||||||
|
if service_running postfix; then echo "postfix: [OK]"; else echo "postfix: [FAIL]"; fi
|
||||||
|
|
||||||
|
# Dovecot
|
||||||
|
if service_running dovecot; then echo "dovecot: [OK]"; else echo "dovecot: [FAIL]"; fi
|
||||||
|
|
||||||
|
# Amavis (only if enabled)
|
||||||
|
if [[ "$ENABLE_AMAVIS" == "1" ]]; then
|
||||||
|
if service_running amavis; then echo "amavis: [OK]"; else echo "amavis: [FAIL]"; fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SpamAssassin (always via Amavis)
|
||||||
|
echo "spamassassin: [OK] (via Amavis)"
|
||||||
|
|
||||||
|
# ClamAV (only if enabled)
|
||||||
|
if [[ "$ENABLE_CLAMAV" == "1" ]]; then
|
||||||
|
if service_running clamav; then echo "clamav: [OK]"; else echo "clamav: [FAIL]"; fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
QUEUE=$(docker exec "$MAILSERVER_CONTAINER" mailq | grep -c "^[A-F0-9]")
|
||||||
|
echo "Queue Size: $QUEUE"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo " HEALTH CHECK COMPLETE"
|
||||||
|
echo "=========================================="
|
||||||
|
echo ""
|
||||||
42
tools/check_mail_usage.sh
Executable file
42
tools/check_mail_usage.sh
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# check_mail_usage.sh
|
||||||
|
#
|
||||||
|
# Checks Maildir usage by executing du inside the Docker-Mailserver container.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./check_mail_usage.sh
|
||||||
|
#
|
||||||
|
|
||||||
|
CONTAINER="mailserver"
|
||||||
|
MAILDIR="/var/mail"
|
||||||
|
|
||||||
|
echo "Scanning Maildir sizes inside container '$CONTAINER' ..."
|
||||||
|
echo
|
||||||
|
|
||||||
|
TMPFILE=$(mktemp)
|
||||||
|
|
||||||
|
# List <domain>/<user> directories inside container
|
||||||
|
docker exec "$CONTAINER" bash -c "
|
||||||
|
find $MAILDIR -mindepth 2 -maxdepth 2 -type d
|
||||||
|
" | while read -r DIR; do
|
||||||
|
SIZE_MB=$(docker exec "$CONTAINER" bash -c "du -sm \"$DIR\" | awk '{print \$1}'")
|
||||||
|
USER=$(basename "$DIR")
|
||||||
|
DOMAIN=$(basename "$(dirname "$DIR")")
|
||||||
|
echo \"$SIZE_MB MB $USER@$DOMAIN\" >> "$TMPFILE"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "======================"
|
||||||
|
echo " MAILDIR USAGE"
|
||||||
|
echo "======================"
|
||||||
|
echo
|
||||||
|
|
||||||
|
sort -nr "$TMPFILE" | head -n 10
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "----------------------"
|
||||||
|
TOTAL=$(docker exec "$CONTAINER" bash -c "du -sm $MAILDIR | awk '{print \$1}'")
|
||||||
|
echo "Total mail storage used: $TOTAL MB"
|
||||||
|
echo "----------------------"
|
||||||
|
|
||||||
|
rm "$TMPFILE"
|
||||||
50
tools/generate_dkim.sh
Executable file
50
tools/generate_dkim.sh
Executable file
@@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# generate_dkim.sh
|
||||||
|
# Generate a new DKIM selector for a domain for Docker-Mailserver.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./generate_dkim.sh <domain>
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# ./generate_dkim.sh knusperkerne.de
|
||||||
|
#
|
||||||
|
|
||||||
|
DOMAIN="$1"
|
||||||
|
CONTAINER="mailserver" # Name of your DMS container
|
||||||
|
SELECTOR="mail" # Default DKIM selector
|
||||||
|
DKIM_PATH="/tmp/docker-mailserver/opendkim/keys/$DOMAIN"
|
||||||
|
|
||||||
|
if [ -z "$DOMAIN" ]; then
|
||||||
|
echo "Usage: $0 <domain>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Generating DKIM key for domain: $DOMAIN"
|
||||||
|
echo "Selector: $SELECTOR"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Generate DKIM key inside the DMS container
|
||||||
|
docker exec "$CONTAINER" \
|
||||||
|
setup config dkim \
|
||||||
|
--domain "$DOMAIN" \
|
||||||
|
--selector "$SELECTOR" \
|
||||||
|
--bits 2048
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "ERROR: DKIM generation failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "DKIM key generated successfully."
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Show public DKIM key for DNS
|
||||||
|
echo "Your DKIM TXT record (add to DNS):"
|
||||||
|
echo "----------------------------------"
|
||||||
|
docker exec "$CONTAINER" \
|
||||||
|
cat "$DKIM_PATH/$SELECTOR.txt"
|
||||||
|
|
||||||
|
echo "----------------------------------"
|
||||||
|
echo
|
||||||
|
echo "DKIM generation complete."
|
||||||
177
tools/health_check.sh
Executable file
177
tools/health_check.sh
Executable file
@@ -0,0 +1,177 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# mail_health_check.sh
|
||||||
|
#
|
||||||
|
# Full health checker for Docker-Mailserver:
|
||||||
|
# - DNS (SPF, DKIM, DMARC, MX, A, rDNS)
|
||||||
|
# - TLS (SMTP/587, SMTP/25, IMAPS/993)
|
||||||
|
# - Authentication tests
|
||||||
|
# - Local queue and service checks
|
||||||
|
#
|
||||||
|
|
||||||
|
DOMAIN="knusperkerne.de"
|
||||||
|
MAIL_HOST="mailsystem.$DOMAIN"
|
||||||
|
MAIL_IP="89.58.2.51"
|
||||||
|
SMTP_PORT=587
|
||||||
|
IMAP_PORT=993
|
||||||
|
CONTAINER="mailserver"
|
||||||
|
TEST_USER="lars@knusperkerne.de"
|
||||||
|
TEST_PASS="REPLACE_WITH_REAL_PASSWORD" # (only needed for auth tests)
|
||||||
|
COLOR_OK="\e[32m[OK]\e[0m"
|
||||||
|
COLOR_WARN="\e[33m[WARN]\e[0m"
|
||||||
|
COLOR_FAIL="\e[31m[FAIL]\e[0m"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "=========================================="
|
||||||
|
echo " MAILSERVER HEALTH CHECK"
|
||||||
|
echo " Domain: $DOMAIN"
|
||||||
|
echo " Host: $MAIL_HOST ($MAIL_IP)"
|
||||||
|
echo "=========================================="
|
||||||
|
echo
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
# 1. DNS CHECKS
|
||||||
|
# ------------------------------------------
|
||||||
|
echo "Checking DNS..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
|
||||||
|
MX=$(dig +short MX "$DOMAIN")
|
||||||
|
A=$(dig +short A "$MAIL_HOST")
|
||||||
|
SPF=$(dig +short TXT "$DOMAIN" | grep "v=spf1")
|
||||||
|
DKIM=$(dig +short TXT "mail._domainkey.$DOMAIN")
|
||||||
|
DMARC=$(dig +short TXT "_dmarc.$DOMAIN")
|
||||||
|
RDNS=$(dig -x "$MAIL_IP" +short)
|
||||||
|
|
||||||
|
[[ -n "$MX" ]] && echo -e "MX: $COLOR_OK $MX" || echo -e "MX: $COLOR_FAIL"
|
||||||
|
[[ "$A" == "$MAIL_IP" ]] && echo -e "A: $COLOR_OK $A" || echo -e "A: $COLOR_FAIL"
|
||||||
|
[[ -n "$SPF" ]] && echo -e "SPF: $COLOR_OK $SPF" || echo -e "SPF: $COLOR_FAIL"
|
||||||
|
[[ -n "$DKIM" ]] && echo -e "DKIM: $COLOR_OK" || echo -e "DKIM: $COLOR_FAIL"
|
||||||
|
[[ -n "$DMARC" ]] && echo -e "DMARC: $COLOR_OK" || echo -e "DMARC: $COLOR_FAIL"
|
||||||
|
[[ -n "$RDNS" ]] && echo -e "rDNS: $COLOR_OK $RDNS" || echo -e "rDNS: $COLOR_FAIL"
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
# 2. SMTP / TLS CHECK (587)
|
||||||
|
# ------------------------------------------
|
||||||
|
echo "Checking SMTP TLS (Port 587)..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
|
||||||
|
TLS587=$(echo | openssl s_client -starttls smtp -connect "$MAIL_HOST:$SMTP_PORT" -servername "$MAIL_HOST" 2>/dev/null | grep -Eo "Protocol.*TLS|Cipher.*")
|
||||||
|
|
||||||
|
if [[ -n "$TLS587" ]]; then
|
||||||
|
echo -e "587/TLS: $COLOR_OK"
|
||||||
|
echo "$TLS587"
|
||||||
|
else
|
||||||
|
echo -e "587/TLS: $COLOR_FAIL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
# 3. SMTP / TLS CHECK (25)
|
||||||
|
# ------------------------------------------
|
||||||
|
echo "Checking SMTP (Port 25)..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
|
||||||
|
TLS25=$(echo | openssl s_client -starttls smtp -connect "$MAIL_HOST:25" -servername "$MAIL_HOST" 2>/dev/null | grep -Eo "Protocol.*TLS|Cipher.*")
|
||||||
|
|
||||||
|
if [[ -n "$TLS25" ]]; then
|
||||||
|
echo -e "25/TLS: $COLOR_OK"
|
||||||
|
echo "$TLS25"
|
||||||
|
else
|
||||||
|
echo -e "25/TLS: $COLOR_FAIL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
# 4. IMAPS TLS CHECK
|
||||||
|
# ------------------------------------------
|
||||||
|
echo "Checking IMAPS TLS (993)..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
|
||||||
|
TLS_IMAP=$(echo | openssl s_client -connect "$MAIL_HOST:$IMAP_PORT" -servername "$MAIL_HOST" 2>/dev/null | grep -Eo "Protocol.*TLS|Cipher.*")
|
||||||
|
|
||||||
|
if [[ -n "$TLS_IMAP" ]]; then
|
||||||
|
echo -e "993/TLS: $COLOR_OK"
|
||||||
|
echo "$TLS_IMAP"
|
||||||
|
else
|
||||||
|
echo -e "993/TLS: $COLOR_FAIL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
# 5. SMTP-AUTH TEST
|
||||||
|
# ------------------------------------------
|
||||||
|
if [[ "$TEST_PASS" != "REPLACE_WITH_REAL_PASSWORD" ]]; then
|
||||||
|
echo "Checking SMTP AUTH..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
|
||||||
|
AUTH_SMTP=$(swaks --to test@$DOMAIN \
|
||||||
|
--from "$TEST_USER" \
|
||||||
|
--server "$MAIL_HOST" \
|
||||||
|
--port 587 \
|
||||||
|
--auth LOGIN \
|
||||||
|
--auth-user "$TEST_USER" \
|
||||||
|
--auth-password "$TEST_PASS" \
|
||||||
|
--quit-after AUTH 2>&1)
|
||||||
|
|
||||||
|
if echo "$AUTH_SMTP" | grep -q "235 "; then
|
||||||
|
echo -e "SMTP AUTH: $COLOR_OK"
|
||||||
|
else
|
||||||
|
echo -e "SMTP AUTH: $COLOR_FAIL"
|
||||||
|
echo "$AUTH_SMTP"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "SMTP AUTH TEST: skipped (no password configured)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
# 6. IMAP AUTH TEST
|
||||||
|
# ------------------------------------------
|
||||||
|
if [[ "$TEST_PASS" != "REPLACE_WITH_REAL_PASSWORD" ]]; then
|
||||||
|
echo "Checking IMAP AUTH..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
|
||||||
|
AUTH_IMAP=$(swaks --server "$MAIL_HOST" \
|
||||||
|
--port 993 \
|
||||||
|
--auth-user "$TEST_USER" \
|
||||||
|
--auth-password "$TEST_PASS" \
|
||||||
|
--imap \
|
||||||
|
--quit-after AUTH 2>&1)
|
||||||
|
|
||||||
|
if echo "$AUTH_IMAP" | grep -q "SUCCESS"; then
|
||||||
|
echo -e "IMAP AUTH: $COLOR_OK"
|
||||||
|
else
|
||||||
|
echo -e "IMAP AUTH: $COLOR_FAIL"
|
||||||
|
echo "$AUTH_IMAP"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "IMAP AUTH TEST: skipped (no password configured)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
# ------------------------------------------
|
||||||
|
# 7. LOCAL MAILSERVER COMPONENTS
|
||||||
|
# ------------------------------------------
|
||||||
|
echo "Checking local mail services (inside container)..."
|
||||||
|
echo "------------------------------------------"
|
||||||
|
|
||||||
|
docker exec "$CONTAINER" supervisorctl status postfix &>/dev/null && echo -e "Postfix: $COLOR_OK" || echo -e "Postfix: $COLOR_FAIL"
|
||||||
|
docker exec "$CONTAINER" supervisorctl status dovecot &>/dev/null && echo -e "Dovecot: $COLOR_OK" || echo -e "Dovecot: $COLOR_FAIL"
|
||||||
|
docker exec "$CONTAINER" supervisorctl status rspamd* &>/dev/null && echo -e "Rspamd: $COLOR_OK" || echo -e "Rspamd: $COLOR_FAIL"
|
||||||
|
docker exec "$CONTAINER" supervisorctl status amavis &>/dev/null && echo -e "Amavis: $COLOR_OK" || echo -e "Amavis: $COLOR_WARN (optional)"
|
||||||
|
|
||||||
|
QUEUE_SIZE=$(docker exec "$CONTAINER" mailq 2>/dev/null | grep -c "^[A-F0-9]")
|
||||||
|
echo "Queue Size: $QUEUE_SIZE"
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo " HEALTH CHECK COMPLETE"
|
||||||
|
echo "=========================================="
|
||||||
|
echo
|
||||||
16
tools/test_imaps_login.sh
Executable file
16
tools/test_imaps_login.sh
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Usage: ./test_imaps_login.sh <server> <email> <password>
|
||||||
|
# Example: ./test_imaps_login.sh mailsystem.knusperkerne.de postmaster@knusperkerne.de PASSWORT
|
||||||
|
|
||||||
|
SERVER="$1"
|
||||||
|
USER="$2"
|
||||||
|
PASS="$3"
|
||||||
|
|
||||||
|
if [ -z "$SERVER" ] || [ -z "$USER" ] || [ -z "$PASS" ]; then
|
||||||
|
echo "Usage: $0 <server> <email> <password>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "a LOGIN $USER $PASS\r\na LOGOUT\r\n" | \
|
||||||
|
openssl s_client -connect "$SERVER:993" -quiet
|
||||||
24
tools/test_smtp_submission.sh
Executable file
24
tools/test_smtp_submission.sh
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Usage: ./test_smtp_submission.sh <server> <email> <password>
|
||||||
|
# Example: ./test_smtp_submission.sh mailsystem.knusperkerne.de postmaster@knusperkerne.de PASSWORT
|
||||||
|
|
||||||
|
SERVER="$1"
|
||||||
|
USER="$2"
|
||||||
|
PASS="$3"
|
||||||
|
|
||||||
|
if [ -z "$SERVER" ] || [ -z "$USER" ] || [ -z "$PASS" ]; then
|
||||||
|
echo "Usage: $0 <server> <email> <password>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
swaks \
|
||||||
|
--to "$USER" \
|
||||||
|
--from "$USER" \
|
||||||
|
--server "$SERVER" \
|
||||||
|
--auth LOGIN \
|
||||||
|
--auth-user "$USER" \
|
||||||
|
--auth-password "$PASS" \
|
||||||
|
--port 587 \
|
||||||
|
--tls \
|
||||||
|
--quit-after MAIL
|
||||||
Reference in New Issue
Block a user