Merge branch 'master' into dmarc_reporting_docs

Dieser Commit ist enthalten in:
Dmitriy Alekseev 2021-08-28 15:18:21 +03:00 committet von GitHub
Commit 0b92341946
Es konnte kein GPG-SchlĂŒssel zu dieser Signatur gefunden werden
GPG-SchlĂŒssel-ID: 4AEE18F83AFDEB23
59 geÀnderte Dateien mit 1464 neuen und 438 gelöschten Zeilen

27
.github/workflows/gh-pages.yml gevendort Normale Datei
Datei anzeigen

@ -0,0 +1,27 @@
name: Build and deploy to gh-pages
on:
push:
branches:
- master
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout đŸ“„
uses: actions/checkout@v2.3.4
- name: Install dependencies 🐄
run: |
sudo apt-get -y update
sudo apt-get -y install python3-pip
pip install mkdocs-material==7.2.5 pygments==2.10.0 mkdocs-redirects==1.0.3
- name: Build site 🔧
run: |
mkdocs build --verbose --clean
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@4.1.5
with:
branch: gh-pages # The branch the action should deploy to.
folder: site # The folder the action should deploy.

Datei anzeigen

@ -1,14 +0,0 @@
language: python
install:
- pip install mkdocs-material pygments
script:
- mkdocs build --verbose --clean
deploy:
provider: pages
skip_cleanup: true
github_token: $GITHUB_TOKEN
local_dir: site
name: $BOT_NAME
email: $BOT_EMAIL
on:
branch: master

Datei anzeigen

@ -1,4 +1,4 @@
![TRAVIS-CI](https://api.travis-ci.org/mailcow/mailcow-dockerized-docs.svg?branch=master)
[![Build and deploy to gh-pages](https://github.com/mailcow/mailcow-dockerized-docs/actions/workflows/gh-pages.yml/badge.svg)](https://github.com/mailcow/mailcow-dockerized-docs/actions/workflows/gh-pages.yml)
# mailcow: dockerized documentation
@ -9,6 +9,6 @@ https://mailcow.github.io/mailcow-dockerized-docs
To build it locally, you need the [Material theme for MkDocs](https://squidfunk.github.io/mkdocs-material/), [MkDocs](https://www.mkdocs.org/) itself and [Pygments](http://pygments.org/). To install these with [pip](https://pip.pypa.io/en/stable/) and get it up and running, fire up your terminal and enter
```
pip install mkdocs-material
pip install mkdocs-material==7.2.5 pygments==2.10.0 mkdocs-redirects==1.0.3
mkdocs serve
```

Datei anzeigen

@ -0,0 +1,40 @@
So you deleted a mailbox and have no backups, he?
If you noticed your mistake within a few hours, you can probably recover the users data.
### SOGo
We automatically create daily backups (24h interval starting from running up -d) in `/var/lib/docker/volumes/mailcowdockerized_sogo-userdata-backup-vol-1/_data/`.
**Make sure the user you want to restore exists in your mailcow**. Re-create them if they are missing.
Copy the file named after the user you want to restore to `__MAILCOW_DIRECTORY__/data/conf/sogo`.
1\. Copy the backup: `cp /var/lib/docker/volumes/mailcowdockerized_sogo-userdata-backup-vol-1/_data/restoreme@example.org __MAILCOW_DIRECTORY__/data/conf/sogo`
2\. Run `docker-compose exec -u sogo sogo-mailcow sogo-tool restore -F ALL /etc/sogo restoreme@example.org`
Run `sogo-tool` without parameters to check for possible restore options.
3\. Delete the copied backup by running `rm __MAILCOW_DIRECTORY__/data/conf/sogo`
4\. Restart SOGo and Memcached: `docker-compose restart sogo-mailcow memcached-mailcow`
### Mail
In case of an accidental deletion of a mailbox, you will be able to recover for (by default) 5 days. This depends on the `MAILDIR_GC_TIME` parameter in `mailcow.conf`.
A deleted mailbox is copied in its encrypted form to `/var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/_garbage`.
The folder inside _garbage follows the structure `[timestamp]_[domain_sanitized][user_sanitized]`, for example `1629109708_exampleorgtest in case of test@example.org deleted on 1629109708.
To restore make sure you are actually restoring to the same mailcow it was deleted from or you use the same encryption keys in `crypt-vol-1`.
**Make sure the user you want to restore exists in your mailcow**. Re-create them if they are missing.
Copy the folders from `/var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/_garbage/[timestamp]_[domain_sanitized][user_sanitized]` back to `/var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data/[domain]/[user]` and resync the folder and recalc the quota:
```
docker-compose exec dovecot-mailcow doveadm force-resync -u restoreme@example.net '*'
docker-compose exec dovecot-mailcow doveadm quota recalc -u restoreme@example.net
```

Datei anzeigen

@ -1,5 +1,7 @@
### Backup
#### Manual
You can use the provided script `helper-scripts/backup_and_restore.sh` to backup mailcow automatically.
Please do not copy this script to another location.
@ -30,3 +32,66 @@ To run a backup unattended, define MAILCOW_BACKUP_LOCATION as environment variab
```
MAILCOW_BACKUP_LOCATION=/opt/backup /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all
```
#### Cronjob
You can run the backup script regularly via cronjob. Make sure `BACKUP_LOCATION` exists:
```
5 4 * * * cd /opt/mailcow-dockerized/; MAILCOW_BACKUP_LOCATION=/mnt/mailcow_backups /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3
```
Per default cron sends the full result of each backup operation by email. If you want cron to only mail on error (non-zero exit code) you may want to use the following snippet. Pathes need to be modified according to your setup (this script is a user contribution).
This following script may be placed in `/etc/cron.daily/mailcow-backup` - do not forget to mark it as executable via `chmod +x`:
```
#!/bin/sh
# Backup mailcow data
# https://mailcow.github.io/mailcow-dockerized-docs/b_n_r_backup/
set -e
OUT="$(mktemp)"
export MAILCOW_BACKUP_LOCATION="/opt/backup"
SCRIPT="/opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh"
PARAMETERS="backup all"
OPTIONS="--delete-days 30"
# run command
set +e
"${SCRIPT}" ${PARAMETERS} ${OPTIONS} 2>&1 > "$OUT"
RESULT=$?
if [ $RESULT -ne 0 ]
then
echo "${SCRIPT} ${PARAMETERS} ${OPTIONS} encounters an error:"
echo "RESULT=$RESULT"
echo "STDOUT / STDERR:"
cat "$OUT"
fi
```
# Backup strategy with rsync and mailcow backup script
Create the destination directory for mailcows helper script:
```
mkdir -p /external_share/backups/backup_script
```
Create cronjobs:
```
25 1 * * * rsync -aH --delete /opt/mailcow-dockerized /external_share/backups/mailcow-dockerized
40 2 * * * rsync -aH --delete /var/lib/docker/volumes /external_share/backups/var_lib_docker_volumes
5 4 * * * cd /opt/mailcow-dockerized/; BACKUP_LOCATION=/external_share/backups/backup_script /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql crypt redis --delete-days 3
# If you want to, use the acl util to backup permissions of some/all folders/files: getfacl -Rn /path
```
On the destination (in this case `/external_share/backups`) you may want to have snapshot capabilities (ZFS, Btrfs etc.). Snapshot daily and keep for n days for a consistent backup.
Do **not** rsync to a Samba share, you need to keep the correct permissions!
To restore you'd simply need to run rsync the other way round and restart Docker to re-read the volumes. Run `docker-compose pull` and `docker-compose up -d`.
If you are lucky Redis and MariaDB can automatically fix the inconsistent databases (if they _are_ inconsistent).
In case of a corrupted database you'd need to use the helper script to restore the inconsistent elements. If a restore fails, try to extract the backups and copy the files back manually. Keep the file permissions!

Datei anzeigen

@ -54,3 +54,28 @@ Automatic configuration of calendars and address books in Thunderbird is not cur
<div class="client_variables_unavailable" markdown="1">
Automatic configuration of calendars and address books (from step 9 onward) in Thunderbird is only supported if your server administrator has enabled [SOGo Connector](https://mailcow.github.io/mailcow-dockerized-docs/third_party-thunderbird).
</div>
## Different method of connecting Cal-/CardDAV in Thunderbird with automatic detection of address books and calendars
Instead of using SOGo Connector you can use a combination of
- https://addons.thunderbird.net/de/thunderbird/addon/tbsync/ and
- https://addons.thunderbird.net/de/thunderbird/addon/dav-4-tbsync/
1. To add your Cal-/CardDAV accounts go to `Tools` and find TbSync
![TbSync](../images/thunderbird-tbsync.png)
2. You can add new accounts via the CalDAV & CardDAV provider:
![TbSync - CalDAV & CardDAV Provider](../images/thunderbird-tbsync-caldav.png)
3. Choose "Automatic Configuration". Use your mail address as account and username. Use your mail password as DAV password. The server URL is your MAILCOW_HOSTNAME (specifying any protocol is not necessary, just enter the full domain).
4. Now tick the checkbox for "Enable and synchronize this account" in the synchronization status tab:
![TbSync - Enable](../images/thunderbird-tbsync-enable.png)
5. Several available resources should appear in the same window area now. Tick all checkboxes of the resources (address books and calendars) that you want to sync. Choose a synchronization period (in minutes) in the same window area before clicking on "Synchronize now". If you leave the sync at "0" it will only sync manually so choose at least 30 minutes for periodic synchronization.
If you want to manually synchronize you can find this option under "Account actions" - the dropdown-menu where you added the Cal-/CardDAV account (step 2).

Datei anzeigen

@ -1,7 +1,7 @@
if (window.location.href.indexOf('/client/') >= 0) {
window.window.addEventListener('load', function () {
function setCookie(name, value) {
document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + "; path=/";
sessionStorage.setItem(name, value);
}
function getParameterByName(name) {
@ -39,18 +39,7 @@ if (window.location.href.indexOf('/client/') >= 0) {
if (window.location.href.indexOf('/client') >= 0) {
window.window.addEventListener('load', function () {
function getCookie(cn) {
var fixedcn = encodeURIComponent(cn);
var cs = document.cookie.split(';');
for (var i = 0; i < cs.length; i++) {
var c = cs[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(fixedcn + "=") == 0) {
return decodeURIComponent(c.substring(cn.length + 1, c.length));
}
}
return "";
return sessionStorage.getItem(cn);
}
/* Hide variable fields if no values are available */

Datei anzeigen

@ -36,6 +36,8 @@ Here is a brief overview of what container / service does what:
| redis-mailcow | Storage back-end for DKIM keys and Rspamd |
| rspamd-mailcow | Mail filtering system. Used for av handling, dkim signing, spam handling |
| clamd-mailcow | Scans attachments for viruses |
| olefy-mailcow | Scans attached office documents for macro-viruses |
| solr-mailcow | Provides full-text search in Dovecot |
| sogo-mailcow | Webmail client that handles Microsoft ActiveSync and Cal- / CardDav |
| nginx-mailcow | Nginx remote proxy that handles all mailcow related HTTP / HTTPS requests |
| acme-mailcow | Automates HTTPS (SSL/TLS) certificate deployment |

Datei anzeigen

@ -10,7 +10,7 @@ Please check in your mailcow UI if you made the domain a **backup MX**:
There are a lot of things that could prevent you from sending mail:
- Check if your IP is on any blacklists. You could use [dnsbl.info](http://www.dnsbl.info/) or any other similar service to check for your IP.
- Check if your IP address is on any blacklists. You could use [dnsbl.info](http://www.dnsbl.info/) or any other similar service to check for your IP address.
- There are some consumer ISP routers out there, that block mail ports for non whitelisted domains. Please check if you can reach your server on the ports `465` or `587`:
```
@ -40,7 +40,7 @@ This error tries to tell you that one of the (health) conditions for a certain c
A wrong configured firewall could also cause such a failure. The containers need to be able to talk to each other over the network 172.22.1.1/24.
It might also be wrongly linked file (i.e. SSL certificate) that prevents a crucial container (nginx) from starting, so always check your logs to get an Idea where your problem is coming from.
It might also be wrongly linked file (i.e. SSL certificate) that prevents a crucial container (nginx) from starting, so always check your logs to get an idea where your problem is coming from.
## Address already in use
@ -51,7 +51,7 @@ If you get an error message like:
ERROR: for postfix-mailcow Cannot start service postfix-mailcow: driver failed programming external connectivity on endpoint mailcowdockerized_postfix-mailcow_1: Error starting userland proxy: listen tcp 0.0.0.0:25: bind: address already in use
```
while trying to start / install mailcow: dockerized, make sure you've followed our section on the [prerequisites](prerequisite-system/#firewall-ports).
while trying to start / install mailcow: dockerized, make sure you've followed our section on the [prerequisites](../prerequisite-system/#firewall-ports).
## XYZ can't connect to ...

17
docs/debug-reset-tls.md Normale Datei
Datei anzeigen

@ -0,0 +1,17 @@
In case you encounter problems with your certificate, key or Let's Encrypt account, please try to reset the TLS assets:
```
source mailcow.conf
docker-compose down
rm -rf data/assets/ssl
mkdir data/assets/ssl
openssl req -x509 -newkey rsa:4096 -keyout data/assets/ssl-example/key.pem -out data/assets/ssl-example/cert.pem -days 365 -subj "/C=DE/ST=NRW/L=Willich/O=mailcow/OU=mailcow/CN=${MAILCOW_HOSTNAME}" -sha256 -nodes
cp -n -d data/assets/ssl-example/*.pem data/assets/ssl/
docker-compose up -d
```
This will stop mailcow, source the variables we need, create a self-signed certificate and start mailcow.
If you use Let's Encrypt you should be careful as you will create a new account and a new set of certificates. You will run into a ratelimit sooner or later.
Please also note that previous TLSA records will be invalid.

Datei anzeigen

@ -1,6 +1,6 @@
## mailcow Admin Account
Reset mailcow admin to `admin:moohoo`. Older mailcow: dockerized installations may find `mailcow-reset-admin.sh` in their mailcow root directory (mailcow_path).
Resets the mailcow admin account to a random password. Older mailcow: dockerized installations may find the `mailcow-reset-admin.sh` script in their mailcow root directory (mailcow_path).
```
cd mailcow_path
@ -36,6 +36,8 @@ MariaDB [(none)]> show databases;
### 2\. Reset one or more users
#### 2\.1 Maria DB < 10.4 (older mailcow installations)
Both "password" and "authentication_string" exist. Currently "password" is used, but better set both.
```
@ -43,7 +45,7 @@ MariaDB [(none)]> SELECT user FROM mysql.user;
+--------------+
| user |
+--------------+
| mailcow_user | <=====
| mailcow | <=====
| root |
+--------------+
2 rows in set (0.00 sec)
@ -54,11 +56,38 @@ MariaDB [(none)]> UPDATE mysql.user SET authentication_string = PASSWORD('mookuh
MariaDB [(none)]> FLUSH PRIVILEGES;
```
#### 2\.2 Maria DB >= 10.4 (current mailcows)
```
MariaDB [(none)]> SELECT user FROM mysql.user;
+--------------+
| user |
+--------------+
| mailcow | <=====
| root |
+--------------+
2 rows in set (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
MariaDB [(none)]> ALTER USER 'mailcow'@'%' IDENTIFIED BY 'mookuh';
MariaDB [(none)]> ALTER USER 'root'@'%' IDENTIFIED BY 'gotr00t';
MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'gotr00t';
MariaDB [(none)]> FLUSH PRIVILEGES;
```
## Remove Two-Factor Authentication
### For mailcow WebUI:
This works similar to resetting a MySQL password, now we do it from the host without connecting to the MySQL CLI:
```
source mailcow.conf
docker-compose exec mysql-mailcow mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM tfa WHERE username='YOUR_USERNAME';"
```
### For SOGo:
```
docker-compose exec -u sogo sogo-mailcow sogo-tool user-preferences set defaults user@example.com SOGoGoogleAuthenticatorEnabled '{"SOGoGoogleAuthenticatorEnabled":0}'
```

Datei anzeigen

@ -1,6 +1,6 @@
You may want to remove a set of persistent data to resolve a conflict or to start over.
`mailcowdockerized` can vary and depends on your compose project name (if it's unchanged, `mailcowdockerized` is the correct value). If you are unsure about volume names, run `docker volumes ls` for a full list.
`mailcowdockerized` can vary and depends on your compose project name (if it's unchanged, `mailcowdockerized` is the correct value). If you are unsure about volume names, run `docker volume ls` for a full list.
Delete a single volume:

Datei anzeigen

@ -10,27 +10,28 @@ fi
cd $(dirname $0)
wget -O connector.tar.gz https://github.com/inverse-inc/sogo-connector/archive/master.tar.gz
mkdir -p connector
tar --strip-components=1 -C connector -xf connector.tar.gz
# we have to use the master branch, because there is no tag or release at the moment
wget -O connector.zip https://github.com/inverse-inc/sogo-connector/archive/master.zip
unzip connector.zip
# build custom connector
while read DOMAINS; do
for DOMAIN in $DOMAINS; do
echo "Building SOGo Connector for $DOMAIN hosted on $MAILHOST"
cd connector
cd sogo-connector-master
mkdir -p custom/${DOMAIN}
cp -r custom/sogo-demo/* custom/${DOMAIN}/
sed -i "s/http:\/\/sogo-demo\.inverse\.ca/https:\/\/${MAILHOST}/g" custom/${DOMAIN}/chrome/content/sogo-connector/global/extensions.rdf
sed -i "s/plugins\/updates\.php[?]/thunderbird-plugins.php?domain=${DOMAIN}\&amp;/g" custom/${DOMAIN}/chrome/content/sogo-connector/global/extensions.rdf
echo > custom/${DOMAIN}/defaults/preferences/site.js
echo 'pref("sogo-connector.autocomplete.server.urlid", "'${DOMAIN}'");' > custom/${DOMAIN}/defaults/preferences/site.js
echo 'pref("mail.collect_email_address_outgoing", false);' >> custom/${DOMAIN}/defaults/preferences/site.js
#sed -i 's/<\/Seq>/<li><Description em:id="sieve@mozdev.org" em:name="Sieve"\/><\/li><li><Description em:id="imap-acl@sirphreak.com" em:name="Imap-ACL-Extension"\/><\/li><\/Seq>/g' custom/${DOMAIN}/chrome/content/sogo-connector/global/extensions.rdf
sed -i "s/https:\/\/demo\.sogo\.nu/https:\/\/${MAILHOST}/g" custom/${DOMAIN}/chrome/content/sogo-connector/general/custom-preferences.js
sed -i "s/plugins\/updates\.php[?]/thunderbird-plugins.php?domain=${DOMAIN}\&amp;/g" chrome/content/sogo-connector/global/extensions.rdf
# adjust sogo-connector.autocomplete.server.urlid
sed -i "s/\"public\"/\"${MAILHOST}\"/g" custom/${DOMAIN}/chrome/content/sogo-connector/general/custom-preferences.js
# remove wrong timezone setting
sed -i 's/char_pref(\"calendar\.timezone\.local\", \"\/mozilla\.org\/20070129_1\/America\/Montreal\");//g' custom/${DOMAIN}/chrome/content/sogo-connector/general/custom-preferences.js
echo 'bool_pref("mail.collect_email_address_outgoing", false);' >> custom/${DOMAIN}/chrome/content/sogo-connector/general/custom-preferences.js
make build=${DOMAIN}
CONNECTOR_VER=$(grep em:version install.rdf | awk -F '"' '{print $2}')
CONNECTOR_MIN_VER=$(grep em:minVersion install.rdf | grep -Eo '[0-9\.]+' | head -n 1)
CONNECTOR_VER=$(grep \"version\" manifest.json | awk -F '"' '{print $4}')
CONNECTOR_MIN_VER=$(grep strict_min_version manifest.json | grep -Eo '[0-9\.]+' | head -n 1)
mv sogo-connector-*.xpi ../sogo-connector-${CONNECTOR_VER}-${DOMAIN}.xpi
cd ..
done
@ -57,4 +58,4 @@ echo "sogo-connector@inverse.ca;${CONNECTOR_VER};sogo-connector-${CONNECTOR_VER}
# echo "sieve@mozdev.org;${SIEVE_VER};sieve-${SIEVE_VER}.xpi" >> version.csv
# echo "imap-acl@sirphreak.com;${IMAP_ACL_VER};imap_acl_extension-${IMAP_ACL_VER}-tb.xpi" >> version.csv
rm -rf connector *.tar.gz
rm -rf sogo-connector-master *.zip

Datei anzeigen

@ -38,6 +38,7 @@ version: '2.1'
services:
ipv6nat-mailcow:
image: bash:latest
restart: "no"
entrypoint: ["echo", "ipv6nat disabled in compose.override.yml"]
```
@ -72,6 +73,7 @@ Create `data/conf/postfix/extra.cf` and set `smtp_address_preference` to `ipv4`:
```
smtp_address_preference = ipv4
inet_protocols = ipv4
```
Restart Postfix:

Datei anzeigen

@ -8,15 +8,16 @@ To adjust one or multiple IPv4 bindings, open `mailcow.conf` and edit one, multi
```
# For technical reasons, http bindings are a bit different from other service bindings.
# You will find the following variables, separated by a bind address and its port:
# Example: HTTP_BIND=1.2.3.4
HTTP_PORT=80
HTTP_BIND=0.0.0.0
HTTP_BIND=
HTTPS_PORT=443
HTTPS_BIND=0.0.0.0
HTTPS_BIND=
# Other services are bound by using the following format:
# SMTP_PORT=25 equals to SMTP_PORT=0.0.0.0:25
# SMTP_PORT=1.2.3.4:25 will bind SMTP to the IP 1.2.3.4 on port 25
# Important! Specifying an IPv4 address will skip all IPv6 bindings since Docker 20.x.
# doveadm, SQL as well as Solr are bound to local ports only, please do not change that, unless you know what you are doing.
SMTP_PORT=25

Datei anzeigen

@ -26,6 +26,8 @@ Redis keys will only hold logs from applications and filter out system messages
### Logging drivers
#### Via docker-compose.override.yml
Here is the good news: Since Docker has some great logging drivers, you can integrate mailcow: dockerized into your existing logging environment with ease.
Create a `docker-compose.override.yml` and add, for example, this block to use the "gelf" logging plugin for `postfix-mailcow`:
@ -40,7 +42,46 @@ services:
gelf-address: "udp://graylog:12201"
```
If you want to change the logging driver globally, edit Dockers daemon configuration file `/etc/docker/daemon.json` and restart the Docker service:
Another example for **Syslog**:
```
version: '2.1'
services:
postfix-mailcow: # or any other
logging:
driver: "syslog"
options:
syslog-address: "udp://127.0.0.1:514"
syslog-facility: "local3"
dovecot-mailcow: # or any other
logging:
driver: "syslog"
options:
syslog-address: "udp://127.0.0.1:514"
syslog-facility: "local3"
rspamd-mailcow: # or any other
logging:
driver: "syslog"
options:
syslog-address: "udp://127.0.0.1:514"
syslog-facility: "local3"
# For Rsyslog only:
# To move local3 input to /var/log/mailcow.log and stop processing, create a file "/etc/rsyslog.d/docker.conf":
local3.* /var/log/mailcow.logs
& ~
# Restart rsyslog afterwards.
```
#### via daemon.json (globally)
If you want to **change the logging driver globally**, edit Dockers daemon configuration file `/etc/docker/daemon.json` and restart the Docker service:
```
{

Datei anzeigen

@ -1,11 +0,0 @@
Per default, mailcow considers all private RFC1918 networks (i.e. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) as trusted. Though it is reasonable in most cases, you may want to restrict this setting under certain circumstances. In particular, if you are using some kind of reverse proxy for SMTP TCP ports. If your reverse proxy host is located in a private net, mailcow will consider all traffic from it as trusted, which may result in an open relay.
To change this behaviour override the default value of `mynetworks` parameter through the `data/conf/postfix/extra.cf` configuration file.
**Important**: Do **not** remove the networks listed as `IPV4_NETWORK` and `IPV6_NETWORK` in your mailcow.conf. You should also keep local addresses.
The default values for those variables - `172.22.1.0/24` and `fd4d:6169:6c63:6f77::/64` - would result in the following, minimal configuration:
```
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64
```

Datei anzeigen

@ -15,6 +15,11 @@ This will also change the bindings inside the Nginx container! This is important
Recreate affected containers by running `docker-compose up -d`.
**Important information, please read them carefully!**
!!! info
If you plan to use a reverse proxy and want to use another server name that is **not** MAILCOW_HOSTNAME, you need to read **Adding additional server names for mailcow UI** at the bottom of this page.
!!! warning
Make sure you run `generate_config.sh` before you enable any site configuration examples below.
The script `generate_config.sh` copies snake-oil certificates to the correct location, so the services will not fail to start due to missing files.
@ -50,7 +55,7 @@ Let's Encrypt will follow our rewrite, certificate requests in mailcow will work
ServerAlias autoconfig.*
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTPS} off
RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [R=301,L]
ProxyPass / http://127.0.0.1:8080/
@ -176,7 +181,7 @@ For this we'll have to set `SKIP_LETS_ENCRYPT=y` on our `mailcow.conf`, and run
Then we'll create a `docker-compose.override.yml` file in order to override the main `docker-compose.yml` found in your mailcow root folder.
```
```yaml
version: '2.1'
services:
@ -195,10 +200,10 @@ services:
- traefik.http.routers.moo.tls.certresolver=le
# Creates a service called "moo" for the container, and specifies which internal port of the container
# should traefik route the incoming data to.
- traefik.http.services.moo.loadbalancer.server.port=80
- traefik.http.services.moo.loadbalancer.server.port=${HTTP_PORT}
# Specifies which entrypoint (external port) should traefik listen to, for this container.
# websecure being port 443, check the traefik.toml file liked above.
- traefik.http.routers.moo.entrypoints=secure
- traefik.http.routers.moo.entrypoints=websecure
# Make sure traefik uses the web network, not the mailcowdockerized_mailcow-network
- traefik.docker.network=web
@ -248,3 +253,13 @@ dovecot_c=$(docker ps -qaf name=dovecot-mailcow)
nginx_c=$(docker ps -qaf name=nginx-mailcow)
docker restart ${postfix_c} ${dovecot_c} ${nginx_c}
```
### Adding additional server names for mailcow UI
If you plan to use a server name that is not `MAILCOW_HOSTNAME` in your reverse proxy, make sure to populate that name in mailcow.conf via `ADDITIONAL_SERVER_NAMES` first. Names must be separated by commas and **must not** contain spaces. If you skip this step, mailcow may respond to your reverse proxy with an incorrect site.
```
ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld
```
Run `docker-compose up -d` to apply.

Datei anzeigen

@ -1,4 +1,4 @@
Rspamd (https://rspamd.com/webui/) is an easy to use spam filtering tool presently installed with mailcow.
[Rspamd](https://rspamd.com/) is an easy to use spam filtering tool presently installed with mailcow.
1. Go to the mailcow web admin interface
2. Navigate to the Access tab. (Configuration > Administration > Access)

Datei anzeigen

@ -1,7 +1,5 @@
## SNAT
SNAT is used to change the source address of the packets sent by mailcow.
It can be used to change the outgoing IP on systems with multiple IP addresses.
It can be used to change the outgoing IP address on systems with multiple IP addresses.
Open `mailcow.conf`, set either or both of the following parameters:

Datei anzeigen

@ -7,7 +7,7 @@ The "acme-mailcow" container will try to obtain a LE certificate for `${MAILCOW_
By default, which means **0 domains** are added to mailcow, it will try to obtain a certificate for `${MAILCOW_HOSTNAME}`.
For each domain you add, it will try to resolve `autodiscover.ADDED_MAIL_DOMAIN` and `autoconfig.ADDED_MAIL_DOMAIN` to its IPv6 or - if IPv6 is not configured in your domain - IPv4 address. If it succeeds, a name will be added as SAN to the certificate request.
For each domain you add, it will try to resolve `autodiscover.ADDED_MAIL_DOMAIN` and `autoconfig.ADDED_MAIL_DOMAIN` to its IPv6 address or - if IPv6 is not configured in your domain - IPv4 address. If it succeeds, a name will be added as SAN to the certificate request.
Only names that can be validated, will be added as SAN.
@ -25,12 +25,23 @@ Do not use quotes (`"`) and do not use spaces between the names!
ADDITIONAL_SAN=smtp.*,cert1.example.com,cert2.example.org,whatever.*
```
Each name will be validated against its IPv6 or - if IPv6 is not configured in your domain - IPv4 address.
Each name will be validated against its IPv6 address or - if IPv6 is not configured in your domain - IPv4 address.
A wildcard name like `smtp.*` will try to obtain a smtp.DOMAIN_NAME SAN for each domain added to mailcow.
Run `docker-compose up -d` to recreate affected containers automatically.
!!! info
Using names other name `MAILCOW_HOSTNAME` to access the mailcow UI may need further configuration.
If you plan to use a server name that is not `MAILCOW_HOSTNAME` to access the mailcow UI (for example by adding `mail.*` to `ADDITIONAL_SAN` make sure to populate that name in mailcow.conf via `ADDITIONAL_SERVER_NAMES`. Names must be separated by commas and **must not** contain spaces. If you skip this step, mailcow may respond with an incorrect site.
```
ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld
```
Run `docker-compose up -d` to apply.
### Force renewal
To force a renewal, you need to create a file named `force_renew` and restart the `acme-mailcow` container:
@ -47,9 +58,9 @@ The file will be deleted automatically.
### Validation errors and how to skip validation
You can skip the **IP verification** by setting `SKIP_IP_CHECK=y` in mailcow.conf (no quotes). Be warned that a misconfiguration will get you ratelimited by Let's Encrypt! This is primarily useful for multi-IP setups where the IP check would return the incorrect source IP. Due to using dynamic IPs for acme-mailcow, source NAT is not consistent over restarts.
You can skip the **IP verification** by setting `SKIP_IP_CHECK=y` in mailcow.conf (no quotes). Be warned that a misconfiguration will get you ratelimited by Let's Encrypt! This is primarily useful for multi-IP setups where the IP check would return the incorrect source IP address. Due to using dynamic IPs for acme-mailcow, source NAT is not consistent over restarts.
If you encounter problems with "HTTP validation", but your IP confirmation succeeds, you are most likely using firewalld, ufw or any other firewall, that disallows connections from `br-mailcow` to your external interface. Both firewalld and ufw disallow this by default. It is often not enough to just stop these firewall services. You'd need to stop mailcow (`docker-compose down`), stop the firewall service, flush the chains and restart Docker.
If you encounter problems with "HTTP validation", but your IP address confirmation succeeds, you are most likely using firewalld, ufw or any other firewall, that disallows connections from `br-mailcow` to your external interface. Both firewalld and ufw disallow this by default. It is often not enough to just stop these firewall services. You'd need to stop mailcow (`docker-compose down`), stop the firewall service, flush the chains and restart Docker.
You can also skip this validation method by setting `SKIP_HTTP_VERIFICATION=y` in "mailcow.conf". Be warned that this is discouraged. In most cases, the HTTP verification is skipped to workaround unknown NAT reflection issues, which are not resolved by ignoring this specific network misconfiguration. If you encounter problems generating TLSA records in the DNS overview within mailcow, you are most likely having issues with NAT reflection you should fix.
@ -73,9 +84,10 @@ By default, "acme-mailcow" will create a single SAN certificate for all validate
This provides best compatibility but means the Let's Encrypt limit exceeds if you add too many domains to a single mailcow installation.
To solve this, you can configure `ENABLE_SSL_SNI` to generate:
* A main server certificate with `MAILCOW_HOSTNAME` and all fully qualified domain names in the `ADDITIONAL_SAN` config
* One additional certificate for each domain found in the database with autodiscover.*, autoconfig.* and any other `ADDITIONAL_SAN` configured in this format (subdomain.*).
* Limitations: A certificate name `ADDITIONAL_SAN=test.example.com` will be added as SAN to the main certificate. A separate certificate/key pair will **not** be generated for this format.
- A main server certificate with `MAILCOW_HOSTNAME` and all fully qualified domain names in the `ADDITIONAL_SAN` config
- One additional certificate for each domain found in the database with autodiscover.*, autoconfig.* and any other `ADDITIONAL_SAN` configured in this format (subdomain.*).
- Limitations: A certificate name `ADDITIONAL_SAN=test.example.com` will be added as SAN to the main certificate. A separate certificate/key pair will **not** be generated for this format.
Postfix, Dovecot and Nginx will then serve these certificates with SNI.
@ -86,14 +98,16 @@ Set `ENABLE_SSL_SNI=y` in "mailcow.conf" and recreate "acme-mailcow" by running
You should make sure these clients use the `MAILCOW_HOSTNAME` for secure connections if you enable this feature.
Here is an example:
* `MAILCOW_HOSTNAME=server.email.tld`
* `ADDITIONAL_SAN=webmail.email.tld,mail.*`
* Mailcow email domains: "domain1.tld" and "domain2.tld"
- `MAILCOW_HOSTNAME=server.email.tld`
- `ADDITIONAL_SAN=webmail.email.tld,mail.*`
- Mailcow email domains: "domain1.tld" and "domain2.tld"
The following certificates will be generated:
* `server.email.tld, webmail.email.tld` -> this is the default certificate, all clients can connect with these domains
* `mail.domain1.tld, autoconfig.domain1.tld, autodiscover.domain1.tld` -> individual certificate for domain1.tld, cannot be used by clients without SNI support
* `mail.domain2.tld, autoconfig.domain2.tld, autodiscover.domain2.tld` -> individual certificate for domain2.tld, cannot be used by clients without SNI support
- `server.email.tld, webmail.email.tld` -> this is the default certificate, all clients can connect with these domains
- `mail.domain1.tld, autoconfig.domain1.tld, autodiscover.domain1.tld` -> individual certificate for domain1.tld, cannot be used by clients without SNI support
- `mail.domain2.tld, autoconfig.domain2.tld, autodiscover.domain2.tld` -> individual certificate for domain2.tld, cannot be used by clients without SNI support
### How to use your own certificate
@ -101,6 +115,8 @@ Make sure you disable mailcows internal LE client (see above).
To use your own certificates, just save the combined certificate (containing the certificate and intermediate CA/CA if any) to `data/assets/ssl/cert.pem` and the corresponding key to `data/assets/ssl/key.pem`.
**IMPORTANT:** Do not use symbolic links! Make sure you copy the certificates and do not link them to `data/assets/ssl`.
Restart affected services afterwards:
```
@ -109,7 +125,7 @@ docker restart $(docker ps -qaf name=nginx-mailcow)
docker restart $(docker ps -qaf name=dovecot-mailcow)
```
See https://mailcow.github.io/mailcow-dockerized-docs/firststeps-rp/#optional-post-hook-script-for-non-mailcow-acme-clients for a full example script.
See [Post-hook script for non-mailcow ACME clients](../firststeps-rp/#optional-post-hook-script-for-non-mailcow-acme-clients) for a full example script.
### Test against staging ACME directory

Datei anzeigen

@ -10,7 +10,7 @@ Sync jobs are used to copy or move existing emails from an external IMAP server
3. Fill in the "Host" and "Port" fields with their respective correct values from the upstream IMAP server.
4. In the "Username" and 'Password" fields, supply the correct access credentials from the upstream IMAP server.
4. In the "Username" and "Password" fields, supply the correct access credentials from the upstream IMAP server.
5. Select the "Encryption Method". If the upstream IMAP server uses port 143, it is likely that the encryption method is TLS and SSL for port 993. Nevertheless, you can use PLAIN authentication, but it is stongly discouraged.
@ -19,4 +19,4 @@ Sync jobs are used to copy or move existing emails from an external IMAP server
7. Make sure to tick "Active" and click "Add".
!!! info
Once Completed, log into the mailbox and check if all emails are imported correctly. If all goes well, All your mails shall end up in your new mailbox. And don't forget to delete or deactivate the sync job after it is used.
Once Completed, log into the mailbox and check if all emails are imported correctly. If all goes well, all your mails shall end up in your new mailbox. And don't forget to delete or deactivate the sync job after it is used.

Datei anzeigen

@ -0,0 +1,39 @@
By default mailcow considers **all networks as untrusted** excluding its own IPV4_NETWORK and IPV6_NETWORK scopes. Though it is reasonable in most cases, there may be circumstances that you need to loosen this restriction.
By default mailcow uses `mynetworks_style = subnet` to determine internal subnets and leaves `mynetworks` unconfigured.
If you decide to set `mynetworks`, Postfix ignores the mynetworks_style setting. This means you **have to** add the IPV4_NETWORK and IPV6_NETWORK scopes as well as loopback subnets manually!
## Unauthenticated relaying
!!! Warning
Incorrect setup of `mynetworks` will allow your server to be used as an open relay. If abused, this **will** affect your ability to send emails and can take some time to be resolved.
### IPv4 hosts/subnets
To add the subnet `192.168.2.0/24` to the trusted networks you may use the following configuration, depending on your IPV4_NETWORK and IPV6_NETWORK scopes:
Edit `data/conf/postfix/extra.cf`:
```
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 192.168.2.0/24
```
Run `docker-compose restart postfix-mailcow` to apply your new settings.
### IPv6 hosts/subnets
Adding IPv6 hosts is done the same as IPv4, however the subnet needs to be placed in brackets `[]` with the netmask appended.
To add the subnet 2001:db8::/32 to the trusted networks you may use the following configuration, depending on your IPV4_NETWORK and IPV6_NETWORK scopes:
Edit `data/conf/postfix/extra.cf`:
```
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10 172.22.1.0/24 [fd4d:6169:6c63:6f77::]/64 [2001:db8::]/32
```
Run `docker-compose restart postfix-mailcow` to apply your new settings.
!!! Info
More information about mynetworks can be found in the [Postfix documentation](http://www.postfix.org/postconf.5.html#mynetworks).

Datei anzeigen

@ -1,9 +1,4 @@
!!! warning
Make sure you've read ["Prepare Your System"](https://mailcow.github.io/mailcow-dockerized-docs/prerequisite-system) before proceeding!
**Do not** use CentOS 8 with Centos 7 Docker packages. You may create an open relay.
You need Docker and Docker Compose.
You need Docker (a version >= `20.10.2` is required) and Docker Compose.
**1\.** Learn how to install [Docker](https://docs.docker.com/install/) and [Docker Compose](https://docs.docker.com/compose/install/).
@ -13,8 +8,7 @@ Quick installation for most operation systems:
```
curl -sSL https://get.docker.com/ | CHANNEL=stable sh
# After the installation process is finished, you may need to enable the service and make sure it is started (e.g. CentOS 7)
systemctl enable docker.service
systemctl start docker.service
systemctl enable --now docker
```
- Docker-Compose
@ -30,6 +24,36 @@ chmod +x /usr/local/bin/docker-compose
Please use the latest Docker engine available and do not use the engine that ships with your distros repository.
**1\.1\.** On SELinux enabled systems, e.g. CentOS 7:
- Check if "container-selinux" package is present on your system:
```
rpm -qa | grep container-selinux
```
If the above command returns an empty or no output, you should install it via your package manager.
- Check if docker has SELinux support enabled:
```
docker info | grep selinux
```
If the above command returns an empty or no output, create or edit `/etc/docker/daemon.json` and add `"selinux-enabled": true`. Example file content:
```
{
"selinux-enabled": true
}
```
Restart the docker daemon and verify SELinux is now enabled.
This step is required to make sure mailcows volumes are properly labeled as declared in the compose file.
If you are interested in how this works, you can check out the readme of https://github.com/containers/container-selinux which links to a lot of useful information on that topic.
**2\.** Clone the master branch of the repository, make sure your umask equals 0022. Please clone the repository as root user and also control the stack as root. We will modify attributes - if necessary - while boostrapping the containers automatically and make sure everything is secured. The update.sh script must therefore also be run as root. It might be necessary to change ownership and other attributes of files you will otherwise not have access to. **We drop permissions for every exposed application** and will not run an exposed service as root! Controlling the Docker daemon as non-root user does not give you additional security. The unprivileged user will spawn the containers as root likewise. The behaviour of the stack is identical.
```
@ -78,7 +102,7 @@ networks:
If you do not have an IPv6 enabled network on your host and you don't care for a better internet (thehe), it is recommended to [disable IPv6](https://mailcow.github.io/mailcow-dockerized-docs/firststeps-disable_ipv6/) for the mailcow network to prevent unforeseen issues.
**5\.** Pull the images and run the composer file. The parameter `-d` will start mailcow: dockerized detached:
**5\.** Pull the images and run the compose file. The parameter `-d` will start mailcow: dockerized detached:
```
docker-compose pull
docker-compose up -d
@ -88,7 +112,7 @@ Done!
You can now access **https://${MAILCOW_HOSTNAME}** with the default credentials `admin` + password `moohoo`.
!!! info
!!! info
If you are not using mailcow behind a reverse proxy, you should [redirect all HTTP requests to HTTPS](https://mailcow.github.io/mailcow-dockerized-docs/u_e-80_to_443/).
The database will be initialized right after a connection to MySQL can be established.

Datei anzeigen

@ -18,7 +18,7 @@ Some minor conflicts will be auto-corrected (in favour for the mailcow: dockeriz
```
# Options can be combined
# - Check for updates
# - Check for updates and show changes
./update.sh --check
# Do not try to update docker-compose, **make sure to use the latest docker-compose available**
@ -41,52 +41,34 @@ Some minor conflicts will be auto-corrected (in favour for the mailcow: dockeriz
./update.sh --prefetch
```
## Manual update (not maintained anymore, please use update.sh)
### I forgot what I changed before running update.sh
### Step 1
See `git log --pretty=oneline | grep -i "before update"`, you will have an output similar to this:
```
22cd00b5e28893ef9ddef3c2b5436453cc5223ab Before update on 2020-09-28_19_25_45
dacd4fb9b51e9e1c8a37d84485b92ffaf6c59353 Before update on 2020-08-07_13_31_31
```
Run `git diff 22cd00b5e28893ef9ddef3c2b5436453cc5223ab` to see what changed.
### Can I roll back?
Yes.
See the topic above, instead of a diff, you run checkout:
```
docker-compose down
```
Fetch new data from GitHub, commit changes and merge remote repository:
```
# 1. Get updates/changes
git fetch origin master
# 2. Add all changed files to local clone
git add -A
# 3. Commit changes, ignore git complaining about username and mail address
git commit -m "Local config at $(date)"
# 4. Merge changes, prefer mailcow repository, replace "theirs" by "ours" to change merge strategy
git merge -Xtheirs -Xpatience
# If it conflicts with files that were deleted from the mailcow repository, just run...
git status --porcelain | grep -E "UD|DU" | awk '{print $2}' | xargs rm -v
# ...and repeat step 2 and 3
```
### Step 2
Pull new images (if any) and recreate changed containers:
```
# Replace commit ID 22cd00b5e28893ef9ddef3c2b5436453cc5223ab by your ID
git checkout 22cd00b5e28893ef9ddef3c2b5436453cc5223ab
docker-compose pull
docker-compose up -d --remove-orphans
docker-compose up -d
```
### Step 3
Clean-up dangling (unused) images and volumes:
It is **very important** to _not_ run these commands when your containers are deleted.
Running `docker-compose down` - for example - will delete your containers. Your volumes are now in a dangling state! Running the commands shown below, _will_ remove your volumes and therefore your data.
```
docker rmi -f $(docker images -f "dangling=true" -q)
docker volume rm $(docker volume ls -qf dangling=true)
```
### Hooks
You can hook into the update mechanism by adding scripts called `pre_commit_hook.sh` and `post_commit_hook.sh` to your mailcows root directory. See [this](./u_e-update-hooks.md) for more details.
## Footnotes

BinÀre Datei nicht angezeigt.

Vorher

Breite:  |  Höhe:  |  GrĂ¶ĂŸe: 6,7 KiB

Nachher

Breite:  |  Höhe:  |  GrĂ¶ĂŸe: 10 KiB

BinÀre Datei nicht angezeigt.

Nachher

Breite:  |  Höhe:  |  GrĂ¶ĂŸe: 32 KiB

BinÀre Datei nicht angezeigt.

Nachher

Breite:  |  Höhe:  |  GrĂ¶ĂŸe: 39 KiB

BinÀre Datei nicht angezeigt.

Nachher

Breite:  |  Höhe:  |  GrĂ¶ĂŸe: 22 KiB

Datei anzeigen

@ -64,29 +64,33 @@ The integrated **mailcow UI** allows administrative work on your mail server ins
mailcow: dockerized comes with multiple containers linked in one bridged network.
Each container represents a single application.
- [Dovecot](https://www.dovecot.org/)
- [ACME](https://letsencrypt.org/)
- [ClamAV](https://www.clamav.net/) (optional)
- [Solr](http://lucene.apache.org/solr/) (optional)
- [Oletools](https://github.com/decalage2/oletools) via [Olefy](https://github.com/HeinleinSupport/olefy)
- [Memcached](https://www.memcached.org/)
- [Redis](https://redis.io/)
- [Dovecot](https://www.dovecot.org/)
- [MariaDB](https://mariadb.org/)
- [Unbound](https://unbound.net/)
- [Memcached](https://www.memcached.org/)
- [Netfilter](https://www.netfilter.org/) (Fail2ban-like integration by [@mkuron](https://github.com/mkuron))
- [Nginx](https://nginx.org/)
- [Oletools](https://github.com/decalage2/oletools) via [Olefy](https://github.com/HeinleinSupport/olefy)
- [PHP](https://php.net/)
- [Postfix](http://www.postfix.org/)
- [ACME](https://letsencrypt.org/)
- [Nginx](https://nginx.org/)
- [Redis](https://redis.io/)
- [Rspamd](https://www.rspamd.com/)
- [SOGo](https://sogo.nu/)
- [Netfilter](https://www.netfilter.org/) (Fail2ban-like integration by [@mkuron](https://github.com/mkuron))
- [Solr](https://solr.apache.org/) (optional)
- [Unbound](https://unbound.net/)
- A Watchdog to provide basic monitoring
**Docker volumes** to keep dynamic data - take care of them!
- vmail-vol-1
- solr-vol-1
- redis-vol-1
- mysql-vol-1
- rspamd-vol-1
- postfix-vol-1
- crypt-vol-1
- mysql-socket-vol-1
- mysql-vol-1
- postfix-vol-1
- redis-vol-1
- rspamd-vol-1
- sogo-userdata-backup-vol-1
- sogo-web-vol-1
- solr-vol-1
- vmail-index-vol-1
- vmail-vol-1

49
docs/model-passwd.md Normale Datei
Datei anzeigen

@ -0,0 +1,49 @@
## Fully supported hashing methods
The most current mailcow fully supports the following hashing methods.
The default hashing method is written in bold:
- **BLF-CRYPT**
- SSHA
- SSHA256
- SSHA512
The methods above can be used in `mailcow.conf` as `MAILCOW_PASS_SCHEME` value.
## Read-only hashing methods
The following methods are supported **read only**.
If you plan to use SOGo (as per default), you need a SOGo compatible hashing method. Please see the note at the bottom of this page how to update the view if necessary.
With SOGo disabled, all hashing methods below will be able to be read by mailcow and Dovecot.
- ARGON2I (SOGo compatible)
- ARGON2ID (SOGo compatible)
- CLEAR
- CLEARTEXT
- CRYPT (SOGo compatible)
- DES-CRYPT
- LDAP-MD5 (SOGo compatible)
- MD5 (SOGo compatible)
- MD5-CRYPT (SOGo compatible)
- PBKDF2 (SOGo compatible)
- PLAIN (SOGo compatible)
- PLAIN-MD4
- PLAIN-MD5
- PLAIN-TRUNC
- SHA (SOGo compatible)
- SHA1 (SOGo compatible)
- SHA256 (SOGo compatible)
- SHA256-CRYPT (SOGo compatible)
- SHA512 (SOGo compatible)
- SHA512-CRYPT (SOGo compatible)
- SMD5 (SOGo compatible)
That means mailcow is able to verify users with a hash like `{MD5}1a1dc91c907325c69271ddf0c944bc72` from the database.
The value of `MAILCOW_PASS_SCHEME` will _always_ be used to encrypt new passwords.
---
> I changed the password hashes in the "mailbox" SQL table and cannot login.
A "view" needs to be updated. You can trigger this by restarting sogo-mailcow: `docker-compose restart sogo-mailcow`

Datei anzeigen

@ -8,10 +8,13 @@ Below you can find a list of **recommended DNS records**. While some are mandato
["Best Practices on Email Protection: SPF, DKIM and DMARC"](https://wiki.zimbra.com/wiki/Best_Practices_on_Email_Protection:_SPF,_DKIM_and_DMARC)
- An in-depth discussion of SPF, DKIM and DMARC:
["How to eliminate spam and protect your name with DMARC"](https://www.skelleton.net/2015/03/21/how-to-eliminate-spam-and-protect-your-name-with-dmarc/)
- A thorough guide on understanding DMARC:
["Demystifying DMARC: A guide to preventing email spoofing"](https://seanthegeek.net/459/demystifying-dmarc/)
## Reverse DNS of your IP
Make sure that the PTR record of your IP matches the FQDN of your mailcow host: `${MAILCOW_HOSTNAME}` [^1]. This record is usually set at the provider you leased the IP (server) from.
## Reverse DNS of your IP address
Make sure that the PTR record of your IP address matches the FQDN of your mailcow host: `${MAILCOW_HOSTNAME}` [^1]. This record is usually set at the provider you leased the IP address (server) from.
## The minimal DNS configuration
@ -20,10 +23,9 @@ This example shows you a set of records for one domain managed by mailcow. Each
```
# Name Type Value
mail IN A 1.2.3.4
autodiscover IN CNAME mail
autoconfig IN CNAME mail
@ IN MX 10 mail
autodiscover IN CNAME mail.example.org. (your ${MAILCOW_HOSTNAME})
autoconfig IN CNAME mail.example.org. (your ${MAILCOW_HOSTNAME})
@ IN MX 10 mail.example.org. (your ${MAILCOW_HOSTNAME})
```
## DKIM, SPF and DMARC
@ -31,18 +33,21 @@ autoconfig IN CNAME mail
In the example DNS zone file snippet below, a simple **SPF** TXT record is used to only allow THIS server (the MX) to send mail for your domain. Every other server is disallowed but able to ("`~all`"). Please refer to [SPF Project](http://www.open-spf.org/) for further reading.
```
# Name Type Value
@ IN TXT "v=spf1 mx a -all"
```
It is highly recommended to create a **DKIM** TXT record in your mailcow UI and set the corresponding TXT record in your DNS records. Please refer to [OpenDKIM](http://www.opendkim.org) for further reading.
```
# Name Type Value
dkim._domainkey IN TXT "v=DKIM1; k=rsa; t=s; s=email; p=..."
```
The last step in protecting yourself and others is the implementation of a **DMARC** TXT record, for example by using the [DMARC Assistant](http://www.kitterman.com/dmarc/assistant.html) ([check](https://dmarcian.com/dmarc-inspector/google.com)).
```
# Name Type Value
_dmarc IN TXT "v=DMARC1; p=reject; rua=mailto:mailauth-reports@example.org"
```
@ -51,18 +56,19 @@ _dmarc IN TXT "v=DMARC1; p=reject; rua=mailto:mailauth-reports@
**SRV** records specify the server(s) for a specific protocol on your domain. If you want to explicitly announce a service as not provided, give "." as the target address (instead of "mail.example.org."). Please refer to [RFC 2782](https://tools.ietf.org/html/rfc2782).
```
_imap._tcp IN SRV 0 1 143 mail.example.org.
_imaps._tcp IN SRV 0 1 993 mail.example.org.
_pop3._tcp IN SRV 0 1 110 mail.example.org.
_pop3s._tcp IN SRV 0 1 995 mail.example.org.
_submission._tcp IN SRV 0 1 587 mail.example.org.
_smtps._tcp IN SRV 0 1 465 mail.example.org.
_sieve._tcp IN SRV 0 1 4190 mail.example.org.
_autodiscover._tcp IN SRV 0 1 443 mail.example.org.
_carddavs._tcp IN SRV 0 1 443 mail.example.org.
_carddavs._tcp IN TXT "path=/SOGo/dav/"
_caldavs._tcp IN SRV 0 1 443 mail.example.org.
# Name Type Priority Weight Port Value
_autodiscover._tcp IN SRV 0 1 443 mail.example.org. (your ${MAILCOW_HOSTNAME})
_caldavs._tcp IN SRV 0 1 443 mail.example.org. (your ${MAILCOW_HOSTNAME})
_caldavs._tcp IN TXT "path=/SOGo/dav/"
_carddavs._tcp IN SRV 0 1 443 mail.example.org. (your ${MAILCOW_HOSTNAME})
_carddavs._tcp IN TXT "path=/SOGo/dav/"
_imap._tcp IN SRV 0 1 143 mail.example.org. (your ${MAILCOW_HOSTNAME})
_imaps._tcp IN SRV 0 1 993 mail.example.org. (your ${MAILCOW_HOSTNAME})
_pop3._tcp IN SRV 0 1 110 mail.example.org. (your ${MAILCOW_HOSTNAME})
_pop3s._tcp IN SRV 0 1 995 mail.example.org. (your ${MAILCOW_HOSTNAME})
_sieve._tcp IN SRV 0 1 4190 mail.example.org. (your ${MAILCOW_HOSTNAME})
_smtps._tcp IN SRV 0 1 465 mail.example.org. (your ${MAILCOW_HOSTNAME})
_submission._tcp IN SRV 0 1 587 mail.example.org. (your ${MAILCOW_HOSTNAME})
```
## Testing
@ -73,13 +79,52 @@ Here are some tools you can use to verify your DNS configuration:
- [port25.com](https://www.port25.com/dkim-wizard/) (DKIM, SPF)
- [Mail-tester](https://www.mail-tester.com/) (DKIM, DMARC, SPF)
- [DMARC Analyzer](https://www.dmarcanalyzer.com/spf/checker/) (DMARC, SPF)
- [MultiRBL.valli.org](http://multirbl.valli.org/) (DNSBL, RBL, FCrDNS)
## Misc
If you are interested in statistics, you can additionally register with the [Postmaster Tool](https://gmail.com/postmaster) by Google and supply a **google-site-verification** TXT record, which will give you details about spam-classified mails by your domain. This is clearly optional.
### Optional DMARC Statistics
If you are interested in statistics, you can additionally register with some of the many below DMARC statistic services - or self-host your own.
!!! Tip
It is worth considering that if you request DMARC statistic reports to your mailcow server and your mailcow server is not configured correctly to receive these reports, you may not get accurate and complete results. Please consider using an alternative email domain for receiving DMARC reports.
It is worth mentioning, that the following suggestions are not a comprehensive list of all services and tools available, but only a small few of the many choices.
- [Postmaster Tool](https://gmail.com/postmaster)
- [parsedmarc](https://github.com/domainaware/parsedmarc) (self-hosted)
- [Fraudmarc](https://fraudmarc.com/)
- [Postmark](https://dmarc.postmarkapp.com)
- [Dmarcian](https://dmarcian.com/)
!!! Tip
These services may provide you with a TXT record you need to insert into your DNS records as the provider specifies. Please ensure you read the provider's documentation from the service you choose as this process may vary.
### Email test for SPF, DKIM and DMARC:
To run a rudimentary email authentication check, send a mail to `check-auth at verifier.port25.com` and wait for a reply. You will find a report similar to the following:
```
@ IN TXT "google-site-verification=..."
==========================================================
Summary of Results
==========================================================
SPF check: pass
"iprev" check: pass
DKIM check: pass
DKIM check: pass
SpamAssassin check: ham
==========================================================
Details:
==========================================================
....
```
[^1]: A **Fully Qualified Domain Name** (**FQDN**) is the complete (absolute) domain name for a specific computer or host, on the Internet. The FQDN consists of at least three parts divided by a dot: the hostname (myhost), the domain name (mydomain) and the top level domain in short **tld** (com). In the example of `mx.mailcow.email` the hostname would be `mx`, the domain name 'mailcow' and the tld `email`.
The full report will contain more technical details.
### Fully Qualified Domain Name (FQDN)
[^1]: A **Fully Qualified Domain Name** (**FQDN**) is the complete (absolute) domain name for a specific computer or host, on the Internet. The FQDN consists of at least three parts divided by a dot: the hostname, the domain name, and the Top Level Domain (**TLD** for short). In the example of `mx.mailcow.email` the hostname would be `mx`, the domain name `mailcow` and the TLD `email`.

Datei anzeigen

@ -2,7 +2,6 @@ Before you run **mailcow: dockerized**, there are a few requirements that you sh
!!! warning
Do **not** try to install mailcow on a Synology/QNAP device (any NAS), OpenVZ, LXC or other container platforms. KVM, ESX, Hyper-V and other full virtualization platforms are supported.
Do **not** use CentOS 8 with Centos 7 Docker packages. You may create an open relay.
!!! info
- mailcow: dockerized requires [some ports](#default-ports) to be open for incoming connections, so make sure that your firewall is not blocking these.
@ -12,37 +11,47 @@ Before you run **mailcow: dockerized**, there are a few requirements that you sh
## Minimum System Resources
**Do not** use OpenVZ or LXC as guests for mailcow.
**OpenVZ, Virtuozzo and LXC are not supported**.
Please make sure that your system has at least the following resources:
| Resource | mailcow: dockerized |
| ----------------------- | -------------------------------------------- |
| ----------------------- | ------------------------------------------------ |
| CPU | 1 GHz |
| RAM                     | Minimum 4 GiB + Swap |
| RAM                     | **Minimum** 6 GiB + 1 GiB swap (default config) |
| Disk | 20 GiB (without emails) |
| System Type | x86_64 |
As of today (29th Dec 2019), we recommend using any distribution listed as supported by Docker CE (check https://docs.docker.com/install/). We test on CentOS 7, Debian 9/10 and Ubuntu 18.04.
We recommend using any distribution listed as supported by Docker CE (check https://docs.docker.com/install/). We test on CentOS 7, Debian 9/10 and Ubuntu 18.04/20.04.
ClamAV and Solr are greedy RAM munchers. You can disable them in `mailcow.conf` by settings SKIP_CLAMD=y and SKIP_SOLR=y.
ClamAV and Solr can be greedy with RAM. You may disable them in `mailcow.conf` by settings `SKIP_CLAMD=y` and `SKIP_SOLR=y`.
**Info**: We are aware that a pure MTA can run on 128 MiB RAM. mailcow is a full-grown and ready-to-use groupware with many extras making life easier. mailcow comes with a webserver, webmailer, ActiveSync (MS), antivirus, antispam, indexing (Solr), document scanner (Oletools), SQL (MariaDB), Cache (Redis), MDA, MTA, various web services etc.
A single SOGo worker **can** acquire ~350 MiB RAM before it gets purged. The more ActiveSync connections you plan to use, the more RAM you will need. A default configuration spawns 20 workers.
#### Usage examples
A company with 15 phones (EAS enabled) and about 50 concurrent IMAP connections should plan 16 GiB RAM.
6 GiB RAM + 1 GiB swap are fine for most private installations while 8 GiB RAM are recommended for ~5 to 10 users.
We can help to correctly plan your setup as part of our support.
## Firewall & Ports
Please check if any of mailcow's standard ports are open and not in use by other applications:
```
ss -tlpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190'
ss -tlpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190|5222|5269|5443'
# or:
netstat -tulpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190'
netstat -tulpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190|5222|5269|5443'
```
!!! warning
There are several problems with running mailcow on a firewalld/ufw enabled system. You should disable it (if possible) and move your ruleset to the DOCKER-USER chain, which is not cleared by a Docker service restart, instead. See [this blog post](https://blog.donnex.net/docker-and-iptables-filtering/) for information about how to use iptables-persistent with the DOCKER-USER chain.
There are several problems with running mailcow on a firewalld/ufw enabled system. You should disable it (if possible) and move your ruleset to the DOCKER-USER chain, which is not cleared by a Docker service restart, instead. See [this (blog.donnex.net)](https://blog.donnex.net/docker-and-iptables-filtering/) or [this (unrouted.io)](https://unrouted.io/2017/08/15/docker-firewall/) guide for information about how to use iptables-persistent with the DOCKER-USER chain.
As mailcow runs dockerized, INPUT rules have no effect on restricting access to mailcow. Use the FORWARD chain instead.
**
If this command returns any results please remove or stop the application running on that port. You may also adjust mailcows ports via the `mailcow.conf` configuration file.
### Default Ports
@ -50,7 +59,7 @@ If this command returns any results please remove or stop the application runnin
If you have a firewall in front of mailcow, please make sure that these ports are open for incoming connections:
| Service | Protocol | Port | Container | Variable |
| --------------------|:--------:|:-------|:----------------|----------------------------------|
| --------------------|:--------:|:-------|:------------------|----------------------------------|
| Postfix SMTP | TCP | 25 | postfix-mailcow | `${SMTP_PORT}` |
| Postfix SMTPS | TCP | 465 | postfix-mailcow | `${SMTPS_PORT}` |
| Postfix Submission | TCP | 587 | postfix-mailcow | `${SUBMISSION_PORT}` |
@ -65,6 +74,51 @@ To bind a service to an IP address, you can prepend the IP like this: `SMTP_PORT
**Important**: You cannot use IP:PORT bindings in HTTP_PORT and HTTPS_PORT. Please use `HTTP_PORT=1234` and `HTTP_BIND=1.2.3.4` instead.
### Important for Hetzner firewalls
Quoting https://github.com/chermsen via https://github.com/mailcow/mailcow-dockerized/issues/497#issuecomment-469847380 (THANK YOU!):
For all who are struggling with the Hetzner firewall:
Port 53 unimportant for the firewall configuration in this case. According to the documentation unbound uses the port range 1024-65535 for outgoing requests.
Since the Hetzner Robot Firewall is a static firewall (each incoming packet is checked isolated) - the following rules must be applied:
**For TCP**
```
SRC-IP: ---
DST IP: ---
SRC Port: ---
DST Port: 1024-65535
Protocol: tcp
TCP flags: ack
Action: Accept
```
**For UDP**
```
SRC-IP: ---
DST IP: ---
SRC Port: ---
DST Port: 1024-65535
Protocol: udp
Action: Accept
```
If you want to apply a more restrictive port range you have to change the config of unbound first (after installation):
{mailcow-dockerized}/data/conf/unbound/unbound.conf:
```
outgoing-port-avoid: 0-32767
```
Now the firewall rules can be adjusted as follows:
```
[...]
DST Port: 32768-65535
[...]
```
## Date and Time
To ensure that you have the correct date and time setup on your system, please check the output of `timedatectl status`:

Datei anzeigen

@ -0,0 +1,15 @@
_WIP_
# Protocol restrictions and IP access
Denied access will be shown to the user as failed login attempts.
## Protocol restrictions in Dovecot
Protocol restrictions work by filtering the passdb query for IMAP and POP3 as well as reading the JSON value for %s_access where %s reflects the protocol seen by Dovecot.
In the future we may use virtual colums in SQL to add an index on these values.
## Protocol restrictions in Postfix
Filtering SMTP protocol access works by using a check_sasl_map in the smtpd_recipient_restrictions.

247
docs/third_party-borgmatic.md Normale Datei
Datei anzeigen

@ -0,0 +1,247 @@
# Borgmatic Backup
## Introduction
Borgmatic is a great way to run backups on your Mailcow setup as it securely encrypts your data and is extremely easy to
set up.
Due to it's deduplication capabilities you can store a great number of backups without wasting large amounts of disk
space. This allows you to run backups in very short intervals to ensure minimal data loss when the need arises to
recover data from a backup.
This document guides you through the process to enable continuous backups for mailcow with borgmatic. The borgmatic
functionality is provided by the [borgmatic Docker image by b3vis](https://github.com/b3vis/docker-borgmatic). Check out
the `README` in that repository to find out about the other options (such as push notifications) that are available.
This guide only covers the basics.
## Setting up borgmatic
### Create or amend `docker-compose.override.yml`
In the mailcow-dockerized root folder create or edit `docker-compose.override.yml` and insert the following
configuration:
```yaml
version: '2.1'
services:
borgmatic-mailcow:
image: b3vis/borgmatic
restart: always
dns: ${IPV4_NETWORK:-172.22.1}.254
volumes:
- vmail-vol-1:/mnt/source/vmail:ro
- mysql-socket-vol-1:/var/run/mysqld/:z
- ./data/conf/borgmatic/etc:/etc/borgmatic.d:Z
- ./data/conf/borgmatic/state:/root/.config/borg:Z
- ./data/conf/borgmatic/ssh:/root/.ssh:Z
environment:
- TZ=${TZ}
- BORG_PASSPHRASE=YouBetterPutSomethingRealGoodHere
networks:
mailcow-network:
aliases:
- borgmatic
```
Ensure that you change the `BORG_PASSPHRASE` to a secure passphrase of your choosing.
For security reasons we mount the maildir as read-only. If you later want to restore data you will need to remove
the `ro` flag prior to restoring the data. This is described in the section on restoring backups.
### Create `data/conf/borgmatic/etc/config.yaml`
Next, we need to create the borgmatic configuration.
```shell
source mailcow.conf
cat <<EOF > data/conf/borgmatic/etc/config.yaml
location:
source_directories:
- /mnt/source
repositories:
- user@rsync.net:mailcow
remote_path: borg1
retention:
keep_hourly: 24
keep_daily: 7
keep_weekly: 4
keep_monthly: 6
hooks:
mysql_databases:
- name: ${DBNAME}
username: ${DBUSER}
password: ${DBPASS}
options: --default-character-set=utf8mb4
EOF
```
Creating the file in this way ensures the correct MySQL credentials are pulled in from `mailcow.conf`.
This file is a minimal example for using borgmatic with an account `user` on the cloud storage provider `rsync.net` for
a repository called `mailcow` (see `repositories` setting). It will backup both the maildir and MySQL database, which is
all you should need to restore your mailcow setup after an incident. The retention settings will keep one archive for
each hour of the past 24 hours, one per day of the week, one per week of the month and one per month of the past half
year.
Check the [borgmatic documentation](https://torsion.org/borgmatic/) on how to use other types of repositories or
configuration options. If you choose to use a local filesystem as a backup destination make sure to mount it into the
container. The container defines a volume called `/mnt/borg-repository` for this purpose.
!!! note
If you do not use rsync.net you can most likely drop the `remote_path` element from your config.
### Create a crontab
Create a new text file in `data/conf/borgmatic/etc/crontab.txt` with the following content:
```
14 * * * * PATH=$PATH:/usr/bin /usr/bin/borgmatic --stats -v 0 2>&1
```
This file expects crontab syntax. The example shown here will trigger the backup to run every hour at 14 minutes past
the hour and log some nice stats at the end.
### Place SSH keys in folder
Place the SSH keys you intend to use for remote repository connections in `data/conf/borgmatic/ssh`. OpenSSH expects the
usual `id_rsa`, `id_ed25519` or similar to be in this directory. Ensure the file is `chmod 600` and not world readable
or OpenSSH will refuse to use the SSH key.
### Bring up the container
For the next step we need the container to be up and running in a configured state. To do that run:
```shell
docker-compose up -d
```
### Initialize the repository
By now your borgmatic container is up and running, but the backups will currently fail due to the repository not being
initialized.
To initialize the repository run:
```shell
docker-compose exec borgmatic-mailcow borgmatic init --encryption repokey-blake2
```
You will be asked you to authenticate the SSH host key of your remote repository server. See if it matches and confirm
the prompt by entering `yes`. The repository will be initialized with the passphrase you set in the `BORG_PASSPHRASE`
environment variable earlier.
When using any of the `repokey` encryption methods the encryption key will be stored in the repository itself and not on
the client, so there is no further action required in this regard. If you decide to use a `keyfile` instead of
a `repokey` make sure you export the key and back it up separately. Check the [Exporting Keys](#exporting-keys) section
for how to retrieve the key.
### Restart container
Now that we finished configuring and initializing the repository restart the container to ensure it is in a defined
state:
```shell
docker-compose restart borgmatic-mailcow
```
## Restoring from a backup
Restoring a backup assumes you are starting off with a fresh installation of mailcow, and you currently do not have
any custom data in your maildir or your mailcow database.
### Restore maildir
!!! warning
Doing this will overwrite files in your maildir! Do not run this unless you actually intend to recover mail
files from a backup.
!!! note "If you use SELinux in Enforcing mode"
If you are using mailcow on a host with SELinux in Enforcing mode you will have to temporarily disable it during
extraction of the archive as the mailcow setup labels the vmail volume as private, belonging to the dovecot container
exclusively. SELinux will (rightfully) prevent any other container, such as the borgmatic container, from writing to
this volume.
Before running a restore you must make the vmail volume writeable in `docker-compose.override.yml` by removing
the `ro` flag from the volume.
Then you can use the following command to restore the maildir from a backup:
```shell
docker-compose exec borgmatic-mailcow borgmatic extract --path mnt/source --archive latest
```
Alternatively you can specify any archive name from the list of archives (see
[Listing all available archives](#listing-all-available-archives))
### Restore MySQL
!!! warning
Running this command will delete and recreate the mailcow database! Do not run this unless you actually
intend to recover the mailcow database from a backup.
To restore the MySQL database from the latest archive use this command:
```shell
docker-compose exec borgmatic-mailcow borgmatic restore --archive latest
```
Alternatively you can specify any archive name from the list of archives (see
[Listing all available archives](#listing-all-available-archives))
### After restoring
After restoring you need to restart mailcow. If you disabled SELinux enforcing mode now would be a good time to
re-enable it.
To restart mailcow use the follwing command:
```shell
docker-compose down && docker-compose up -d
```
If you use SELinux this will also trigger the re-labeling of all files in your vmail volume. Be patient, as this may
take a while if you have lots of files.
## Useful commands
### Manual archiving run (with debugging output)
```shell
docker-compose exec borgmatic-mailcow borgmatic -v 2
```
### Listing all available archives
```shell
docker-compose exec borgmatic-mailcow borgmatic list
```
### Break lock
When borg is interrupted during an archiving run it will leave behind a stale lock that needs to be cleared before any
new operations can be performed:
```shell
docker-compose exec borgmatic-mailcow borg break-lock user@rsync.net:mailcow
```
Where `user@rsync.net:mailcow` is the URI to your repository.
Now would be a good time to do a manual archiving run to ensure it can be successfully performed.
### Exporting keys
When using any of the `keyfile` methods for encryption you **MUST** take care of backing up the key files yourself. The
key files are generated when you initialize the repository. The `repokey` methods store the key file within the
repository, so a manual backup isn't as essential.
Note that in either case you also must have the passphrase to decrypt any archives.
To fetch the keyfile run:
```shell
docker-compose exec borgmatic-mailcow borg key export --paper user@rsync.net:mailcow
```
Where `user@rsync.net:mailcow` is the URI to your repository.

Datei anzeigen

@ -0,0 +1,42 @@
Using Microsoft Exchange in a hybrid setup is possible with mailcow. With this setup you can add mailboxes on your mailcow and still use [Exchange Online Protection](https://docs.microsoft.com/microsoft-365/security/office-365-security/exchange-online-protection-overview?view=o365-worldwide).
**All mailboxes setup in Exchange will receive their mails as usual**, while with the hybrid approach additional Mailboxes can be setup in mailcow without any further configuration.
This setup becomes very handy if you have enabled the [Office 365 security defaults](https://docs.microsoft.com/azure/active-directory/fundamentals/concept-fundamentals-security-defaults) and third party applications can no longer login into your mailboxes by any of the [supported methods](https://docs.microsoft.com/exchange/mail-flow-best-practices/how-to-set-up-a-multifunction-device-or-application-to-send-email-using-microsoft-365-or-office-365).
## Requirements
- The mx Record of your domain needs to point at the Exchange mail service. Log into your Admin center and look out for the dns settings of your domain to find your personalized gateway domain. It should look like this `contoso-com.mail.protection.outlook.com`. Contact your domain registrant to get further information on how to change mx record.
- The domain you want to have additional mailboxes for must be setup as `internal relay domain` in Exchange.
1. Log in to your [Exchange Admin Center](https://admin.exchange.microsoft.com)
2. Select the `mail flow` pane and click on `accepted domains`
3. Select the domain and switch it from `authorative` to `internal relay`
## Set up the mailcow
Your mailcow needs to relay all mails to your personalized Exchange Host. It is the same host address we already looked up for the mx Record.
1. Add the domain to your mailcow
2. [Add your personalized Exchange Host address as relayhost](/firststeps-relayhost)
3. Add your personalized Exchange Host address as forwarding host to unconditionally accepted all relayed mails from Exchange. (Admin > Configuration & Details > Configuration Dropdown > Forwarding Hosts)
4. Go to the domain settings and select the newly added host on the `Sender-dependent transports` dropdown. Enable relaying by ticking the `Relay this domain`, `Relay all recipients` and the `Relay non-existing mailboxes only.` checkboxes
!!! info
From now on your mailcow will accept all mails relayed from Exchange. The **inbound filtering and so the neural learning of your cow will no longer work**. Because all mails are routed through Exchange the [filtering process is handled there](https://docs.microsoft.com/exchange/antispam-and-antimalware/antispam-and-antimalware?view=exchserver-2019).
## Set up Connectors in Exchange
All mail traffic now goes through Exchange. At this point the Exchange Online Protection already filters all incoming and outgoing mails. Now we need to set up two connectors to relay incoming mails from our Exchange Service to the mailcow and another one to allow mails relayed from the mailcow to our exchange service. You can follow the [official guide from Microsoft](https://docs.microsoft.com/exchange/mail-flow-best-practices/use-connectors-to-configure-mail-flow/set-up-connectors-to-route-mail#2-set-up-a-connector-from-microsoft-365-or-office-365-to-your-email-server).
!!! warning
For the connector that handles mails from your mailcow to Exchange Microsoft offers two ways of authenticating it. The recommended way is to use a tls certificate configured with a subject name that matches an accepted domain in Exchange. Otherwise you need to choose authentication with the static ip address of your mailcow.
## Validating
The easiest way to validate the hybrid setup is by sending a mail from the internet to a mailbox that only exists on the mailcow and vice versa.
### Common Issues
- The connector validation from Exchange to your mailcow failed with `550 5.1.10 RESOLVER.ADR.RecipientNotFound; Recipient test@contoso.com not found by SMTP address lookup`
**Possible Solution:** Your domain is not set up as `internal relay`. Exchange therefore cannot find the recipient
- Mails sent from the mailcow to a mailbox in the internet cannot be sent. Non Delivery Report with error `550 5.7.64 TenantAttribution; Relay Access Denied`
**Possible Solution:** The authentication method failed. Make sure the certificate subject matches an accepted domain in Exchange. Try authenticating by static ip instead.
Microsoft Guide for the connector setup and additional requirements: https://docs.microsoft.com/exchange/mail-flow-best-practices/use-connectors-to-configure-mail-flow/set-up-connectors-to-route-mail#prerequisites-for-your-on-premises-email-environment

Datei anzeigen

@ -33,11 +33,13 @@ GITEA_SSH_PORT=127.0.0.1:4000
5\. Run `docker-compose up -d` to bring up the gitea container and run `docker-compose restart nginx-mailcow` afterwards.
6\. Open `http://${MAILCOW_HOSTNAME}/gitea/`, for example `http://mx.example.org/gitea/`. For database details set `mysql` as database host. Use the value of DBNAME found in mailcow.conf as database name, DBUSER as database user and DBPASS as database password.
6\. If you forced mailcow to https, execute step 9 and restart gitea with `docker-compose restart gitea-mailcow` . Go head with step 7 (Remember to use https instead of http, `https://mx.example.org/gitea/`
7\. Once the installation is complete, login as admin and set "settings" -> "authorization" -> "enable SMTP". SMTP Host should be `postfix` with port `587`, set `Skip TLS Verify` as we are using an unlisted SAN ("postfix" is most likely not part of your certificate).
7\. Open `http://${MAILCOW_HOSTNAME}/gitea/`, for example `http://mx.example.org/gitea/`. For database details set `mysql` as database host. Use the value of DBNAME found in mailcow.conf as database name, DBUSER as database user and DBPASS as database password.
8\. Create `data/gitea/gitea/conf/app.ini` and set following values. You can consult [gitea cheat sheet](https://docs.gitea.io/en-us/config-cheat-sheet/) for their meaning and other possible values.
8\. Once the installation is complete, login as admin and set "settings" -> "authorization" -> "enable SMTP". SMTP Host should be `postfix` with port `587`, set `Skip TLS Verify` as we are using an unlisted SAN ("postfix" is most likely not part of your certificate).
9\. Create `data/gitea/gitea/conf/app.ini` and set following values. You can consult [gitea cheat sheet](https://docs.gitea.io/en-us/config-cheat-sheet/) for their meaning and other possible values.
```
[server]
@ -49,4 +51,4 @@ SSH_PORT = 4000
ROOT_URL = https://mx.example.org/gitea/
```
9\. Restart gitea with `docker-compose restart gitea-mailcow`. Your users should be able to login with mailcow managed accounts.
10\. Restart gitea with `docker-compose restart gitea-mailcow`. Your users should be able to login with mailcow managed accounts.

Datei anzeigen

@ -2,6 +2,9 @@ This is a simple integration of mailcow aliases and the mailbox name into mailpi
**Disclaimer**: This is not officially maintained nor supported by the mailcow project nor its contributors. No warranty or support is being provided, however you're free to open issues on GitHub for filing a bug or provide further ideas. [GitHub repo can be found here](https://github.com/patschi/mailpiler-mailcow-integration).
!!! info
Support for domain wildcards were implemented in Piler 1.3.10 which was released on 03.01.2021. Prior versions basically do work, but after logging in you won't see emails sent from or to the domain alias. (e.g. when @example.com is an alias for admin@example.com)
## The problem to solve
mailpiler offers the authentication based on IMAP, for example:
@ -30,7 +33,7 @@ Note: File paths might vary depending on your setup.
### Requirements
- A working mailcow instance
- A working mailpiler instance ([You can find an installation guide here](https://patrik.kernstock.net/2020/08/mailpiler-installation-guide/))
- A working mailpiler instance ([You can find an installation guide here](https://patrik.kernstock.net/2020/08/mailpiler-installation-guide/), [check supported versions here](https://github.com/patschi/mailpiler-mailcow-integration#piler))
- An mailcow API key (read-only works just fine): `Configuration & Details - Access - Read-Only Access`. Don't forget to allow API access from your mailpiler IP.
!!! warning

Datei anzeigen

@ -1,58 +1,105 @@
NextCloud can be set up with the [helper script](https://github.com/mailcow/mailcow-dockerized/raw/master/helper-scripts/nextcloud.sh) included with mailcow. You can also set up NextCloud on a different server and still use mailcow for authentication.
In the following, we will only assume that you have already set up NextCloud at _cloud.example.com_ and that your mailcow is running at _mail.example.com_.
To set up authentication via mailcow, you can use OAuth2 as described below.
## Manage Nextcloud using the helper script
1. Log into mailcow as administrator.
2. Scroll down to _OAuth2 Apps_ and click the _Add_ button. Specify the redirect URI as `https://cloud.example.com/index.php/apps/sociallogin/custom_oauth2/Mailcow` and click _Add_. Save the client ID and secret for later.
Nextcloud can be set up (parameter `-i`) and removed (parameter `-p`) with the [helper script](https://github.com/mailcow/mailcow-dockerized/raw/master/helper-scripts/nextcloud.sh) included with mailcow. In order to install Nextcloud simply navigate to your mailcow-dockerized root folder and run the helper script as follows:
`./helper-scripts/nextcloud.sh -i`
In case you have forgotten the password (e.g. for admin) and can't request a new one [via the password reset link on the login screen](https://docs.nextcloud.com/server/20/admin_manual/configuration_user/reset_admin_password.html?highlight=reset) calling the helper script with `-r` as parameter allows you to set a new password. Only use this option if your Nextcloud isn't configured to use mailcow for authentication as described in the next section.
## Configure Nextcloud to use mailcow for authentication
The following describes how set up authentication via mailcow using the OAuth2 protocol. We will only assume that you have already set up Nextcloud at _cloud.example.com_ and that your mailcow is running at _mail.example.com_. It does not matter if your Nextcloud is running on a different server, you can still use mailcow for authentication.
1\. Log into mailcow as administrator.
2\. Scroll down to _OAuth2 Apps_ and click the _Add_ button. Specify the redirect URI as `https://cloud.example.com/index.php/apps/sociallogin/custom_oauth2/Mailcow` and click _Add_. Save the client ID and secret for later.
!!! info
Some installations, including those setup using the helper script of mailcow, need to remove index.php/ from the URL to get a successful redirect: `https://cloud.example.com/apps/sociallogin/custom_oauth2/Mailcow`
3. Log into NextCloud as administrator.
4. Click the button in the top right corner and select _Apps_. Click the search button in the toolbar, search for the [_Social Login_](https://apps.nextcloud.com/apps/sociallogin) plugin and click _Download and enable_ next to it.
5. Click the button in the top right corner and select _Settings_. Scroll down to the _Administration_ section on the left and click _Social login_.
6. Uncheck the following items:
- _Disable auto create new users_,
- _Allow users to connect social logins with their accounts_,
- _Do not prune not available user groups on login_,
- _Automatically create groups if they do not exists_,
- _Restrict login for users without mapped groups_,
3\. Log into Nextcloud as administrator.
and check the following items:
- _Prevent creating an account if the email address exists in another account_,
- _Update user profile every login_,
- _Disable notify admins about new users_.
4\. Click the button in the top right corner and select _Apps_. Click the search button in the toolbar, search for the [_Social Login_](https://apps.nextcloud.com/apps/sociallogin) plugin and click _Download and enable_ next to it.
Click the _Save_ button.
5\. Click the button in the top right corner and select _Settings_. Scroll down to the _Administration_ section on the left and click _Social login_.
7. Scroll down to _Custom OAuth2_ and click the _+_ button.
8. Configure the parameters as follows:
- Internal name: `Mailcow`
- Title: `Mailcow`
- API Base URL: `https://mail.example.com`
- Authorize URL: `https://mail.example.com/oauth/authorize`
- Token URL: `https://mail.example.com/oauth/token`
- Profile URL: `https://mail.example.com/oauth/profile`
- Logout URL: (leave blank)
- Client ID: (what you obtained in step 1)
- Client Secret: (what you obtained in step 1)
- Scope: `profile`
6\. Uncheck the following items:
- "Disable auto create new users"
- "Allow users to connect social logins with their accounts"
- "Do not prune not available user groups on login"
- "Automatically create groups if they do not exists"
- "Restrict login for users without mapped groups"
7\. Check the following items:
- "Prevent creating an account if the email address exists in another account"
- "Update user profile every login"
- "Disable notify admins about new users"
Click the _Save_ button.
8\. Scroll down to _Custom OAuth2_ and click the _+_ button.
9\. Configure the parameters as follows:
- Internal name: `Mailcow`
- Title: `Mailcow`
- API Base URL: `https://mail.example.com`
- Authorize URL: `https://mail.example.com/oauth/authorize`
- Token URL: `https://mail.example.com/oauth/token`
- Profile URL: `https://mail.example.com/oauth/profile`
- Logout URL: (leave blank)
- Client ID: (what you obtained in step 1)
- Client Secret: (what you obtained in step 1)
- Scope: `profile`
Click the _Save_ button at the very bottom of the page.
If you have previously used NextCloud with mailcow authentication via user\_external/IMAP, you need to perform some additional steps to link your existing user accounts with OAuth2.
---
1. Click the button in the top right corner and select _Apps_. Scroll down to the _External user authentication_ app and click _Remove_ next to it.
2. Run the following queries in your Nextcloud database (if you set up Nextcloud using mailcow's script, you can run `source mailcow.conf && docker-compose exec mysql-mailcow mysql -u$DBUSER -p$DBPASS $DBNAME`):
If you have previously used Nextcloud with mailcow authentication via user\_external/IMAP, you need to perform some additional steps to link your existing user accounts with OAuth2.
1\. Click the button in the top right corner and select _Apps_. Scroll down to the _External user authentication_ app and click _Remove_ next to it.
2\. Run the following queries in your Nextcloud database (if you set up Nextcloud using mailcow's script, you can run `source mailcow.conf && docker-compose exec mysql-mailcow mysql -u$DBUSER -p$DBPASS $DBNAME`):
```
INSERT INTO nc_users (uid, uid_lower) SELECT DISTINCT uid, LOWER(uid) FROM nc_users_external;
INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users_external;
```
If you have previously used NextCloud without mailcow authentication, but with the same usernames as mailcow, you can also link your existing user accounts with OAuth2.
---
1. Run the following queries in your Nextcloud database (if you set up Nextcloud using mailcow's script, you can run `source mailcow.conf && docker-compose exec mysql-mailcow mysql -u$DBUSER -p$DBPASS $DBNAME`):
If you have previously used Nextcloud without mailcow authentication, but with the same usernames as mailcow, you can also link your existing user accounts with OAuth2.
1\. Run the following queries in your Nextcloud database (if you set up Nextcloud using mailcow's script, you can run `source mailcow.conf && docker-compose exec mysql-mailcow mysql -u$DBUSER -p$DBPASS $DBNAME`):
```
INSERT INTO nc_sociallogin_connect (uid, identifier) SELECT DISTINCT uid, CONCAT("Mailcow-", uid) FROM nc_users;
```
---
## Update
The Nextcloud instance can be updated easily with the web update mechanism. In the case of larger updates, there may be further changes to be made after the update. After the Nextcloud instance has been checked, problems are shown. This can be e.g. missing indices in the DB or similar.
It shows which commands have to be executed, these have to be placed in the php-fpm-mailcow container.
As an an example run the following command to add the missing indices.
`docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) bash -c "php /web/nextcloud/occ db:add-missing-indices"`
---
## Debugging & Troubleshooting
It may happen that you cannot reach the Nextcloud instance from your network. This may be due to the fact that the entry of your subnet in the array 'trusted_proxies' is missing. You can make changes in the Nextcloud config.php in `data/web/nextcloud/config/*`.
```
'trusted_proxies' =>
array (
0 => 'fd4d:6169:6c63:6f77::/64',
1 => '172.22.1.0/24',
2 => 'NewSubnet/24',
),
```
After the changes have been made, the nginx container must be restarted.
`docker-compose restart nginx-mailcow`

Datei anzeigen

@ -5,7 +5,7 @@ In order to enable Portainer, the docker-compose.yml and site.conf for Nginx mus
version: '2.1'
services:
portainer-mailcow:
image: portainer/portainer
image: portainer/portainer-ce
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data/conf/portainer:/data

Datei anzeigen

@ -1,10 +1,10 @@
Download Roundcube 1.4.x to the web htdocs directory and extract it (here `rc/`):
Download Roundcube 1.5.x to the web htdocs directory and extract it (here `rc/`):
```
# Check for a newer release!
cd data/web
wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.4.8/roundcubemail-1.4.8-complete.tar.gz | tar xfvz -
wget -O - https://github.com/roundcube/roundcubemail/releases/download/1.5-rc/roundcubemail-1.5-rc-complete.tar.gz | tar xfvz -
# Change folder name
mv roundcubemail-1.4.8 rc
mv roundcubemail-1.5-rc rc
# Change permissions
chown -R root: rc/
```
@ -102,10 +102,10 @@ $config['password_query'] = "UPDATE mailbox SET password = %P WHERE username = %
### Integrate CardDAV addressbooks in Roundcube
Download the latest release of [RCMCardDAV](https://github.com/blind-coder/rcmcarddav/) to the Roundcube plugin directory and extract it (here `rc/plugins`):
Download the latest release of [RCMCardDAV](https://github.com/mstilkerich/rcmcarddav) to the Roundcube plugin directory and extract it (here `rc/plugins`):
```
cd data/web/rc/plugins
wget -O - https://github.com/blind-coder/rcmcarddav/releases/download/v3.0.3/carddav-3.0.3.tar.bz2 | tar xfvj -
wget -O - https://github.com/mstilkerich/rcmcarddav/releases/download/v4.1.2/carddav-v4.1.2.tar.gz | tar xfvz -
chown -R root: carddav/
```

Datei anzeigen

@ -24,5 +24,5 @@ echo example.com example.org | ./build-plugins.sh mailcow.example.com
# Install it in Thunderbird
After you have set up your mailcow IMAP account in Thunderbird, download the SOGo Connector plugin for your domain, e.g. https://mailcow.example.com/thunderbird-plugins/sogo-connector-68.0.0-example.com.xpi, and install it into Thunderbird.
After you have set up your mailcow IMAP account in Thunderbird, download the SOGo Connector plugin for your domain, e.g. https://mailcow.example.com/thunderbird-plugins/sogo-connector-68.0.1-example.com.xpi (see `data/web/thunderbird-plugins`), and install it into Thunderbird.
All your address books and calendars will be configured automatically.

Datei anzeigen

@ -2,7 +2,7 @@ Since February the 28th 2017 mailcow does come with port 80 and 443 enabled.
**Do not use the config below for reverse proxy setups**, please see our reverse proxy guide for this, which includes a redirect from HTTP to HTTPS.
Open `mailcow.conf` and set `HTTP_BIND=0.0.0.0` - if not already set.
Open `mailcow.conf` and set `HTTP_BIND=` - if not already set.
Create a new file `data/conf/nginx/redirect.conf` and add the following server config to the file:

Datei anzeigen

@ -1,68 +0,0 @@
The most important configuration files are mounted from the host into the related containers:
```
data/conf
├── unbound
│   └── unbound.conf
├── dovecot
│   ├── dovecot.conf
│   ├── dovecot-master.passwd
│   ├── sieve_after
│   └── sql
│   ├── dovecot-dict-sql.conf
│   └── dovecot-mysql.conf
├── mysql
│   └── my.cnf
├── nginx
│   ├── dynmaps.conf
│   ├── site.conf
│   └── templates
│   ├── listen_plain.template
│   ├── listen_ssl.template
│   └── server_name.template
├── postfix
│   ├── main.cf
│   ├── master.cf
│   ├── postscreen_access.cidr
│   ├── smtp_dsn_filter
│   └── sql
│   ├── mysql_relay_recipient_maps.cf
│   ├── mysql_tls_enforce_in_policy.cf
│   ├── mysql_tls_enforce_out_policy.cf
│   ├── mysql_virtual_alias_domain_catchall_maps.cf
│   ├── mysql_virtual_alias_domain_maps.cf
│   ├── mysql_virtual_alias_maps.cf
│   ├── mysql_virtual_domains_maps.cf
│   ├── mysql_virtual_mailbox_maps.cf
│   ├── mysql_virtual_relay_domain_maps.cf
│   ├── mysql_virtual_sender_acl.cf
│   └── mysql_virtual_spamalias_maps.cf
├── rspamd
│   ├── dynmaps
│   │   ├── authoritative.php
│   │   ├── settings.php
│   │   ├── tags.php
│   │   └── vars.inc.php -> ../../../web/inc/vars.inc.php
│   ├── local.d
│   │   ├── dkim.conf
│   │   ├── metrics.conf
│   │   ├── options.inc
│   │   ├── redis.conf
│   │   ├── rspamd.conf.local
│   │   └── statistic.conf
│   ├── lua
│   │   └── rspamd.local.lua
│   └── override.d
│   ├── logging.inc
│   ├── worker-controller.inc
│   └── worker-normal.inc
└── sogo
├── sieve.creds
└── sogo.conf
```
Just change the according configuration file on the host and restart the related service:
```
docker-compose restart service-mailcow
```

Datei anzeigen

@ -16,6 +16,12 @@ Delete **all** user's mails in the junk folder that are **older** than 7 days
docker-compose exec dovecot-mailcow doveadm expunge -A mailbox 'Junk' savedbefore 7d
```
Delete **all** mails (of all users) in **all** folders that are **older** than 52 weeks (internal date of the mail, not the date it was saved on the system => `before` instead of `savedbefore`). Useful for deleting very old mails on all users and folders (thus especially useful for GDPR-compliance).
```
docker-compose exec dovecot-mailcow doveadm expunge -A mailbox % before 52w
```
Delete mails inside a custom folder **inside** a user's inbox that are **not** flagged and **older** than 2 weeks
```
@ -25,7 +31,9 @@ docker-compose exec dovecot-mailcow doveadm expunge -u 'mailbox@example.com' mai
!!! info
For possible [time spans](https://wiki.dovecot.org/Tools/Doveadm/SearchQuery#section_date_specification) or [search keys](https://wiki.dovecot.org/Tools/Doveadm/SearchQuery#section_search_keys) have a look at [man doveadm-search-query](https://wiki.dovecot.org/Tools/Doveadm/SearchQuery)
## Make it automatic
## Job scheduler
### via the host system cron
If you want to automate such a task you can create a cron job on your host that calls a script like the one below:
@ -45,3 +53,41 @@ To create a cron job you may execute `crontab -e` and insert something like the
# Execute everyday at 04:00 A.M.
0 4 * * * /path/to/your/expunge_mailboxes.sh
```
### via Docker job scheduler
To archive this with a docker job scheduler use this docker-compose.override.yml with your mailcow:
```
version: '2.1'
services:
ofelia:
image: mcuadros/ofelia:latest
restart: always
command: daemon --docker
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
network_mode: none
dovecot-mailcow:
labels:
- "ofelia.enabled=true"
- "ofelia.job-exec.dovecot-expunge-trash.schedule=0 4 * * *"
- "ofelia.job-exec.dovecot-expunge-trash.command=doveadm expunge -A mailbox 'Junk' savedbefore 2w"
- "ofelia.job-exec.dovecot-expunge-trash.tty=false"
```
The job controller just need access to the docker control socket to be able to emulate the behavior of "exec". Then we add a few label to our dovecot-container to activate the job scheduler and tell him in a cron compatible scheduling format when to run. If you struggle with that schedule string you can use [crontab guru](https://crontab.guru/).
This docker-compose.override.yml deletes all mails older then 2 weeks from the "Junk" folder every day at 4 am. To see if things ran proper, you can not only see in your mailbox but also check Ofelia's docker log if it looks something like this:
```
common.go:124 ▶ NOTICE [Job "dovecot-expunge-trash" (8759567efa66)] Started - doveadm expunge -A mailbox 'Junk' savedbefore 2w,
common.go:124 ▶ NOTICE [Job "dovecot-expunge-trash" (8759567efa66)] Finished in "285.032291ms", failed: false, skipped: false, error: none,
```
If it failed it will say so and give you the output of the doveadm in the log to make it easy on you to debug.
In case you want to add more jobs, ensure you change the "dovecot-expunge-trash" part after "ofelia.job-exec." to something else, it defines the name of the job. Syntax of the labels you find at [mcuadros/ofelia](https://github.com/mcuadros/ofelia).

Datei anzeigen

@ -0,0 +1,21 @@
Random master usernames and passwords are automatically created on every restart of dovecot-mailcow.
**That's recommended and should not be changed.**
If you need the user to be static anyway, please specify two variables in `mailcow.conf`.
**Both** parameters must not be empty!
```
DOVECOT_MASTER_USER=mymasteruser
DOVECOT_MASTER_PASS=mysecretpass
```
Run `docker-compose up -d` to apply your changes.
The static master username will be expanded to `DOVECOT_MASTER_USER@mailcow.local`.
To login as `test@example.org` this would equal to `test@example.org*mymasteruser@mailcow.local` with the specified password above.
A login to SOGo is not possible with this username. A click-to-login function for SOGo is available for admins as described [here](https://mailcow.github.io/mailcow-dockerized-docs/debug-admin_login_sogo/)
No master user is required.

Datei anzeigen

@ -1,4 +1,22 @@
If you want to use another folder for the vmail-volume, you can create an `docker-compose.override.yml` file and add:
## The "new" way
**WARNING**: Newer Docker versions seem to complain about existing volumes. You can fix this temporarily by removing the existing volume and start mailcow with the override file. But it seems to be problematic after a reboot (needs to be confirmed).
An easy, dirty, yet stable workaround is to stop mailcow (`docker-compose down`), remove `/var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data` and create a new link to your remote filesystem location, for example:
```
mv /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data_backup
ln -s /mnt/volume-xy/vmail_data /var/lib/docker/volumes/mailcowdockerized_vmail-vol-1/_data
```
Start mailcow afterwards.
---
## The "old" way
If you want to use another folder for the vmail-volume, you can create a `docker-compose.override.yml` file and add the following content:
```
version: '2.1'
volumes:

15
docs/u_e-fido2.md Normale Datei
Datei anzeigen

@ -0,0 +1,15 @@
## How is UV handled in mailcow?
The UV flag (as in "user verification") enforces WebAuthn to verify the user before it allows access to the key (think of a PIN). We don't enforce UV to allow logins via iOS and NFC (YubiKey).
## Login and key processing
mailcow uses **client-side key processing**. We ask the authenticator (i.e. YubiKey) to save the registration in its memory.
A user does not need to enter a username. The available credentials - if any - will be shown to the user when selecting the "key login" via mailcow UI login.
When calling the login process, the authenticator is not given any credential IDs. This will force it to lookup credentials in its own memory.
## Who can use WebAuthn to login to mailcow?
As of today, only administrators and domain administrators are able to setup WebAuthn/FIDO2.

3
docs/u_e-mailcow_ui-css.md Normale Datei
Datei anzeigen

@ -0,0 +1,3 @@
For custom overrides of specific elements via CSS, use `data/web/css/build/0081-custom-mailcow.css`.
The file is excluded from tracking and persists over updates.

Datei anzeigen

@ -1,4 +1,4 @@
So far three methods for *Two-Factor Authentication* are implemented: U2F, Yubi OTP, and TOTP
So far three methods for _Two-Factor Authentication_ are implemented: U2F, Yubi OTP, and TOTP
- For U2F to work, you need an encrypted connection to the server (HTTPS) as well as a FIDO security key.
- Both U2F and Yubi OTP work well with the fantastic [Yubikey](https://www.yubico.com).
@ -19,8 +19,22 @@ The API ID, API key and the first 12 characters (your YubiKeys ID in modhex) are
### U2F
Only Google Chrome (+derivatives) and Opera support U2F authentication to this day natively.
Since version 67 Mozilla Firefox can handle U2F natively. ([Source](https://support.yubico.com/support/solutions/articles/15000017511-enabling-u2f-support-in-mozilla-firefox))
To use U2F, the browser must support this standard.
The following desktop browsers support this authentication type:
- Edge (>=79)
- Firefox (>=47, enabled by default since version 67)
- Chrome (>=41)
- Safari (>=13)
- Opera (40, >=42, not 41)
The following mobile browsers support this authentication type:
- Safari on iOS (>=13.3)
- Firefox on Android (>=68)
Sources: [caniuse.com](https://caniuse.com/u2f), [blog.mozilla.org](https://blog.mozilla.org/security/2019/08/05/web-authentication-in-firefox-for-android/)
U2F works without an internet connection.

Datei anzeigen

@ -1,25 +1,46 @@
## SSL
Please see [Advanced SSL](https://mailcow.github.io/mailcow-dockerized-docs/firststeps-ssl/) and explicitly check `ADDITIONAL_SERVER_NAMES` for SSL configuration.
Please do not add ADDITIONAL_SERVER_NAMES when you plan to use a different web root.
## New site
To create persistent (over updates) sites hosted by mailcow: dockerized, a new site configuration must be placed inside `data/conf/nginx/`:
A good template to begin with:
```
nano data/conf/nginx/my_custom_site.conf
```
A good template to begin with:
``` hl_lines="9"
``` hl_lines="16"
server {
ssl_certificate /etc/ssl/mail/cert.pem;
ssl_certificate_key /etc/ssl/mail/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_ecdh_curve X25519:X448:secp384r1:secp256k1;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
index index.php index.html;
client_max_body_size 0;
# Location: data/web
root /web;
# Location: data/web/mysite.com
#root /web/mysite.com
include /etc/nginx/conf.d/listen_plain.active;
include /etc/nginx/conf.d/listen_ssl.active;
server_name mysite.example.org;
server_tokens off;
# This allows acme to be validated even with a different web root
location ^~ /.well-known/acme-challenge/ {
allow all;
default_type "text/plain";
rewrite /.well-known/acme-challenge/(.*) /$1 break;
root /web/.well-known/acme-challenge/;
}
if ($scheme = http) {
@ -28,7 +49,56 @@ server {
}
```
The filename is not important, as long as the filename carries a .conf extension.
## New site with proxy to a remote location
Another example with a reverse proxy configuration:
```
nano data/conf/nginx/my_custom_site.conf
```
``` hl_lines="16 28"
server {
ssl_certificate /etc/ssl/mail/cert.pem;
ssl_certificate_key /etc/ssl/mail/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_ecdh_curve X25519:X448:secp384r1:secp256k1;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
index index.php index.html;
client_max_body_size 0;
root /web;
include /etc/nginx/conf.d/listen_plain.active;
include /etc/nginx/conf.d/listen_ssl.active;
server_name example.domain.tld;
server_tokens off;
location ^~ /.well-known/acme-challenge/ {
allow all;
default_type "text/plain";
}
if ($scheme = http) {
return 301 https://$host$request_uri;
}
location / {
proxy_pass http://service:3000/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 0;
}
}
```
## Config expansion in mailcows Nginx
The filename used for a new site is not important, as long as the filename carries a .conf extension.
It is also possible to extend the configuration of the default file `site.conf` file:
@ -36,7 +106,7 @@ It is also possible to extend the configuration of the default file `site.conf`
nano data/conf/nginx/site.my_content.custom
```
This filename does not need to have a ".conf" extension, but follows the pattern `site.*.custom`, where `*` is a custom name.
This filename does not need to have a ".conf" extension but follows the pattern `site.*.custom`, where `*` is a custom name.
If PHP is to be included in a custom site, please use the PHP-FPM listener on phpfpm:9002 or create a new listener in `data/conf/phpfpm/php-fpm.d/pools.conf`.
@ -46,3 +116,4 @@ Restart Nginx (and PHP-FPM, if a new listener was created):
docker-compose restart nginx-mailcow
docker-compose restart php-fpm-mailcow
```

Datei anzeigen

@ -1,3 +1,20 @@
IPs can be removed from Postscreen and therefore _also_ from RBL checks in `data/conf/postfix/custom_postscreen_whitelist.cidr`.
Postscreen does multiple checks to identify malicious senders. In most cases you want to whitelist an IP to exclude it from blacklist lookups.
The format of the file is as follows:
`CIDR ACTION`
Where CIDR is a single IP address or IP range in CIDR notation, and action is either "permit" or "reject".
Example:
```
# Rules are evaluated in the order as specified.
# Blacklist 192.168.* except 192.168.0.1.
192.168.0.1 permit
192.168.0.0/16 reject
```
The file is reloaded on the fly, postfix restart is not required.

Datei anzeigen

@ -3,12 +3,14 @@ Rspamd is used for AV handling, DKIM signing and SPAM handling. It's a powerful
## Learn Spam & Ham
Rspamd learns mail as spam or ham when you move a message in or out of the junk folder to any mailbox besides trash.
This is achieved by using the Dovecot plugin "antispam" and a simple parser script.
This is achieved by using the Sieve plugin "sieve_imapsieve" and parser scripts.
Rspamd also auto-learns mail when a high or low score is detected (see https://rspamd.com/doc/configuration/statistic.html#autolearning)
Rspamd also auto-learns mail when a high or low score is detected (see https://rspamd.com/doc/configuration/statistic.html#autolearning). We configured the plugin to keep a sane ratio between spam and ham learns.
The bayes statistics are written to Redis as keys `BAYES_HAM` and `BAYES_SPAM`.
Besides bayes, a local fuzzy storage is used to learn recurring patterns in text or images that indicate ham or spam.
You can also use Rspamd's web UI to learn ham and / or spam or to adjust certain settings of Rspamd.
### Learn Spam or Ham from existing directory
@ -128,20 +130,20 @@ reject_message = "My custom reject message";
Save the file and restart Rspamd: `docker-compose restart rspamd-mailcow`.
While the above works for rejected mails with a high spam score, global maps (as found in "Global filter maps" in /admin) will ignore this setting. For these maps, the multimap module in Rspamd needs to be adjusted:
While the above works for rejected mails with a high spam score, prefilter reject actions will ignore this setting. For these maps, the multimap module in Rspamd needs to be adjusted:
1. Open `{mailcow-dir}/data/conf/rspamd/local.d/multimap.conf` and find the desired map symbol (e.g. `GLOBAL_SMTP_FROM_BL`).
1. Find prefilet reject symbol for which you want change message, to do it run: `grep -R "SYMBOL_YOU_WANT_TO_ADJUST" /opt/mailcow-dockerized/data/conf/rspamd/`
2. Add your custom message as new line:
```
GLOBAL_SMTP_FROM_BL {
type = "from";
message = "Your domain is blacklisted, contact postmaster@your.domain to resolve this case.";`
map = "$LOCAL_CONFDIR/custom/global_smtp_from_blacklist.map";
GLOBAL_RCPT_BL {
type = "rcpt";
map = "${LOCAL_CONFDIR}/custom/global_rcpt_blacklist.map";
regexp = true;
prefilter = true;
action = "reject";
message = "Sending mail to this recipient is prohibited by postmaster@your.domain";
}
```
@ -210,3 +212,31 @@ Restart Rspamd:
```bash
docker-compose exec redis-mailcow sh
```
## Trigger a resend of quarantine notifications
Should be used for debugging only!
```
docker-compose exec dovecot-mailcow bash
mysql -umailcow -p$DBPASS mailcow -e "update quarantine set notified = 0;"
redis-cli -h redis DEL Q_LAST_NOTIFIED
quarantine_notify.py
```
## Increase history retention
By default Rspamd keeps 1000 elements in the history.
The history is stored compressed.
It is recommended not to use a disproportionate high value here, try something along 5000 or 10000 and see how your server handles it:
Edit `data/conf/rspamd/local.d/history_redis.conf`:
```
nrows = 1000; # change this value
```
Restart Rspamd afterwards: `docker-compose restart rspamd-mailcow`

Datei anzeigen

@ -1,11 +1,49 @@
SOGo is used for accessing your mails via a webbrowser, adding and sharing your contacts or calendars. For a more in-depth documentation on SOGo please visit its [own documentation](http://wiki.sogo.nu/).
## Change Theme
As of December 21 2018 we removed our custom themes due to complains about missing colors in some address book and calendar sections. Some other problems were still existing and would not be fixed in the near future (switching colors on login screen, for example).
## Apply custom SOGo theme
mailcow builds after 28 January 2021 can change SOGo's theme by editing `data/conf/sogo/custom-theme.js`.
Please check the AngularJS Material [intro](https://material.angularjs.org/latest/Theming/01_introduction) and [documentation](https://material.angularjs.org/latest/Theming/03_configuring_a_theme) as well as the [material style guideline](https://material.io/archive/guidelines/style/color.html#color-color-palette) to learn how this works.
## Change Logo
mailcow builds after 21 December 2018 can change SOGo's logo by replacing `data/conf/sogo/sogo-full.svg`.
You can use the provided `custom-theme.js` as an example starting point by removing the comments.
After you modified `data/conf/sogo/custom-theme.js` and made changes to your new SOGo theme you need to
* edit `data/conf/sogo/sogo.conf` and append/set `SOGoUIxDebugEnabled = YES;`
* restart SOGo and Memcached containers by executing `docker-compose restart memcached-mailcow sogo-mailcow`.
## Reset to SOGo default theme
Checkout `data/conf/sogo/custom-theme.js` by executing `git fetch ; git checkout origin/master data/conf/sogo/custom-theme.js data/conf/sogo/custom-theme.js`
Find in `data/conf/sogo/custom-theme.js`:
```
// Apply new palettes to the default theme, remap some of the hues
$mdThemingProvider.theme('default')
.primaryPalette('green-cow', {
'default': '400', // background color of top toolbars
'hue-1': '400',
'hue-2': '600', // background color of sidebar toolbar
'hue-3': 'A700'
})
.accentPalette('green', {
'default': '600', // background color of fab buttons and login screen
'hue-1': '300', // background color of center list toolbar
'hue-2': '300', // highlight color for selected mail and current day calendar
'hue-3': 'A700'
})
.backgroundPalette('frost-grey');
```
and replace with:
```
$mdThemingProvider.theme('default');
```
## Change favicon
mailcow builds after 31 January 2021 can change SOGo's favicon by replacing `data/conf/sogo/custom-favicon.ico` for SOGo and `data/web/favicon.png` for mailcow UI.
**Note**: You can use `.png` favicons for SOGo by renaming them to `custom-favicon.ico`.
For both SOGo and mailcow UI favicons you need use one of the standard dimensions: 16x16, 32x32, 64x64, 128x128 and 256x256.
After you replaced said file you need to restart SOGo and Memcached containers by executing `docker-compose restart memcached-mailcow sogo-mailcow`.
## Change logo
mailcow builds after 21 December 2018 can change SOGo's logo by replacing or creating (if missing) `data/conf/sogo/sogo-full.svg`.
After you replaced said file you need to restart SOGo and Memcached containers by executing `docker-compose restart memcached-mailcow sogo-mailcow`.
## Connect domains
@ -34,5 +72,5 @@ Restart SOGo: `docker-compose restart sogo-mailcow`
Edit `data/conf/sogo/sogo.conf` and **change** `SOGoPasswordChangeEnabled` to `NO`. Please do not add a new parameter.
Run `docker-compose restart sogo-mailcow memcached-mailcow` to activate the changes.
Run `docker-compose restart memcached-mailcow sogo-mailcow` to activate the changes.

Datei anzeigen

@ -11,8 +11,8 @@ Edit `data/conf/unbound/unbound.conf` and append the following parameters:
```
forward-zone:
name: "."
forward-addr: 8.8.8.8 # NO NOT USE PUBLIC DNS SERVERS - JUST AN EXAMPLE
forward-addr: 8.8.4.4 # NO NOT USE PUBLIC DNS SERVERS - JUST AN EXAMPLE
forward-addr: 8.8.8.8 # DO NOT USE PUBLIC DNS SERVERS - JUST AN EXAMPLE
forward-addr: 8.8.4.4 # DO NOT USE PUBLIC DNS SERVERS - JUST AN EXAMPLE
```
Restart Unbound:

10
docs/u_e-update-hooks.md Normale Datei
Datei anzeigen

@ -0,0 +1,10 @@
It is possible to add pre- and post-update-hooks to the `update.sh` script that upgrades your whole mailcow installation.
To do so, just add the corresponding bash script into your mailcows root directory:
* `pre_update_hook.sh` for commands that should run before the update
* `post_uddate_hook.sh` for commands that should run after the update is completed
Keep in mind that `pre_update_hook.sh` runs every time you call `update.sh` and `post_update_hook.sh` will only run if the update was successful and the script doesn't have to be re-run.
The scripts will be run by bash, an interpreter (e.g. `#!/bin/bash`) as well as an execute permission flag ("+x") are not required.

Datei anzeigen

@ -1,4 +1,4 @@
**Edit**: TODO: This guide only applies to non SNI enabled configurations. The certificate path needs to be adjusted if SNI is enabled. Something like `ssl_certificate,key /etc/ssl/mail/webmail.example.org/cert.pem,key.pem;` will do. **But**: The certificate should be acquired **first** and only after the certificate exists a site config should be created. Nginx will fail to start if it cannot find the certificate and key.
**IMPORTANT**: This guide only applies to non SNI enabled configurations. The certificate path needs to be adjusted if SNI is enabled. Something like `ssl_certificate,key /etc/ssl/mail/webmail.example.org/cert.pem,key.pem;` will do. **But**: The certificate should be acquired **first** and only after the certificate exists a site config should be created. Nginx will fail to start if it cannot find the certificate and key.
To create a subdomain `webmail.example.org` and redirect it to SOGo, you need to create a **new** Nginx site. Take care of "CHANGE_TO_MAILCOW_HOSTNAME"!
@ -14,7 +14,7 @@ server {
include /etc/nginx/conf.d/listen_plain.active;
include /etc/nginx/conf.d/listen_ssl.active;
server_name webmail.example.org;
server_tokens off;
location ^~ /.well-known/acme-challenge/ {
allow all;
default_type "text/plain";

Datei anzeigen

@ -1,11 +1,14 @@
site_name: 'mailcow: dockerized documentation'
site_name: "mailcow: dockerized documentation"
site_url: https://mailcow.github.io/mailcow-dockerized-docs/
copyright: 'Copyright &copy; 2020 André Peters'
copyright: "Copyright &copy; 2021 André Peters"
repo_name: mailcow/mailcow-dockerized
repo_url: https://github.com/mailcow/mailcow-dockerized
edit_uri: ../mailcow-dockerized-docs/edit/master/docs/
remote_branch: gh-pages
theme: material
theme:
name: material
logo: images/logo.svg
favicon: images/favicon.png
markdown_extensions:
- codehilite:
guess_lang: true
@ -20,32 +23,34 @@ markdown_extensions:
- pymdownx.extra
- footnotes
nav:
- 'Information & Support': 'index.md'
- 'Prerequisites':
- 'Information & Support': 'index.md'
- 'Prerequisites':
- 'Prepare your system': 'prerequisite-system.md'
- 'DNS setup': 'prerequisite-dns.md'
- 'Installation, Update & Migration':
- 'Installation, Update & Migration':
- 'Installation': 'i_u_m_install.md'
- 'Update': 'i_u_m_update.md'
- 'Migration': 'i_u_m_migration.md'
- 'First Steps (optional)':
- 'Untrust RFC 1918': 'firststeps-rfc-1918.md'
- 'Deinstallation': 'i_u_m_deinstall.md'
- 'Post Installation Tasks':
- 'Advanced SSL': 'firststeps-ssl.md'
- 'Disable IPv6': 'firststeps-disable_ipv6.md'
- 'IP bindings': 'firststeps-ip_bindings.md'
- 'Local MTA on Docker host': 'firststeps-local_mta.md'
- 'Logging': 'firststeps-logging.md'
- 'Relayhosts': 'firststeps-relayhost.md'
- 'Reverse Proxy': 'firststeps-rp.md'
- 'Rspamd UI': 'firststeps-rspamd_ui.md'
- 'DMARC Reporting': 'firststeps-dmarc_reporting.md'
- 'Reverse Proxy': 'firststeps-rp.md'
- 'SNAT': 'firststeps-snat.md'
- 'Disable IPv6': 'firststeps-disable_ipv6.md'
- 'Relayhosts': 'firststeps-relayhost.md'
- 'Logging': 'firststeps-logging.md'
- 'Local MTA on Docker host': 'firststeps-local_mta.md'
- 'Sync job migration': 'firststeps-sync_jobs_migration.md'
- 'IP bindings': 'firststeps-ip_bindings.md'
- 'Models':
- 'Sender and receiver model': 'model-sender_rcv.md'
- 'Add trusted networks': 'firststeps-trust_networks.md'
- 'Models':
- 'ACL': 'model-acl.md'
- 'Debugging & Troubleshooting':
- 'Introduction': debug.md
- 'Password hashing': 'model-passwd.md'
- 'Sender and receiver model': 'model-sender_rcv.md'
- 'General Troubleshooting':
- 'Introduction': 'debug.md'
- 'Logs': 'debug-logs.md'
- 'Attach a Container': 'debug-attach_service.md'
- 'Reset Passwords (incl. SQL)': 'debug-reset_pw.md'
@ -53,22 +58,27 @@ nav:
- 'Remove Persistent Data': 'debug-rm_volumes.md'
- 'Common Problems': 'debug-common_problems.md'
- 'Admin login to SOGo': 'debug-admin_login_sogo.md'
- 'Backup & Restore':
- 'Reset TLS certificates': 'debug-reset-tls.md'
- 'Backup & Restore':
- 'Helper script':
- 'Backup': 'b_n_r_backup.md'
- 'Restore': 'b_n_r_restore.md'
- 'Manually':
- 'Maildir': 'u_e-backup_restore-maildir.md'
- 'MySQL': 'u_e-backup_restore-mysql.md'
- 'Usage & Examples':
- 'Automatic backups':
- 'Recover accidentally deleted data': 'b_n_r_accidental_deletion.md'
- 'Manual/Guides/Examples':
- 'mailcow UI':
- 'Configuration': 'u_e-mailcow_ui-config.md'
- 'CSS overrides': 'u_e-mailcow_ui-css.md'
- 'Blacklist / Whitelist': 'u_e-mailcow_ui-bl_wl.md'
- 'Pushover': 'u_e-mailcow_ui-pushover.md'
- 'Spamfilter': 'u_e-mailcow_ui-spamfilter.md'
- 'Temporary email aliases': 'u_e-mailcow_ui-spamalias.md'
- 'Tagging': 'u_e-mailcow_ui-tagging.md'
- 'Two-Factor Authentication': 'u_e-mailcow_ui-tfa.md'
- 'WebAuthn / FIDO2': 'u_e-fido2.md'
- 'Postfix':
- 'Custom transport maps': 'u_e-postfix-custom_transport.md'
- 'Whitelist IP in Postscreen': 'u_e-postfix-postscreen_whitelist.md'
@ -80,14 +90,15 @@ nav:
- 'Using an external DNS service': 'u_e-unbound-fwd.md'
- 'Dovecot':
- 'Enable "any" ACL settings': 'u_e-dovecot-any_acl.md'
- 'Public folders': 'u_e-dovecot-public_folder.md'
- 'Expunge a Users mails': 'u_e-dovecot-expunge.md'
- 'Customize/Expand dovecot.conf': 'u_e-dovecot-extra_conf.md'
- 'FTS (Solr)': 'u_e-dovecot-fts.md'
- 'IMAP IDLE interval': 'u_e-dovecot-idle_interval.md'
- 'Mail crypt': 'u_e-dovecot-mail-crypt.md'
- 'More Examples with DOVEADM': 'u_e-dovecot-more.md'
- 'Move vmail volume': 'u_e-dovecot-vmail-volume.md'
- 'IMAP IDLE interval': 'u_e-dovecot-idle_interval.md'
- 'FTS (Solr)': 'u_e-dovecot-fts.md'
- 'Move Maildir (vmail)': 'u_e-dovecot-vmail-volume.md'
- 'Public folders': 'u_e-dovecot-public_folder.md'
- 'Static master user': 'u_e-dovecot-static_master.md'
- 'Nginx':
- 'Custom sites': 'u_e-nginx.md'
- 'Create subdomain webmail.example.org': 'u_e-webmail-site.md'
@ -100,11 +111,9 @@ nav:
- 'Why unbound?': 'u_e-why_unbound.md'
- 'Autodiscover / Autoconfig': 'u_e-autodiscover_config.md'
- 'Redirect HTTP to HTTPS': 'u_e-80_to_443.md'
- 'Adjust Service Configurations': 'u_e-change_config.md'
- 'Deinstall': 'u_e-deinstall.md'
- 'Re-enable TLS 1.0 and TLS 1.1': 'u_e-reeanble-weak-protocols.md'
- 'Mailpiler Integration': 'u_e-mailpiler-integration.md'
- 'Client Configuration':
- "Run scripts before and after updates": "u_e-update-hooks.md"
- 'Client Configuration':
- 'Overview': 'client.md'
- 'Android': 'client/client-android.md'
- 'Apple macOS / iOS': 'client/client-apple.md'
@ -115,23 +124,29 @@ nav:
- 'Windows Mail': 'client/client-windows.md'
- 'Windows Phone': 'client/client-windowsphone.md'
- 'Manual configuration': 'client/client-manual.md'
- 'Third party apps':
- 'SOGo Connector for Thunderbird': 'third_party-thunderbird.md'
- 'Roundcube': 'third_party-roundcube.md'
- 'Portainer': 'third_party-portainer.md'
- 'Gogs': 'third_party-gogs.md'
- 'Third party apps':
- 'Borgmatic Backup': 'third_party-borgmatic.md'
- 'Exchange Hybrid Setup': 'third_party-exchange_onprem.md'
- 'Gitea': 'third_party-gitea.md'
- 'Gogs': 'third_party-gogs.md'
- 'Mailpiler Integration': 'third_party-mailpiler_integration.md'
- 'Nextcloud': 'third_party-nextcloud.md'
icon:
logo: 'images/logo.svg'
- 'Portainer': 'third_party-portainer.md'
- 'Roundcube': 'third_party-roundcube.md'
- 'SOGo Connector for Thunderbird': 'third_party-thunderbird.md'
extra:
palette:
primary: 'indigo'
accent: 'orange'
primary: "indigo"
accent: "orange"
social:
- icon: fontawesome/solid/globe-americas
link: https://mailcow.email
- icon: fontawesome/brands/github-alt
link: https://github.com/mailcow
extra_css: [extra.css]
extra_javascript: [clients.js]
extra_css: [ extra.css ]
extra_javascript: [ clients.js ]
plugins:
- search
- redirects:
redirect_maps:
'u_e-mailpiler-integration.md': 'third_party-mailpiler_integration.md'