Complex "puzzle", I suspect that needs configuration at DMS and Roundcube containers.Caddy container appears to be doing his part: delivering
X-Real-IP and
X-Forwarded-For to Roundcube.
Problem occurs when someone tries to login on Roundcube... Three failed attempts and fail2ban on Docker Mailserver blocks docker gateway, 172.18.0.1; then, nobody can login on Roundcube until ban expires. Would like to pin/understand right configuration and not circunvent/disable fail2ban.
After two days of intense research, I suspect that solution may envolve:
- "$config['use_https'] = true;" and "$config['proxy_whitelist'] = ['172.18.0.0/16'];" on Roundcube
- "login_trusted_networks = 172.18.0.0/16" on Dovecot
Tried so many things that I got lost at the problem...
external IP | Linux Server with Containers
----------------------------------------------------------------
(172.18.0.2)
|- 80 -|
|-| |--- Caddy ---|
| |- 443 -| | (172.18.0.6)
| | | |
| |- 80 -|--- Roundcube ---|
20.112.52.29 -| | | |
| |
| (172.18.0.6) |
| |- 25 -| | |
| |- 143 -| | |
|-|- 465 -|--- DMS ---|---------------|
|- 587 -| |
|- 993 -| |
----------------------------------------------------------------
external IP | Linux Server with Containers
Caddyfile block relative to Roundcube:
webmail.mydomain.net {
reverse_proxy http://roundcube:80 {
header_up X-Real-IP {remote_host}
}
}
Any ideas/suggestions are welcome.
One year ago I tried to solve this problem but despite some help/ideas I could not discover how to do it.
https://github.com/orgs/docker-mailserver/discussions/2603
Instead of "ressurrect" that old discussion I thought it would be better start a new topic.
---
# Caddy / docker-compose.yml
version: "3.9"
services:
caddy:
image: caddy-with-cloudflare:2.6.4
hostname: caddy
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- $PWD/Caddyfile:/etc/caddy/Caddyfile
- $PWD/srv:/srv
- data:/data
- config:/config
volumes:
data:
config:
networks:
default:
name: caddy_net
external: true
# OpenLDAP & phpLDAPadmin / docker-compose.yml
version: "3.9"
services:
openldap:
image: osixia/openldap:latest
container_name: openldap
hostname: ldap
restart: unless-stopped
ports:
#- "389:389"
- "636:636"
volumes:
- config:/etc/ldap/slapd.d
- data:/var/lib/ldap
- /var/lib/docker/volumes/caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/ldap.mydomain.net:/container/service/slapd/assets/certs
environment:
LDAP_LOG_LEVEL: 256
LDAP_ORGANISATION: MYDOMAIN Net
LDAP_DOMAIN: mydomain.net
LDAP_BASE_DN:
LDAP_ADMIN_PASSWORD: admin-password-123
LDAP_CONFIG_PASSWORD: config-password-123
LDAP_READONLY_USER: false
#LDAP_READONLY_USER_USERNAME: readonly
#LDAP_READONLY_USER_PASSWORD: readonly
LDAP_RFC2307BIS_SCHEMA: true
LDAP_BACKEND: mdb
LDAP_TLS: true
LDAP_TLS_CRT_FILENAME: ldap.mydomain.net.crt
LDAP_TLS_KEY_FILENAME: ldap.mydomain.net.key
LDAP_TLS_CA_CRT_FILENAME: ldap.mydomain.net.crt
#LDAP_TLS_DH_PARAM_FILENAME: dhparam.pem
LDAP_TLS_ENFORCE: false
LDAP_TLS_CIPHER_SUITE: NORMAL:SECURE256:-VERS-SSL3.0
LDAP_TLS_VERIFY_CLIENT: try
LDAP_REPLICATION: false
KEEP_EXISTING_CONFIG: false
LDAP_REMOVE_CONFIG_AFTER_SETUP: true
LDAP_SSL_HELPER_PREFIX: ldap
LDAP_OPENLDAP_UID: 0
LDAP_OPENLDAP_GID: 0
tty: true
stdin_open: true
domainname: mydomain.net
phpldapadmin:
image: osixia/phpldapadmin:latest
container_name: phpldapadmin
hostname: phpldapadmin
restart: unless-stopped
#ports:
# - "8080:80"
volumes:
- phpldapadmin:/var/www/phpldapadmin
environment:
PHPLDAPADMIN_LDAP_HOSTS: ldap
PHPLDAPADMIN_HTTPS: false
depends_on:
- openldap
volumes:
config:
data:
phpldapadmin:
networks:
default:
name: caddy_net
external: true
# Docker Mailserver / docker-compose.yml
version: "3.9"
services:
mailserver:
image: ghcr.io/docker-mailserver/docker-mailserver:12.0.0
container_name: dms
hostname: mail
domainname: mydomain.net
ports:
- "25:25" # SMTP (explicit TLS => STARTTLS)
- "143:143" # IMAP4 (explicit TLS => STARTTLS)
- "465:465" # ESMTP (implicit TLS)
- "587:587" # ESMTP (explicit TLS => STARTTLS)
- "993:993" # IMAP4 (implicit TLS)
- "4190:4190" # Managesieve
volumes:
- $PWD/config/:/tmp/docker-mailserver/
- $PWD/mail-data/:/var/mail/
- $PWD/mail-logs/:/var/log/mail/
- $PWD/mail-state/:/var/mail-state/
- /etc/localtime:/etc/localtime:ro
- /var/lib/docker/volumes/caddy_data/_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory:/tmp/dms/custom-certs/:ro
environment:
- OVERRIDE_HOSTNAME=mail.mydomain.net
- LOG_LEVEL=info
- ACCOUNT_PROVISIONER=LDAP
- TZ=America/Sao_Paulo
- SPOOF_PROTECTION=1
- ENABLE_POLICYD_SPF=0
- ENABLE_CLAMAV=1
- ENABLE_RSPAMD=1
- RSPAMD_LEARN=1
- RSPAMD_GREYLISTING=1
- ENABLE_DNSBL=1
- ENABLE_FAIL2BAN=1
- FAIL2BAN_BLOCKTYPE=reject
- ENABLE_MANAGESIEVE=1
- SSL_TYPE=manual
- SSL_CERT_PATH=/tmp/dms/custom-certs/mail.mydomain.net/mail.mydomain.net.crt
- SSL_KEY_PATH=/tmp/dms/custom-certs/mail.mydomain.net/mail.mydomain.net.key
- POSTFIX_MAILBOX_SIZE_LIMIT=1073741824
- POSTFIX_MESSAGE_SIZE_LIMIT=52428800
- PFLOGSUMM_TRIGGER=logrotate
- LOGWATCH_INTERVAL=weekly
- [email protected]
- LOGROTATE_INTERVAL=monthly
- POSTFIX_INET_PROTOCOLS=ipv4
- DOVECOT_INET_PROTOCOLS=ipv4
- ENABLE_SPAMASSASSIN=1
- SPAMASSASSIN_SPAM_TO_INBOX=1
- ENABLE_SPAMASSASSIN_KAM=1
- MOVE_SPAM_TO_JUNK=1
- ENABLE_POSTGREY=1
- LDAP_START_TLS=yes
- LDAP_SERVER_HOST=ldap
- LDAP_SEARCH_BASE=dc=mydomain,dc=net
- LDAP_BIND_DN=cn=admin,dc=mydomain,dc=net
- LDAP_BIND_PW=admin-password-123
- LDAP_QUERY_FILTER_DOMAIN=(mail=*@%s)
- LDAP_QUERY_FILTER_USER=(&(mail=%s)(mailEnabled=TRUE))
- LDAP_QUERY_FILTER_ALIAS=(&(mailAlias=%s)(mailEnabled=TRUE))
- LDAP_QUERY_FILTER_GROUP=(&(objectclass=groupOfUniqueNames)(cn=%s))
- LDAP_QUERY_FILTER_SENDERS=(|(mail=%s)(mailAlias=%s)(mail=admin@*))
- DOVECOT_USER_FILTER=(&(objectClass=PostfixBookMailAccount)(mail=%u)(mailEnabled=TRUE))
- DOVECOT_PASS_FILTER=(&(objectClass=PostfixBookMailAccount)(mail=%u)(mailEnabled=TRUE))
- DOVECOT_AUTH_BIND=yes
- ENABLE_SASLAUTHD=1
- SASLAUTHD_MECHANISMS=ldap
- SASLAUTHD_LDAP_SERVER=ldap
- SASLAUTHD_LDAP_BIND_DN=cn=admin,dc=mydomain,dc=net
- SASLAUTHD_LDAP_PASSWORD=admin-password-123
- SASLAUTHD_LDAP_SEARCH_BASE=dc=mydomain,dc=net
- SASLAUTHD_LDAP_FILTER=(&(objectClass=PostfixBookMailAccount)(mail=%u@%r)(mailEnabled=TRUE))
cap_add:
- NET_ADMIN # For Fail2Ban to work
restart: always
networks:
default:
name: caddy_net
external: true
# Roundcube / docker-compose.yml
version: "3.9"
services:
roundcube:
image: roundcube/roundcubemail:1.6.1-apache
container_name: roundcube
hostname: roundcube
restart: unless-stopped
volumes:
- $PWD/config:/var/roundcube/config
- app:/var/www/html
- data:/var/roundcube/db
environment:
- ROUNDCUBEMAIL_DEFAULT_HOST=tls://mail.mydomain.net
- ROUNDCUBEMAIL_SMTP_SERVER=tls://mail.mydomain.net
- ROUNDCUBEMAIL_DB_TYPE=sqlite
- ROUNDCUBEMAIL_SKIN=elastic
- ROUNDCUBEMAIL_UPLOAD_MAX_FILESIZE=25M
volumes:
app:
data:
networks:
default:
name: caddy_net
external: true
Problem not in your Roundcube. Your fail2ban have rules for imap,smtp,web logs.
Config your fail2ban - add this IP to whitelist.
Use case: Firefox on Android phone tries to login on Roundcube using existing user with wrong password.Pay attention that Roundcube received (and knows) X-Real-IP and X-Forwarded-For.So, some configuration must be done at Roundcube and DMS to use that information, X-Real-IP and/or X-Forwarded-For.
At Roundcube config level, maybe one or more of this parameters must be adjusted:
// tell PHP that it should work as under secure connection
// even if it doesn't recognize it as secure ($_SERVER['HTTPS'] is not set)
// e.g. when you're running Roundcube behind a https proxy
// this option is mutually exclusive to 'force_https' and only either one of them should be set to true.
$config['use_https'] = false;
// List of trusted proxies
// X_FORWARDED_* and X_REAL_IP headers are only accepted from these IPs
$config['proxy_whitelist'] = [];
Complete config file at https://github.com/roundcube/roundcubemail/blob/master/config/defaults.inc.php
At DMS config level, for sure something on Dovecot, like:
https://doc.dovecot.org/configuration_manual/forwarding_parameters/
and
https://doc.dovecot.org/settings/core/#core_setting-login_trusted_networks
Below, pertinent parts of DMS and Roundcube logs.
DMS
[ INF ] Welcome to docker-mailserver 12.0.0
[ INF ] Checking configuration
[ INF ] Configuring mail server
[ WARNING ] Rspamd integration is work in progress - expect (breaking) changes at any time
[ WARNING ] (Rspamd setup) Running Amavis/SA & Rspamd at the same time is discouraged
[ INF ] Starting daemons
[ INF ] mail.mydomain.net is up and running
Apr 19 11:58:21 mail amavis[1204]: starting. /usr/sbin/amavisd-new at mail.mydomain.net amavisd-new-2.11.1 (20181009), Unicode aware, LC_CTYPE="C.UTF-8"
Apr 19 11:58:21 mail amavis[1204]: perl=5.032001, user=, EUID: 109 (109); group=, EGID: 111 111 (111 111)
Apr 19 11:58:21 mail amavis[1204]: Net::Server: Group Not Defined. Defaulting to EGID '111 111'
Apr 19 11:58:21 mail amavis[1204]: Net::Server: User Not Defined. Defaulting to EUID '109'
Apr 19 11:58:21 mail amavis[1204]: No ext program for .zoo, tried: zoo
Apr 19 11:58:21 mail amavis[1204]: No ext program for .doc, tried: ripole
Apr 19 11:58:21 mail amavis[1204]: No decoder for .F
Apr 19 11:58:21 mail amavis[1204]: No decoder for .doc
Apr 19 11:58:21 mail amavis[1204]: No decoder for .zoo
Apr 19 11:58:21 mail amavis[1204]: Using primary internal av scanner code for ClamAV-clamd
Apr 19 11:58:21 mail amavis[1204]: Found secondary av scanner ClamAV-clamscan at /usr/bin/clamscan
...
Apr 19 12:07:28 mail dovecot: auth: ldap([email protected],172.18.0.1,<H5pGyLH5YpusEgAB>): Password mismatch (for LDAP bind) (SHA1 of given password: 2e6f9b)
Apr 19 12:07:30 mail dovecot: imap-login: Disconnected: Connection closed (auth failed, 1 attempts in 2 secs): user=<[email protected]>, method=PLAIN, rip=172.18.0.1, lip=172.18.0.7, TLS, session=<H5pGyLH5YpusEgAB>
Roundcube
roundcubemail found in /var/www/html - installing update...
Target installation already in version 1.6.1. Do you want to update again? (y/N)
Copying files to target location...done.
Running update script at target...
Executing database schema update.
/usr/bin/composer
Executing /usr/bin/composer to update dependencies...
Loading composer repositories with package information
Info from https://repo.packagist.org: #StandWithUkraine
Updating dependencies
Nothing to modify in lock file
Installing dependencies from lock file
Nothing to install, update or remove
Generating autoload files
4 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found
This instance of Roundcube is up-to-date.
Have fun!
All done.
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Installing dependencies from lock file
Nothing to install, update or remove
Generating autoload files
4 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found
Write Docker config to /var/www/html/config/config.docker.inc.php
Checking for database schema updates...
Generating locales (this might take a while)...
en_US.UTF-8... done
Generation complete.
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.6. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.6. Set the 'ServerName' directive globally to suppress this message
[Wed Apr 19 15:00:54.610207 2023] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.56 (Debian) PHP/8.1.17 configured -- resuming normal operations
[Wed Apr 19 15:00:54.610224 2023] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
...
172.18.0.2 - - [19/Apr/2023:15:04:22 +0000] "GET / HTTP/1.1" 200 2956 "-" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:22 +0000] "GET /plugins/jqueryui/js/i18n/datepicker-pt-BR.js?s=1674504193 HTTP/1.1" 200 967 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:22 +0000] "GET /program/js/common.min.js?s=1674504194 HTTP/1.1" 200 5156 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:22 +0000] "GET /skins/elastic/images/logo.svg?s=1674504194 HTTP/1.1" 200 680 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:22 +0000] "GET /skins/elastic/styles/styles.min.css?s=1674504194 HTTP/1.1" 200 22637 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:22 +0000] "GET /skins/elastic/deps/bootstrap.min.css?s=1674504210 HTTP/1.1" 200 24161 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:22 +0000] "GET /plugins/jqueryui/js/jquery-ui.min.js?s=1674504193 HTTP/1.1" 200 70755 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:22 +0000] "GET /skins/elastic/ui.min.js?s=1674504194 HTTP/1.1" 200 19970 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:22 +0000] "GET /skins/elastic/deps/bootstrap.bundle.min.js?s=1674504210 HTTP/1.1" 200 22065 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:22 +0000] "GET /program/js/jquery.min.js?s=1674504197 HTTP/1.1" 200 32003 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:23 +0000] "GET /program/js/jstz.min.js?s=1674504197 HTTP/1.1" 200 5309 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:23 +0000] "GET /plugins/jqueryui/themes/elastic/jquery-ui.min.css?s=1674504193 HTTP/1.1" 200 7659 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:24 +0000] "GET /program/js/app.min.js?s=1674504194 HTTP/1.1" 200 48356 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:25 +0000] "GET /skins/elastic/fonts/fa-solid-900.woff2 HTTP/1.1" 200 75697 "https://webmail.mydomain.net/skins/elastic/styles/styles.min.css?s=1674504194" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
172.18.0.2 - - [19/Apr/2023:15:04:25 +0000] "GET /skins/elastic/images/favicon.ico?s=1674504194 HTTP/1.1" 200 1991 "-" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"
127.0.0.1 - - [19/Apr/2023:15:04:26 +0000] "OPTIONS * HTTP/1.0" 200 126 "-" "Apache/2.4.56 (Debian) PHP/8.1.17 (internal dummy connection)"
127.0.0.1 - - [19/Apr/2023:15:04:27 +0000] "OPTIONS * HTTP/1.0" 200 126 "-" "Apache/2.4.56 (Debian) PHP/8.1.17 (internal dummy connection)"
127.0.0.1 - - [19/Apr/2023:15:04:28 +0000] "OPTIONS * HTTP/1.0" 200 126 "-" "Apache/2.4.56 (Debian) PHP/8.1.17 (internal dummy connection)"
127.0.0.1 - - [19/Apr/2023:15:04:29 +0000] "OPTIONS * HTTP/1.0" 200 126 "-" "Apache/2.4.56 (Debian) PHP/8.1.17 (internal dummy connection)"
127.0.0.1 - - [19/Apr/2023:15:04:30 +0000] "OPTIONS * HTTP/1.0" 200 126 "-" "Apache/2.4.56 (Debian) PHP/8.1.17 (internal dummy connection)"
127.0.0.1 - - [19/Apr/2023:15:04:31 +0000] "OPTIONS * HTTP/1.0" 200 126 "-" "Apache/2.4.56 (Debian) PHP/8.1.17 (internal dummy connection)"
127.0.0.1 - - [19/Apr/2023:15:04:32 +0000] "OPTIONS * HTTP/1.0" 200 126 "-" "Apache/2.4.56 (Debian) PHP/8.1.17 (internal dummy connection)"
127.0.0.1 - - [19/Apr/2023:15:04:33 +0000] "OPTIONS * HTTP/1.0" 200 126 "-" "Apache/2.4.56 (Debian) PHP/8.1.17 (internal dummy connection)"
127.0.0.1 - - [19/Apr/2023:15:04:34 +0000] "OPTIONS * HTTP/1.0" 200 126 "-" "Apache/2.4.56 (Debian) PHP/8.1.17 (internal dummy connection)"
127.0.0.1 - - [19/Apr/2023:15:04:35 +0000] "OPTIONS * HTTP/1.0" 200 126 "-" "Apache/2.4.56 (Debian) PHP/8.1.17 (internal dummy connection)"
...
errors: <bb16ea71> IMAP Error: Login failed for [email protected] against mail.mydomain.net from 172.18.0.2 (X-Real-IP: 177.57.148.177,X-Forwarded-For: 177.57.148.177). AUTHENTICATE PLAIN: Authentication failed. in /var/www/html/program/lib/Roundcube/rcube_imap.php on line 211 (POST /?_task=login&_action=login)
172.18.0.2 - - [19/Apr/2023:15:07:28 +0000] "POST /?_task=login HTTP/1.1" 401 3120 "https://webmail.mydomain.net/" "Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/111.0 Firefox/111.0"