diff --git a/core/admin/mailu/configuration.py b/core/admin/mailu/configuration.py
index d2d34d88..7cd3a56b 100644
--- a/core/admin/mailu/configuration.py
+++ b/core/admin/mailu/configuration.py
@@ -32,6 +32,7 @@ DEFAULT_CONFIG = {
'DOMAIN': 'mailu.io',
'HOSTNAMES': 'mail.mailu.io,alternative.mailu.io,yetanother.mailu.io',
'POSTMASTER': 'postmaster',
+ 'WILDCARD_SENDERS': '',
'TLS_FLAVOR': 'cert',
'INBOUND_TLS_ENFORCE': False,
'AUTH_RATELIMIT': '1000/minute;10000/hour',
@@ -46,6 +47,7 @@ DEFAULT_CONFIG = {
'DKIM_SELECTOR': 'dkim',
'DKIM_PATH': '/dkim/{domain}.{selector}.key',
'DEFAULT_QUOTA': 1000000000,
+ 'MESSAGE_RATELIMIT': '200/day',
# Web settings
'SITENAME': 'Mailu',
'WEBSITE': 'https://mailu.io',
diff --git a/core/admin/mailu/internal/nginx.py b/core/admin/mailu/internal/nginx.py
index 3f5582cc..5e60cd0c 100644
--- a/core/admin/mailu/internal/nginx.py
+++ b/core/admin/mailu/internal/nginx.py
@@ -81,6 +81,13 @@ def handle_authentication(headers):
raw_password = urllib.parse.unquote(headers["Auth-Pass"])
password = raw_password.encode("iso8859-1").decode("utf8")
ip = urllib.parse.unquote(headers["Client-Ip"])
+ service_port = int(urllib.parse.unquote(headers["Auth-Port"]))
+ if service_port == 25:
+ return {
+ "Auth-Status": "AUTH not supported",
+ "Auth-Error-Code": "502 5.5.1",
+ "Auth-Wait": 0
+ }
user = models.User.query.get(user_email)
if check_credentials(user, password, ip, protocol):
return {
diff --git a/core/admin/mailu/internal/views/auth.py b/core/admin/mailu/internal/views/auth.py
index 2baeddce..1686e1cb 100644
--- a/core/admin/mailu/internal/views/auth.py
+++ b/core/admin/mailu/internal/views/auth.py
@@ -50,7 +50,7 @@ def user_authentication():
if (not flask_login.current_user.is_anonymous
and flask_login.current_user.enabled):
response = flask.Response()
- response.headers["X-User"] = flask_login.current_user.get_id()
+ response.headers["X-User"] = models.IdnaEmail.process_bind_param(flask_login, flask_login.current_user.get_id(), "")
response.headers["X-User-Token"] = models.User.get_temp_token(flask_login.current_user.get_id())
return response
return flask.abort(403)
@@ -67,7 +67,7 @@ def basic_authentication():
user = models.User.query.get(user_email.decode("utf8"))
if nginx.check_credentials(user, password.decode('utf-8'), flask.request.remote_addr, "web"):
response = flask.Response()
- response.headers["X-User"] = user.email
+ response.headers["X-User"] = models.IdnaEmail.process_bind_param(flask_login, user.email, "")
return response
response = flask.Response(status=401)
response.headers["WWW-Authenticate"] = 'Basic realm="Login Required"'
diff --git a/core/admin/mailu/internal/views/postfix.py b/core/admin/mailu/internal/views/postfix.py
index c358c37f..2e7d0b9b 100644
--- a/core/admin/mailu/internal/views/postfix.py
+++ b/core/admin/mailu/internal/views/postfix.py
@@ -1,5 +1,6 @@
-from mailu import models
+from mailu import models, utils
from mailu.internal import internal
+from flask import current_app as app
import flask
import idna
@@ -31,7 +32,6 @@ def postfix_alias_map(alias):
destination = models.Email.resolve_destination(localpart, domain_name)
return flask.jsonify(",".join(destination)) if destination else flask.abort(404)
-
@internal.route("/postfix/transport/MX
points to this server"
msgstr ""
+"כדי לרשום שם תחום חדש, תחילה עליך להקים את אזור התחום\n"
+" (domain zone) כדי שה־MX
של שם התחום יפנה לשרת הזה"
#: mailu/ui/templates/domain/signup.html:18
msgid ""
"If you do not know how to setup an MX
record for your DNS "
"zone,\n"
-" please contact your DNS provider or administrator. Also, please wait "
-"a\n"
+" please contact your DNS provider or administrator. Also, please wait a\n"
" couple minutes after the MX
is set so the local server "
"cache\n"
" expires."
msgstr ""
+"אם לא ברור לך איך להקים רשומת MX
עבור אזור ה־DNS שלך,\n"
+" נא ליצור קשר עם ספק ה־ DNS או ההנהלה שלך. כמו כן, נא להמתין מספר דקות\n"
+" לאחר הגדרת ה־MX
כדי לאפשר לתוקף המטמון המקורי בשרת\n"
+" לפוג."
#: mailu/ui/templates/fetch/create.html:4
msgid "Add a fetched account"
-msgstr ""
+msgstr "הוספת חשבון נמשך"
#: mailu/ui/templates/fetch/edit.html:4
msgid "Update a fetched account"
-msgstr ""
+msgstr "עדכון חשבון שנמשך"
#: mailu/ui/templates/fetch/list.html:12
msgid "Add an account"
-msgstr ""
+msgstr "הוספת חשבון"
#: mailu/ui/templates/fetch/list.html:19
msgid "Endpoint"
-msgstr ""
+msgstr "נקודת גישה"
#: mailu/ui/templates/fetch/list.html:21
msgid "Keep emails"
-msgstr ""
+msgstr "לשמור על ההודעות"
#: mailu/ui/templates/fetch/list.html:22
msgid "Last check"
-msgstr ""
+msgstr "בדיקה אחרונה"
#: mailu/ui/templates/fetch/list.html:35
msgid "yes"
-msgstr ""
+msgstr "כן"
#: mailu/ui/templates/fetch/list.html:35
msgid "no"
-msgstr ""
+msgstr "לא"
#: mailu/ui/templates/manager/create.html:4
msgid "Add a manager"
-msgstr ""
+msgstr "הוספת מנהל"
#: mailu/ui/templates/manager/list.html:4
msgid "Manager list"
-msgstr ""
+msgstr "רשימת מנהלים"
#: mailu/ui/templates/manager/list.html:12
msgid "Add manager"
-msgstr ""
+msgstr "הוספת מנהל"
#: mailu/ui/templates/relay/create.html:4
msgid "New relay domain"
-msgstr ""
+msgstr "שם תחום מועבר"
#: mailu/ui/templates/relay/edit.html:4
msgid "Edit relayd domain"
-msgstr ""
+msgstr "עריכת שמות תחום מועברים"
#: mailu/ui/templates/relay/list.html:4
msgid "Relayed domain list"
-msgstr ""
+msgstr "רשימת שמות תחום מועברים"
#: mailu/ui/templates/relay/list.html:9
msgid "New relayed domain"
-msgstr ""
+msgstr "שם תחום מועבר חדש"
#: mailu/ui/templates/token/create.html:4
msgid "Create an authentication token"
-msgstr ""
+msgstr "יצירת אסימון אימות"
#: mailu/ui/templates/token/list.html:12
msgid "New token"
-msgstr ""
+msgstr "אסימון חדש"
#: mailu/ui/templates/user/create.html:4
msgid "New user"
-msgstr ""
+msgstr "משתמש חדש"
#: mailu/ui/templates/user/create.html:15
msgid "General"
-msgstr ""
+msgstr "כללי"
#: mailu/ui/templates/user/create.html:22
msgid "Features and quotas"
-msgstr ""
+msgstr "יכולות ומיכסות"
#: mailu/ui/templates/user/edit.html:4
msgid "Edit user"
-msgstr ""
+msgstr "עריכת משתמש"
#: mailu/ui/templates/user/forward.html:4
msgid "Forward emails"
-msgstr ""
+msgstr "העברת הודעות"
#: mailu/ui/templates/user/list.html:4
msgid "User list"
-msgstr ""
+msgstr "רשימת משתמשים"
#: mailu/ui/templates/user/list.html:12
msgid "Add user"
-msgstr ""
+msgstr "הוספת משתמש"
#: mailu/ui/templates/user/list.html:19 mailu/ui/templates/user/settings.html:4
msgid "User settings"
-msgstr ""
+msgstr "הגדרות משתמש"
#: mailu/ui/templates/user/list.html:21
msgid "Features"
-msgstr ""
+msgstr "יכולות"
#: mailu/ui/templates/user/password.html:4
msgid "Password update"
-msgstr ""
+msgstr "עדכון סיסמה"
#: mailu/ui/templates/user/reply.html:4
msgid "Automatic reply"
-msgstr ""
+msgstr "מענה אוטומטי"
#: mailu/ui/templates/user/settings.html:22
msgid "Auto-forward"
-msgstr ""
+msgstr "העברה אוטומטית"
#: mailu/ui/templates/user/signup_domain.html:8
msgid "pick a domain for the new account"
-msgstr ""
+msgstr "נא לבחור שם תחום לחשבון החדש"
#: mailu/ui/templates/user/signup_domain.html:14
msgid "Domain"
-msgstr ""
+msgstr "שם תחום"
#: mailu/ui/templates/user/signup_domain.html:15
msgid "Available slots"
-msgstr ""
+msgstr "מקומות פנויים"
diff --git a/core/dovecot/conf/ham.script b/core/dovecot/conf/ham.script
index aa25cefb..910df8e4 100755
--- a/core/dovecot/conf/ham.script
+++ b/core/dovecot/conf/ham.script
@@ -1,5 +1,12 @@
#!/bin/bash
-tee >(rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu learn_ham /dev/stdin) \
- >(rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu -f 11 fuzzy_del /dev/stdin) \
- | rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu -f 13 fuzzy_add /dev/stdin
+RSPAMD_HOST="$(getent hosts {{ ANTISPAM_WEBUI_ADDRESS }}|cut -d\ -f1)"
+if [[ $? -ne 0 ]]
+then
+ echo "Failed to lookup {{ ANTISPAM_WEBUI_ADDRESS }}" >&2
+ exit 1
+fi
+
+tee >(rspamc -h $RSPAMD_HOST -P mailu learn_ham /dev/stdin) \
+ >(rspamc -h $RSPAMD_HOST -P mailu -f 11 fuzzy_del /dev/stdin) \
+ | rspamc -h $RSPAMD_HOST -P mailu -f 13 fuzzy_add /dev/stdin
diff --git a/core/dovecot/conf/spam.script b/core/dovecot/conf/spam.script
index 05a3832d..e7d20427 100755
--- a/core/dovecot/conf/spam.script
+++ b/core/dovecot/conf/spam.script
@@ -1,5 +1,13 @@
#!/bin/bash
-tee >(rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu learn_spam /dev/stdin) \
- >(rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu -f 13 fuzzy_del /dev/stdin) \
- | rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu -f 11 fuzzy_add /dev/stdin
+RSPAMD_HOST="$(getent hosts {{ ANTISPAM_WEBUI_ADDRESS }}|cut -d\ -f1)"
+if [[ $? -ne 0 ]]
+then
+ echo "Failed to lookup {{ ANTISPAM_WEBUI_ADDRESS }}" >&2
+ exit 1
+fi
+
+
+tee >(rspamc -h $RSPAMD_HOST -P mailu learn_spam /dev/stdin) \
+ >(rspamc -h $RSPAMD_HOST -P mailu -f 13 fuzzy_del /dev/stdin) \
+ | rspamc -h $RSPAMD_HOST -P mailu -f 11 fuzzy_add /dev/stdin
diff --git a/core/nginx/conf/dhparam.pem b/core/nginx/conf/dhparam.pem
index 3cf0fcbc..4f25f663 100644
--- a/core/nginx/conf/dhparam.pem
+++ b/core/nginx/conf/dhparam.pem
@@ -1,13 +1,11 @@
-----BEGIN DH PARAMETERS-----
-MIICCAKCAgEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
-+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
-87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
-YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
-7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
-ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3
-7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32
-nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZp4e
-8W5vUsMWTfT7eTDp5OWIV7asfV9C1p9tGHdjzx1VA0AEh/VbpX4xzHpxNciG77Qx
-iu1qHgEtnmgyqQdgCpGBMMRtx3j5ca0AOAkpmaMzy4t6Gh25PXFAADwqTs6p+Y0K
-zAqCkc3OyX3Pjsm1Wn+IpGtNtahR9EGC4caKAH5eZV9q//////////8CAQI=
+MIIBiAKCAYEAtQlUSOKGjpdXJ154qmMEa1pEs+9CdSxWiZFkiXBJb0lTafOh8cfF
+2IkcWSwzxWwjW4Ad26UQQFh1poGf2QBzVk2vuKCekYzPAs/WqH8VwiXBiWR5R9lh
+v/+CkEBYuQOzAhXLN6ZGdPPa2sjdI49rlaIqyLJE4D0TI/VHYmC/vEwqkJUgaGrS
+19LhHZimnmouvrnyBPyf00czXlMow0RnmYeHVZ7W5hu7t9TH9o3QAN/GKiFfxFj+
+RkdLM7beQdS0He5YeTaElM5l1YT5d5gHFbOzEQyKHd10ux+bgVcgUeVbBnI1SAIC
+w53yc1PkDAiRijSP5j5aWq1djtJPheS13o35HyIf0cHzkNYhKfX5JWPj/cbgdM+C
+FL1bnRc8sL5oxmkDoGJhiNZIf4n2WtS8Zu28gUgat6S+vCm/4yavIc/T1g6UiNKE
+X41HPbsma/QWUwOL6S+b2qr+7rKqjI5TzVek8vBMellEV4mBvfQU3NDSQ4WvxbTq
+ZEOgLPA178nrAgEC
-----END DH PARAMETERS-----
diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf
index 5158ca5c..9ce12980 100644
--- a/core/nginx/conf/nginx.conf
+++ b/core/nginx/conf/nginx.conf
@@ -250,6 +250,7 @@ mail {
listen 10025;
protocol smtp;
smtp_auth plain;
+ auth_http_header Auth-Port 10025;
}
# Default IMAP server for the webmail (no encryption, but authentication)
@@ -257,6 +258,7 @@ mail {
listen 10143;
protocol imap;
smtp_auth plain;
+ auth_http_header Auth-Port 10043;
}
# SMTP is always enabled, to avoid losing emails when TLS is failing
@@ -271,6 +273,7 @@ mail {
{% endif %}
protocol smtp;
smtp_auth none;
+ auth_http_header Auth-Port 25;
}
# All other protocols are disabled if TLS is failing
@@ -283,6 +286,7 @@ mail {
{% endif %}
protocol imap;
imap_auth plain;
+ auth_http_header Auth-Port 143;
}
server {
@@ -293,6 +297,7 @@ mail {
{% endif %}
protocol pop3;
pop3_auth plain;
+ auth_http_header Auth-Port 110;
}
server {
@@ -303,6 +308,7 @@ mail {
{% endif %}
protocol smtp;
smtp_auth plain login;
+ auth_http_header Auth-Port 587;
}
{% if TLS %}
@@ -311,6 +317,7 @@ mail {
listen [::]:465 ssl;
protocol smtp;
smtp_auth plain login;
+ auth_http_header Auth-Port 465;
}
server {
@@ -318,6 +325,7 @@ mail {
listen [::]:993 ssl;
protocol imap;
imap_auth plain;
+ auth_http_header Auth-Port 993;
}
server {
@@ -325,6 +333,7 @@ mail {
listen [::]:995 ssl;
protocol pop3;
pop3_auth plain;
+ auth_http_header Auth-Port 995;
}
{% endif %}
{% endif %}
diff --git a/core/nginx/conf/tls.conf b/core/nginx/conf/tls.conf
index 5d7ec031..f663bfd2 100644
--- a/core/nginx/conf/tls.conf
+++ b/core/nginx/conf/tls.conf
@@ -1,5 +1,10 @@
ssl_certificate {{ TLS[0] }};
ssl_certificate_key {{ TLS[1] }};
+{% if TLS_FLAVOR in ['letsencrypt','mail-letsencrypt'] %}
+ssl_certificate {{ TLS[2] }};
+ssl_certificate_key {{ TLS[3] }};
+ssl_trusted_certificate /etc/ssl/certs/ca-cert-DST_Root_CA_X3.pem;
+{% endif %}
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_dhparam /conf/dhparam.pem;
diff --git a/core/nginx/config.py b/core/nginx/config.py
index 6fc9c082..9fa75877 100755
--- a/core/nginx/config.py
+++ b/core/nginx/config.py
@@ -26,11 +26,11 @@ cert_name = os.getenv("TLS_CERT_FILENAME", default="cert.pem")
keypair_name = os.getenv("TLS_KEYPAIR_FILENAME", default="key.pem")
args["TLS"] = {
"cert": ("/certs/%s" % cert_name, "/certs/%s" % keypair_name),
- "letsencrypt": ("/certs/letsencrypt/live/mailu/fullchain.pem",
- "/certs/letsencrypt/live/mailu/privkey.pem"),
+ "letsencrypt": ("/certs/letsencrypt/live/mailu/nginx-chain.pem",
+ "/certs/letsencrypt/live/mailu/privkey.pem", "/certs/letsencrypt/live/mailu-ecdsa/nginx-chain.pem", "/certs/letsencrypt/live/mailu-ecdsa/privkey.pem"),
"mail": ("/certs/%s" % cert_name, "/certs/%s" % keypair_name),
- "mail-letsencrypt": ("/certs/letsencrypt/live/mailu/fullchain.pem",
- "/certs/letsencrypt/live/mailu/privkey.pem"),
+ "mail-letsencrypt": ("/certs/letsencrypt/live/mailu/nginx-chain.pem",
+ "/certs/letsencrypt/live/mailu/privkey.pem", "/certs/letsencrypt/live/mailu-ecdsa/nginx-chain.pem", "/certs/letsencrypt/live/mailu-ecdsa/privkey.pem"),
"notls": None
}[args["TLS_FLAVOR"]]
diff --git a/core/nginx/letsencrypt.py b/core/nginx/letsencrypt.py
index 3fe8ea92..e3db05f1 100755
--- a/core/nginx/letsencrypt.py
+++ b/core/nginx/letsencrypt.py
@@ -4,7 +4,6 @@ import os
import time
import subprocess
-
command = [
"certbot",
"-n", "--agree-tos", # non-interactive
@@ -14,16 +13,47 @@ command = [
"--cert-name", "mailu",
"--preferred-challenges", "http", "--http-01-port", "8008",
"--keep-until-expiring",
- "--rsa-key-size", "4096",
+ "--renew-with-new-domains",
+ "--config-dir", "/certs/letsencrypt",
+ "--post-hook", "/config.py"
+]
+command2 = [
+ "certbot",
+ "-n", "--agree-tos", # non-interactive
+ "-d", os.environ["HOSTNAMES"],
+ "-m", "{}@{}".format(os.environ["POSTMASTER"], os.environ["DOMAIN"]),
+ "certonly", "--standalone",
+ "--cert-name", "mailu-ecdsa",
+ "--preferred-challenges", "http", "--http-01-port", "8008",
+ "--keep-until-expiring",
+ "--key-type", "ecdsa",
+ "--renew-with-new-domains",
"--config-dir", "/certs/letsencrypt",
"--post-hook", "/config.py"
]
+def format_for_nginx(fullchain, output):
+ """ We may want to strip ISRG Root X1 out
+ """
+ certs = []
+ with open(fullchain, 'r') as pem:
+ cert = ''
+ for line in pem:
+ cert += line
+ if '-----END CERTIFICATE-----' in line:
+ certs += [cert]
+ cert = ''
+ with open(output, 'w') as pem:
+ for cert in certs[:-1] if len(certs)>2 and os.getenv('LETSENCRYPT_SHORTCHAIN', default="False") else certs:
+ pem.write(cert)
+
# Wait for nginx to start
time.sleep(5)
-# Run certbot every hour
+# Run certbot every day
while True:
subprocess.call(command)
- time.sleep(3600)
-
+ format_for_nginx('/certs/letsencrypt/live/mailu/fullchain.pem', '/certs/letsencrypt/live/mailu/nginx-chain.pem')
+ subprocess.call(command2)
+ format_for_nginx('/certs/letsencrypt/live/mailu-ecdsa/fullchain.pem', '/certs/letsencrypt/live/mailu-ecdsa/nginx-chain.pem')
+ time.sleep(86400)
diff --git a/core/postfix/conf/main.cf b/core/postfix/conf/main.cf
index 9cd4010e..7f84ade7 100644
--- a/core/postfix/conf/main.cf
+++ b/core/postfix/conf/main.cf
@@ -33,7 +33,8 @@ relayhost = {{ RELAYHOST }}
{% if RELAYUSER %}
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = lmdb:/etc/postfix/sasl_passwd
-smtp_sasl_security_options = noanonymous
+smtp_sasl_security_options = noanonymous, noplaintext
+smtp_sasl_tls_security_options = noanonymous
{% endif %}
# Recipient delimiter for extended addresses
@@ -50,15 +51,20 @@ smtpd_authorized_xclient_hosts={{ POD_ADDRESS_RANGE or SUBNET }}
# General TLS configuration
tls_high_cipherlist = EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA
tls_preempt_cipherlist = yes
-tls_ssl_options = NO_COMPRESSION
+tls_ssl_options = NO_COMPRESSION, NO_TICKET
# By default, outgoing TLS is more flexible because
# 1. not all receiving servers will support TLS,
# 2. not all will have and up-to-date TLS stack.
-smtp_tls_security_level = {{ OUTBOUND_TLS_LEVEL|default('may') }}
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
smtp_tls_protocols =!SSLv2,!SSLv3
-smtp_tls_session_cache_database = lmdb:${data_directory}/smtp_scache
+smtp_tls_security_level = {{ OUTBOUND_TLS_LEVEL|default('may') }}
+smtp_tls_policy_maps=hash:/etc/postfix/tls_policy.map
+smtp_tls_CApath = /etc/ssl/certs
+smtp_tls_session_cache_database = lmdb:/dev/shm/postfix/smtp_scache
+smtpd_tls_session_cache_database = lmdb:/dev/shm/postfix/smtpd_scache
+smtp_host_lookup = dns
+smtp_dns_support_level = dnssec
###############
# Virtual
@@ -99,6 +105,8 @@ smtpd_sender_login_maps = ${podop}senderlogin
# Restrictions for incoming SMTP, other restrictions are applied in master.cf
smtpd_helo_required = yes
+check_ratelimit = check_sasl_access ${podop}senderrate
+
smtpd_client_restrictions =
permit_mynetworks,
check_sender_access ${podop}senderaccess,
diff --git a/core/postfix/conf/master.cf b/core/postfix/conf/master.cf
index e45a8ccf..15613476 100644
--- a/core/postfix/conf/master.cf
+++ b/core/postfix/conf/master.cf
@@ -7,7 +7,8 @@ smtp inet n - n - - smtpd
# Internal SMTP service
10025 inet n - n - - smtpd
-o smtpd_sasl_auth_enable=yes
- -o smtpd_client_restrictions=reject_unlisted_sender,reject_authenticated_sender_login_mismatch,permit
+ -o smtpd_discard_ehlo_keywords=pipelining
+ -o smtpd_client_restrictions=$check_ratelimit,reject_unlisted_sender,reject_authenticated_sender_login_mismatch,permit
-o smtpd_reject_unlisted_recipient={% if REJECT_UNLISTED_RECIPIENT %}{{ REJECT_UNLISTED_RECIPIENT }}{% else %}no{% endif %}
-o cleanup_service_name=outclean
outclean unix n - n - 0 cleanup
diff --git a/core/postfix/start.py b/core/postfix/start.py
index e0c781b7..799d42f5 100755
--- a/core/postfix/start.py
+++ b/core/postfix/start.py
@@ -15,6 +15,7 @@ log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING"))
def start_podop():
os.setuid(getpwnam('postfix').pw_uid)
+ os.mkdir('/dev/shm/postfix',mode=0o700)
url = "http://" + os.environ["ADMIN_ADDRESS"] + "/internal/postfix/"
# TODO: Remove verbosity setting from Podop?
run_server(0, "postfix", "/tmp/podop.socket", [
@@ -25,7 +26,8 @@ def start_podop():
("recipientmap", "url", url + "recipient/map/§"),
("sendermap", "url", url + "sender/map/§"),
("senderaccess", "url", url + "sender/access/§"),
- ("senderlogin", "url", url + "sender/login/§")
+ ("senderlogin", "url", url + "sender/login/§"),
+ ("senderrate", "url", url + "sender/rate/§")
])
def is_valid_postconf_line(line):
@@ -66,6 +68,12 @@ for map_file in glob.glob("/overrides/*.map"):
os.system("postmap {}".format(destination))
os.remove(destination)
+if not os.path.exists("/etc/postfix/tls_policy.map.db"):
+ with open("/etc/postfix/tls_policy.map", "w") as f:
+ for domain in ['gmail.com', 'yahoo.com', 'hotmail.com', 'aol.com', 'outlook.com', 'comcast.net', 'icloud.com', 'msn.com', 'hotmail.co.uk', 'live.com', 'yahoo.co.in', 'me.com', 'mail.ru', 'cox.net', 'yahoo.co.uk', 'verizon.net', 'ymail.com', 'hotmail.it', 'kw.com', 'yahoo.com.tw', 'mac.com', 'live.se', 'live.nl', 'yahoo.com.br', 'googlemail.com', 'libero.it', 'web.de', 'allstate.com', 'btinternet.com', 'online.no', 'yahoo.com.au', 'live.dk', 'earthlink.net', 'yahoo.fr', 'yahoo.it', 'gmx.de', 'hotmail.fr', 'shawinc.com', 'yahoo.de', 'moe.edu.sg', 'naver.com', 'bigpond.com', 'statefarm.com', 'remax.net', 'rocketmail.com', 'live.no', 'yahoo.ca', 'bigpond.net.au', 'hotmail.se', 'gmx.at', 'live.co.uk', 'mail.com', 'yahoo.in', 'yandex.ru', 'qq.com', 'charter.net', 'indeedemail.com', 'alice.it', 'hotmail.de', 'bluewin.ch', 'optonline.net', 'wp.pl', 'yahoo.es', 'hotmail.no', 'pindotmedia.com', 'orange.fr', 'live.it', 'yahoo.co.id', 'yahoo.no', 'hotmail.es', 'morganstanley.com', 'wellsfargo.com', 'wanadoo.fr', 'facebook.com', 'yahoo.se', 'fema.dhs.gov', 'rogers.com', 'yahoo.com.hk', 'live.com.au', 'nic.in', 'nab.com.au', 'ubs.com', 'shaw.ca', 'umich.edu', 'westpac.com.au', 'yahoo.com.mx', 'yahoo.com.sg', 'farmersagent.com', 'yahoo.dk', 'dhs.gov']:
+ f.write(f'{domain}\tsecure\n')
+ os.system("postmap /etc/postfix/tls_policy.map")
+
if "RELAYUSER" in os.environ:
path = "/etc/postfix/sasl_passwd"
conf.jinja("/conf/sasl_passwd", os.environ, path)
diff --git a/docs/compose/traefik/traefik.toml b/docs/compose/traefik/traefik.toml
index c09cf42a..7e09de58 100644
--- a/docs/compose/traefik/traefik.toml
+++ b/docs/compose/traefik/traefik.toml
@@ -28,6 +28,6 @@ entryPoint = "http"
# This should include all of your mail domains, and main= should be your $TRAEFIK_DOMAIN
[[acme.domains]]
- main = "mail.your.doma.in"
- sans = ["web.mail.your.doma.in", "smtp.mail.doma.in", "imap.mail.doma.in"]
+ main = "mail.example.com"
+ sans = ["web.mail.example.com", "smtp.mail.example.com", "imap.mail.example.com"]
diff --git a/docs/configuration.rst b/docs/configuration.rst
index 21effc52..27f8db7d 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -37,6 +37,8 @@ The ``POSTMASTER`` is the local part of the postmaster email address. It is
recommended to setup a generic value and later configure a mail alias for that
address.
+The ``WILDCARD_SENDERS`` setting is a comma delimited list of user email addresses that are allowed to send emails from any existing address (spoofing the sender).
+
The ``AUTH_RATELIMIT`` holds a security setting for fighting attackers that
try to guess user passwords. The value is the limit of failed authentication attempts
that a single IP address can perform against IMAP, POP and SMTP authentication endpoints.
@@ -70,8 +72,8 @@ mail in following format: ``[HOST]:PORT``.
``RELAYUSER`` and ``RELAYPASSWORD`` can be used when authentication is needed.
By default postfix uses "opportunistic TLS" for outbound mail. This can be changed
-by setting ``OUTBOUND_TLS_LEVEL`` to ``encrypt``. This setting is highly recommended
-if you are a relayhost that supports TLS.
+by setting ``OUTBOUND_TLS_LEVEL`` to ``encrypt`` or ``secure``. This setting is highly recommended
+if you are using a relayhost that supports TLS.
Similarily by default nginx uses "opportunistic TLS" for inbound mail. This can be changed
by setting ``INBOUND_TLS_ENFORCE`` to ``True``. Please note that this is forbidden for
@@ -163,6 +165,11 @@ See the `python docs`_ for more information.
.. _`python docs`: https://docs.python.org/3.6/library/logging.html#logging-levels
+The ``LETSENCRYPT_SHORTCHAIN`` (default: False) setting controls whether we send the ISRG Root X1 certificate in TLS handshakes. This is required for `android handsets older than 7.1.1` but slows down the performance of modern devices.
+
+.. _`android handsets older than 7.1.1`: https://community.letsencrypt.org/t/production-chain-changes/150739
+
+
Antivirus settings
------------------
diff --git a/docs/kubernetes/mailu/admin.yaml b/docs/kubernetes/mailu/admin.yaml
deleted file mode 100644
index 08c06e44..00000000
--- a/docs/kubernetes/mailu/admin.yaml
+++ /dev/null
@@ -1,63 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: mailu-admin
- namespace: mailu-mailserver
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-admin
- role: mail
- tier: backend
- spec:
- containers:
- - name: admin
- image: mailu/admin:master
- imagePullPolicy: Always
- envFrom:
- - configMapRef:
- name: mailu-config
- volumeMounts:
- - name: maildata
- mountPath: /data
- subPath: maildata
- - name: maildata
- mountPath: /dkim
- subPath: dkim
- ports:
- - name: http
- containerPort: 80
- protocol: TCP
- resources:
- requests:
- memory: 500Mi
- cpu: 500m
- limits:
- memory: 500Mi
- cpu: 500m
- volumes:
- - name: maildata
- persistentVolumeClaim:
- claimName: mail-storage
----
-
-apiVersion: v1
-kind: Service
-metadata:
- name: admin
- namespace: mailu-mailserver
- labels:
- app: mailu-admin
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-admin
- role: mail
- tier: backend
- ports:
- - name: http
- port: 80
- protocol: TCP
diff --git a/docs/kubernetes/mailu/configmap.yaml b/docs/kubernetes/mailu/configmap.yaml
deleted file mode 100644
index 6a674c53..00000000
--- a/docs/kubernetes/mailu/configmap.yaml
+++ /dev/null
@@ -1,175 +0,0 @@
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: mailu-config
- namespace: mailu-mailserver
- data:
- # Mailu main configuration file
- #
- # Most configuration variables can be modified through the Web interface,
- # these few settings must however be configured before starting the mail
- # server and require a restart upon change.
-
- ###################################
- # Common configuration variables
- ###################################
-
- # Set this to the path where Mailu data and configuration is stored
- ROOT: "/mailu"
-
- # Mailu version to run (1.0, 1.1, etc. or master)
- VERSION: "master"
-
- # Set to a randomly generated 16 bytes string
- SECRET_KEY: "MySup3rS3cr3tPas"
-
- # Address where listening ports should bind
- BIND_ADDRESS4: "127.0.0.1"
- #BIND_ADDRESS6: "::1"
-
- # Main mail domain
- DOMAIN: "example.com"
-
- # Hostnames for this server, separated with comas
- HOSTNAMES: "mail.example.com"
-
- # Postmaster local part (will append the main mail domain)
- POSTMASTER: "admin"
-
- # Choose how secure connections will behave (value: letsencrypt, cert, notls, mail, mail-letsencrypt)
- TLS_FLAVOR: "cert"
-
- # Authentication rate limit (per source IP address)
- AUTH_RATELIMIT: "10/minute;1000/hour"
-
- # Opt-out of statistics, replace with "True" to opt out
- DISABLE_STATISTICS: "False"
-
- ###################################
- # Kubernetes configuration
- ###################################
-
- # Use Kubernetes Ingress Controller to handle all actions on port 80 and 443
- # This way we can make use of the advantages of the cert-manager deployment
- KUBERNETES_INGRESS: "true"
-
- # POD_ADDRESS_RANGE is normally provided by default with Kubernetes
- # Only use this value when you are using Flannel, Calico or a special kind of CNI
- # Provide the IPs of your network interface or bridge which is used for VXLAN network traffic
- # POD_ADDRESS_RANGE: 10.2.0.0/16,10.1.6.0/24
-
- ###################################
- # Optional features
- ###################################
-
- # Expose the admin interface (value: true, false)
- ADMIN: "true"
- # Run the admin interface in debug mode
- #DEBUG: "True"
-
- # Choose which webmail to run if any (values: roundcube, rainloop, none)
- WEBMAIL: "roundcube"
-
- # Dav server implementation (value: radicale, none)
- WEBDAV: "radicale"
-
- # Antivirus solution (value: clamav, none)
- ANTIVIRUS: "clamav"
-
- ###################################
- # Mail settings
- ###################################
-
- # Message size limit in bytes
- # Default: accept messages up to 50MB
- MESSAGE_SIZE_LIMIT: "50000000"
-
- # Will relay all outgoing mails if configured
- #RELAYHOST=
-
- # This part is needed for the XCLIENT login for postfix. This should be the POD ADDRESS range
- FRONT_ADDRESS: "front.mailu-mailserver.svc.cluster.local"
-
- # This value is needed by the webmail to find the correct imap backend
- IMAP_ADDRESS: "imap.mailu-mailserver.svc.cluster.local"
-
- # This value is used by Dovecot to find the Redis server in the cluster
- REDIS_ADDRESS: "redis.mailu-mailserver.svc.cluster.local"
-
- # Fetchmail delay
- FETCHMAIL_DELAY: "600"
-
- # Recipient delimiter, character used to delimiter localpart from custom address part
- # e.g. localpart+custom@domain;tld
- RECIPIENT_DELIMITER: "+"
-
- # DMARC rua and ruf email
- DMARC_RUA: "root"
- DMARC_RUF: "root"
-
- # Welcome email, enable and set a topic and body if you wish to send welcome
- # emails to all users.
- WELCOME: "false"
- WELCOME_SUBJECT: "Welcome to your new email account"
- WELCOME_BODY: "Welcome to your new email account, if you can read this, then it is configured properly!"
-
- ###################################
- # Web settings
- ###################################
-
- # Path to the admin interface if enabled
- # Kubernetes addition: You need to change ALL the ingresses, when you want this URL to be different!!!
- WEB_ADMIN: "/admin"
-
- # Path to the webmail if enabled
- # Currently, this is not used, because we intended to use a different subdomain: webmail.example.com
- # This option can be added in a feature release
- WEB_WEBMAIL: "/webmail"
-
- # Website name
- SITENAME: "Mailu"
-
- # Linked Website URL
- WEBSITE: "https://example.com"
-
- # Registration reCaptcha settings (warning, this has some privacy impact)
- # RECAPTCHA_PUBLIC_KEY=
- # RECAPTCHA_PRIVATE_KEY=
-
- # Domain registration, uncomment to enable
- # DOMAIN_REGISTRATION=true
-
- ###################################
- # Advanced settings
- ###################################
-
- # Create an admin account if it does not exist yet. It will also create the email domain for the account.
- # INITIAL_ADMIN_ACCOUNT: "admin"
- # INITIAL_ADMIN_DOMAIN: "example.com"
- # INITIAL_ADMIN_PW: "s3cr3t"
-
- # Docker-compose project name, this will prepended to containers names.
- COMPOSE_PROJECT_NAME: "mailu"
-
- # Default password scheme used for newly created accounts and changed passwords
- # (value: SHA512-CRYPT, SHA256-CRYPT, MD5-CRYPT, CRYPT)
- PASSWORD_SCHEME: "SHA512-CRYPT"
-
- # Header to take the real ip from
- #REAL_IP_HEADER:
-
- # IPs for nginx set_real_ip_from (CIDR list separated by commas)
- #REAL_IP_FROM:
-
- # Host settings
- HOST_IMAP: "imap.mailu-mailserver.svc.cluster.local"
- HOST_POP3: "imap.mailu-mailserver.svc.cluster.local"
- HOST_SMTP: "smtp.mailu-mailserver.svc.cluster.local"
- HOST_AUTHSMTP: "smtp.mailu-mailserver.svc.cluster.local"
- HOST_WEBMAIL: "webmail.mailu-mailserver.svc.cluster.local"
- HOST_ADMIN: "admin.mailu-mailserver.svc.cluster.local"
- HOST_WEBDAV: "webdav.mailu-mailserver.svc.cluster.local:5232"
- HOST_ANTISPAM_MILTER: "antispam.mailu-mailserver.svc.cluster.local:11332"
- HOST_ANTISPAM_WEBUI: "antispam.mailu-mailserver.svc.cluster.local:11334"
- HOST_ANTIVIRUS: "antivirus.mailu-mailserver.svc.cluster.local:3310"
- HOST_REDIS: "redis.mailu-mailserver.svc.cluster.local"
diff --git a/docs/kubernetes/mailu/fetchmail.yaml b/docs/kubernetes/mailu/fetchmail.yaml
deleted file mode 100644
index d454f95b..00000000
--- a/docs/kubernetes/mailu/fetchmail.yaml
+++ /dev/null
@@ -1,39 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: mailu-fetchmail
- namespace: mailu-mailserver
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-fetchmail
- role: mail
- tier: backend
- spec:
- containers:
- - name: fetchmail
- image: mailu/fetchmail:master
- imagePullPolicy: Always
- envFrom:
- - configMapRef:
- name: mailu-config
- volumeMounts:
- - name: maildata
- mountPath: /data
- subPath: maildata
- ports:
- - containerPort: 5232
- - containerPort: 80
- resources:
- requests:
- memory: 100Mi
- cpu: 100m
- limits:
- memory: 100Mi
- cpu: 100m
- volumes:
- - name: maildata
- persistentVolumeClaim:
- claimName: mail-storage
diff --git a/docs/kubernetes/mailu/front.yaml b/docs/kubernetes/mailu/front.yaml
deleted file mode 100644
index 2fba1026..00000000
--- a/docs/kubernetes/mailu/front.yaml
+++ /dev/null
@@ -1,148 +0,0 @@
-apiVersion: apps/v1
-kind: DaemonSet
-metadata:
- name: mailu-front
- namespace: mailu-mailserver
- labels:
- k8s-app: mail-loadbalancer
- component: ingress-controller
- type: nginx
-spec:
- selector:
- matchLabels:
- k8s-app: mail-loadbalancer
- component: ingress-controller
- type: nginx
- template:
- metadata:
- labels:
- k8s-app: mail-loadbalancer
- component: ingress-controller
- type: nginx
- spec:
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: node-role.kubernetes.io/node
- operator: Exists
- nodeSelector:
- node-role.kubernetes.io/node: ""
- dnsPolicy: ClusterFirstWithHostNet
- restartPolicy: Always
- terminationGracePeriodSeconds: 60
- containers:
- - name: front
- image: mailu/nginx:master
- imagePullPolicy: Always
- envFrom:
- - configMapRef:
- name: mailu-config
- volumeMounts:
- - name: certs
- mountPath: /certs
- ports:
- - name: pop3
- containerPort: 110
- hostPort: 110
- protocol: TCP
- - name: pop3s
- containerPort: 995
- hostPort: 995
- protocol: TCP
- - name: imap
- containerPort: 143
- hostPort: 143
- protocol: TCP
- - name: imaps
- containerPort: 993
- hostPort: 993
- protocol: TCP
- - name: smtp
- containerPort: 25
- hostPort: 25
- protocol: TCP
- - name: smtps
- containerPort: 465
- hostPort: 465
- protocol: TCP
- - name: smtpd
- containerPort: 587
- hostPort: 587
- protocol: TCP
- # internal services (not exposed externally)
- - name: smtp-auth
- containerPort: 10025
- protocol: TCP
- - name: imap-auth
- containerPort: 10143
- protocol: TCP
- - name: auth
- containerPort: 8000
- protocol: TCP
- - name: http
- containerPort: 80
- protocol: TCP
- resources:
- requests:
- memory: 100Mi
- cpu: 100m
- limits:
- memory: 200Mi
- cpu: 200m
- volumes:
- - name: certs
- secret:
- items:
- - key: tls.crt
- path: cert.pem
- - key: tls.key
- path: key.pem
- secretName: letsencrypt-certs-all
----
-apiVersion: v1
-kind: Service
-metadata:
- name: front
- namespace: mailu-mailserver
- labels:
- k8s-app: mail-loadbalancer
- component: ingress-controller
- type: nginx
-spec:
- selector:
- k8s-app: mail-loadbalancer
- component: ingress-controller
- type: nginx
- ports:
- - name: pop3
- port: 110
- protocol: TCP
- - name: pop3s
- port: 995
- protocol: TCP
- - name: imap
- port: 143
- protocol: TCP
- - name: imaps
- port: 993
- protocol: TCP
- - name: smtp
- port: 25
- protocol: TCP
- - name: smtps
- port: 465
- protocol: TCP
- - name: smtpd
- port: 587
- protocol: TCP
- - name: smtp-auth
- port: 10025
- protocol: TCP
- - name: imap-auth
- port: 10143
- protocol: TCP
- - name: http
- port: 80
- protocol: TCP
diff --git a/docs/kubernetes/mailu/imap.yaml b/docs/kubernetes/mailu/imap.yaml
deleted file mode 100644
index 64e69930..00000000
--- a/docs/kubernetes/mailu/imap.yaml
+++ /dev/null
@@ -1,84 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: mailu-imap
- namespace: mailu-mailserver
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-imap
- role: mail
- tier: backend
- spec:
- containers:
- - name: imap
- image: mailu/dovecot:master
- imagePullPolicy: Always
- envFrom:
- - configMapRef:
- name: mailu-config
- volumeMounts:
- - mountPath: /data
- name: maildata
- subPath: maildata
- - mountPath: /mail
- name: maildata
- subPath: mailstate
- - mountPath: /overrides
- name: maildata
- subPath: overrides
- ports:
- - name: imap-auth
- containerPort: 2102
- - name: imap-transport
- containerPort: 2525
- - name: pop3
- containerPort: 110
- - name: imap-default
- containerPort: 143
- - name: sieve
- containerPort: 4190
- resources:
- requests:
- memory: 1Gi
- cpu: 1000m
- limits:
- memory: 1Gi
- cpu: 1000m
- volumes:
- - name: maildata
- persistentVolumeClaim:
- claimName: mail-storage
----
-apiVersion: v1
-kind: Service
-metadata:
- name: imap
- namespace: mailu-mailserver
- labels:
- app: mailu
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-imap
- role: mail
- tier: backend
- ports:
- - name: imap-auth
- port: 2102
- protocol: TCP
- - name: imap-transport
- port: 2525
- protocol: TCP
- - name: pop3
- port: 110
- protocol: TCP
- - name: imap-default
- port: 143
- protocol: TCP
- - name: sieve
- port: 4190
- protocol: TCP
diff --git a/docs/kubernetes/mailu/index.rst b/docs/kubernetes/mailu/index.rst
index 0af3942e..853f3689 100644
--- a/docs/kubernetes/mailu/index.rst
+++ b/docs/kubernetes/mailu/index.rst
@@ -3,222 +3,9 @@
Kubernetes setup
================
-> Hold up!
-> These instructions are not recommended for setting up Mailu in a production Kubernetes environment.
-> Please see [the Helm Chart documentation](https://github.com/Mailu/helm-charts/blob/master/mailu/README.md).
+Please see `the Helm Chart documentation`_.
-Prequisites
------------
+We are looking for maintainers: if you are interested please join our `Matrix`_ room.
-Structure
-~~~~~~~~~
-
-There’s chosen to have a double NGINX stack for Mailu, this way the main
-ingress can still be used to access other websites/domains on your
-cluster. This is the current structure:
-
-- ``NGINX Ingress controller``: Listens to the nodes ports 80 & 443. We have chosen to have a double NGINX stack for Mailu.
-- ``Cert manager``: Creates automatic Lets Encrypt certificates based on an ``Ingress``-objects domain name.
-- ``Mailu NGINX Front daemonset``: This daemonset runs in parallel with the Nginx Ingress Controller and only listens on all E-mail specific ports (25, 110, 143, 587,...). It also listens on 80 and delegates the various http endpoints to the correct services.
-- ``Mailu components``: All Mailu components (imap, smtp, security, webmail,...) are split into separate files to make them more handy to use, you can find the ``YAML`` files in this directory
-
-What you need
-~~~~~~~~~~~~~
-
-- A working Kubernetes cluster (tested with 1.10.5)
-- A working `cert-manager`_ installation
-- A working nginx-ingress controller needed for the lets-encrypt
- certificates. You can find those files in the ``nginx`` subfolder.
- Other ingress controllers that support cert-manager (e.g. traefik)
- should also work.
-
-Cert manager
-^^^^^^^^^^^^
-
-The ``Cert-manager`` is quite easy to deploy using Helm when reading the
-`docs`_. After booting the ``Cert-manager`` you’ll need a
-``ClusterIssuer`` which takes care of all required certificates through
-``Ingress`` items. We chose to provide a ``clusterIssuer`` so you can provide SSL certificates
-for other namespaces (different websites/services), if you don't need this option, you can easily change this by
-changing ``clusterIssuer`` to ``Issuer`` and adding the ``namespace: mailu-mailserver`` to the metadata.
-An example of a production and a staging ``clusterIssuer``:
-
-.. code:: yaml
-
- # This clusterIssuer example uses the staging environment for testing first
- apiVersion: certmanager.k8s.io/v1alpha1
- kind: ClusterIssuer
- metadata:
- name: letsencrypt-stage
- spec:
- acme:
- email: something@example.com
- http01: {}
- privateKeySecretRef:
- name: letsencrypt-stage
- server: https://acme-staging-v02.api.letsencrypt.org/directory
-
-.. code:: yaml
-
- # This clusterIssuer example uses the production environment
- apiVersion: certmanager.k8s.io/v1alpha1
- kind: ClusterIssuer
- metadata:
- name: letsencrypt-prod
- spec:
- acme:
- email: something@example.com
- http01: {}
- privateKeySecretRef:
- name: letsencrypt-prod
- server: https://acme-v02.api.letsencrypt.org/directory
-
-**IMPORTANT**: ``ingress.yaml`` uses the ``letsencrypt-stage`` ``clusterIssuer``. If you are ready for production,
-change this field in ``ingress.yaml`` file to ``letsencrypt-prod`` or whatever name you chose for the production.
-If you choose for ``Issuer`` instead of ``clusterIssuer`` you also need to change the annotation to ``certmanager.k8s.io/issuer`` instead of ``certmanager.k8s.io/cluster-issuer``
-
-Deploying Mailu
----------------
-
-All manifests can be found in the ``mailu`` subdirectory. All commands
-below need to be run from this subdirectory
-
-Personalization
-~~~~~~~~~~~~~~~
-
-- All services run in the same namespace, currently ``mailu-mailserver``. So if you want to use a different one, change the ``namespace`` value in **every** file
-- Check the ``storage-class`` field in the ``pvc.yaml`` file, you can also change the sizes to your liking. Note that you need ``RWX`` (read-write-many) and ``RWO`` (read-write-once) storageclasses.
-- Check the ``configmap.yaml`` and adapt it to your needs. Be sure to check the kubernetes DNS values at the end (if you use a different namespace)
-- Check the ``ingress.yaml`` file and change it to the domain you want (this is for the kubernetes ingress controller to handle the admin, webmail, webdav and auth connections)
-
-Installation
-------------
-
-Boot the Mailu components
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To start Mailu, run the following commands from the ``docs/kubernetes/mailu`` directory
-
-.. code-block:: bash
-
- kubectl create -f rbac.yaml
- kubectl create -f configmap.yaml
- kubectl create -f pvc.yaml
- kubectl create -f redis.yaml
- kubectl create -f front.yaml
- kubectl create -f webmail.yaml
- kubectl create -f imap.yaml
- kubectl create -f security.yaml
- kubectl create -f smtp.yaml
- kubectl create -f fetchmail.yaml
- kubectl create -f admin.yaml
- kubectl create -f webdav.yaml
- kubectl create -f ingress.yaml
-
-
-Create the first admin account
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When the cluster is online you need to create you master user to access https://mail.example.com/admin
-
-You can create it now manually, or have the system create it automatically.
-
-If you want the system to create the admin user account automatically, see :ref:`admin_account`
-about the environment variables needed (``INITIAL_ADMIN_*``).
-Also, important, taking into consideration that a pod in Kubernetes can be stopped/rescheduled at
-any time, you should set ``INITIAL_ADMIN_MODE`` to either ``update`` or ``ifmissing`` - depending on what you
-want to happen to its password.
-
-
-To create the admin user account manually, enter the main ``admin`` pod:
-
-.. code-block:: bash
-
- kubectl -n mailu-mailserver get po
- kubectl -n mailu-mailserver exec -it mailu-admin-.... /bin/sh
-
-And in the pod run the following command. The command uses following entries:
-
-.. code-block:: bash
-
- flask mailu admin root example.com password
-
-- ``admin`` Make it an admin user
-- ``root`` The first part of the e-mail address (ROOT@example.com)
-- ``example.com`` the domain appendix
-- ``password`` the chosen password for the user
-
-
-Now you should be able to login on the mail account: https://mail.example.com/admin
-
-
-Adaptations
------------
-
-Dovecot
-~~~~~~~
-
-- If you are using Dovecot on a shared file system (Glusterfs, NFS,...), you need to create a special override otherwise a lot of indexing errors will occur on your Dovecot pod.
-- I also higher the number of max connections per IP. Now it's limited to 10.
-
-Enter the dovecot pod:
-
-.. code:: bash
-
- kubectl -n mailu-mailserver get po
- kubectl -n mailu-mailserver exec -it mailu-imap-.... /bin/sh
-
-Create the file ``overrides/dovecot.conf``
-
-.. code:: bash
-
- vi /overrides/dovecot.conf
-
-And enter following contents:
-
-.. code:: bash
-
- mail_nfs_index = yes
- mail_nfs_storage = yes
- mail_fsync = always
- mmap_disable = yes
- mail_max_userip_connections=100
-
-Save and close the file and delete the imap pod to get it recreated.
-
-.. code:: bash
-
- kubectl -n mailu-mailserver delete po/mailu-imap-....
-
-Wait for the pod to recreate and you're online!
-Happy mailing!
-
-.. _here: https://github.com/hacor/Mailu/blob/master/core/postfix/conf/main.cf#L35
-.. _cert-manager: https://github.com/jetstack/cert-manager
-.. _docs: https://cert-manager.io/docs/installation/kubernetes/#installing-with-helm
-
-Imap login fix
-~~~~~~~~~~~~~~
-
-If it seems you're not able to login using IMAP on your Mailu accounts, check the logs of the imap container to see whether it's a permissions problem on the database.
-This problem can be easily fixed by running following commands:
-
-.. code:: bash
-
- kubectl -n mailu-mailserver exec -it mailu-imap-... /bin/sh
- chmod 777 /data/main.db
-
-If the login problem still persists, or more specific, happens now and then and you see some Auth problems on your webmail or mail client, try following steps:
-
-- Add ``auth_debug=yes`` to the ``/overrides/dovecot.conf`` file and delete the pod in order to start a new one, which loads the configuration
-- Depending on your network configuration you could still see some ``allow_nets check failed`` results in the logs. This means that the IP is not allowed a login
-- If this is happening your network plugin has troubles with the Nginx Ingress Controller using the ``hostNetwork: true`` option. Known cases: Flannel and Calico.
-- You should uncomment ``POD_ADDRESS_RANGE`` in the ``configmap.yaml`` file and add the IP range of your pod network bridge (the range that sadly has failed the ``allowed_nets`` test)
-- Delete the Admin pod and wait for it to restart
-
-.. code:: bash
-
- kubectl -n mailu-mailserver get po
- kubectl -n mailu-mailserver delete po/mailu-admin...
-
-Happy mailing!
+.. _`the Helm Chart documentation`: https://github.com/Mailu/helm-charts/blob/master/mailu/README.md
+.. _`Matrix`: https://matrix.to/#/#mailu:tedomum.net
diff --git a/docs/kubernetes/mailu/ingress.yaml b/docs/kubernetes/mailu/ingress.yaml
deleted file mode 100644
index 5a941e97..00000000
--- a/docs/kubernetes/mailu/ingress.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-apiVersion: apps/v1
-kind: Ingress
-metadata:
- name: mailu-ingress
- namespace: mailu-mailserver
- annotations:
- kubernetes.io/tls-acme: "true"
- certmanager.k8s.io/cluster-issuer: letsencrypt-stage
- labels:
- app: mailu
- role: mail
- tier: backend
-spec:
- tls:
- - hosts:
- - "mail.example.com"
- secretName: letsencrypt-certs-all # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt
- rules:
- - host: "mail.example.com"
- http:
- paths:
- - path: "/"
- backend:
- serviceName: front
- servicePort: 80
diff --git a/docs/kubernetes/mailu/pvc.yaml b/docs/kubernetes/mailu/pvc.yaml
deleted file mode 100644
index 0ec2852f..00000000
--- a/docs/kubernetes/mailu/pvc.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-kind: PersistentVolumeClaim
-apiVersion: v1
-metadata:
- name: redis-hdd
- namespace: mailu-mailserver
- annotations:
- volume.beta.kubernetes.io/storage-class: "glusterblock-hdd"
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 1Gi
----
-kind: PersistentVolumeClaim
-apiVersion: v1
-metadata:
- name: mail-storage
- namespace: mailu-mailserver
- annotations:
- volume.beta.kubernetes.io/storage-class: "gluster-heketi-hdd"
-spec:
- accessModes:
- - ReadWriteMany
- resources:
- requests:
- storage: 100Gi
diff --git a/docs/kubernetes/mailu/rbac.yaml b/docs/kubernetes/mailu/rbac.yaml
deleted file mode 100644
index 33255130..00000000
--- a/docs/kubernetes/mailu/rbac.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-apiVersion: v1
-kind: Namespace
-metadata:
- name: mailu-mailserver
\ No newline at end of file
diff --git a/docs/kubernetes/mailu/redis.yaml b/docs/kubernetes/mailu/redis.yaml
deleted file mode 100644
index f453a3ff..00000000
--- a/docs/kubernetes/mailu/redis.yaml
+++ /dev/null
@@ -1,60 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: mailu-redis
- namespace: mailu-mailserver
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: mailu-redis
- role: mail
- tier: backend
- template:
- metadata:
- labels:
- app: mailu-redis
- role: mail
- tier: backend
- spec:
- containers:
- - name: redis
- image: redis:5-alpine
- imagePullPolicy: Always
- volumeMounts:
- - mountPath: /data
- name: redisdata
- ports:
- - containerPort: 6379
- name: redis
- protocol: TCP
- resources:
- requests:
- memory: 200Mi
- cpu: 100m
- limits:
- memory: 300Mi
- cpu: 200m
- volumes:
- - name: redisdata
- persistentVolumeClaim:
- claimName: redis-hdd
----
-apiVersion: v1
-kind: Service
-metadata:
- name: redis
- namespace: mailu-mailserver
- labels:
- app: mailu-redis
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-redis
- role: mail
- tier: backend
- ports:
- - name: redis
- port: 6379
- protocol: TCP
diff --git a/docs/kubernetes/mailu/security.yaml b/docs/kubernetes/mailu/security.yaml
deleted file mode 100644
index 419c7ac4..00000000
--- a/docs/kubernetes/mailu/security.yaml
+++ /dev/null
@@ -1,115 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: mailu-security
- namespace: mailu-mailserver
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-security
- role: mail
- tier: backend
- spec:
- containers:
- - name: antispam
- image: mailu/rspamd:master
- imagePullPolicy: Always
- envFrom:
- - configMapRef:
- name: mailu-config
- resources:
- requests:
- memory: 100Mi
- cpu: 100m
- limits:
- memory: 200Mi
- cpu: 200m
- ports:
- - name: antispam
- containerPort: 11332
- protocol: TCP
- - name: antispam-http
- containerPort: 11334
- protocol: TCP
- volumeMounts:
- - name: filter
- subPath: filter
- mountPath: /var/lib/rspamd
- - name: filter
- mountPath: /dkim
- subPath: dkim
- - name: filter
- mountPath: /etc/rspamd/override.d
- subPath: rspamd-overrides
- - name: antivirus
- image: mailu/clamav:master
- imagePullPolicy: Always
- resources:
- requests:
- memory: 1Gi
- cpu: 1000m
- limits:
- memory: 2Gi
- cpu: 1000m
- envFrom:
- - configMapRef:
- name: mailu-config
- ports:
- - name: antivirus
- containerPort: 3310
- protocol: TCP
- volumeMounts:
- - name: filter
- subPath: filter
- mountPath: /data
- volumes:
- - name: filter
- persistentVolumeClaim:
- claimName: mail-storage
-
----
-
-apiVersion: v1
-kind: Service
-metadata:
- name: antispam
- namespace: mailu-mailserver
- labels:
- app: mailu-antispam
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-security
- role: mail
- tier: backend
- ports:
- - name: antispam
- port: 11332
- protocol: TCP
- - name: antispam-http
- protocol: TCP
- port: 11334
-
----
-
-apiVersion: v1
-kind: Service
-metadata:
- name: antivirus
- namespace: mailu-mailserver
- labels:
- app: mailu-antivirus
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-security
- role: mail
- tier: backend
- ports:
- - name: antivirus
- port: 3310
- protocol: TCP
diff --git a/docs/kubernetes/mailu/smtp.yaml b/docs/kubernetes/mailu/smtp.yaml
deleted file mode 100644
index 6002d508..00000000
--- a/docs/kubernetes/mailu/smtp.yaml
+++ /dev/null
@@ -1,80 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: mailu-smtp
- namespace: mailu-mailserver
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-smtp
- role: mail
- tier: backend
- spec:
- containers:
- - name: smtp
- image: mailu/postfix:master
- imagePullPolicy: Always
- envFrom:
- - configMapRef:
- name: mailu-config
- resources:
- requests:
- memory: 2Gi
- cpu: 500m
- limits:
- memory: 2Gi
- cpu: 500m
- volumeMounts:
- - mountPath: /queue
- name: maildata
- subPath: mailqueue
- - mountPath: /overrides
- name: maildata
- subPath: overrides
- ports:
- - name: smtp
- containerPort: 25
- protocol: TCP
- - name: smtp-ssl
- containerPort: 465
- protocol: TCP
- - name: smtp-starttls
- containerPort: 587
- protocol: TCP
- - name: smtp-auth
- containerPort: 10025
- protocol: TCP
- volumes:
- - name: maildata
- persistentVolumeClaim:
- claimName: mail-storage
----
-apiVersion: v1
-kind: Service
-metadata:
- name: smtp
- namespace: mailu-mailserver
- labels:
- app: mailu
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-smtp
- role: mail
- tier: backend
- ports:
- - name: smtp
- port: 25
- protocol: TCP
- - name: smtp-ssl
- port: 465
- protocol: TCP
- - name: smtp-starttls
- port: 587
- protocol: TCP
- - name: smtp-auth
- port: 10025
- protocol: TCP
diff --git a/docs/kubernetes/mailu/webdav.yaml b/docs/kubernetes/mailu/webdav.yaml
deleted file mode 100644
index 57dde9a9..00000000
--- a/docs/kubernetes/mailu/webdav.yaml
+++ /dev/null
@@ -1,63 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: mailu-webdav
- namespace: mailu-mailserver
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-webdav
- role: mail
- tier: backend
- spec:
- containers:
- - name: radicale
- image: mailu/radicale:master
- imagePullPolicy: Always
- envFrom:
- - configMapRef:
- name: mailu-config
- volumeMounts:
- - mountPath: /data
- name: maildata
- subPath: dav
- ports:
- - containerPort: 5232
- - containerPort: 80
- resources:
- requests:
- memory: 100Mi
- cpu: 100m
- limits:
- memory: 100Mi
- cpu: 100m
- volumes:
- - name: maildata
- persistentVolumeClaim:
- claimName: mail-storage
----
-
-apiVersion: v1
-kind: Service
-metadata:
- name: webdav
- namespace: mailu-mailserver
- labels:
- app: mailu-webdav
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-webdav
- role: mail
- tier: backend
- ports:
- ports:
- - name: http
- port: 80
- protocol: TCP
- - name: http-ui
- port: 5232
- protocol: TCP
diff --git a/docs/kubernetes/mailu/webmail.yaml b/docs/kubernetes/mailu/webmail.yaml
deleted file mode 100644
index 679ea84a..00000000
--- a/docs/kubernetes/mailu/webmail.yaml
+++ /dev/null
@@ -1,57 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: mailu-roundcube
- namespace: mailu-mailserver
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-roundcube
- role: mail
- tier: frontend
- spec:
- containers:
- - name: roundcube
- image: mailu/roundcube:master
- imagePullPolicy: Always
- envFrom:
- - configMapRef:
- name: mailu-config
- resources:
- requests:
- memory: 100Mi
- cpu: 100m
- limits:
- memory: 200Mi
- cpu: 200m
- volumeMounts:
- - mountPath: /data
- name: maildata
- subPath: webmail
- ports:
- - containerPort: 80
- volumes:
- - name: maildata
- persistentVolumeClaim:
- claimName: mail-storage
----
-apiVersion: v1
-kind: Service
-metadata:
- name: webmail
- namespace: mailu-mailserver
- labels:
- app: mailu-roundcube
- role: mail
- tier: frontend
-spec:
- selector:
- app: mailu-roundcube
- role: mail
- tier: frontend
- ports:
- - name: http
- port: 80
- protocol: TCP
diff --git a/docs/kubernetes/nginx/default-http-backend.yaml b/docs/kubernetes/nginx/default-http-backend.yaml
deleted file mode 100644
index cf881c53..00000000
--- a/docs/kubernetes/nginx/default-http-backend.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: default-http-backend
- labels:
- app: default-http-backend
- namespace: kube-ingress
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: default-http-backend
- template:
- metadata:
- labels:
- app: default-http-backend
- spec:
- terminationGracePeriodSeconds: 60
- containers:
- - name: default-http-backend
- # Any image is permissible as long as:
- # 1. It serves a 404 page at /
- # 2. It serves 200 on a /healthz endpoint
- image: gcr.io/google_containers/defaultbackend:1.4
- livenessProbe:
- httpGet:
- path: /healthz
- port: 8080
- scheme: HTTP
- initialDelaySeconds: 30
- timeoutSeconds: 5
- ports:
- - containerPort: 8080
- resources:
- limits:
- cpu: 10m
- memory: 20Mi
- requests:
- cpu: 10m
- memory: 20Mi
----
-
-apiVersion: v1
-kind: Service
-metadata:
- name: default-http-backend
- namespace: kube-ingress
- labels:
- app: default-http-backend
-spec:
- ports:
- - port: 80
- targetPort: 8080
- selector:
- app: default-http-backend
diff --git a/docs/kubernetes/nginx/nginx-ingress.yaml b/docs/kubernetes/nginx/nginx-ingress.yaml
deleted file mode 100644
index d8b71e21..00000000
--- a/docs/kubernetes/nginx/nginx-ingress.yaml
+++ /dev/null
@@ -1,127 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- # keep it under 24 chars
- name: ingress-lb
- namespace: kube-ingress
- labels:
- k8s-app: ingress-lb
- component: ingress-controller
-spec:
- type: ClusterIP
- selector:
- k8s-app: ingress-lb
- component: ingress-controller
- ports:
- - name: http
- protocol: TCP
- port: 80
- targetPort: 80
- - name: https
- protocol: TCP
- port: 443
- targetPort: 443
----
-kind: ConfigMap
-apiVersion: v1
-metadata:
- name: udp-services
- namespace: kube-ingress
-
----
-kind: ConfigMap
-apiVersion: v1
-metadata:
- name: tcp-services
- namespace: kube-ingress
-data:
-
----
-apiVersion: v1
-data:
- enable-vts-status: "true"
-kind: ConfigMap
-metadata:
- name: nginx-ingress-lb-conf
- namespace: kube-ingress
----
-apiVersion: apps/v1beta2
-kind: DaemonSet
-metadata:
- name: ingress-controller
- namespace: kube-ingress
- annotations:
- prometheus.io/port: "10254"
- prometheus.io/scrape: "true"
- labels:
- k8s-app: ingress-lb
- component: ingress-controller
- type: nginx
-spec:
- updateStrategy:
- rollingUpdate:
- maxUnavailable: 1
- type: RollingUpdate
- selector:
- matchLabels:
- k8s-app: ingress-lb
- component: ingress-controller
- type: nginx
- template:
- metadata:
- labels:
- k8s-app: ingress-lb
- component: ingress-controller
- type: nginx
- spec:
- serviceAccount: kube-nginx-ingress
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: node-role.kubernetes.io/master
- operator: DoesNotExist
- containers:
- - name: nginx-ingress-lb
- image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.16.2
- args:
- - /nginx-ingress-controller
- - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- - --annotations-prefix=ingress.kubernetes.io
- - --enable-ssl-passthrough
- # use downward API
- env:
- - name: POD_NAME
- valueFrom:
- fieldRef:
- fieldPath: metadata.name
- - name: POD_NAMESPACE
- valueFrom:
- fieldRef:
- fieldPath: metadata.namespace
- ports:
- - name: http
- containerPort: 80
- - name: https
- containerPort: 443
- readinessProbe:
- httpGet:
- path: /healthz
- port: 10254
- scheme: HTTP
- livenessProbe:
- initialDelaySeconds: 10
- timeoutSeconds: 1
- httpGet:
- path: /healthz
- port: 10254
- scheme: HTTP
- hostNetwork: true
- nodeSelector:
- node-role.kubernetes.io/node: ""
- dnsPolicy: ClusterFirstWithHostNet
- restartPolicy: Always
- terminationGracePeriodSeconds: 60
diff --git a/docs/kubernetes/nginx/rbac.yaml b/docs/kubernetes/nginx/rbac.yaml
deleted file mode 100644
index d3c01384..00000000
--- a/docs/kubernetes/nginx/rbac.yaml
+++ /dev/null
@@ -1,129 +0,0 @@
-apiVersion: v1
-kind: Namespace
-metadata:
- name: kube-ingress
----
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: kube-nginx-ingress
- namespace: kube-ingress
----
-apiVersion: rbac.authorization.k8s.io/v1beta1
-kind: ClusterRole
-metadata:
- name: kube-nginx-ingress
-rules:
- - apiGroups:
- - ""
- resources:
- - configmaps
- - endpoints
- - nodes
- - pods
- - secrets
- verbs:
- - list
- - watch
- - update
- - apiGroups:
- - ""
- resources:
- - nodes
- verbs:
- - get
- - apiGroups:
- - ""
- resources:
- - services
- verbs:
- - get
- - list
- - watch
- - apiGroups:
- - "extensions"
- resources:
- - ingresses
- verbs:
- - get
- - list
- - watch
- - apiGroups:
- - ""
- resources:
- - events
- verbs:
- - create
- - patch
- - apiGroups:
- - "extensions"
- resources:
- - ingresses/status
- verbs:
- - update
----
-apiVersion: rbac.authorization.k8s.io/v1beta1
-kind: Role
-metadata:
- name: kube-nginx-ingress
- namespace: kube-ingress
-rules:
- - apiGroups:
- - ""
- resources:
- - configmaps
- - pods
- - secrets
- - namespaces
- verbs:
- - get
- - apiGroups:
- - ""
- resources:
- - configmaps
- resourceNames:
- - "ingress-controller-leader-nginx"
- verbs:
- - get
- - update
- - apiGroups:
- - ""
- resources:
- - configmaps
- verbs:
- - create
- - apiGroups:
- - ""
- resources:
- - endpoints
- verbs:
- - get
- - create
- - update
----
-apiVersion: rbac.authorization.k8s.io/v1beta1
-kind: RoleBinding
-metadata:
- name: kube-nginx-ingress
- namespace: kube-ingress
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: Role
- name: kube-nginx-ingress
-subjects:
- - kind: ServiceAccount
- name: kube-nginx-ingress
- namespace: kube-ingress
----
-apiVersion: rbac.authorization.k8s.io/v1beta1
-kind: ClusterRoleBinding
-metadata:
- name: kube-nginx-ingress
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: kube-nginx-ingress
-subjects:
- - kind: ServiceAccount
- name: kube-nginx-ingress
- namespace: kube-ingress
\ No newline at end of file
diff --git a/docs/reverse.rst b/docs/reverse.rst
index 29f9e9e1..14a9154e 100644
--- a/docs/reverse.rst
+++ b/docs/reverse.rst
@@ -3,14 +3,13 @@ Using an external reverse proxy
One of Mailu use cases is as part of a larger services platform, where maybe other Web services are available than Mailu Webmail and admin interface.
-In such a configuration, one would usually run a frontend reverse proxy to serve all Web contents based on criteria like the requested hostname (virtual hosts) and/or the requested path. Mailu Web frontend is disabled in the default setup for security reasons, it is however expected that most users will enable it at some point. Also, due to Docker Compose configuration structure, it is impossible for us to make disabling the Web frontend completely available through a configuration variable. This guide was written to help users setup such an architecture.
+In such a configuration, one would usually run a frontend reverse proxy to serve all Web contents based on criteria like the requested hostname (virtual hosts) and/or the requested path. Mailu Admin Web frontend is disabled in the default setup for security reasons, it is however expected that most users will enable it at some point. Also, due to Docker Compose configuration structure, it is impossible for us to make disabling the Web frontend completely available through a configuration variable. This guide was written to help users setup such an architecture.
There are basically three options, from the most to the least recommended one:
-- have Mailu Web frontend listen locally and use your own Web frontend on top of it
-- use ``Traefik`` in another container as central system-reverse-proxy
-- override Mailu Web frontend configuration
-- disable Mailu Web frontend completely and use your own
+- `have Mailu Web frontend listen locally and use your own Web frontend on top of it`_
+- `use Traefik in another container as central system-reverse-proxy`_
+- `override Mailu Web frontend configuration`_
All options will require that you modify the ``docker-compose.yml`` file.
@@ -89,7 +88,7 @@ Here is an example configuration :
server {
listen
/ day +
+