mailserver: init
This commit is contained in:
parent
a7c73695db
commit
ef19e76b97
6 changed files with 1398 additions and 12 deletions
|
|
@ -174,6 +174,7 @@ Also, the stack fits together nicely thanks to [contracts](#contracts).
|
||||||
- Nextcloud
|
- Nextcloud
|
||||||
- Audiobookshelf
|
- Audiobookshelf
|
||||||
- Deluge + *arr stack
|
- Deluge + *arr stack
|
||||||
|
- Simple NixOS Mailserver
|
||||||
- Firefly-iii
|
- Firefly-iii
|
||||||
- Forgejo
|
- Forgejo
|
||||||
- Grocy
|
- Grocy
|
||||||
|
|
|
||||||
|
|
@ -2720,6 +2720,9 @@
|
||||||
"services-category-documents": [
|
"services-category-documents": [
|
||||||
"services.html#services-category-documents"
|
"services.html#services-category-documents"
|
||||||
],
|
],
|
||||||
|
"services-category-emails": [
|
||||||
|
"services.html#services-category-emails"
|
||||||
|
],
|
||||||
"services-category-finance": [
|
"services-category-finance": [
|
||||||
"services.html#services-category-finance"
|
"services.html#services-category-finance"
|
||||||
],
|
],
|
||||||
|
|
@ -3944,6 +3947,294 @@
|
||||||
"services-karakeep-usage": [
|
"services-karakeep-usage": [
|
||||||
"services-karakeep.html#services-karakeep-usage"
|
"services-karakeep.html#services-karakeep-usage"
|
||||||
],
|
],
|
||||||
|
"services-mailserver": [
|
||||||
|
"services-mailserver.html#services-mailserver"
|
||||||
|
],
|
||||||
|
"services-mailserver-certs": [
|
||||||
|
"services-mailserver.html#services-mailserver-certs"
|
||||||
|
],
|
||||||
|
"services-mailserver-debug": [
|
||||||
|
"services-mailserver.html#services-mailserver-debug"
|
||||||
|
],
|
||||||
|
"services-mailserver-debug-auth": [
|
||||||
|
"services-mailserver.html#services-mailserver-debug-auth"
|
||||||
|
],
|
||||||
|
"services-mailserver-debug-folder-mapping": [
|
||||||
|
"services-mailserver.html#services-mailserver-debug-folder-mapping"
|
||||||
|
],
|
||||||
|
"services-mailserver-debug-folders": [
|
||||||
|
"services-mailserver.html#services-mailserver-debug-folders"
|
||||||
|
],
|
||||||
|
"services-mailserver-debug-local-folders": [
|
||||||
|
"services-mailserver.html#services-mailserver-debug-local-folders"
|
||||||
|
],
|
||||||
|
"services-mailserver-debug-ports": [
|
||||||
|
"services-mailserver.html#services-mailserver-debug-ports"
|
||||||
|
],
|
||||||
|
"services-mailserver-debug-systemd": [
|
||||||
|
"services-mailserver.html#services-mailserver-debug-systemd"
|
||||||
|
],
|
||||||
|
"services-mailserver-declarative-ldap": [
|
||||||
|
"services-mailserver.html#services-mailserver-declarative-ldap"
|
||||||
|
],
|
||||||
|
"services-mailserver-impermanence": [
|
||||||
|
"services-mailserver.html#services-mailserver-impermanence"
|
||||||
|
],
|
||||||
|
"services-mailserver-mobile": [
|
||||||
|
"services-mailserver.html#services-mailserver-mobile"
|
||||||
|
],
|
||||||
|
"services-mailserver-options": [
|
||||||
|
"services-mailserver.html#services-mailserver-options"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.adminPassword": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.adminPassword"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.adminPassword.request": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.adminPassword.request"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.adminPassword.request.group": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.adminPassword.request.group"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.adminPassword.request.mode": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.adminPassword.request.mode"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.adminPassword.request.owner": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.adminPassword.request.owner"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.adminPassword.request.restartUnits": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.adminPassword.request.restartUnits"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.adminPassword.result": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.adminPassword.result"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.adminPassword.result.path": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.adminPassword.result.path"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.adminUsername": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.adminUsername"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.backup": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.backup"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.backup.request": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.backup.request"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.backup.request.excludePatterns": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.backup.request.excludePatterns"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.backup.request.hooks": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.backup.request.hooks"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.backup.request.hooks.afterBackup": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.backup.request.hooks.afterBackup"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.backup.request.hooks.beforeBackup": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.backup.request.hooks.beforeBackup"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.backup.request.sourceDirectories": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.backup.request.sourceDirectories"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.backup.request.user": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.backup.request.user"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.backup.result": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.backup.result"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.backup.result.backupService": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.backup.result.backupService"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.backup.result.restoreScript": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.backup.result.restoreScript"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.domain": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.domain"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.enable": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.enable"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.host": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.host"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.mapSpecialDrafts": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.mapSpecialDrafts"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.mapSpecialJunk": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.mapSpecialJunk"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.mapSpecialSent": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.mapSpecialSent"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.mapSpecialTrash": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.mapSpecialTrash"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.request": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.request"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.request.group": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.request.group"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.request.mode": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.request.mode"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.request.owner": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.request.owner"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.request.restartUnits": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.request.restartUnits"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.result": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.result"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.result.path": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.password.result.path"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.port": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.port"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.sslType": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.sslType"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.timeout": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.timeout"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.accounts._name_.username": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.accounts._name_.username"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.debug": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.debug"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.imapSync.syncTimer": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.imapSync.syncTimer"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.impermanence": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.impermanence"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.account": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.account"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.adminName": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.adminName"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.adminPassword": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.adminPassword"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.adminPassword.request": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.adminPassword.request"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.adminPassword.request.group": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.adminPassword.request.group"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.adminPassword.request.mode": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.adminPassword.request.mode"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.adminPassword.request.owner": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.adminPassword.request.owner"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.adminPassword.request.restartUnits": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.adminPassword.request.restartUnits"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.adminPassword.result": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.adminPassword.result"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.adminPassword.result.path": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.adminPassword.result.path"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.dcdomain": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.dcdomain"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.enable": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.enable"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.host": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.host"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.port": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.port"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ldap.userGroup": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ldap.userGroup"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay.host": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay.host"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay.password": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay.password"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay.password.request": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay.password.request"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay.password.request.group": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay.password.request.group"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay.password.request.mode": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay.password.request.mode"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay.password.request.owner": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay.password.request.owner"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay.password.request.restartUnits": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay.password.request.restartUnits"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay.password.result": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay.password.result"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay.password.result.path": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay.password.result.path"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay.port": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay.port"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.smtpRelay.username": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.smtpRelay.username"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ssl": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ssl"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ssl.paths": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ssl.paths"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ssl.paths.cert": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ssl.paths.cert"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ssl.paths.key": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ssl.paths.key"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.ssl.systemdService": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.ssl.systemdService"
|
||||||
|
],
|
||||||
|
"services-mailserver-options-shb.mailserver.subdomain": [
|
||||||
|
"services-mailserver.html#services-mailserver-options-shb.mailserver.subdomain"
|
||||||
|
],
|
||||||
|
"services-mailserver-usage": [
|
||||||
|
"services-mailserver.html#services-mailserver-usage"
|
||||||
|
],
|
||||||
|
"services-mailserver-usage-backup": [
|
||||||
|
"services-mailserver.html#services-mailserver-usage-backup"
|
||||||
|
],
|
||||||
|
"services-mailserver-usage-disk-layout": [
|
||||||
|
"services-mailserver.html#services-mailserver-usage-disk-layout"
|
||||||
|
],
|
||||||
|
"services-mailserver-usage-ldap": [
|
||||||
|
"services-mailserver.html#services-mailserver-usage-ldap"
|
||||||
|
],
|
||||||
|
"services-mailserver-usage-secrets": [
|
||||||
|
"services-mailserver.html#services-mailserver-usage-secrets"
|
||||||
|
],
|
||||||
"services-monitoring-features": [
|
"services-monitoring-features": [
|
||||||
"blocks-monitoring.html#services-monitoring-features"
|
"blocks-monitoring.html#services-monitoring-features"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,19 @@ Not all services are yet documented. You can find all available services [in the
|
||||||
The following table summarizes for each documented service what features it provides. More
|
The following table summarizes for each documented service what features it provides. More
|
||||||
information is provided in the respective manual sections.
|
information is provided in the respective manual sections.
|
||||||
|
|
||||||
| Service | Backup | Reverse Proxy | SSO | LDAP | Monitoring | Profiling |
|
| Service | Backup | Reverse Proxy | SSO | LDAP | Monitoring | Profiling |
|
||||||
|----------------------|--------|---------------|-----|-------|------------|-----------|
|
|-----------------------------|--------|---------------|-----|-------|------------|-----------|
|
||||||
| [*Arr][] | Y (1) | Y | Y | Y (4) | Y (2) | N |
|
| [*Arr][] | Y (1) | Y | Y | Y (4) | Y (2) | N |
|
||||||
| [Firefly-iii][] | Y (1) | Y | Y | Y | Y (2) | N |
|
| [Firefly-iii][] | Y (1) | Y | Y | Y | Y (2) | N |
|
||||||
| [Forgejo][] | Y (1) | Y | Y | Y | Y (2) | N |
|
| [Forgejo][] | Y (1) | Y | Y | Y | Y (2) | N |
|
||||||
| [Home-Assistant][] | Y (1) | Y | N | Y | Y (2) | N |
|
| [Home-Assistant][] | Y (1) | Y | N | Y | Y (2) | N |
|
||||||
| [Jellyfin][] | Y (1) | Y | Y | Y | Y (2) | N |
|
| [Jellyfin][] | Y (1) | Y | Y | Y | Y (2) | N |
|
||||||
| [Karakeep][] | Y (1) | Y | Y | Y | Y (2) | N |
|
| [Karakeep][] | Y (1) | Y | Y | Y | Y (2) | N |
|
||||||
| [Nextcloud Server][] | Y (1) | Y | Y | Y | Y (2) | P (3) |
|
| [Nextcloud Server][] | Y (1) | Y | Y | Y | Y (2) | P (3) |
|
||||||
| [Open WebUI][] | Y (1) | Y | Y | Y | Y (2) | N |
|
| [Open WebUI][] | Y (1) | Y | Y | Y | Y (2) | N |
|
||||||
| [Pinchflat][] | Y | Y | Y | Y (4) | Y (5) | N |
|
| [Pinchflat][] | Y | Y | Y | Y (4) | Y (5) | N |
|
||||||
| [Vaultwarden][] | Y (1) | Y | Y | Y | Y (2) | N |
|
| [Simple NixOS Mailserver][] | Y | Y | N | Y | Y | N |
|
||||||
|
| [Vaultwarden][] | Y (1) | Y | Y | Y | Y (2) | N |
|
||||||
|
|
||||||
Legend: **N**: no but WIP; **P**: partial; **Y**: yes
|
Legend: **N**: no but WIP; **P**: partial; **Y**: yes
|
||||||
|
|
||||||
|
|
@ -44,6 +45,7 @@ Legend: **N**: no but WIP; **P**: partial; **Y**: yes
|
||||||
[Nextcloud Server]: services-nextcloud.html
|
[Nextcloud Server]: services-nextcloud.html
|
||||||
[Open WebUI]: services-open-webui.html
|
[Open WebUI]: services-open-webui.html
|
||||||
[Pinchflat]: services-pinchflat.html
|
[Pinchflat]: services-pinchflat.html
|
||||||
|
[Simple NixOS Mailserver]: services-mailserver.html
|
||||||
[Vaultwarden]: services-vaultwarden.html
|
[Vaultwarden]: services-vaultwarden.html
|
||||||
|
|
||||||
## Documents {#services-category-documents}
|
## Documents {#services-category-documents}
|
||||||
|
|
@ -52,6 +54,12 @@ Legend: **N**: no but WIP; **P**: partial; **Y**: yes
|
||||||
modules/services/nextcloud-server/docs/default.md
|
modules/services/nextcloud-server/docs/default.md
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Emails {#services-category-emails}
|
||||||
|
|
||||||
|
```{=include=} chapters html:into-file=//services-mailserver.html
|
||||||
|
modules/services/mailserver/docs/default.md
|
||||||
|
```
|
||||||
|
|
||||||
## Passwords {#services-category-passwords}
|
## Passwords {#services-category-passwords}
|
||||||
|
|
||||||
```{=include=} chapters html:into-file=//services-vaultwarden.html
|
```{=include=} chapters html:into-file=//services-vaultwarden.html
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@
|
||||||
"services/home-assistant" = ./modules/services/home-assistant.nix;
|
"services/home-assistant" = ./modules/services/home-assistant.nix;
|
||||||
"services/jellyfin" = ./modules/services/jellyfin.nix;
|
"services/jellyfin" = ./modules/services/jellyfin.nix;
|
||||||
"services/karakeep" = ./modules/services/karakeep.nix;
|
"services/karakeep" = ./modules/services/karakeep.nix;
|
||||||
|
"services/mailserver" = ./modules/services/mailserver.nix;
|
||||||
"services/nextcloud-server" = {
|
"services/nextcloud-server" = {
|
||||||
module = ./modules/services/nextcloud-server.nix;
|
module = ./modules/services/nextcloud-server.nix;
|
||||||
optionRoot = [
|
optionRoot = [
|
||||||
|
|
@ -398,6 +399,7 @@
|
||||||
self.nixosModules.home-assistant
|
self.nixosModules.home-assistant
|
||||||
self.nixosModules.jellyfin
|
self.nixosModules.jellyfin
|
||||||
self.nixosModules.karakeep
|
self.nixosModules.karakeep
|
||||||
|
self.nixosModules.mailserver
|
||||||
self.nixosModules.nextcloud-server
|
self.nixosModules.nextcloud-server
|
||||||
self.nixosModules.open-webui
|
self.nixosModules.open-webui
|
||||||
self.nixosModules.pinchflat
|
self.nixosModules.pinchflat
|
||||||
|
|
@ -435,6 +437,7 @@
|
||||||
nixosModules.home-assistant = modules/services/home-assistant.nix;
|
nixosModules.home-assistant = modules/services/home-assistant.nix;
|
||||||
nixosModules.jellyfin = modules/services/jellyfin.nix;
|
nixosModules.jellyfin = modules/services/jellyfin.nix;
|
||||||
nixosModules.karakeep = modules/services/karakeep.nix;
|
nixosModules.karakeep = modules/services/karakeep.nix;
|
||||||
|
nixosModules.mailserver = modules/services/mailserver.nix;
|
||||||
nixosModules.nextcloud-server = modules/services/nextcloud-server.nix;
|
nixosModules.nextcloud-server = modules/services/nextcloud-server.nix;
|
||||||
nixosModules.open-webui = modules/services/open-webui.nix;
|
nixosModules.open-webui = modules/services/open-webui.nix;
|
||||||
nixosModules.paperless = modules/services/paperless.nix;
|
nixosModules.paperless = modules/services/paperless.nix;
|
||||||
|
|
|
||||||
703
modules/services/mailserver.nix
Normal file
703
modules/services/mailserver.nix
Normal file
|
|
@ -0,0 +1,703 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
shb,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.shb.mailserver;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(
|
||||||
|
builtins.fetchGit {
|
||||||
|
url = "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver.git";
|
||||||
|
ref = "master";
|
||||||
|
rev = "5965fae920b6b97f39f94bdb6195631e274c93a5";
|
||||||
|
}
|
||||||
|
+ "/default.nix"
|
||||||
|
)
|
||||||
|
../blocks/lldap.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
options.shb.mailserver = {
|
||||||
|
enable = lib.mkEnableOption "SHB's nixos-mailserver module";
|
||||||
|
|
||||||
|
subdomain = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Subdomain under which imap and smtp functions will be served.";
|
||||||
|
default = "imap";
|
||||||
|
};
|
||||||
|
|
||||||
|
domain = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "domain under which imap and smtp functions will be served.";
|
||||||
|
example = "mydomain.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
ssl = lib.mkOption {
|
||||||
|
description = "Path to SSL files";
|
||||||
|
type = lib.types.nullOr shb.contracts.ssl.certs;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
adminUsername = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Admin username.
|
||||||
|
|
||||||
|
postmaster will be made an alias of this user.
|
||||||
|
'';
|
||||||
|
example = "admin";
|
||||||
|
};
|
||||||
|
|
||||||
|
adminPassword = lib.mkOption {
|
||||||
|
description = "Admin user password.";
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (
|
||||||
|
lib.types.submodule {
|
||||||
|
options = shb.contracts.secret.mkRequester {
|
||||||
|
mode = "0400";
|
||||||
|
owner = config.services.postfix.user;
|
||||||
|
ownerText = "services.postfix.user";
|
||||||
|
restartUnits = [ "dovecot.service" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
imapSync = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Synchronize one or more email providers through IMAP
|
||||||
|
to your dovecot2 instance.
|
||||||
|
|
||||||
|
This allows you to backup that email provider
|
||||||
|
and centralize your accounts in this dovecot2 instance.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (
|
||||||
|
lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
syncTimer = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "5m";
|
||||||
|
description = ''
|
||||||
|
Systemd timer for when imap sync job should happen.
|
||||||
|
|
||||||
|
This timer is not scheduling the job at regular intervals.
|
||||||
|
After a job finishes, the given amount of time is waited then the next job is started.
|
||||||
|
|
||||||
|
The default is set deliberatily slow to not spam you when setting up your mailserver.
|
||||||
|
When everything works, you will want to reduce it to 10s or something like that.
|
||||||
|
'';
|
||||||
|
example = "10s";
|
||||||
|
};
|
||||||
|
|
||||||
|
debug = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable verbose mbsync logging.";
|
||||||
|
};
|
||||||
|
|
||||||
|
accounts = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Accounts to sync emails from using IMAP.
|
||||||
|
|
||||||
|
Emails will be stored under `''${config.mailserver.mailDirectory}/''${name}/''${username}`
|
||||||
|
'';
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
host = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Hostname of the email's provider IMAP server.";
|
||||||
|
example = "imap.fastmail.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
description = "Port of the email's provider IMAP server.";
|
||||||
|
default = 993;
|
||||||
|
};
|
||||||
|
|
||||||
|
username = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Username used to login to the email's provider IMAP server.";
|
||||||
|
example = "userA@fastmail.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
password = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Password used to login to the email's provider IMAP server.
|
||||||
|
|
||||||
|
The password could be an "app password" like for [Fastmail](https://www.fastmail.help/hc/en-us/articles/360058752854-App-passwords)
|
||||||
|
'';
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = shb.contracts.secret.mkRequester {
|
||||||
|
mode = "0400";
|
||||||
|
owner = config.mailserver.vmailUserName;
|
||||||
|
restartUnits = [ "mbsync.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
sslType = lib.mkOption {
|
||||||
|
description = "Connection security method.";
|
||||||
|
type = lib.types.enum [
|
||||||
|
"IMAPS"
|
||||||
|
"STARTTLS"
|
||||||
|
];
|
||||||
|
default = "IMAPS";
|
||||||
|
};
|
||||||
|
|
||||||
|
timeout = lib.mkOption {
|
||||||
|
description = "Connect and data timeout.";
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 120;
|
||||||
|
};
|
||||||
|
|
||||||
|
mapSpecialDrafts = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "Drafts";
|
||||||
|
description = ''
|
||||||
|
Drafts special folder name on far side.
|
||||||
|
|
||||||
|
You only need to change this if mbsync logs the following error:
|
||||||
|
|
||||||
|
Error: ... far side box Drafts cannot be opened
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
mapSpecialSent = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "Sent";
|
||||||
|
description = ''
|
||||||
|
Sent special folder name on far side.
|
||||||
|
|
||||||
|
You only need to change this if mbsync logs the following error:
|
||||||
|
|
||||||
|
Error: ... far side box Sent cannot be opened
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
mapSpecialTrash = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "Trash";
|
||||||
|
description = ''
|
||||||
|
Trash special folder name on far side.
|
||||||
|
|
||||||
|
You only need to change this if mbsync logs the following error:
|
||||||
|
|
||||||
|
Error: ... far side box Trash cannot be opened
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
mapSpecialJunk = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "Junk";
|
||||||
|
description = ''
|
||||||
|
Junk special folder name on far side.
|
||||||
|
|
||||||
|
You only need to change this if mbsync logs the following error:
|
||||||
|
|
||||||
|
Error: ... far side box Junk cannot be opened
|
||||||
|
'';
|
||||||
|
example = "Spam";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
smtpRelay = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Proxy outgoing emails through an email provider.
|
||||||
|
|
||||||
|
In short, this can help you avoid having your outgoing emails marked as spam.
|
||||||
|
See the manual for a lengthier explanation.
|
||||||
|
'';
|
||||||
|
default = null;
|
||||||
|
type = lib.types.nullOr (
|
||||||
|
lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
host = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Hostname of the email's provider SMTP server.";
|
||||||
|
example = "smtp.fastmail.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
description = "Port of the email's provider SMTP server.";
|
||||||
|
default = 587;
|
||||||
|
};
|
||||||
|
|
||||||
|
username = lib.mkOption {
|
||||||
|
description = "Username used to login to the email's provider SMTP server.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
password = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Password used to login to the email's provider IMAP server.
|
||||||
|
|
||||||
|
The password could be an "app password" like for [Fastmail](https://www.fastmail.help/hc/en-us/articles/360058752854-App-passwords)
|
||||||
|
'';
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = shb.contracts.secret.mkRequester {
|
||||||
|
mode = "0400";
|
||||||
|
owner = config.services.postfix.user;
|
||||||
|
ownerText = "services.postfix.user";
|
||||||
|
restartUnits = [ "postfix.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ldap = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
LDAP Integration.
|
||||||
|
|
||||||
|
Enabling this app will create a new LDAP configuration or update one that exists with
|
||||||
|
the given host.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
type = lib.types.nullOr (
|
||||||
|
lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
enable = lib.mkEnableOption "LDAP app.";
|
||||||
|
|
||||||
|
host = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
Host serving the LDAP server.
|
||||||
|
'';
|
||||||
|
default = "127.0.0.1";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
description = ''
|
||||||
|
Port of the service serving the LDAP server.
|
||||||
|
'';
|
||||||
|
default = 389;
|
||||||
|
};
|
||||||
|
|
||||||
|
dcdomain = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "dc domain for ldap.";
|
||||||
|
example = "dc=mydomain,dc=com";
|
||||||
|
};
|
||||||
|
|
||||||
|
account = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
Select one account from those defined in `shb.mailserver.imapSync.accounts`
|
||||||
|
to login with.
|
||||||
|
|
||||||
|
Using LDAP, you can only connect to one account.
|
||||||
|
This limitation could maybe be lifted, feel free to post an issue if you need this.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
adminName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Admin user of the LDAP server.";
|
||||||
|
default = "admin";
|
||||||
|
};
|
||||||
|
|
||||||
|
adminPassword = lib.mkOption {
|
||||||
|
description = "LDAP server admin password.";
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = shb.contracts.secret.mkRequester {
|
||||||
|
mode = "0400";
|
||||||
|
owner = "nextcloud";
|
||||||
|
restartUnits = [ "dovecot.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
userGroup = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Group users must belong to to be able to use mails.";
|
||||||
|
default = "mail_user";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
backup = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Backup emails.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = shb.contracts.backup.mkRequester {
|
||||||
|
user = config.mailserver.vmailUserName;
|
||||||
|
sourceDirectories = builtins.filter (x: x != null) [
|
||||||
|
config.mailserver.indexDir
|
||||||
|
config.mailserver.mailDirectory
|
||||||
|
config.mailserver.sieveDirectory
|
||||||
|
config.mailserver.dkimKeyDirectory
|
||||||
|
];
|
||||||
|
sourceDirectoriesText = ''
|
||||||
|
[
|
||||||
|
config.mailserver.indexDir
|
||||||
|
config.mailserver.mailDirectory
|
||||||
|
config.mailserver.sieveDirectory
|
||||||
|
config.mailserver.dkimKeyDirectory
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
impermanence = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Path to save when using impermanence setup.
|
||||||
|
'';
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
default = {
|
||||||
|
index = config.mailserver.indexDir;
|
||||||
|
mail = config.mailserver.mailDirectory;
|
||||||
|
sieve = config.mailserver.sieveDirectory;
|
||||||
|
dkim = config.mailserver.dkimKeyDirectory;
|
||||||
|
};
|
||||||
|
defaultText = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
index = config.mailserver.indexDir;
|
||||||
|
mail = config.mailserver.mailDirectory;
|
||||||
|
sieve = config.mailserver.sieveDirectory;
|
||||||
|
dkim = config.mailserver.dkimKeyDirectory;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkMerge [
|
||||||
|
(lib.mkIf cfg.enable {
|
||||||
|
mailserver = {
|
||||||
|
enable = true;
|
||||||
|
stateVersion = 3;
|
||||||
|
fqdn = "${cfg.subdomain}.${cfg.domain}";
|
||||||
|
domains = [ cfg.domain ];
|
||||||
|
|
||||||
|
localDnsResolver = false;
|
||||||
|
|
||||||
|
certificateScheme = "acme-nginx";
|
||||||
|
enableImapSsl = true;
|
||||||
|
enableSubmissionSsl = true;
|
||||||
|
|
||||||
|
# Using / is needed for iOS mail.
|
||||||
|
# Both following options are used to organize subfolders in subdirectories.
|
||||||
|
hierarchySeparator = "/";
|
||||||
|
useFsLayout = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postfix.config = {
|
||||||
|
smtpd_tls_security_level = lib.mkForce "encrypt";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Is probably needed for iOS mail.
|
||||||
|
services.dovecot2.extraConfig = ''
|
||||||
|
ssl_min_protocol = TLSv1.2
|
||||||
|
ssl_cipher_list = HIGH:!aNULL:!MD5
|
||||||
|
'';
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
virtualHosts."${cfg.domain}" =
|
||||||
|
let
|
||||||
|
announce = pkgs.writeTextDir "config-v1.1.xml" ''
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<clientConfig version="1.1">
|
||||||
|
<emailProvider id="${cfg.domain}">
|
||||||
|
<domain>${cfg.domain}</domain>
|
||||||
|
<displayName>${cfg.domain} Mailserver</displayName>
|
||||||
|
|
||||||
|
<!-- Incoming IMAP server -->
|
||||||
|
<incomingServer type="imap">
|
||||||
|
<hostname>${cfg.subdomain}.${cfg.domain}</hostname>
|
||||||
|
<port>993</port>
|
||||||
|
<socketType>SSL</socketType>
|
||||||
|
<authentication>password-cleartext</authentication>
|
||||||
|
<username>%EMAILADDRESS%</username>
|
||||||
|
</incomingServer>
|
||||||
|
|
||||||
|
<!-- Outgoing SMTP server -->
|
||||||
|
<outgoingServer type="smtp">
|
||||||
|
<hostname>${cfg.subdomain}.${cfg.domain}</hostname>
|
||||||
|
<port>465</port>
|
||||||
|
<socketType>STARTTLS</socketType>
|
||||||
|
<authentication>password-cleartext</authentication>
|
||||||
|
<username>%EMAILADDRESS%</username>
|
||||||
|
</outgoingServer>
|
||||||
|
|
||||||
|
</emailProvider>
|
||||||
|
</clientConfig>
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
forceSSL = true; # Redirect HTTP → HTTPS
|
||||||
|
root = "/var/www"; # Dummy root
|
||||||
|
locations."/.well-known/autoconfig/mail/" = {
|
||||||
|
alias = "${announce}/";
|
||||||
|
extraConfig = ''
|
||||||
|
default_type application/xml;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(lib.mkIf (cfg.enable && cfg.adminUsername != null) {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = cfg.adminPassword != null;
|
||||||
|
message = "`shb.mailserver.adminPassword` must be not null if `shb.mailserver.adminUsername` is not null.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
mailserver = {
|
||||||
|
# To create the password hashes, use:
|
||||||
|
# nix run nixpkgs#mkpasswd -- --run 'mkpasswd -s'
|
||||||
|
loginAccounts = {
|
||||||
|
"${cfg.adminUsername}@${cfg.domain}" = {
|
||||||
|
hashedPasswordFile = cfg.adminPassword.result.path;
|
||||||
|
aliases = [ "postmaster@${cfg.domain}" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(lib.mkIf (cfg.enable && cfg.ldap != null) {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = cfg.adminUsername == null;
|
||||||
|
message = "`shb.mailserver.adminUsername` must be null `shb.mailserver.ldap` integration is set.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
shb.lldap.ensureGroups = {
|
||||||
|
${cfg.ldap.userGroup} = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
mailserver = {
|
||||||
|
ldap = {
|
||||||
|
enable = true;
|
||||||
|
uris = [
|
||||||
|
"ldap://${cfg.ldap.host}:${toString cfg.ldap.port}"
|
||||||
|
];
|
||||||
|
searchBase = "ou=people,${cfg.ldap.dcdomain}";
|
||||||
|
searchScope = "sub";
|
||||||
|
bind = {
|
||||||
|
dn = "uid=${cfg.ldap.adminName},ou=people,${cfg.ldap.dcdomain}";
|
||||||
|
passwordFile = cfg.ldap.adminPassword.result.path;
|
||||||
|
};
|
||||||
|
# Note that nixos simple mailserver sets auth_bind=yes
|
||||||
|
# which means authentication binds are used.
|
||||||
|
# https://doc.dovecot.org/2.3/configuration_manual/authentication/ldap_bind/#authentication-ldap-bind
|
||||||
|
dovecot =
|
||||||
|
let
|
||||||
|
filter = "(&(objectClass=inetOrgPerson)(mail=%{user})(memberOf=cn=${cfg.ldap.userGroup},ou=groups,${cfg.ldap.dcdomain}))";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
passAttrs = "user=user";
|
||||||
|
passFilter = filter;
|
||||||
|
userAttrs = lib.concatStringsSep "," [
|
||||||
|
"=home=${config.mailserver.mailDirectory}/${cfg.ldap.account}/%u"
|
||||||
|
# "mail=maildir:${config.mailserver.mailDirectory}/${cfg.ldap.account}/%u/mail"
|
||||||
|
"uid=${config.mailserver.vmailUserName}"
|
||||||
|
"gid=${config.mailserver.vmailGroupName}"
|
||||||
|
];
|
||||||
|
userFilter = filter;
|
||||||
|
};
|
||||||
|
postfix = {
|
||||||
|
filter = "(&(objectClass=inetOrgPerson)(mail=%s)(memberOf=cn=${cfg.ldap.userGroup},ou=groups,${cfg.ldap.dcdomain}))";
|
||||||
|
mailAttribute = "mail";
|
||||||
|
uidAttribute = "mail";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(lib.mkIf (cfg.enable && cfg.imapSync != null) {
|
||||||
|
systemd.services.mbsync =
|
||||||
|
let
|
||||||
|
configFile =
|
||||||
|
let
|
||||||
|
mkAccount = name: acct: ''
|
||||||
|
# ${name} account
|
||||||
|
|
||||||
|
IMAPAccount ${name}
|
||||||
|
Host ${acct.host}
|
||||||
|
Port ${toString acct.port}
|
||||||
|
User ${acct.username}
|
||||||
|
PassCmd "cat ${acct.password.result.path}"
|
||||||
|
TLSType ${acct.sslType}
|
||||||
|
AuthMechs LOGIN
|
||||||
|
Timeout ${toString acct.timeout}
|
||||||
|
|
||||||
|
IMAPStore ${name}-remote
|
||||||
|
Account ${name}
|
||||||
|
|
||||||
|
MaildirStore ${name}-local
|
||||||
|
INBOX ${config.mailserver.mailDirectory}/${name}/${acct.username}/mail/
|
||||||
|
# Maps subfolders on far side to actual subfolders on disk.
|
||||||
|
# The other option is Maildir++ but then the mailserver.hierarchySeparator must be set to a dot '.'
|
||||||
|
SubFolders Verbatim
|
||||||
|
Path ${config.mailserver.mailDirectory}/${name}/${acct.username}/mail/
|
||||||
|
|
||||||
|
Channel ${name}-main
|
||||||
|
Far :${name}-remote:
|
||||||
|
Near :${name}-local:
|
||||||
|
Patterns * !Drafts !Sent !Trash !Junk !${acct.mapSpecialDrafts} !${acct.mapSpecialSent} !${acct.mapSpecialTrash} !${acct.mapSpecialJunk}
|
||||||
|
Create Both
|
||||||
|
Expunge Both
|
||||||
|
SyncState *
|
||||||
|
Sync All
|
||||||
|
CopyArrivalDate yes # Preserve date from incoming message.
|
||||||
|
|
||||||
|
Channel ${name}-drafts
|
||||||
|
Far :${name}-remote:"${acct.mapSpecialDrafts}"
|
||||||
|
Near :${name}-local:"Drafts"
|
||||||
|
Create Both
|
||||||
|
Expunge Both
|
||||||
|
SyncState *
|
||||||
|
Sync All
|
||||||
|
CopyArrivalDate yes # Preserve date from incoming message.
|
||||||
|
|
||||||
|
Channel ${name}-sent
|
||||||
|
Far :${name}-remote:"${acct.mapSpecialSent}"
|
||||||
|
Near :${name}-local:"Sent"
|
||||||
|
Create Both
|
||||||
|
Expunge Both
|
||||||
|
SyncState *
|
||||||
|
Sync All
|
||||||
|
CopyArrivalDate yes # Preserve date from incoming message.
|
||||||
|
|
||||||
|
Channel ${name}-trash
|
||||||
|
Far :${name}-remote:"${acct.mapSpecialTrash}"
|
||||||
|
Near :${name}-local:"Trash"
|
||||||
|
Create Both
|
||||||
|
Expunge Both
|
||||||
|
SyncState *
|
||||||
|
Sync All
|
||||||
|
CopyArrivalDate yes # Preserve date from incoming message.
|
||||||
|
|
||||||
|
Channel ${name}-junk
|
||||||
|
Far :${name}-remote:"${acct.mapSpecialJunk}"
|
||||||
|
Near :${name}-local:"Junk"
|
||||||
|
Create Both
|
||||||
|
Expunge Both
|
||||||
|
SyncState *
|
||||||
|
Sync All
|
||||||
|
CopyArrivalDate yes # Preserve date from incoming message.
|
||||||
|
|
||||||
|
Group ${name}
|
||||||
|
Channel ${name}-main
|
||||||
|
Channel ${name}-drafts
|
||||||
|
Channel ${name}-sent
|
||||||
|
Channel ${name}-trash
|
||||||
|
Channel ${name}-junk
|
||||||
|
|
||||||
|
# END ${name} account
|
||||||
|
'';
|
||||||
|
|
||||||
|
in
|
||||||
|
pkgs.writeText "mbsync.conf" (
|
||||||
|
lib.concatStringsSep "\n" (lib.mapAttrsToList mkAccount cfg.imapSync.accounts)
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
description = "Sync mailbox";
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = config.mailserver.vmailUserName;
|
||||||
|
};
|
||||||
|
script =
|
||||||
|
let
|
||||||
|
debug = if cfg.imapSync.debug then "-V" else "";
|
||||||
|
in
|
||||||
|
''
|
||||||
|
${pkgs.isync}/bin/mbsync --all ${debug} --config ${configFile}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules =
|
||||||
|
let
|
||||||
|
mkAccount =
|
||||||
|
name: acct:
|
||||||
|
# The equal sign makes sure parent directories have the corret user and group too.
|
||||||
|
[
|
||||||
|
"d '${config.mailserver.mailDirectory}/${name}' 0750 ${config.mailserver.vmailUserName} ${config.mailserver.vmailGroupName} - -"
|
||||||
|
"d '${config.mailserver.mailDirectory}/${name}/${acct.username}' 0750 ${config.mailserver.vmailUserName} ${config.mailserver.vmailGroupName} - -"
|
||||||
|
];
|
||||||
|
in
|
||||||
|
lib.flatten (lib.mapAttrsToList mkAccount cfg.imapSync.accounts);
|
||||||
|
|
||||||
|
systemd.timers.mbsync = {
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnBootSec = cfg.imapSync.syncTimer;
|
||||||
|
OnUnitActiveSec = cfg.imapSync.syncTimer;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(lib.mkIf (cfg.enable && cfg.smtpRelay != null) (
|
||||||
|
let
|
||||||
|
url = "[${cfg.smtpRelay.host}]:${toString cfg.smtpRelay.port}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = lib.hasAttr cfg.adminPassword != null;
|
||||||
|
message = "`shb.mailserver.adminPassword` must be not null if `shb.mailserver.adminUsername` is not null.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
# Inspiration from https://www.brull.me/postfix/debian/fastmail/2016/08/16/fastmail-smtp.html
|
||||||
|
services.postfix = {
|
||||||
|
settings.main = {
|
||||||
|
relayhost = [ url ];
|
||||||
|
smtp_sasl_auth_enable = "yes";
|
||||||
|
smtp_sasl_password_maps = "texthash:/run/secrets/postfix/postfix-smtp-relay-password";
|
||||||
|
smtp_sasl_security_options = "noanonymous";
|
||||||
|
smtp_use_tls = "yes";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.postfix-pre = {
|
||||||
|
script = shb.replaceSecrets {
|
||||||
|
userConfig = {
|
||||||
|
inherit url;
|
||||||
|
inherit (cfg.smtpRelay) username;
|
||||||
|
password.source = cfg.smtpRelay.password.result.path;
|
||||||
|
};
|
||||||
|
generator =
|
||||||
|
name:
|
||||||
|
{
|
||||||
|
url,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
}:
|
||||||
|
pkgs.writeText "postfix-smtp-relay-password" ''
|
||||||
|
${url} ${username}:${password}
|
||||||
|
'';
|
||||||
|
resultPath = "/run/secrets/postfix/postfix-smtp-relay-password";
|
||||||
|
user = config.services.postfix.user;
|
||||||
|
};
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
before = [ "postfix.service" ];
|
||||||
|
requiredBy = [ "postfix.service" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
))
|
||||||
|
];
|
||||||
|
}
|
||||||
380
modules/services/mailserver/docs/default.md
Normal file
380
modules/services/mailserver/docs/default.md
Normal file
|
|
@ -0,0 +1,380 @@
|
||||||
|
# Mailserver Service {#services-mailserver}
|
||||||
|
|
||||||
|
Defined in [`/modules/services/mailserver.nix`](@REPO@/modules/services/mailserver.nix).
|
||||||
|
|
||||||
|
This NixOS module is a service that sets up
|
||||||
|
the [NixOS Simple Mailserver](https://gitlab.com/simple-nixos-mailserver/nixos-mailserver) project.
|
||||||
|
It integrates the upstream project
|
||||||
|
with the SHB modules like the SSL module, the contract for secrets and the LLDAP module.
|
||||||
|
|
||||||
|
It also exposes an XML file which allows some email clients to auto configure themselves.
|
||||||
|
|
||||||
|
Setting up a self-hosted email server in this age
|
||||||
|
can be quite time consuming because you need to maintain
|
||||||
|
a good IP hygiene to avoid being marked as spam from the big players.
|
||||||
|
To avoid needing to deal with this,
|
||||||
|
this module provides the means
|
||||||
|
to use an email provider (like Fastmail or ProtonMail) as a mere proxy.
|
||||||
|
If you also setup the email provider using your own custom domain,
|
||||||
|
this combination allows you to change email provider
|
||||||
|
without needing to change your clients or notify your email correspondents
|
||||||
|
and keep a backup of all your emails at the same time.
|
||||||
|
The setup looks like so:
|
||||||
|
|
||||||
|
```
|
||||||
|
Domain --[ DNS records ]-> Email Provider --[ mbsync ]-> SHB Server
|
||||||
|
|
||||||
|
Internet <---------------- Email Provider <-[ postfix ]-- SHB Server
|
||||||
|
```
|
||||||
|
|
||||||
|
Configuring your domain name to point to your email provider is out of scope here.
|
||||||
|
See the documentation for "custom domain" for you email provider,
|
||||||
|
like for [Fastmail](https://www.fastmail.com/features/domains/)
|
||||||
|
and [ProtonMail](https://proton.me/support/custom-domain)
|
||||||
|
|
||||||
|
To use an email provider as a proxy, use the
|
||||||
|
[shb.mailserver.imapSync](#services-mailserver-options-shb.mailserver.imapSync)
|
||||||
|
and [shb.mailserver.smtpRelay](#services-mailserver-options-shb.mailserver.smtpRelay),
|
||||||
|
options.
|
||||||
|
|
||||||
|
## Usage {#services-mailserver-usage}
|
||||||
|
|
||||||
|
The following snippet assumes a few blocks have been setup already:
|
||||||
|
|
||||||
|
- the [secrets block](usage.html#usage-secrets) with SOPS,
|
||||||
|
- the [`shb.ssl` block](blocks-ssl.html#usage),
|
||||||
|
- the [`shb.lldap` block](blocks-lldap.html#blocks-lldap-global-setup).
|
||||||
|
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
domain = "example.com";
|
||||||
|
username = "me@example.com";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
selfhostblocks.nixosModules.mailserver
|
||||||
|
];
|
||||||
|
|
||||||
|
shb.mailserver = {
|
||||||
|
enable = true;
|
||||||
|
inherit domain;
|
||||||
|
subdomain = "imap";
|
||||||
|
ssl = config.shb.certs.certs.letsencrypt."domain";
|
||||||
|
|
||||||
|
imapSync = {
|
||||||
|
syncTimer = "10s";
|
||||||
|
accounts.fastmail = {
|
||||||
|
host = "imap.fastmail.com";
|
||||||
|
port = 993;
|
||||||
|
inherit username;
|
||||||
|
password.result = config.shb.sops.secret."mailserver/imap/fastmail/password".result;
|
||||||
|
mapSpecialJunk = "Spam";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
smtpRelay = {
|
||||||
|
host = "smtp.fastmail.com";
|
||||||
|
port = 587;
|
||||||
|
inherit username;
|
||||||
|
password.result = config.shb.sops.secret."mailserver/smtp/fastmail/password".result;
|
||||||
|
};
|
||||||
|
|
||||||
|
ldap = {
|
||||||
|
enable = true;
|
||||||
|
host = "127.0.0.1";
|
||||||
|
port = config.shb.lldap.ldapPort;
|
||||||
|
dcdomain = config.shb.lldap.dcdomain;
|
||||||
|
adminName = "admin";
|
||||||
|
adminPassword.result = config.shb.sops.secret."mailserver/ldap_admin_password".result;
|
||||||
|
account = "fastmail";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Optionally add some mailboxes
|
||||||
|
mailserver.mailboxes = {
|
||||||
|
Drafts = {
|
||||||
|
auto = "subscribe";
|
||||||
|
specialUse = "Drafts";
|
||||||
|
};
|
||||||
|
Junk = {
|
||||||
|
auto = "subscribe";
|
||||||
|
specialUse = "Junk";
|
||||||
|
};
|
||||||
|
Sent = {
|
||||||
|
auto = "subscribe";
|
||||||
|
specialUse = "Sent";
|
||||||
|
};
|
||||||
|
Trash = {
|
||||||
|
auto = "subscribe";
|
||||||
|
specialUse = "Trash";
|
||||||
|
};
|
||||||
|
Archive = {
|
||||||
|
auto = "subscribe";
|
||||||
|
specialUse = "Archive";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
shb.sops.secret."mailserver/smtp/fastmail/password".request =
|
||||||
|
config.shb.mailserver.smtpRelay.password.request;
|
||||||
|
|
||||||
|
shb.sops.secret."mailserver/imap/fastmail/password".request =
|
||||||
|
config.shb.mailserver.imapSync.accounts.fastmail.password.request;
|
||||||
|
|
||||||
|
shb.sops.secret."mailserver/ldap_admin_password" = {
|
||||||
|
request = config.shb.mailserver.ldap.adminPassword.request;
|
||||||
|
# This reuses the admin password set in the shb.lldap module.
|
||||||
|
settings.key = "lldap/user_password";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Secrets {#services-mailserver-usage-secrets}
|
||||||
|
|
||||||
|
Secrets can be randomly generated with `nix run nixpkgs#openssl -- rand -hex 64`.
|
||||||
|
|
||||||
|
### LDAP {#services-mailserver-usage-ldap}
|
||||||
|
|
||||||
|
The [user](#services-mailserver-options-shb.mailserver.ldap.userGroup)
|
||||||
|
LDAP group is created automatically.
|
||||||
|
|
||||||
|
### Disk Layout {#services-mailserver-usage-disk-layout}
|
||||||
|
|
||||||
|
The disk layout has been purposely set to use slashes `/` for subfolders.
|
||||||
|
By experience, this works better with iOS mail.
|
||||||
|
|
||||||
|
### Backup {#services-mailserver-usage-backup}
|
||||||
|
|
||||||
|
Backing up your emails using the [Restic block](blocks-restic.html) is done like so:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
shb.restic.instances."mailserver" = {
|
||||||
|
request = config.shb.mailserver.backup;
|
||||||
|
settings = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
The name `"mailserver"` in the `instances` can be anything.
|
||||||
|
The `config.shb.mailserver.backup` option provides what directories to backup.
|
||||||
|
You can define any number of Restic instances to backup your emails multiple times.
|
||||||
|
|
||||||
|
You will then need to configure more options like the `repository`,
|
||||||
|
as explained in the [restic](blocks-restic.html) documentation.
|
||||||
|
|
||||||
|
### Certificates {#services-mailserver-certs}
|
||||||
|
|
||||||
|
For Let's Encrypt certificates, add:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
domain = "example.com";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
shb.certs.certs.letsencrypt.${domain}.extraDomains = [
|
||||||
|
"${config.shb.mailserver.subdomain}.${config.shb.mailserver.domain}"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Impermanence {#services-mailserver-impermanence}
|
||||||
|
|
||||||
|
To save the data folder in an impermanence setup, add:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
shb.zfs.datasets."safe/mailserver/index".path = config.shb.mailserver.impermanence.index;
|
||||||
|
shb.zfs.datasets."safe/mailserver/mail".path = config.shb.mailserver.impermanence.mail;
|
||||||
|
shb.zfs.datasets."safe/mailserver/sieve".path = config.shb.mailserver.impermanence.sieve;
|
||||||
|
shb.zfs.datasets."safe/mailserver/dkim".path = config.shb.mailserver.impermanence.dkim;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Declarative LDAP {#services-mailserver-declarative-ldap}
|
||||||
|
|
||||||
|
To add a user `USERNAME` to the user group, add:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
shb.lldap.ensureUsers.USERNAME.groups = [
|
||||||
|
config.shb.mailserver.ldap.userGroup
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
## Debug {#services-mailserver-debug}
|
||||||
|
|
||||||
|
Debugging this will be certainly necessary.
|
||||||
|
The first issue you will encounter will probably be with `mbsync`
|
||||||
|
under the [shb.mailserver.imapSync](#services-mailserver-options-shb.mailserver.imapSync) option
|
||||||
|
with the folder name mapping.
|
||||||
|
|
||||||
|
### Systemd Services {#services-mailserver-debug-systemd}
|
||||||
|
|
||||||
|
The 3 systemd services setup by this module are:
|
||||||
|
|
||||||
|
- `mbsync.service`
|
||||||
|
- `dovecot.service`
|
||||||
|
- `postfix.service`
|
||||||
|
|
||||||
|
### Folders {#services-mailserver-debug-folders}
|
||||||
|
|
||||||
|
The 4 folders where state is stored are:
|
||||||
|
|
||||||
|
- `config.mailserver.indexDir` = `/var/lib/dovecot/indices`
|
||||||
|
- `config.mailserver.mailDirectory` = `/var/vmail`
|
||||||
|
- `config.mailserver.sieveDirectory` = `/var/sieve`
|
||||||
|
- `config.mailserver.dkimKeyDirectory` = `/var/dkim`
|
||||||
|
|
||||||
|
### Open Ports {#services-mailserver-debug-ports}
|
||||||
|
|
||||||
|
The ports opened by default in this module are:
|
||||||
|
|
||||||
|
- Submissions: 465
|
||||||
|
- Imap: 993
|
||||||
|
|
||||||
|
You will need to forward those ports on your router
|
||||||
|
if you want to access to your emails from the internet.
|
||||||
|
|
||||||
|
The complete list can be found in the [upstream repository](https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/blob/5965fae920b6b97f39f94bdb6195631e274c93a5/mail-server/networking.nix).
|
||||||
|
|
||||||
|
### List Email Provider Folder Mapping {#services-mailserver-debug-folder-mapping}
|
||||||
|
|
||||||
|
Replace `$USER` and `$PASSWORD` by those used to connect to your email provider.
|
||||||
|
Yes, you will need to enter verbatim `a LOGIN ...` and `b LIST "" "*"`.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ nix run nixpkgs#openssl -- s_client -connect imap.fastmail.com:993 -crlf -quiet
|
||||||
|
a LOGIN $USER $password
|
||||||
|
b LIST "" "*"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example output will be:
|
||||||
|
|
||||||
|
```
|
||||||
|
* LIST (\HasNoChildren) "/" INBOX
|
||||||
|
* LIST (\HasNoChildren \Drafts) "/" Drafts
|
||||||
|
* LIST (\HasNoChildren \Sent) "/" Sent
|
||||||
|
* LIST (\Noinferiors \HasNoChildren \Junk) "/" Spam
|
||||||
|
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Here you can see the special folder `\Junk` is actually named `Spam`.
|
||||||
|
To handle this, set the `.mapSpecial*` options:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
shb.mailserver.imapSync.accounts.<account> = {
|
||||||
|
mapSpecialJunk = "Spam";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### List Local Folders {#services-mailserver-debug-local-folders}
|
||||||
|
|
||||||
|
Check the local folders to make sure the mapping is correct
|
||||||
|
and all folders are correctly downloaded.
|
||||||
|
For example, if the mapping above is wrong, you will see both a
|
||||||
|
`Junk` and `Spam` folder while if it is correct,
|
||||||
|
you will only see the `Junk` folder.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo doveadm mailbox list -u $USER
|
||||||
|
Junk
|
||||||
|
Trash
|
||||||
|
Drafts
|
||||||
|
Sent
|
||||||
|
INBOX
|
||||||
|
MyCustomFolder
|
||||||
|
```
|
||||||
|
|
||||||
|
The following command shows the number of messages in a folder:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo doveadm mailbox status -u $USER messages INBOX
|
||||||
|
INBOX messages=13591
|
||||||
|
```
|
||||||
|
|
||||||
|
If any folder is not appearing or has 0 message but should have some,
|
||||||
|
it could mean dovecot is not setup correctly and assumes an incorrect folder layout.
|
||||||
|
If that is the case, check the user config with:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo doveadm user $USER
|
||||||
|
field value
|
||||||
|
uid 5000
|
||||||
|
gid 5000
|
||||||
|
home /var/vmail/fastmail/$USER
|
||||||
|
mail maildir:~/mail:LAYOUT=fs
|
||||||
|
virtualMail
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Auth {#services-mailserver-debug-auth}
|
||||||
|
|
||||||
|
To test authentication to your dovecot instance, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ nix run nixpkgs#openssl -- s_client -connect $SUBDOMAIN.$DOMAIN:993 -crlf -quiet
|
||||||
|
. LOGIN $USER $PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
You must here also enter the second line verbatim,
|
||||||
|
replacing your user and password with the real one.
|
||||||
|
|
||||||
|
On success, you will see:
|
||||||
|
|
||||||
|
```
|
||||||
|
. OK [CAPABILITY IMAP4rev1 ...] Logged in
|
||||||
|
```
|
||||||
|
|
||||||
|
Otherwise, either if the password is wrong or,
|
||||||
|
when using LDAP if the user is not part of the LDAP group, you will see:
|
||||||
|
|
||||||
|
```
|
||||||
|
. NO [AUTHENTICATIONFAILED] Authentication failed.
|
||||||
|
```
|
||||||
|
|
||||||
|
To test the postfix instance, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ swaks \
|
||||||
|
--server $SUBDOMAIN.$DOMAIN \
|
||||||
|
--port 465 \
|
||||||
|
--tls-on-connect \
|
||||||
|
--auth LOGIN \
|
||||||
|
--auth-user $USER \
|
||||||
|
--auth-password '$PASSWORD' \
|
||||||
|
--from $USER \
|
||||||
|
--to $USER
|
||||||
|
```
|
||||||
|
|
||||||
|
Try once with a wrong password and once with a correct one.
|
||||||
|
The former should log:
|
||||||
|
|
||||||
|
```
|
||||||
|
<~* 535 5.7.8 Error: authentication failed: (reason unavailable)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mobile Apps {#services-mailserver-mobile}
|
||||||
|
|
||||||
|
This module was tested with:
|
||||||
|
- the iOS mail mobile app,
|
||||||
|
- Thunderbird on NixOS.
|
||||||
|
|
||||||
|
The iOS mail app is pretty finicky.
|
||||||
|
If downloading emails does not work,
|
||||||
|
make sure the certificate used includes the whole chain:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ openssl s_client -connect $SUBDOMAIN.$DOMAIN:993 -showcerts
|
||||||
|
```
|
||||||
|
|
||||||
|
Normally, the other options are setup correctly but if it fails for you,
|
||||||
|
feel free to open an issue.
|
||||||
|
|
||||||
|
## Options Reference {#services-mailserver-options}
|
||||||
|
|
||||||
|
```{=include=} options
|
||||||
|
id-prefix: services-mailserver-options-
|
||||||
|
list-id: selfhostblocks-service-mailserver-options
|
||||||
|
source: @OPTIONS_JSON@
|
||||||
|
```
|
||||||
Loading…
Reference in a new issue