mirror of
https://github.com/Mailu/Mailu.git
synced 2024-12-14 10:53:30 +02:00
Merge branch 'master' into AdminLTE-3
This commit is contained in:
commit
00276d8b70
@ -32,6 +32,7 @@ DEFAULT_CONFIG = {
|
|||||||
'DOMAIN': 'mailu.io',
|
'DOMAIN': 'mailu.io',
|
||||||
'HOSTNAMES': 'mail.mailu.io,alternative.mailu.io,yetanother.mailu.io',
|
'HOSTNAMES': 'mail.mailu.io,alternative.mailu.io,yetanother.mailu.io',
|
||||||
'POSTMASTER': 'postmaster',
|
'POSTMASTER': 'postmaster',
|
||||||
|
'WILDCARD_SENDERS': '',
|
||||||
'TLS_FLAVOR': 'cert',
|
'TLS_FLAVOR': 'cert',
|
||||||
'INBOUND_TLS_ENFORCE': False,
|
'INBOUND_TLS_ENFORCE': False,
|
||||||
'AUTH_RATELIMIT': '1000/minute;10000/hour',
|
'AUTH_RATELIMIT': '1000/minute;10000/hour',
|
||||||
@ -46,6 +47,7 @@ DEFAULT_CONFIG = {
|
|||||||
'DKIM_SELECTOR': 'dkim',
|
'DKIM_SELECTOR': 'dkim',
|
||||||
'DKIM_PATH': '/dkim/{domain}.{selector}.key',
|
'DKIM_PATH': '/dkim/{domain}.{selector}.key',
|
||||||
'DEFAULT_QUOTA': 1000000000,
|
'DEFAULT_QUOTA': 1000000000,
|
||||||
|
'MESSAGE_RATELIMIT': '200/day',
|
||||||
# Web settings
|
# Web settings
|
||||||
'SITENAME': 'Mailu',
|
'SITENAME': 'Mailu',
|
||||||
'WEBSITE': 'https://mailu.io',
|
'WEBSITE': 'https://mailu.io',
|
||||||
|
@ -81,6 +81,13 @@ def handle_authentication(headers):
|
|||||||
raw_password = urllib.parse.unquote(headers["Auth-Pass"])
|
raw_password = urllib.parse.unquote(headers["Auth-Pass"])
|
||||||
password = raw_password.encode("iso8859-1").decode("utf8")
|
password = raw_password.encode("iso8859-1").decode("utf8")
|
||||||
ip = urllib.parse.unquote(headers["Client-Ip"])
|
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)
|
user = models.User.query.get(user_email)
|
||||||
if check_credentials(user, password, ip, protocol):
|
if check_credentials(user, password, ip, protocol):
|
||||||
return {
|
return {
|
||||||
|
@ -50,7 +50,7 @@ def user_authentication():
|
|||||||
if (not flask_login.current_user.is_anonymous
|
if (not flask_login.current_user.is_anonymous
|
||||||
and flask_login.current_user.enabled):
|
and flask_login.current_user.enabled):
|
||||||
response = flask.Response()
|
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())
|
response.headers["X-User-Token"] = models.User.get_temp_token(flask_login.current_user.get_id())
|
||||||
return response
|
return response
|
||||||
return flask.abort(403)
|
return flask.abort(403)
|
||||||
@ -67,7 +67,7 @@ def basic_authentication():
|
|||||||
user = models.User.query.get(user_email.decode("utf8"))
|
user = models.User.query.get(user_email.decode("utf8"))
|
||||||
if nginx.check_credentials(user, password.decode('utf-8'), flask.request.remote_addr, "web"):
|
if nginx.check_credentials(user, password.decode('utf-8'), flask.request.remote_addr, "web"):
|
||||||
response = flask.Response()
|
response = flask.Response()
|
||||||
response.headers["X-User"] = user.email
|
response.headers["X-User"] = models.IdnaEmail.process_bind_param(flask_login, user.email, "")
|
||||||
return response
|
return response
|
||||||
response = flask.Response(status=401)
|
response = flask.Response(status=401)
|
||||||
response.headers["WWW-Authenticate"] = 'Basic realm="Login Required"'
|
response.headers["WWW-Authenticate"] = 'Basic realm="Login Required"'
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from mailu import models
|
from mailu import models, utils
|
||||||
from mailu.internal import internal
|
from mailu.internal import internal
|
||||||
|
from flask import current_app as app
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
import idna
|
import idna
|
||||||
@ -31,7 +32,6 @@ def postfix_alias_map(alias):
|
|||||||
destination = models.Email.resolve_destination(localpart, domain_name)
|
destination = models.Email.resolve_destination(localpart, domain_name)
|
||||||
return flask.jsonify(",".join(destination)) if destination else flask.abort(404)
|
return flask.jsonify(",".join(destination)) if destination else flask.abort(404)
|
||||||
|
|
||||||
|
|
||||||
@internal.route("/postfix/transport/<path:email>")
|
@internal.route("/postfix/transport/<path:email>")
|
||||||
def postfix_transport(email):
|
def postfix_transport(email):
|
||||||
if email == '*' or re.match("(^|.*@)\[.*\]$", email):
|
if email == '*' or re.match("(^|.*@)\[.*\]$", email):
|
||||||
@ -133,12 +133,20 @@ def postfix_sender_map(sender):
|
|||||||
|
|
||||||
@internal.route("/postfix/sender/login/<path:sender>")
|
@internal.route("/postfix/sender/login/<path:sender>")
|
||||||
def postfix_sender_login(sender):
|
def postfix_sender_login(sender):
|
||||||
|
wildcard_senders = [s for s in flask.current_app.config.get('WILDCARD_SENDERS', '').lower().replace(' ', '').split(',') if s]
|
||||||
localpart, domain_name = models.Email.resolve_domain(sender)
|
localpart, domain_name = models.Email.resolve_domain(sender)
|
||||||
if localpart is None:
|
if localpart is None:
|
||||||
return flask.abort(404)
|
return flask.jsonify(",".join(wildcard_senders)) if wildcard_senders else flask.abort(404)
|
||||||
destination = models.Email.resolve_destination(localpart, domain_name, True)
|
destination = models.Email.resolve_destination(localpart, domain_name, True)
|
||||||
|
destination = [*destination, *wildcard_senders] if destination else [*wildcard_senders]
|
||||||
return flask.jsonify(",".join(destination)) if destination else flask.abort(404)
|
return flask.jsonify(",".join(destination)) if destination else flask.abort(404)
|
||||||
|
|
||||||
|
@internal.route("/postfix/sender/rate/<path:sender>")
|
||||||
|
def postfix_sender_rate(sender):
|
||||||
|
""" Rate limit outbound emails per sender login
|
||||||
|
"""
|
||||||
|
user = models.User.get(sender) or flask.abort(404)
|
||||||
|
return flask.abort(404) if user.sender_limiter.hit() else flask.jsonify("450 4.2.1 You are sending too many emails too fast.")
|
||||||
|
|
||||||
@internal.route("/postfix/sender/access/<path:sender>")
|
@internal.route("/postfix/sender/access/<path:sender>")
|
||||||
def postfix_sender_access(sender):
|
def postfix_sender_access(sender):
|
||||||
|
@ -27,7 +27,7 @@ from sqlalchemy.ext.hybrid import hybrid_property
|
|||||||
from sqlalchemy.inspection import inspect
|
from sqlalchemy.inspection import inspect
|
||||||
from werkzeug.utils import cached_property
|
from werkzeug.utils import cached_property
|
||||||
|
|
||||||
from mailu import dkim
|
from mailu import dkim, utils
|
||||||
|
|
||||||
|
|
||||||
db = flask_sqlalchemy.SQLAlchemy()
|
db = flask_sqlalchemy.SQLAlchemy()
|
||||||
@ -501,6 +501,12 @@ class User(Base, Email):
|
|||||||
self.reply_enddate > now
|
self.reply_enddate > now
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sender_limiter(self):
|
||||||
|
return utils.limiter.get_limiter(
|
||||||
|
app.config["MESSAGE_RATELIMIT"], "sender", self.email
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_password_context(cls):
|
def get_password_context(cls):
|
||||||
""" create password context for hashing and verification
|
""" create password context for hashing and verification
|
||||||
|
@ -1,29 +1,30 @@
|
|||||||
# Translations template for PROJECT.
|
# Translations template for Mailu.
|
||||||
# Copyright (C) 2018 ORGANIZATION
|
# Copyright (C) 2018 Mailu
|
||||||
# This file is distributed under the same license as the PROJECT project.
|
# This file is distributed under the same license as the Mailu project.
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2018.
|
# Modi Sacks, 2019-2021.
|
||||||
|
# Yaron Shahrabani <sh.yaron@gmail.com>, 2021.
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: Mailu 1.5.1\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: heb-bugzap@projects.hamakor.org.il \n"
|
||||||
"POT-Creation-Date: 2018-04-22 12:10+0200\n"
|
"POT-Creation-Date: 2018-04-22 12:10+0200\n"
|
||||||
"PO-Revision-Date: 2019-11-27 22:20+0000\n"
|
"PO-Revision-Date: 2021-07-19 09:04+0300\n"
|
||||||
"Last-Translator: Mordi Sacks \n"
|
"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n"
|
||||||
"Language-Team: Hebrew <https://translate.tedomum.net/projects/mailu/admin/he/"
|
"Language-Team: Hebrew <https://translate.tedomum.net/projects/mailu/admin/he/"
|
||||||
">\n"
|
">\n"
|
||||||
"Language: he\n"
|
"Language: he\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && "
|
"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && "
|
||||||
"n % 10 == 0) ? 2 : 3));\n"
|
"n % 10 == 0) ? 2 : 3));\n"
|
||||||
"X-Generator: Weblate 3.3\n"
|
"X-Generator: Poedit 3.0\n"
|
||||||
"Generated-By: Babel 2.5.3\n"
|
"Generated-By: Babel 2.5.3\n"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:32
|
#: mailu/ui/forms.py:32
|
||||||
msgid "Invalid email address."
|
msgid "Invalid email address."
|
||||||
msgstr "כתובת דוא\"ל לא חוקית."
|
msgstr "כתובת דוא״ל שגויה."
|
||||||
|
|
||||||
#: mailu/ui/forms.py:36
|
#: mailu/ui/forms.py:36
|
||||||
msgid "Confirm"
|
msgid "Confirm"
|
||||||
@ -31,7 +32,7 @@ msgstr "אישור"
|
|||||||
|
|
||||||
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
|
#: mailu/ui/forms.py:40 mailu/ui/forms.py:77
|
||||||
msgid "E-mail"
|
msgid "E-mail"
|
||||||
msgstr "דוא\"ל"
|
msgstr "דוא״ל"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
|
#: mailu/ui/forms.py:41 mailu/ui/forms.py:78 mailu/ui/forms.py:90
|
||||||
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
|
#: mailu/ui/forms.py:109 mailu/ui/forms.py:162
|
||||||
@ -48,23 +49,23 @@ msgstr "כניסה"
|
|||||||
#: mailu/ui/templates/domain/details.html:27
|
#: mailu/ui/templates/domain/details.html:27
|
||||||
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
|
#: mailu/ui/templates/domain/list.html:18 mailu/ui/templates/relay/list.html:17
|
||||||
msgid "Domain name"
|
msgid "Domain name"
|
||||||
msgstr "שם דומיין"
|
msgstr "שם תחום"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:47
|
#: mailu/ui/forms.py:47
|
||||||
msgid "Maximum user count"
|
msgid "Maximum user count"
|
||||||
msgstr ""
|
msgstr "כמות המשתמשים המרבית"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:48
|
#: mailu/ui/forms.py:48
|
||||||
msgid "Maximum alias count"
|
msgid "Maximum alias count"
|
||||||
msgstr ""
|
msgstr "כמות הכינויים המרבית"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:49
|
#: mailu/ui/forms.py:49
|
||||||
msgid "Maximum user quota"
|
msgid "Maximum user quota"
|
||||||
msgstr ""
|
msgstr "מיכסת המשתמשים המרבית"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:50
|
#: mailu/ui/forms.py:50
|
||||||
msgid "Enable sign-up"
|
msgid "Enable sign-up"
|
||||||
msgstr ""
|
msgstr "לאפשר הרשמה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
|
#: mailu/ui/forms.py:51 mailu/ui/forms.py:72 mailu/ui/forms.py:83
|
||||||
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
|
#: mailu/ui/forms.py:128 mailu/ui/forms.py:140
|
||||||
@ -72,53 +73,53 @@ msgstr ""
|
|||||||
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
|
#: mailu/ui/templates/relay/list.html:19 mailu/ui/templates/token/list.html:19
|
||||||
#: mailu/ui/templates/user/list.html:23
|
#: mailu/ui/templates/user/list.html:23
|
||||||
msgid "Comment"
|
msgid "Comment"
|
||||||
msgstr ""
|
msgstr "תגובה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
|
#: mailu/ui/forms.py:52 mailu/ui/forms.py:61 mailu/ui/forms.py:66
|
||||||
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
|
#: mailu/ui/forms.py:73 mailu/ui/forms.py:132 mailu/ui/forms.py:141
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr ""
|
msgstr "יצירה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:57
|
#: mailu/ui/forms.py:57
|
||||||
msgid "Initial admin"
|
msgid "Initial admin"
|
||||||
msgstr ""
|
msgstr "מנהל ראשוני"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:58
|
#: mailu/ui/forms.py:58
|
||||||
msgid "Admin password"
|
msgid "Admin password"
|
||||||
msgstr ""
|
msgstr "סיסמת ניהול"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
|
#: mailu/ui/forms.py:59 mailu/ui/forms.py:79 mailu/ui/forms.py:91
|
||||||
msgid "Confirm password"
|
msgid "Confirm password"
|
||||||
msgstr ""
|
msgstr "אישור סיסמה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:65
|
#: mailu/ui/forms.py:65
|
||||||
msgid "Alternative name"
|
msgid "Alternative name"
|
||||||
msgstr ""
|
msgstr "שם חלופי"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:70
|
#: mailu/ui/forms.py:70
|
||||||
msgid "Relayed domain name"
|
msgid "Relayed domain name"
|
||||||
msgstr ""
|
msgstr "שם תחום מועבר"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
|
#: mailu/ui/forms.py:71 mailu/ui/templates/relay/list.html:18
|
||||||
msgid "Remote host"
|
msgid "Remote host"
|
||||||
msgstr ""
|
msgstr "מארח מרוחק"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
|
#: mailu/ui/forms.py:80 mailu/ui/templates/user/list.html:22
|
||||||
#: mailu/ui/templates/user/signup_domain.html:16
|
#: mailu/ui/templates/user/signup_domain.html:16
|
||||||
msgid "Quota"
|
msgid "Quota"
|
||||||
msgstr ""
|
msgstr "מיכסה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:81
|
#: mailu/ui/forms.py:81
|
||||||
msgid "Allow IMAP access"
|
msgid "Allow IMAP access"
|
||||||
msgstr ""
|
msgstr "לאפשר גישה ב־IMAP"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:82
|
#: mailu/ui/forms.py:82
|
||||||
msgid "Allow POP3 access"
|
msgid "Allow POP3 access"
|
||||||
msgstr ""
|
msgstr "לאפשר גישה ב־POP3"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:84
|
#: mailu/ui/forms.py:84
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr ""
|
msgstr "מופעל"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:85
|
#: mailu/ui/forms.py:85
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
@ -126,7 +127,7 @@ msgstr "שמירה"
|
|||||||
|
|
||||||
#: mailu/ui/forms.py:89
|
#: mailu/ui/forms.py:89
|
||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "דואר אלקטרוני"
|
msgstr "כתובת דוא״ל"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
|
#: mailu/ui/forms.py:93 mailu/ui/templates/sidebar.html:117
|
||||||
#: mailu/ui/templates/user/signup.html:4
|
#: mailu/ui/templates/user/signup.html:4
|
||||||
@ -136,244 +137,244 @@ msgstr "הרשמה"
|
|||||||
|
|
||||||
#: mailu/ui/forms.py:97
|
#: mailu/ui/forms.py:97
|
||||||
msgid "Displayed name"
|
msgid "Displayed name"
|
||||||
msgstr ""
|
msgstr "שם מוצג"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:98
|
#: mailu/ui/forms.py:98
|
||||||
msgid "Enable spam filter"
|
msgid "Enable spam filter"
|
||||||
msgstr ""
|
msgstr "הפעלת מסנן ספאם"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:99
|
#: mailu/ui/forms.py:99
|
||||||
msgid "Spam filter tolerance"
|
msgid "Spam filter tolerance"
|
||||||
msgstr ""
|
msgstr "סובלנות מסנן הספאם"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:100
|
#: mailu/ui/forms.py:100
|
||||||
msgid "Enable forwarding"
|
msgid "Enable forwarding"
|
||||||
msgstr ""
|
msgstr "הפעלת העברה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:101
|
#: mailu/ui/forms.py:101
|
||||||
msgid "Keep a copy of the emails"
|
msgid "Keep a copy of the emails"
|
||||||
msgstr ""
|
msgstr "להשאיר עותק מההודעות"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
|
#: mailu/ui/forms.py:103 mailu/ui/forms.py:139
|
||||||
#: mailu/ui/templates/alias/list.html:20
|
#: mailu/ui/templates/alias/list.html:20
|
||||||
msgid "Destination"
|
msgid "Destination"
|
||||||
msgstr ""
|
msgstr "יעד"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:105
|
#: mailu/ui/forms.py:105
|
||||||
msgid "Save settings"
|
msgid "Save settings"
|
||||||
msgstr ""
|
msgstr "שמירת הגדרות"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:110
|
#: mailu/ui/forms.py:110
|
||||||
msgid "Password check"
|
msgid "Password check"
|
||||||
msgstr ""
|
msgstr "בדיקת סיסמה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
|
#: mailu/ui/forms.py:111 mailu/ui/templates/sidebar.html:16
|
||||||
msgid "Update password"
|
msgid "Update password"
|
||||||
msgstr ""
|
msgstr "עדכון סיסמה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:115
|
#: mailu/ui/forms.py:115
|
||||||
msgid "Enable automatic reply"
|
msgid "Enable automatic reply"
|
||||||
msgstr ""
|
msgstr "הפעלת תגובה אוטומטית"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:116
|
#: mailu/ui/forms.py:116
|
||||||
msgid "Reply subject"
|
msgid "Reply subject"
|
||||||
msgstr ""
|
msgstr "נושא התגובה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:117
|
#: mailu/ui/forms.py:117
|
||||||
msgid "Reply body"
|
msgid "Reply body"
|
||||||
msgstr ""
|
msgstr "גוף התגובה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:119
|
#: mailu/ui/forms.py:119
|
||||||
msgid "End of vacation"
|
msgid "End of vacation"
|
||||||
msgstr ""
|
msgstr "סוף החופשה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:120
|
#: mailu/ui/forms.py:120
|
||||||
msgid "Update"
|
msgid "Update"
|
||||||
msgstr ""
|
msgstr "עדכון"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:125
|
#: mailu/ui/forms.py:125
|
||||||
msgid "Your token (write it down, as it will never be displayed again)"
|
msgid "Your token (write it down, as it will never be displayed again)"
|
||||||
msgstr ""
|
msgstr "האסימון שלך (כדאי לשמור עליו היטב כיוון שהוא לא יופיע פעם נוספת)"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
|
#: mailu/ui/forms.py:130 mailu/ui/templates/token/list.html:20
|
||||||
msgid "Authorized IP"
|
msgid "Authorized IP"
|
||||||
msgstr ""
|
msgstr "כתובת IP מורשית"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:136
|
#: mailu/ui/forms.py:136
|
||||||
msgid "Alias"
|
msgid "Alias"
|
||||||
msgstr ""
|
msgstr "כינוי"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:138
|
#: mailu/ui/forms.py:138
|
||||||
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
|
msgid "Use SQL LIKE Syntax (e.g. for catch-all aliases)"
|
||||||
msgstr ""
|
msgstr "להשתמש בתחביר דמוי SQL (למשל: catch-all aliases)"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:145
|
#: mailu/ui/forms.py:145
|
||||||
msgid "Admin email"
|
msgid "Admin email"
|
||||||
msgstr ""
|
msgstr "דוא״ל ההנהלה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
|
#: mailu/ui/forms.py:146 mailu/ui/forms.py:151 mailu/ui/forms.py:164
|
||||||
msgid "Submit"
|
msgid "Submit"
|
||||||
msgstr ""
|
msgstr "הגשה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:150
|
#: mailu/ui/forms.py:150
|
||||||
msgid "Manager email"
|
msgid "Manager email"
|
||||||
msgstr ""
|
msgstr "דוא״ל המפקח"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:155
|
#: mailu/ui/forms.py:155
|
||||||
msgid "Protocol"
|
msgid "Protocol"
|
||||||
msgstr ""
|
msgstr "פרוטוקול"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:158
|
#: mailu/ui/forms.py:158
|
||||||
msgid "Hostname or IP"
|
msgid "Hostname or IP"
|
||||||
msgstr ""
|
msgstr "שם מארח או כתובת IP"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
|
#: mailu/ui/forms.py:159 mailu/ui/templates/client.html:20
|
||||||
#: mailu/ui/templates/client.html:47
|
#: mailu/ui/templates/client.html:47
|
||||||
msgid "TCP port"
|
msgid "TCP port"
|
||||||
msgstr ""
|
msgstr "פתחת TCP"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:160
|
#: mailu/ui/forms.py:160
|
||||||
msgid "Enable TLS"
|
msgid "Enable TLS"
|
||||||
msgstr ""
|
msgstr "הפעלת TLS"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
|
#: mailu/ui/forms.py:161 mailu/ui/templates/client.html:28
|
||||||
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
|
#: mailu/ui/templates/client.html:55 mailu/ui/templates/fetch/list.html:20
|
||||||
msgid "Username"
|
msgid "Username"
|
||||||
msgstr ""
|
msgstr "שם משתמש"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:163
|
#: mailu/ui/forms.py:163
|
||||||
msgid "Keep emails on the server"
|
msgid "Keep emails on the server"
|
||||||
msgstr ""
|
msgstr "להשאיר את ההודעות על השרת"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:168
|
#: mailu/ui/forms.py:168
|
||||||
msgid "Announcement subject"
|
msgid "Announcement subject"
|
||||||
msgstr ""
|
msgstr "נושא ההכרזה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:170
|
#: mailu/ui/forms.py:170
|
||||||
msgid "Announcement body"
|
msgid "Announcement body"
|
||||||
msgstr ""
|
msgstr "גוף ההכרזה"
|
||||||
|
|
||||||
#: mailu/ui/forms.py:172
|
#: mailu/ui/forms.py:172
|
||||||
msgid "Send"
|
msgid "Send"
|
||||||
msgstr ""
|
msgstr "שליחה"
|
||||||
|
|
||||||
#: mailu/ui/templates/announcement.html:4
|
#: mailu/ui/templates/announcement.html:4
|
||||||
msgid "Public announcement"
|
msgid "Public announcement"
|
||||||
msgstr ""
|
msgstr "הכרזה פומבית"
|
||||||
|
|
||||||
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
|
#: mailu/ui/templates/client.html:4 mailu/ui/templates/sidebar.html:82
|
||||||
msgid "Client setup"
|
msgid "Client setup"
|
||||||
msgstr ""
|
msgstr "הגדרת לקוח"
|
||||||
|
|
||||||
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
|
#: mailu/ui/templates/client.html:16 mailu/ui/templates/client.html:43
|
||||||
msgid "Mail protocol"
|
msgid "Mail protocol"
|
||||||
msgstr ""
|
msgstr "פרוטוקול דוא״ל"
|
||||||
|
|
||||||
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
|
#: mailu/ui/templates/client.html:24 mailu/ui/templates/client.html:51
|
||||||
msgid "Server name"
|
msgid "Server name"
|
||||||
msgstr ""
|
msgstr "שם שרת"
|
||||||
|
|
||||||
#: mailu/ui/templates/confirm.html:4
|
#: mailu/ui/templates/confirm.html:4
|
||||||
msgid "Confirm action"
|
msgid "Confirm action"
|
||||||
msgstr ""
|
msgstr "אישור הפעולה"
|
||||||
|
|
||||||
#: mailu/ui/templates/confirm.html:13
|
#: mailu/ui/templates/confirm.html:13
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "You are about to %(action)s. Please confirm your action."
|
msgid "You are about to %(action)s. Please confirm your action."
|
||||||
msgstr ""
|
msgstr "פעולה זו תבצע %(action)s. נא לאשר את הפעולה שלך."
|
||||||
|
|
||||||
#: mailu/ui/templates/docker-error.html:4
|
#: mailu/ui/templates/docker-error.html:4
|
||||||
msgid "Docker error"
|
msgid "Docker error"
|
||||||
msgstr ""
|
msgstr "שגיאת Docker"
|
||||||
|
|
||||||
#: mailu/ui/templates/docker-error.html:12
|
#: mailu/ui/templates/docker-error.html:12
|
||||||
msgid "An error occurred while talking to the Docker server."
|
msgid "An error occurred while talking to the Docker server."
|
||||||
msgstr ""
|
msgstr "אירעה שגיאה בעת החיבור לשרת ה־Docker."
|
||||||
|
|
||||||
#: mailu/ui/templates/login.html:8
|
#: mailu/ui/templates/login.html:8
|
||||||
msgid "to access the administration tools"
|
msgid "to access the administration tools"
|
||||||
msgstr ""
|
msgstr "כדי לגשת לכלי הניהול"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:11 mailu/ui/templates/user/list.html:34
|
#: mailu/ui/templates/sidebar.html:11 mailu/ui/templates/user/list.html:34
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr "הגדרות"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
|
#: mailu/ui/templates/sidebar.html:21 mailu/ui/templates/user/list.html:35
|
||||||
msgid "Auto-reply"
|
msgid "Auto-reply"
|
||||||
msgstr ""
|
msgstr "מענה אוטומטית"
|
||||||
|
|
||||||
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
|
#: mailu/ui/templates/fetch/list.html:4 mailu/ui/templates/sidebar.html:26
|
||||||
#: mailu/ui/templates/user/list.html:36
|
#: mailu/ui/templates/user/list.html:36
|
||||||
msgid "Fetched accounts"
|
msgid "Fetched accounts"
|
||||||
msgstr ""
|
msgstr "חשבונות נמשכים"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
|
#: mailu/ui/templates/sidebar.html:31 mailu/ui/templates/token/list.html:4
|
||||||
msgid "Authentication tokens"
|
msgid "Authentication tokens"
|
||||||
msgstr ""
|
msgstr "אסימוני אימות"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:35
|
#: mailu/ui/templates/sidebar.html:35
|
||||||
msgid "Administration"
|
msgid "Administration"
|
||||||
msgstr ""
|
msgstr "ניהול"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:44
|
#: mailu/ui/templates/sidebar.html:44
|
||||||
msgid "Announcement"
|
msgid "Announcement"
|
||||||
msgstr ""
|
msgstr "הכרזה"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:49
|
#: mailu/ui/templates/sidebar.html:49
|
||||||
msgid "Administrators"
|
msgid "Administrators"
|
||||||
msgstr ""
|
msgstr "מנהלים"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:54
|
#: mailu/ui/templates/sidebar.html:54
|
||||||
msgid "Relayed domains"
|
msgid "Relayed domains"
|
||||||
msgstr ""
|
msgstr "שמות תחום מועברים"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
|
#: mailu/ui/templates/sidebar.html:59 mailu/ui/templates/user/settings.html:15
|
||||||
msgid "Antispam"
|
msgid "Antispam"
|
||||||
msgstr ""
|
msgstr "מניעת ספאם"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:66
|
#: mailu/ui/templates/sidebar.html:66
|
||||||
msgid "Mail domains"
|
msgid "Mail domains"
|
||||||
msgstr ""
|
msgstr "דמות תחום לדוא״ל"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:72
|
#: mailu/ui/templates/sidebar.html:72
|
||||||
msgid "Go to"
|
msgid "Go to"
|
||||||
msgstr ""
|
msgstr "מעבר אל"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:76
|
#: mailu/ui/templates/sidebar.html:76
|
||||||
msgid "Webmail"
|
msgid "Webmail"
|
||||||
msgstr ""
|
msgstr "דוא״ל בדפדפן"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:87
|
#: mailu/ui/templates/sidebar.html:87
|
||||||
msgid "Website"
|
msgid "Website"
|
||||||
msgstr ""
|
msgstr "אתר"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:92
|
#: mailu/ui/templates/sidebar.html:92
|
||||||
msgid "Help"
|
msgid "Help"
|
||||||
msgstr ""
|
msgstr "עזרה"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
|
#: mailu/ui/templates/domain/signup.html:4 mailu/ui/templates/sidebar.html:98
|
||||||
msgid "Register a domain"
|
msgid "Register a domain"
|
||||||
msgstr ""
|
msgstr "רישום שם תחום"
|
||||||
|
|
||||||
#: mailu/ui/templates/sidebar.html:105
|
#: mailu/ui/templates/sidebar.html:105
|
||||||
msgid "Sign out"
|
msgid "Sign out"
|
||||||
msgstr ""
|
msgstr "יציאה"
|
||||||
|
|
||||||
#: mailu/ui/templates/working.html:4
|
#: mailu/ui/templates/working.html:4
|
||||||
msgid "We are still working on this feature!"
|
msgid "We are still working on this feature!"
|
||||||
msgstr ""
|
msgstr "אנחנו עדיין עובדים על היכולת הזאת!"
|
||||||
|
|
||||||
#: mailu/ui/templates/admin/create.html:4
|
#: mailu/ui/templates/admin/create.html:4
|
||||||
msgid "Add a global administrator"
|
msgid "Add a global administrator"
|
||||||
msgstr ""
|
msgstr "הוספת מנהל כללי"
|
||||||
|
|
||||||
#: mailu/ui/templates/admin/list.html:4
|
#: mailu/ui/templates/admin/list.html:4
|
||||||
msgid "Global administrators"
|
msgid "Global administrators"
|
||||||
msgstr ""
|
msgstr "מנהלים כלליים"
|
||||||
|
|
||||||
#: mailu/ui/templates/admin/list.html:9
|
#: mailu/ui/templates/admin/list.html:9
|
||||||
msgid "Add administrator"
|
msgid "Add administrator"
|
||||||
msgstr ""
|
msgstr "הוספת מנהל"
|
||||||
|
|
||||||
#: mailu/ui/templates/admin/list.html:16 mailu/ui/templates/alias/list.html:18
|
#: mailu/ui/templates/admin/list.html:16 mailu/ui/templates/alias/list.html:18
|
||||||
#: mailu/ui/templates/alternative/list.html:18
|
#: mailu/ui/templates/alternative/list.html:18
|
||||||
@ -382,12 +383,12 @@ msgstr ""
|
|||||||
#: mailu/ui/templates/relay/list.html:16 mailu/ui/templates/token/list.html:18
|
#: mailu/ui/templates/relay/list.html:16 mailu/ui/templates/token/list.html:18
|
||||||
#: mailu/ui/templates/user/list.html:18
|
#: mailu/ui/templates/user/list.html:18
|
||||||
msgid "Actions"
|
msgid "Actions"
|
||||||
msgstr ""
|
msgstr "פעולות"
|
||||||
|
|
||||||
#: mailu/ui/templates/admin/list.html:17 mailu/ui/templates/alias/list.html:19
|
#: mailu/ui/templates/admin/list.html:17 mailu/ui/templates/alias/list.html:19
|
||||||
#: mailu/ui/templates/manager/list.html:19 mailu/ui/templates/user/list.html:20
|
#: mailu/ui/templates/manager/list.html:19 mailu/ui/templates/user/list.html:20
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr ""
|
msgstr "דוא״ל"
|
||||||
|
|
||||||
#: mailu/ui/templates/admin/list.html:22 mailu/ui/templates/alias/list.html:29
|
#: mailu/ui/templates/admin/list.html:22 mailu/ui/templates/alias/list.html:29
|
||||||
#: mailu/ui/templates/alternative/list.html:25
|
#: mailu/ui/templates/alternative/list.html:25
|
||||||
@ -396,23 +397,23 @@ msgstr ""
|
|||||||
#: mailu/ui/templates/relay/list.html:27 mailu/ui/templates/token/list.html:26
|
#: mailu/ui/templates/relay/list.html:27 mailu/ui/templates/token/list.html:26
|
||||||
#: mailu/ui/templates/user/list.html:31
|
#: mailu/ui/templates/user/list.html:31
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr ""
|
msgstr "מחיקה"
|
||||||
|
|
||||||
#: mailu/ui/templates/alias/create.html:4
|
#: mailu/ui/templates/alias/create.html:4
|
||||||
msgid "Create alias"
|
msgid "Create alias"
|
||||||
msgstr ""
|
msgstr "יצירת כינוי"
|
||||||
|
|
||||||
#: mailu/ui/templates/alias/edit.html:4
|
#: mailu/ui/templates/alias/edit.html:4
|
||||||
msgid "Edit alias"
|
msgid "Edit alias"
|
||||||
msgstr ""
|
msgstr "עריכת כינוי"
|
||||||
|
|
||||||
#: mailu/ui/templates/alias/list.html:4
|
#: mailu/ui/templates/alias/list.html:4
|
||||||
msgid "Alias list"
|
msgid "Alias list"
|
||||||
msgstr ""
|
msgstr "רשימת כינויים"
|
||||||
|
|
||||||
#: mailu/ui/templates/alias/list.html:12
|
#: mailu/ui/templates/alias/list.html:12
|
||||||
msgid "Add alias"
|
msgid "Add alias"
|
||||||
msgstr ""
|
msgstr "הוספת כינוי"
|
||||||
|
|
||||||
#: mailu/ui/templates/alias/list.html:22
|
#: mailu/ui/templates/alias/list.html:22
|
||||||
#: mailu/ui/templates/alternative/list.html:20
|
#: mailu/ui/templates/alternative/list.html:20
|
||||||
@ -420,254 +421,259 @@ msgstr ""
|
|||||||
#: mailu/ui/templates/relay/list.html:20 mailu/ui/templates/token/list.html:21
|
#: mailu/ui/templates/relay/list.html:20 mailu/ui/templates/token/list.html:21
|
||||||
#: mailu/ui/templates/user/list.html:24
|
#: mailu/ui/templates/user/list.html:24
|
||||||
msgid "Created"
|
msgid "Created"
|
||||||
msgstr ""
|
msgstr "נוצר"
|
||||||
|
|
||||||
#: mailu/ui/templates/alias/list.html:23 mailu/ui/templates/domain/list.html:23
|
#: mailu/ui/templates/alias/list.html:23 mailu/ui/templates/domain/list.html:23
|
||||||
#: mailu/ui/templates/fetch/list.html:25 mailu/ui/templates/relay/list.html:21
|
#: mailu/ui/templates/fetch/list.html:25 mailu/ui/templates/relay/list.html:21
|
||||||
#: mailu/ui/templates/user/list.html:25
|
#: mailu/ui/templates/user/list.html:25
|
||||||
msgid "Last edit"
|
msgid "Last edit"
|
||||||
msgstr ""
|
msgstr "עריכה אחרונה"
|
||||||
|
|
||||||
#: mailu/ui/templates/alias/list.html:28 mailu/ui/templates/domain/list.html:30
|
#: mailu/ui/templates/alias/list.html:28 mailu/ui/templates/domain/list.html:30
|
||||||
#: mailu/ui/templates/fetch/list.html:30 mailu/ui/templates/relay/list.html:26
|
#: mailu/ui/templates/fetch/list.html:30 mailu/ui/templates/relay/list.html:26
|
||||||
#: mailu/ui/templates/user/list.html:30
|
#: mailu/ui/templates/user/list.html:30
|
||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr ""
|
msgstr "עריכה"
|
||||||
|
|
||||||
#: mailu/ui/templates/alternative/create.html:4
|
#: mailu/ui/templates/alternative/create.html:4
|
||||||
msgid "Create alternative domain"
|
msgid "Create alternative domain"
|
||||||
msgstr ""
|
msgstr "יצירת שם תחום חלופי"
|
||||||
|
|
||||||
#: mailu/ui/templates/alternative/list.html:4
|
#: mailu/ui/templates/alternative/list.html:4
|
||||||
msgid "Alternative domain list"
|
msgid "Alternative domain list"
|
||||||
msgstr ""
|
msgstr "רשימת שמות תחום חלופיים"
|
||||||
|
|
||||||
#: mailu/ui/templates/alternative/list.html:12
|
#: mailu/ui/templates/alternative/list.html:12
|
||||||
msgid "Add alternative"
|
msgid "Add alternative"
|
||||||
msgstr ""
|
msgstr "הוספת חלופה"
|
||||||
|
|
||||||
#: mailu/ui/templates/alternative/list.html:19
|
#: mailu/ui/templates/alternative/list.html:19
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr ""
|
msgstr "שם"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/create.html:4
|
#: mailu/ui/templates/domain/create.html:4
|
||||||
#: mailu/ui/templates/domain/list.html:9
|
#: mailu/ui/templates/domain/list.html:9
|
||||||
msgid "New domain"
|
msgid "New domain"
|
||||||
msgstr ""
|
msgstr "שם תחום חדש"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/details.html:4
|
#: mailu/ui/templates/domain/details.html:4
|
||||||
msgid "Domain details"
|
msgid "Domain details"
|
||||||
msgstr ""
|
msgstr "פרטי שם התחום"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/details.html:15
|
#: mailu/ui/templates/domain/details.html:15
|
||||||
msgid "Regenerate keys"
|
msgid "Regenerate keys"
|
||||||
msgstr ""
|
msgstr "יצירת מפתחות מחדש"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/details.html:17
|
#: mailu/ui/templates/domain/details.html:17
|
||||||
msgid "Generate keys"
|
msgid "Generate keys"
|
||||||
msgstr ""
|
msgstr "יצירת מפתחות"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/details.html:31
|
#: mailu/ui/templates/domain/details.html:31
|
||||||
msgid "DNS MX entry"
|
msgid "DNS MX entry"
|
||||||
msgstr ""
|
msgstr "רשומת MX ב־DNS"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/details.html:35
|
#: mailu/ui/templates/domain/details.html:35
|
||||||
msgid "DNS SPF entries"
|
msgid "DNS SPF entries"
|
||||||
msgstr ""
|
msgstr "רשומות SPF ב־DNS"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/details.html:42
|
#: mailu/ui/templates/domain/details.html:42
|
||||||
msgid "DKIM public key"
|
msgid "DKIM public key"
|
||||||
msgstr ""
|
msgstr "מפתח DKIM ציבורי"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/details.html:46
|
#: mailu/ui/templates/domain/details.html:46
|
||||||
msgid "DNS DKIM entry"
|
msgid "DNS DKIM entry"
|
||||||
msgstr ""
|
msgstr "רשומת DKIM ב־DNS"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/details.html:50
|
#: mailu/ui/templates/domain/details.html:50
|
||||||
msgid "DNS DMARC entry"
|
msgid "DNS DMARC entry"
|
||||||
msgstr ""
|
msgstr "רשומת DMARC ב־DNS"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/edit.html:4
|
#: mailu/ui/templates/domain/edit.html:4
|
||||||
msgid "Edit domain"
|
msgid "Edit domain"
|
||||||
msgstr ""
|
msgstr "עריכת שם תחום"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/list.html:4
|
#: mailu/ui/templates/domain/list.html:4
|
||||||
msgid "Domain list"
|
msgid "Domain list"
|
||||||
msgstr ""
|
msgstr "רשימת שמות תחום"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/list.html:17
|
#: mailu/ui/templates/domain/list.html:17
|
||||||
msgid "Manage"
|
msgid "Manage"
|
||||||
msgstr ""
|
msgstr "ניהול"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/list.html:19
|
#: mailu/ui/templates/domain/list.html:19
|
||||||
msgid "Mailbox count"
|
msgid "Mailbox count"
|
||||||
msgstr ""
|
msgstr "כמות תיבות דוא״ל"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/list.html:20
|
#: mailu/ui/templates/domain/list.html:20
|
||||||
msgid "Alias count"
|
msgid "Alias count"
|
||||||
msgstr ""
|
msgstr "כמות כינויים"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/list.html:28
|
#: mailu/ui/templates/domain/list.html:28
|
||||||
msgid "Details"
|
msgid "Details"
|
||||||
msgstr ""
|
msgstr "פרטים"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/list.html:35
|
#: mailu/ui/templates/domain/list.html:35
|
||||||
msgid "Users"
|
msgid "Users"
|
||||||
msgstr ""
|
msgstr "משתמשים"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/list.html:36
|
#: mailu/ui/templates/domain/list.html:36
|
||||||
msgid "Aliases"
|
msgid "Aliases"
|
||||||
msgstr ""
|
msgstr "כינויים"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/list.html:37
|
#: mailu/ui/templates/domain/list.html:37
|
||||||
msgid "Managers"
|
msgid "Managers"
|
||||||
msgstr ""
|
msgstr "מפקחים"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/list.html:39
|
#: mailu/ui/templates/domain/list.html:39
|
||||||
msgid "Alternatives"
|
msgid "Alternatives"
|
||||||
msgstr ""
|
msgstr "חלופות"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/signup.html:13
|
#: mailu/ui/templates/domain/signup.html:13
|
||||||
msgid ""
|
msgid ""
|
||||||
"In order to register a new domain, you must first setup the\n"
|
"In order to register a new domain, you must first setup the\n"
|
||||||
" domain zone so that the domain <code>MX</code> points to this server"
|
" domain zone so that the domain <code>MX</code> points to this server"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"כדי לרשום שם תחום חדש, תחילה עליך להקים את אזור התחום\n"
|
||||||
|
" (domain zone) כדי שה־<code>MX</code> של שם התחום יפנה לשרת הזה"
|
||||||
|
|
||||||
#: mailu/ui/templates/domain/signup.html:18
|
#: mailu/ui/templates/domain/signup.html:18
|
||||||
msgid ""
|
msgid ""
|
||||||
"If you do not know how to setup an <code>MX</code> record for your DNS "
|
"If you do not know how to setup an <code>MX</code> record for your DNS "
|
||||||
"zone,\n"
|
"zone,\n"
|
||||||
" please contact your DNS provider or administrator. Also, please wait "
|
" please contact your DNS provider or administrator. Also, please wait a\n"
|
||||||
"a\n"
|
|
||||||
" couple minutes after the <code>MX</code> is set so the local server "
|
" couple minutes after the <code>MX</code> is set so the local server "
|
||||||
"cache\n"
|
"cache\n"
|
||||||
" expires."
|
" expires."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"אם לא ברור לך איך להקים רשומת <code>MX</code> עבור אזור ה־DNS שלך,\n"
|
||||||
|
" נא ליצור קשר עם ספק ה־ DNS או ההנהלה שלך. כמו כן, נא להמתין מספר דקות\n"
|
||||||
|
" לאחר הגדרת ה־<code>MX</code> כדי לאפשר לתוקף המטמון המקורי בשרת\n"
|
||||||
|
" לפוג."
|
||||||
|
|
||||||
#: mailu/ui/templates/fetch/create.html:4
|
#: mailu/ui/templates/fetch/create.html:4
|
||||||
msgid "Add a fetched account"
|
msgid "Add a fetched account"
|
||||||
msgstr ""
|
msgstr "הוספת חשבון נמשך"
|
||||||
|
|
||||||
#: mailu/ui/templates/fetch/edit.html:4
|
#: mailu/ui/templates/fetch/edit.html:4
|
||||||
msgid "Update a fetched account"
|
msgid "Update a fetched account"
|
||||||
msgstr ""
|
msgstr "עדכון חשבון שנמשך"
|
||||||
|
|
||||||
#: mailu/ui/templates/fetch/list.html:12
|
#: mailu/ui/templates/fetch/list.html:12
|
||||||
msgid "Add an account"
|
msgid "Add an account"
|
||||||
msgstr ""
|
msgstr "הוספת חשבון"
|
||||||
|
|
||||||
#: mailu/ui/templates/fetch/list.html:19
|
#: mailu/ui/templates/fetch/list.html:19
|
||||||
msgid "Endpoint"
|
msgid "Endpoint"
|
||||||
msgstr ""
|
msgstr "נקודת גישה"
|
||||||
|
|
||||||
#: mailu/ui/templates/fetch/list.html:21
|
#: mailu/ui/templates/fetch/list.html:21
|
||||||
msgid "Keep emails"
|
msgid "Keep emails"
|
||||||
msgstr ""
|
msgstr "לשמור על ההודעות"
|
||||||
|
|
||||||
#: mailu/ui/templates/fetch/list.html:22
|
#: mailu/ui/templates/fetch/list.html:22
|
||||||
msgid "Last check"
|
msgid "Last check"
|
||||||
msgstr ""
|
msgstr "בדיקה אחרונה"
|
||||||
|
|
||||||
#: mailu/ui/templates/fetch/list.html:35
|
#: mailu/ui/templates/fetch/list.html:35
|
||||||
msgid "yes"
|
msgid "yes"
|
||||||
msgstr ""
|
msgstr "כן"
|
||||||
|
|
||||||
#: mailu/ui/templates/fetch/list.html:35
|
#: mailu/ui/templates/fetch/list.html:35
|
||||||
msgid "no"
|
msgid "no"
|
||||||
msgstr ""
|
msgstr "לא"
|
||||||
|
|
||||||
#: mailu/ui/templates/manager/create.html:4
|
#: mailu/ui/templates/manager/create.html:4
|
||||||
msgid "Add a manager"
|
msgid "Add a manager"
|
||||||
msgstr ""
|
msgstr "הוספת מנהל"
|
||||||
|
|
||||||
#: mailu/ui/templates/manager/list.html:4
|
#: mailu/ui/templates/manager/list.html:4
|
||||||
msgid "Manager list"
|
msgid "Manager list"
|
||||||
msgstr ""
|
msgstr "רשימת מנהלים"
|
||||||
|
|
||||||
#: mailu/ui/templates/manager/list.html:12
|
#: mailu/ui/templates/manager/list.html:12
|
||||||
msgid "Add manager"
|
msgid "Add manager"
|
||||||
msgstr ""
|
msgstr "הוספת מנהל"
|
||||||
|
|
||||||
#: mailu/ui/templates/relay/create.html:4
|
#: mailu/ui/templates/relay/create.html:4
|
||||||
msgid "New relay domain"
|
msgid "New relay domain"
|
||||||
msgstr ""
|
msgstr "שם תחום מועבר"
|
||||||
|
|
||||||
#: mailu/ui/templates/relay/edit.html:4
|
#: mailu/ui/templates/relay/edit.html:4
|
||||||
msgid "Edit relayd domain"
|
msgid "Edit relayd domain"
|
||||||
msgstr ""
|
msgstr "עריכת שמות תחום מועברים"
|
||||||
|
|
||||||
#: mailu/ui/templates/relay/list.html:4
|
#: mailu/ui/templates/relay/list.html:4
|
||||||
msgid "Relayed domain list"
|
msgid "Relayed domain list"
|
||||||
msgstr ""
|
msgstr "רשימת שמות תחום מועברים"
|
||||||
|
|
||||||
#: mailu/ui/templates/relay/list.html:9
|
#: mailu/ui/templates/relay/list.html:9
|
||||||
msgid "New relayed domain"
|
msgid "New relayed domain"
|
||||||
msgstr ""
|
msgstr "שם תחום מועבר חדש"
|
||||||
|
|
||||||
#: mailu/ui/templates/token/create.html:4
|
#: mailu/ui/templates/token/create.html:4
|
||||||
msgid "Create an authentication token"
|
msgid "Create an authentication token"
|
||||||
msgstr ""
|
msgstr "יצירת אסימון אימות"
|
||||||
|
|
||||||
#: mailu/ui/templates/token/list.html:12
|
#: mailu/ui/templates/token/list.html:12
|
||||||
msgid "New token"
|
msgid "New token"
|
||||||
msgstr ""
|
msgstr "אסימון חדש"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/create.html:4
|
#: mailu/ui/templates/user/create.html:4
|
||||||
msgid "New user"
|
msgid "New user"
|
||||||
msgstr ""
|
msgstr "משתמש חדש"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/create.html:15
|
#: mailu/ui/templates/user/create.html:15
|
||||||
msgid "General"
|
msgid "General"
|
||||||
msgstr ""
|
msgstr "כללי"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/create.html:22
|
#: mailu/ui/templates/user/create.html:22
|
||||||
msgid "Features and quotas"
|
msgid "Features and quotas"
|
||||||
msgstr ""
|
msgstr "יכולות ומיכסות"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/edit.html:4
|
#: mailu/ui/templates/user/edit.html:4
|
||||||
msgid "Edit user"
|
msgid "Edit user"
|
||||||
msgstr ""
|
msgstr "עריכת משתמש"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/forward.html:4
|
#: mailu/ui/templates/user/forward.html:4
|
||||||
msgid "Forward emails"
|
msgid "Forward emails"
|
||||||
msgstr ""
|
msgstr "העברת הודעות"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/list.html:4
|
#: mailu/ui/templates/user/list.html:4
|
||||||
msgid "User list"
|
msgid "User list"
|
||||||
msgstr ""
|
msgstr "רשימת משתמשים"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/list.html:12
|
#: mailu/ui/templates/user/list.html:12
|
||||||
msgid "Add user"
|
msgid "Add user"
|
||||||
msgstr ""
|
msgstr "הוספת משתמש"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/list.html:19 mailu/ui/templates/user/settings.html:4
|
#: mailu/ui/templates/user/list.html:19 mailu/ui/templates/user/settings.html:4
|
||||||
msgid "User settings"
|
msgid "User settings"
|
||||||
msgstr ""
|
msgstr "הגדרות משתמש"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/list.html:21
|
#: mailu/ui/templates/user/list.html:21
|
||||||
msgid "Features"
|
msgid "Features"
|
||||||
msgstr ""
|
msgstr "יכולות"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/password.html:4
|
#: mailu/ui/templates/user/password.html:4
|
||||||
msgid "Password update"
|
msgid "Password update"
|
||||||
msgstr ""
|
msgstr "עדכון סיסמה"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/reply.html:4
|
#: mailu/ui/templates/user/reply.html:4
|
||||||
msgid "Automatic reply"
|
msgid "Automatic reply"
|
||||||
msgstr ""
|
msgstr "מענה אוטומטי"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/settings.html:22
|
#: mailu/ui/templates/user/settings.html:22
|
||||||
msgid "Auto-forward"
|
msgid "Auto-forward"
|
||||||
msgstr ""
|
msgstr "העברה אוטומטית"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/signup_domain.html:8
|
#: mailu/ui/templates/user/signup_domain.html:8
|
||||||
msgid "pick a domain for the new account"
|
msgid "pick a domain for the new account"
|
||||||
msgstr ""
|
msgstr "נא לבחור שם תחום לחשבון החדש"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/signup_domain.html:14
|
#: mailu/ui/templates/user/signup_domain.html:14
|
||||||
msgid "Domain"
|
msgid "Domain"
|
||||||
msgstr ""
|
msgstr "שם תחום"
|
||||||
|
|
||||||
#: mailu/ui/templates/user/signup_domain.html:15
|
#: mailu/ui/templates/user/signup_domain.html:15
|
||||||
msgid "Available slots"
|
msgid "Available slots"
|
||||||
msgstr ""
|
msgstr "מקומות פנויים"
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
tee >(rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu learn_ham /dev/stdin) \
|
RSPAMD_HOST="$(getent hosts {{ ANTISPAM_WEBUI_ADDRESS }}|cut -d\ -f1)"
|
||||||
>(rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu -f 11 fuzzy_del /dev/stdin) \
|
if [[ $? -ne 0 ]]
|
||||||
| rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu -f 13 fuzzy_add /dev/stdin
|
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
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
tee >(rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu learn_spam /dev/stdin) \
|
RSPAMD_HOST="$(getent hosts {{ ANTISPAM_WEBUI_ADDRESS }}|cut -d\ -f1)"
|
||||||
>(rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu -f 13 fuzzy_del /dev/stdin) \
|
if [[ $? -ne 0 ]]
|
||||||
| rspamc -h {{ ANTISPAM_WEBUI_ADDRESS }} -P mailu -f 11 fuzzy_add /dev/stdin
|
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
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
-----BEGIN DH PARAMETERS-----
|
-----BEGIN DH PARAMETERS-----
|
||||||
MIICCAKCAgEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
MIIBiAKCAYEAtQlUSOKGjpdXJ154qmMEa1pEs+9CdSxWiZFkiXBJb0lTafOh8cfF
|
||||||
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
2IkcWSwzxWwjW4Ad26UQQFh1poGf2QBzVk2vuKCekYzPAs/WqH8VwiXBiWR5R9lh
|
||||||
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
v/+CkEBYuQOzAhXLN6ZGdPPa2sjdI49rlaIqyLJE4D0TI/VHYmC/vEwqkJUgaGrS
|
||||||
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
19LhHZimnmouvrnyBPyf00czXlMow0RnmYeHVZ7W5hu7t9TH9o3QAN/GKiFfxFj+
|
||||||
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
RkdLM7beQdS0He5YeTaElM5l1YT5d5gHFbOzEQyKHd10ux+bgVcgUeVbBnI1SAIC
|
||||||
ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3
|
w53yc1PkDAiRijSP5j5aWq1djtJPheS13o35HyIf0cHzkNYhKfX5JWPj/cbgdM+C
|
||||||
7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32
|
FL1bnRc8sL5oxmkDoGJhiNZIf4n2WtS8Zu28gUgat6S+vCm/4yavIc/T1g6UiNKE
|
||||||
nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZp4e
|
X41HPbsma/QWUwOL6S+b2qr+7rKqjI5TzVek8vBMellEV4mBvfQU3NDSQ4WvxbTq
|
||||||
8W5vUsMWTfT7eTDp5OWIV7asfV9C1p9tGHdjzx1VA0AEh/VbpX4xzHpxNciG77Qx
|
ZEOgLPA178nrAgEC
|
||||||
iu1qHgEtnmgyqQdgCpGBMMRtx3j5ca0AOAkpmaMzy4t6Gh25PXFAADwqTs6p+Y0K
|
|
||||||
zAqCkc3OyX3Pjsm1Wn+IpGtNtahR9EGC4caKAH5eZV9q//////////8CAQI=
|
|
||||||
-----END DH PARAMETERS-----
|
-----END DH PARAMETERS-----
|
||||||
|
@ -250,6 +250,7 @@ mail {
|
|||||||
listen 10025;
|
listen 10025;
|
||||||
protocol smtp;
|
protocol smtp;
|
||||||
smtp_auth plain;
|
smtp_auth plain;
|
||||||
|
auth_http_header Auth-Port 10025;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Default IMAP server for the webmail (no encryption, but authentication)
|
# Default IMAP server for the webmail (no encryption, but authentication)
|
||||||
@ -257,6 +258,7 @@ mail {
|
|||||||
listen 10143;
|
listen 10143;
|
||||||
protocol imap;
|
protocol imap;
|
||||||
smtp_auth plain;
|
smtp_auth plain;
|
||||||
|
auth_http_header Auth-Port 10043;
|
||||||
}
|
}
|
||||||
|
|
||||||
# SMTP is always enabled, to avoid losing emails when TLS is failing
|
# SMTP is always enabled, to avoid losing emails when TLS is failing
|
||||||
@ -271,6 +273,7 @@ mail {
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
protocol smtp;
|
protocol smtp;
|
||||||
smtp_auth none;
|
smtp_auth none;
|
||||||
|
auth_http_header Auth-Port 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
# All other protocols are disabled if TLS is failing
|
# All other protocols are disabled if TLS is failing
|
||||||
@ -283,6 +286,7 @@ mail {
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
protocol imap;
|
protocol imap;
|
||||||
imap_auth plain;
|
imap_auth plain;
|
||||||
|
auth_http_header Auth-Port 143;
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
@ -293,6 +297,7 @@ mail {
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
protocol pop3;
|
protocol pop3;
|
||||||
pop3_auth plain;
|
pop3_auth plain;
|
||||||
|
auth_http_header Auth-Port 110;
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
@ -303,6 +308,7 @@ mail {
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
protocol smtp;
|
protocol smtp;
|
||||||
smtp_auth plain login;
|
smtp_auth plain login;
|
||||||
|
auth_http_header Auth-Port 587;
|
||||||
}
|
}
|
||||||
|
|
||||||
{% if TLS %}
|
{% if TLS %}
|
||||||
@ -311,6 +317,7 @@ mail {
|
|||||||
listen [::]:465 ssl;
|
listen [::]:465 ssl;
|
||||||
protocol smtp;
|
protocol smtp;
|
||||||
smtp_auth plain login;
|
smtp_auth plain login;
|
||||||
|
auth_http_header Auth-Port 465;
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
@ -318,6 +325,7 @@ mail {
|
|||||||
listen [::]:993 ssl;
|
listen [::]:993 ssl;
|
||||||
protocol imap;
|
protocol imap;
|
||||||
imap_auth plain;
|
imap_auth plain;
|
||||||
|
auth_http_header Auth-Port 993;
|
||||||
}
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
@ -325,6 +333,7 @@ mail {
|
|||||||
listen [::]:995 ssl;
|
listen [::]:995 ssl;
|
||||||
protocol pop3;
|
protocol pop3;
|
||||||
pop3_auth plain;
|
pop3_auth plain;
|
||||||
|
auth_http_header Auth-Port 995;
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
ssl_certificate {{ TLS[0] }};
|
ssl_certificate {{ TLS[0] }};
|
||||||
ssl_certificate_key {{ TLS[1] }};
|
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_timeout 1d;
|
||||||
ssl_session_tickets off;
|
ssl_session_tickets off;
|
||||||
ssl_dhparam /conf/dhparam.pem;
|
ssl_dhparam /conf/dhparam.pem;
|
||||||
|
@ -26,11 +26,11 @@ cert_name = os.getenv("TLS_CERT_FILENAME", default="cert.pem")
|
|||||||
keypair_name = os.getenv("TLS_KEYPAIR_FILENAME", default="key.pem")
|
keypair_name = os.getenv("TLS_KEYPAIR_FILENAME", default="key.pem")
|
||||||
args["TLS"] = {
|
args["TLS"] = {
|
||||||
"cert": ("/certs/%s" % cert_name, "/certs/%s" % keypair_name),
|
"cert": ("/certs/%s" % cert_name, "/certs/%s" % keypair_name),
|
||||||
"letsencrypt": ("/certs/letsencrypt/live/mailu/fullchain.pem",
|
"letsencrypt": ("/certs/letsencrypt/live/mailu/nginx-chain.pem",
|
||||||
"/certs/letsencrypt/live/mailu/privkey.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": ("/certs/%s" % cert_name, "/certs/%s" % keypair_name),
|
||||||
"mail-letsencrypt": ("/certs/letsencrypt/live/mailu/fullchain.pem",
|
"mail-letsencrypt": ("/certs/letsencrypt/live/mailu/nginx-chain.pem",
|
||||||
"/certs/letsencrypt/live/mailu/privkey.pem"),
|
"/certs/letsencrypt/live/mailu/privkey.pem", "/certs/letsencrypt/live/mailu-ecdsa/nginx-chain.pem", "/certs/letsencrypt/live/mailu-ecdsa/privkey.pem"),
|
||||||
"notls": None
|
"notls": None
|
||||||
}[args["TLS_FLAVOR"]]
|
}[args["TLS_FLAVOR"]]
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import os
|
|||||||
import time
|
import time
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
command = [
|
command = [
|
||||||
"certbot",
|
"certbot",
|
||||||
"-n", "--agree-tos", # non-interactive
|
"-n", "--agree-tos", # non-interactive
|
||||||
@ -14,16 +13,47 @@ command = [
|
|||||||
"--cert-name", "mailu",
|
"--cert-name", "mailu",
|
||||||
"--preferred-challenges", "http", "--http-01-port", "8008",
|
"--preferred-challenges", "http", "--http-01-port", "8008",
|
||||||
"--keep-until-expiring",
|
"--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",
|
"--config-dir", "/certs/letsencrypt",
|
||||||
"--post-hook", "/config.py"
|
"--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
|
# Wait for nginx to start
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
# Run certbot every hour
|
# Run certbot every day
|
||||||
while True:
|
while True:
|
||||||
subprocess.call(command)
|
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)
|
||||||
|
@ -33,7 +33,8 @@ relayhost = {{ RELAYHOST }}
|
|||||||
{% if RELAYUSER %}
|
{% if RELAYUSER %}
|
||||||
smtp_sasl_auth_enable = yes
|
smtp_sasl_auth_enable = yes
|
||||||
smtp_sasl_password_maps = lmdb:/etc/postfix/sasl_passwd
|
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 %}
|
{% endif %}
|
||||||
|
|
||||||
# Recipient delimiter for extended addresses
|
# Recipient delimiter for extended addresses
|
||||||
@ -50,15 +51,20 @@ smtpd_authorized_xclient_hosts={{ POD_ADDRESS_RANGE or SUBNET }}
|
|||||||
# General TLS configuration
|
# 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_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_preempt_cipherlist = yes
|
||||||
tls_ssl_options = NO_COMPRESSION
|
tls_ssl_options = NO_COMPRESSION, NO_TICKET
|
||||||
|
|
||||||
# By default, outgoing TLS is more flexible because
|
# By default, outgoing TLS is more flexible because
|
||||||
# 1. not all receiving servers will support TLS,
|
# 1. not all receiving servers will support TLS,
|
||||||
# 2. not all will have and up-to-date TLS stack.
|
# 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_mandatory_protocols = !SSLv2, !SSLv3
|
||||||
smtp_tls_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
|
# Virtual
|
||||||
@ -99,6 +105,8 @@ smtpd_sender_login_maps = ${podop}senderlogin
|
|||||||
# Restrictions for incoming SMTP, other restrictions are applied in master.cf
|
# Restrictions for incoming SMTP, other restrictions are applied in master.cf
|
||||||
smtpd_helo_required = yes
|
smtpd_helo_required = yes
|
||||||
|
|
||||||
|
check_ratelimit = check_sasl_access ${podop}senderrate
|
||||||
|
|
||||||
smtpd_client_restrictions =
|
smtpd_client_restrictions =
|
||||||
permit_mynetworks,
|
permit_mynetworks,
|
||||||
check_sender_access ${podop}senderaccess,
|
check_sender_access ${podop}senderaccess,
|
||||||
|
@ -7,7 +7,8 @@ smtp inet n - n - - smtpd
|
|||||||
# Internal SMTP service
|
# Internal SMTP service
|
||||||
10025 inet n - n - - smtpd
|
10025 inet n - n - - smtpd
|
||||||
-o smtpd_sasl_auth_enable=yes
|
-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 smtpd_reject_unlisted_recipient={% if REJECT_UNLISTED_RECIPIENT %}{{ REJECT_UNLISTED_RECIPIENT }}{% else %}no{% endif %}
|
||||||
-o cleanup_service_name=outclean
|
-o cleanup_service_name=outclean
|
||||||
outclean unix n - n - 0 cleanup
|
outclean unix n - n - 0 cleanup
|
||||||
|
@ -15,6 +15,7 @@ log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING"))
|
|||||||
|
|
||||||
def start_podop():
|
def start_podop():
|
||||||
os.setuid(getpwnam('postfix').pw_uid)
|
os.setuid(getpwnam('postfix').pw_uid)
|
||||||
|
os.mkdir('/dev/shm/postfix',mode=0o700)
|
||||||
url = "http://" + os.environ["ADMIN_ADDRESS"] + "/internal/postfix/"
|
url = "http://" + os.environ["ADMIN_ADDRESS"] + "/internal/postfix/"
|
||||||
# TODO: Remove verbosity setting from Podop?
|
# TODO: Remove verbosity setting from Podop?
|
||||||
run_server(0, "postfix", "/tmp/podop.socket", [
|
run_server(0, "postfix", "/tmp/podop.socket", [
|
||||||
@ -25,7 +26,8 @@ def start_podop():
|
|||||||
("recipientmap", "url", url + "recipient/map/§"),
|
("recipientmap", "url", url + "recipient/map/§"),
|
||||||
("sendermap", "url", url + "sender/map/§"),
|
("sendermap", "url", url + "sender/map/§"),
|
||||||
("senderaccess", "url", url + "sender/access/§"),
|
("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):
|
def is_valid_postconf_line(line):
|
||||||
@ -66,6 +68,12 @@ for map_file in glob.glob("/overrides/*.map"):
|
|||||||
os.system("postmap {}".format(destination))
|
os.system("postmap {}".format(destination))
|
||||||
os.remove(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:
|
if "RELAYUSER" in os.environ:
|
||||||
path = "/etc/postfix/sasl_passwd"
|
path = "/etc/postfix/sasl_passwd"
|
||||||
conf.jinja("/conf/sasl_passwd", os.environ, path)
|
conf.jinja("/conf/sasl_passwd", os.environ, path)
|
||||||
|
@ -28,6 +28,6 @@ entryPoint = "http"
|
|||||||
|
|
||||||
# This should include all of your mail domains, and main= should be your $TRAEFIK_DOMAIN
|
# This should include all of your mail domains, and main= should be your $TRAEFIK_DOMAIN
|
||||||
[[acme.domains]]
|
[[acme.domains]]
|
||||||
main = "mail.your.doma.in"
|
main = "mail.example.com"
|
||||||
sans = ["web.mail.your.doma.in", "smtp.mail.doma.in", "imap.mail.doma.in"]
|
sans = ["web.mail.example.com", "smtp.mail.example.com", "imap.mail.example.com"]
|
||||||
|
|
||||||
|
@ -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
|
recommended to setup a generic value and later configure a mail alias for that
|
||||||
address.
|
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
|
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
|
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.
|
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.
|
``RELAYUSER`` and ``RELAYPASSWORD`` can be used when authentication is needed.
|
||||||
|
|
||||||
By default postfix uses "opportunistic TLS" for outbound mail. This can be changed
|
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
|
by setting ``OUTBOUND_TLS_LEVEL`` to ``encrypt`` or ``secure``. This setting is highly recommended
|
||||||
if you are a relayhost that supports TLS.
|
if you are using a relayhost that supports TLS.
|
||||||
|
|
||||||
Similarily by default nginx uses "opportunistic TLS" for inbound mail. This can be changed
|
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
|
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
|
.. _`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
|
Antivirus settings
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -3,222 +3,9 @@
|
|||||||
Kubernetes setup
|
Kubernetes setup
|
||||||
================
|
================
|
||||||
|
|
||||||
> Hold up!
|
Please see `the Helm Chart documentation`_.
|
||||||
> 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).
|
|
||||||
|
|
||||||
Prequisites
|
We are looking for maintainers: if you are interested please join our `Matrix`_ room.
|
||||||
-----------
|
|
||||||
|
|
||||||
Structure
|
.. _`the Helm Chart documentation`: https://github.com/Mailu/helm-charts/blob/master/mailu/README.md
|
||||||
~~~~~~~~~
|
.. _`Matrix`: https://matrix.to/#/#mailu:tedomum.net
|
||||||
|
|
||||||
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!
|
|
||||||
|
@ -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
|
|
@ -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
|
|
@ -1,4 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: mailu-mailserver
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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.
|
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:
|
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
|
- `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
|
- `use Traefik in another container as central system-reverse-proxy`_
|
||||||
- override Mailu Web frontend configuration
|
- `override Mailu Web frontend configuration`_
|
||||||
- disable Mailu Web frontend completely and use your own
|
|
||||||
|
|
||||||
All options will require that you modify the ``docker-compose.yml`` file.
|
All options will require that you modify the ``docker-compose.yml`` file.
|
||||||
|
|
||||||
@ -89,7 +88,7 @@ Here is an example configuration :
|
|||||||
|
|
||||||
server {
|
server {
|
||||||
listen <public_ip>:443;
|
listen <public_ip>:443;
|
||||||
server_name yourpublicname.tld;
|
server_name external.example.com;
|
||||||
# [...] here goes your standard configuration
|
# [...] here goes your standard configuration
|
||||||
|
|
||||||
location /webmail {
|
location /webmail {
|
||||||
@ -99,7 +98,7 @@ Here is an example configuration :
|
|||||||
|
|
||||||
server {
|
server {
|
||||||
listen <internal_ip>:443;
|
listen <internal_ip>:443;
|
||||||
server_name yourinternalname.tld;
|
server_name internal.example.com;
|
||||||
# [...] here goes your standard configuration
|
# [...] here goes your standard configuration
|
||||||
|
|
||||||
location /admin {
|
location /admin {
|
||||||
@ -113,7 +112,7 @@ Depending on how you access the front server, you might want to add a ``proxy_re
|
|||||||
|
|
||||||
.. code-block:: nginx
|
.. code-block:: nginx
|
||||||
|
|
||||||
proxy_redirect https://localhost https://your-domain.com;
|
proxy_redirect https://localhost https://example.com;
|
||||||
|
|
||||||
This will stop redirects (301 and 302) sent by the Webmail, nginx front and admin interface from sending you to ``localhost``.
|
This will stop redirects (301 and 302) sent by the Webmail, nginx front and admin interface from sending you to ``localhost``.
|
||||||
|
|
||||||
@ -151,8 +150,8 @@ Add the respective Traefik labels for your domain/configuration, like
|
|||||||
|
|
||||||
.. note:: Please don’t forget to add ``TRAEFIK_DOMAIN=[...]`` TO YOUR ``.env``
|
.. note:: Please don’t forget to add ``TRAEFIK_DOMAIN=[...]`` TO YOUR ``.env``
|
||||||
|
|
||||||
If your Traefik is configured to automatically request certificates from *letsencrypt*, then you’ll have a certificate for ``mail.your.doma.in`` now. However,
|
If your Traefik is configured to automatically request certificates from *letsencrypt*, then you’ll have a certificate for ``mail.your.example.com`` now. However,
|
||||||
``mail.your.doma.in`` might only be the location where you want the Mailu web-interfaces to live — your mail should be sent/received from ``your.doma.in``,
|
``mail.your.example.com`` might only be the location where you want the Mailu web-interfaces to live — your mail should be sent/received from ``your.example.com``,
|
||||||
and this is the ``DOMAIN`` in your ``.env``?
|
and this is the ``DOMAIN`` in your ``.env``?
|
||||||
To support that use-case, Traefik can request ``SANs`` for your domain. The configuration for this will depend on your Traefik version.
|
To support that use-case, Traefik can request ``SANs`` for your domain. The configuration for this will depend on your Traefik version.
|
||||||
|
|
||||||
@ -171,12 +170,12 @@ Add the appropriate labels for your domain(s) to the ``front`` container in ``do
|
|||||||
# Enable TLS
|
# Enable TLS
|
||||||
- "traefik.http.routers.mailu-secure.tls"
|
- "traefik.http.routers.mailu-secure.tls"
|
||||||
# Your main domain
|
# Your main domain
|
||||||
- "traefik.http.routers.mailu-secure.tls.domains[0].main=your.doma.in"
|
- "traefik.http.routers.mailu-secure.tls.domains[0].main=your.example.com"
|
||||||
# Optional SANs for your main domain
|
# Optional SANs for your main domain
|
||||||
- "traefik.http.routers.mailu-secure.tls.domains[0].sans=mail.your.doma.in,webmail.your.doma.in,smtp.your.doma.in"
|
- "traefik.http.routers.mailu-secure.tls.domains[0].sans=mail.your.example.com,webmail.your.example.com,smtp.your.example.com"
|
||||||
# Optionally add other domains
|
# Optionally add other domains
|
||||||
- "traefik.http.routers.mailu-secure.tls.domains[1].main=mail.other.doma.in"
|
- "traefik.http.routers.mailu-secure.tls.domains[1].main=mail.other.example.com"
|
||||||
- "traefik.http.routers.mailu-secure.tls.domains[1].sans=mail2.other.doma.in,mail3.other.doma.in"
|
- "traefik.http.routers.mailu-secure.tls.domains[1].sans=mail2.other.example.com,mail3.other.example.com"
|
||||||
# Your ACME certificate resolver
|
# Your ACME certificate resolver
|
||||||
- "traefik.http.routers.mailu-secure.tls.certResolver=foo"
|
- "traefik.http.routers.mailu-secure.tls.certResolver=foo"
|
||||||
|
|
||||||
@ -193,8 +192,8 @@ Lets add something like
|
|||||||
|
|
||||||
[acme]
|
[acme]
|
||||||
[[acme.domains]]
|
[[acme.domains]]
|
||||||
main = "your.doma.in" # this is the same as $TRAEFIK_DOMAIN!
|
main = "your.example.com" # this is the same as $TRAEFIK_DOMAIN!
|
||||||
sans = ["mail.your.doma.in", "webmail.your.doma.in", "smtp.your.doma.in"]
|
sans = ["mail.your.example.com", "webmail.your.example.com", "smtp.your.example.com"]
|
||||||
|
|
||||||
to your ``traefik.toml``.
|
to your ``traefik.toml``.
|
||||||
|
|
||||||
@ -259,9 +258,7 @@ You can also download the example configuration files:
|
|||||||
- :download:`compose/traefik/docker-compose.yml`
|
- :download:`compose/traefik/docker-compose.yml`
|
||||||
- :download:`compose/traefik/traefik.toml`
|
- :download:`compose/traefik/traefik.toml`
|
||||||
|
|
||||||
Disable completely Mailu reverse proxy
|
.. _have Mailu Web frontend listen locally and use your own Web frontend on top of it: #have-mailu-web-frontend-listen-locally
|
||||||
--------------------------------------
|
.. _use Traefik in another container as central system-reverse-proxy: #traefik-as-reverse-proxy
|
||||||
|
.. _override Mailu Web frontend configuration: #override-mailu-configuration
|
||||||
|
|
||||||
You must not disable Mailu reverse proxy by removing the ``front`` section from the ``docker-compose.yml``.
|
|
||||||
|
|
||||||
``front`` is handling authentication and is also proxying e.g. SMTP and IMAP. A basic HTTP reverse proxy as described in this document is not sufficient for this.
|
|
||||||
|
@ -315,6 +315,21 @@ This page is also accessible for domain managers. On the users page new users ca
|
|||||||
|
|
||||||
* Fetched accounts. Access the fetched accounts page of the user. See the :ref:`fetched accounts page <webadministration_fetched_accounts>` for more information.
|
* Fetched accounts. Access the fetched accounts page of the user. See the :ref:`fetched accounts page <webadministration_fetched_accounts>` for more information.
|
||||||
|
|
||||||
|
This page also shows an overview of the following settings of an user:
|
||||||
|
|
||||||
|
* Email. The email address of the user.
|
||||||
|
|
||||||
|
* Features. Shows if IMAP or POP3 access is enabled.
|
||||||
|
|
||||||
|
* Storage quota. Shows how much assigned storage has been consumed.
|
||||||
|
|
||||||
|
* Sending Quota. The sending quota is the limit of messages a single user can send per day.
|
||||||
|
|
||||||
|
* Comment. A desription for the user.
|
||||||
|
|
||||||
|
* Created. Date when the user was created.
|
||||||
|
|
||||||
|
* Last edit. Last date when the user was modified.
|
||||||
|
|
||||||
.. _webadministration_add_user:
|
.. _webadministration_add_user:
|
||||||
|
|
||||||
@ -334,7 +349,7 @@ For adding a new user the following options can be configured.
|
|||||||
* Enabled. Tick this checkbox to enable the user account. When an user is disabled, the user is unable to login to the Admin GUI or webmail or access his email via IMAP/POP3 or send mail.
|
* Enabled. Tick this checkbox to enable the user account. When an user is disabled, the user is unable to login to the Admin GUI or webmail or access his email via IMAP/POP3 or send mail.
|
||||||
The email inbox of the user is still retained. This option can be used to temporarily suspend an user account.
|
The email inbox of the user is still retained. This option can be used to temporarily suspend an user account.
|
||||||
|
|
||||||
* Quota. The maximum quota for the user's email box.
|
* Storage Quota. The maximum quota for the user's email box.
|
||||||
|
|
||||||
* Allow IMAP access. When ticked, allows email retrieval via the IMAP protocol.
|
* Allow IMAP access. When ticked, allows email retrieval via the IMAP protocol.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
ARG DISTRO=alpine:3.14
|
ARG DISTRO=alpine:3.12
|
||||||
FROM $DISTRO
|
FROM $DISTRO
|
||||||
# python3 shared with most images
|
# python3 shared with most images
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
|
@ -62,6 +62,11 @@ ANTIVIRUS={{ antivirus_enabled or 'none' }}
|
|||||||
# Max attachment size will be 33% smaller
|
# Max attachment size will be 33% smaller
|
||||||
MESSAGE_SIZE_LIMIT={{ message_size_limit or '50000000' }}
|
MESSAGE_SIZE_LIMIT={{ message_size_limit or '50000000' }}
|
||||||
|
|
||||||
|
# Message rate limit (per user)
|
||||||
|
{% if message_ratelimit_pd > '0' %}
|
||||||
|
MESSAGE_RATELIMIT={{ message_ratelimit_pd }}/day
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
# Networks granted relay permissions
|
# Networks granted relay permissions
|
||||||
# Use this with care, all hosts in this networks will be able to send mail without authentication!
|
# Use this with care, all hosts in this networks will be able to send mail without authentication!
|
||||||
RELAYNETS=
|
RELAYNETS=
|
||||||
|
@ -55,6 +55,13 @@ Or in plain english: if receivers start to classify your mail as spam, this post
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Outgoing message rate limit (per user)</label>
|
||||||
|
<!-- Validates number input only -->
|
||||||
|
<p><input class="form-control" style="width: 7%; display: inline;" type="number" name="message_ratelimit_pd" value="200" required > / day
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-check form-check-inline">
|
<div class="form-check form-check-inline">
|
||||||
<label class="form-check-label">
|
<label class="form-check-label">
|
||||||
<input class="form-check-input" type="checkbox" name="disable_statistics" value="True">
|
<input class="form-check-input" type="checkbox" name="disable_statistics" value="True">
|
||||||
|
1
towncrier/newsfragments/1031.feature
Normal file
1
towncrier/newsfragments/1031.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
Add sending quotas per user
|
1
towncrier/newsfragments/1096.feature
Normal file
1
towncrier/newsfragments/1096.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
Allow specific users to send emails from any address using the WILDCARD_SENDERS setting
|
1
towncrier/newsfragments/1558.feature
Normal file
1
towncrier/newsfragments/1558.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
Make smtp_tls_policy_maps easily configurable
|
1
towncrier/newsfragments/1873.feature
Normal file
1
towncrier/newsfragments/1873.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
Hebrew translation has been completed.
|
5
towncrier/newsfragments/1922.enhancement
Normal file
5
towncrier/newsfragments/1922.enhancement
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Add support for ECDSA certificates when letsencrypt is used. This means dropping compatibility for android < 4.1.1
|
||||||
|
Add LETSENCRYPT_SHORTCHAIN to your configuration to avoid sending ISRG Root X1 (this will break compatibility with android < 7.1.1)
|
||||||
|
Disable AUTH command on port 25
|
||||||
|
Disable TLS tickets, reconfigure the cache to improve Forward Secrecy
|
||||||
|
Prevent clear-text credentials from being sent to relays
|
3
towncrier/newsfragments/1952.bugfix
Normal file
3
towncrier/newsfragments/1952.bugfix
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Webmail and Radicale (webdav) were not useable with domains with special characters such as umlauts.
|
||||||
|
Webmail and radicale now use punycode for logging in.
|
||||||
|
Punycode was not used in the HTTP headers. This resulted in illegal non-ASCII HTTP headers.
|
@ -1,51 +1,71 @@
|
|||||||
ARG ARCH=""
|
ARG ARCH=""
|
||||||
ARG QEMU=other
|
|
||||||
|
|
||||||
# NOTE: only add file if building for arm
|
# NOTE: only add file if building for arm
|
||||||
FROM ${ARCH}php:7.4-apache as build_arm
|
FROM ${ARCH}alpine:3.14
|
||||||
ONBUILD COPY --from=balenalib/rpi-alpine:3.14 /usr/bin/qemu-arm-static /usr/bin/qemu-arm-static
|
ONBUILD COPY --from=balenalib/rpi-alpine:3.14 /usr/bin/qemu-arm-static /usr/bin/qemu-arm-static
|
||||||
|
|
||||||
FROM ${ARCH}php:7.4-apache as build_other
|
# Shared later between dovecot postfix nginx rspamd rainloop and roundloop
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
python3 py3-pip \
|
||||||
|
&& pip3 install socrate==0.2.0
|
||||||
|
|
||||||
FROM build_${QEMU}
|
# https://www.rainloop.net/docs/system-requirements/
|
||||||
#Shared layer between rainloop and roundcube
|
# Rainloop:
|
||||||
RUN apt-get update && apt-get install -y \
|
# cURL Builtin
|
||||||
python3 curl python3-pip git python3-multidict \
|
# iconv php7-iconv
|
||||||
&& rm -rf /var/lib/apt/lists \
|
# json php7-json
|
||||||
&& echo "ServerSignature Off" >> /etc/apache2/apache2.conf
|
# libxml php7-xml
|
||||||
|
# dom php7-dom
|
||||||
|
# openssl php7-openssl
|
||||||
|
# DateTime Builtin
|
||||||
|
# PCRE Builtin
|
||||||
|
# SPL Builtin
|
||||||
|
# Recommended:
|
||||||
|
# php7-fpm FastCGI Process Manager
|
||||||
|
# Optional PHP extension (for contacts):
|
||||||
|
# php7-pdo Accessing databases in PHP
|
||||||
|
# php7-pdo_sqlite Access to SQLite 3 databases
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
nginx \
|
||||||
|
php7 php7-fpm php7-curl php7-iconv php7-json php7-xml php7-dom php7-openssl php7-pdo php7-pdo_sqlite \
|
||||||
|
&& rm /etc/nginx/http.d/default.conf \
|
||||||
|
&& rm /etc/php7/php-fpm.d/www.conf \
|
||||||
|
&& mkdir -p /run/nginx \
|
||||||
|
&& mkdir -p /var/www/rainloop
|
||||||
|
|
||||||
# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, rainloop, roundcube
|
# nginx / PHP config files
|
||||||
RUN pip3 install socrate
|
COPY config/nginx-rainloop.conf /etc/nginx/http.d/rainloop.conf
|
||||||
|
COPY config/php-rainloop.conf /etc/php7/php-fpm.d/rainloop.conf
|
||||||
|
|
||||||
|
# Rainloop login
|
||||||
|
COPY login/include.php /var/www/rainloop/include.php
|
||||||
|
COPY login/sso.php /var/www/rainloop/sso.php
|
||||||
|
|
||||||
|
# Parsed en moved at startup
|
||||||
|
COPY defaults/php.ini /defaults/php.ini
|
||||||
|
COPY defaults/application.ini /defaults/application.ini
|
||||||
|
COPY defaults/default.ini /defaults/default.ini
|
||||||
|
|
||||||
|
# Install Rainloop from source
|
||||||
ENV RAINLOOP_URL https://github.com/RainLoop/rainloop-webmail/releases/download/v1.16.0/rainloop-community-1.16.0.zip
|
ENV RAINLOOP_URL https://github.com/RainLoop/rainloop-webmail/releases/download/v1.16.0/rainloop-community-1.16.0.zip
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y \
|
RUN apk add --no-cache \
|
||||||
unzip python3-jinja2 \
|
curl unzip \
|
||||||
&& rm -rf /var/www/html/ \
|
&& cd /var/www/rainloop \
|
||||||
&& mkdir /var/www/html \
|
|
||||||
&& cd /var/www/html \
|
|
||||||
&& curl -L -O ${RAINLOOP_URL} \
|
&& curl -L -O ${RAINLOOP_URL} \
|
||||||
&& unzip -q *.zip \
|
&& unzip -q *.zip \
|
||||||
&& rm -f *.zip \
|
&& rm -f *.zip \
|
||||||
&& rm -rf data/ \
|
&& rm -rf data/ \
|
||||||
&& find . -type d -exec chmod 755 {} \; \
|
&& find . -type d -exec chmod 755 {} \; \
|
||||||
&& find . -type f -exec chmod 644 {} \; \
|
&& find . -type f -exec chmod 644 {} \; \
|
||||||
&& chown -R www-data: * \
|
&& chown -R nginx:nginx /var/www/rainloop \
|
||||||
&& apt-get purge -y unzip \
|
&& apk del unzip
|
||||||
&& rm -rf /var/lib/apt/lists
|
|
||||||
|
|
||||||
COPY include.php /var/www/html/include.php
|
|
||||||
COPY sso.php /var/www/html/sso.php
|
|
||||||
COPY php.ini /php.ini
|
|
||||||
|
|
||||||
COPY application.ini /application.ini
|
|
||||||
COPY default.ini /default.ini
|
|
||||||
|
|
||||||
COPY start.py /start.py
|
COPY start.py /start.py
|
||||||
|
|
||||||
EXPOSE 80/tcp
|
EXPOSE 80/tcp
|
||||||
VOLUME ["/data"]
|
VOLUME ["/data"]
|
||||||
|
|
||||||
CMD /start.py
|
CMD php-fpm7 && /start.py
|
||||||
|
|
||||||
HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1
|
HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1
|
||||||
|
38
webmails/rainloop/config/nginx-rainloop.conf
Normal file
38
webmails/rainloop/config/nginx-rainloop.conf
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
|
||||||
|
root /var/www/rainloop;
|
||||||
|
|
||||||
|
# /dev/stdout (Default), <path>, off
|
||||||
|
access_log off;
|
||||||
|
|
||||||
|
# /dev/stderr (Default), <path>, debug, info, notice, warn, error, crit, alert, emerg
|
||||||
|
error_log /dev/stderr warn;
|
||||||
|
|
||||||
|
index index.php;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri /index.php?$query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
||||||
|
|
||||||
|
fastcgi_intercept_errors on;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
|
||||||
|
fastcgi_keep_conn on;
|
||||||
|
include /etc/nginx/fastcgi_params;
|
||||||
|
fastcgi_pass unix:/var/run/php7-fpm.sock;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.ht {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /data {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
101
webmails/rainloop/config/php-rainloop.conf
Normal file
101
webmails/rainloop/config/php-rainloop.conf
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
; Start a new pool named 'rainloop'.
|
||||||
|
; the variable $pool can be used in any directive and will be replaced by the
|
||||||
|
; pool name ('rainloop' here)
|
||||||
|
[rainloop]
|
||||||
|
|
||||||
|
; Redirect worker stdout and stderr into main error log. If not set, stdout and
|
||||||
|
; stderr will be redirected to /dev/null according to FastCGI specs.
|
||||||
|
; Default value: no.
|
||||||
|
catch_workers_output = 1
|
||||||
|
|
||||||
|
; Unix user/group of processes
|
||||||
|
; Note: The user is mandatory. If the group is not set, the default user's group
|
||||||
|
; will be used.
|
||||||
|
user = nginx
|
||||||
|
group = nginx
|
||||||
|
|
||||||
|
; The address on which to accept FastCGI requests.
|
||||||
|
; Valid syntaxes are:
|
||||||
|
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
|
||||||
|
; a specific port;
|
||||||
|
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
|
||||||
|
; a specific port;
|
||||||
|
; 'port' - to listen on a TCP socket to all addresses
|
||||||
|
; (IPv6 and IPv4-mapped) on a specific port;
|
||||||
|
; '/path/to/unix/socket' - to listen on a unix socket.
|
||||||
|
; Note: This value is mandatory.
|
||||||
|
listen = /var/run/php7-fpm.sock
|
||||||
|
|
||||||
|
; Set permissions for unix socket, if one is used. In Linux, read/write
|
||||||
|
; permissions must be set in order to allow connections from a web server. Many
|
||||||
|
; BSD-derived systems allow connections regardless of permissions.
|
||||||
|
; Default Values: user and group are set as the running user
|
||||||
|
; mode is set to 0660
|
||||||
|
listen.owner = nginx
|
||||||
|
listen.group = nginx
|
||||||
|
listen.mode = 0660
|
||||||
|
|
||||||
|
; Choose how the process manager will control the number of child processes.
|
||||||
|
; Possible Values:
|
||||||
|
; static - a fixed number (pm.max_children) of child processes;
|
||||||
|
; dynamic - the number of child processes are set dynamically based on the
|
||||||
|
; following directives. With this process management, there will be
|
||||||
|
; always at least 1 children.
|
||||||
|
; pm.max_children - the maximum number of children that can
|
||||||
|
; be alive at the same time.
|
||||||
|
; pm.start_servers - the number of children created on startup.
|
||||||
|
; pm.min_spare_servers - the minimum number of children in 'idle'
|
||||||
|
; state (waiting to process). If the number
|
||||||
|
; of 'idle' processes is less than this
|
||||||
|
; number then some children will be created.
|
||||||
|
; pm.max_spare_servers - the maximum number of children in 'idle'
|
||||||
|
; state (waiting to process). If the number
|
||||||
|
; of 'idle' processes is greater than this
|
||||||
|
; number then some children will be killed.
|
||||||
|
; ondemand - no children are created at startup. Children will be forked when
|
||||||
|
; new requests will connect. The following parameter are used:
|
||||||
|
; pm.max_children - the maximum number of children that
|
||||||
|
; can be alive at the same time.
|
||||||
|
; pm.process_idle_timeout - The number of seconds after which
|
||||||
|
; an idle process will be killed.
|
||||||
|
; Note: This value is mandatory.
|
||||||
|
pm = ondemand
|
||||||
|
|
||||||
|
; The number of child processes to be created when pm is set to 'static' and the
|
||||||
|
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
|
||||||
|
; This value sets the limit on the number of simultaneous requests that will be
|
||||||
|
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
|
||||||
|
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
|
||||||
|
; CGI. The below defaults are based on a server without much resources. Don't
|
||||||
|
; forget to tweak pm.* to fit your needs.
|
||||||
|
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
|
||||||
|
; Note: This value is mandatory.
|
||||||
|
pm.max_children = 5
|
||||||
|
|
||||||
|
; The number of child processes created on startup.
|
||||||
|
; Note: Used only when pm is set to 'dynamic'
|
||||||
|
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
|
||||||
|
; pm.start_servers = 2
|
||||||
|
|
||||||
|
; The desired minimum number of idle server processes.
|
||||||
|
; Note: Used only when pm is set to 'dynamic'
|
||||||
|
; Note: Mandatory when pm is set to 'dynamic'
|
||||||
|
; pm.min_spare_servers = 1
|
||||||
|
|
||||||
|
; The desired maximum number of idle server processes.
|
||||||
|
; Note: Used only when pm is set to 'dynamic'
|
||||||
|
; Note: Mandatory when pm is set to 'dynamic'
|
||||||
|
; pm.max_spare_servers = 3
|
||||||
|
|
||||||
|
; This sets the maximum time in seconds a script is allowed to run before it is
|
||||||
|
; terminated by the parser. This helps prevent poorly written scripts from tying up
|
||||||
|
; the server. The default setting is 30s.
|
||||||
|
; Note: Used only when pm is set to 'ondemand'
|
||||||
|
pm.process_idle_timeout = 10s
|
||||||
|
|
||||||
|
; The number of requests each child process should execute before respawning.
|
||||||
|
; This can be useful to work around memory leaks in 3rd party libraries. For endless
|
||||||
|
; request processing specify '0'.
|
||||||
|
; Equivalent to PHP_FCGI_MAX_REQUESTS. Default value: 0.
|
||||||
|
; Noted: Used only when pm is set to 'ondemand'
|
||||||
|
pm.max_requests = 200
|
@ -18,7 +18,7 @@ if (file_exists(APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/include.php')) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve email and password
|
// Retrieve email and password
|
||||||
if (in_array('HTTP_X_REMOTE_USER', $_SERVER) && in_array('HTTP_X_REMOTE_USER_TOKEN', $_SERVER)) {
|
if (isset($_SERVER['HTTP_X_REMOTE_USER']) && isset($_SERVER['HTTP_X_REMOTE_USER_TOKEN'])) {
|
||||||
$email = $_SERVER['HTTP_X_REMOTE_USER'];
|
$email = $_SERVER['HTTP_X_REMOTE_USER'];
|
||||||
$password = $_SERVER['HTTP_X_REMOTE_USER_TOKEN'];
|
$password = $_SERVER['HTTP_X_REMOTE_USER_TOKEN'];
|
||||||
$ssoHash = \RainLoop\Api::GetUserSsoHash($email, $password);
|
$ssoHash = \RainLoop\Api::GetUserSsoHash($email, $password);
|
@ -19,12 +19,11 @@ shutil.rmtree(base + "domains/", ignore_errors=True)
|
|||||||
os.makedirs(base + "domains", exist_ok=True)
|
os.makedirs(base + "domains", exist_ok=True)
|
||||||
os.makedirs(base + "configs", exist_ok=True)
|
os.makedirs(base + "configs", exist_ok=True)
|
||||||
|
|
||||||
conf.jinja("/default.ini", os.environ, "/data/_data_/_default_/domains/default.ini")
|
conf.jinja("/defaults/default.ini", os.environ, "/data/_data_/_default_/domains/default.ini")
|
||||||
conf.jinja("/application.ini", os.environ, "/data/_data_/_default_/configs/application.ini")
|
conf.jinja("/defaults/application.ini", os.environ, "/data/_data_/_default_/configs/application.ini")
|
||||||
conf.jinja("/php.ini", os.environ, "/usr/local/etc/php/conf.d/rainloop.ini")
|
conf.jinja("/defaults/php.ini", os.environ, "/etc/php7/php.ini")
|
||||||
|
|
||||||
os.system("chown -R www-data:www-data /data")
|
os.system("chown -R nginx:nginx /data")
|
||||||
os.system("chmod -R a+rX /var/www/html/")
|
os.system("chmod -R a+rX /var/www/rainloop/")
|
||||||
|
|
||||||
os.execv("/usr/local/bin/apache2-foreground", ["apache2-foreground"])
|
|
||||||
|
|
||||||
|
os.execv("/usr/sbin/nginx", ["nginx", "-g", "daemon off;"])
|
||||||
|
Loading…
Reference in New Issue
Block a user