1
0
mirror of https://github.com/mailcow/mailcow-dockerized.git synced 2026-01-30 00:57:15 +00:00

Merge pull request #6251 from mailcow/staging

2025-01
This commit is contained in:
FreddleSpl0it
2025-01-23 11:16:38 +01:00
committed by GitHub
119 changed files with 3149 additions and 2174 deletions

View File

@@ -1,7 +1,7 @@
blank_issues_enabled: false
contact_links:
- name: ❓ Community-driven support (Free)
url: https://docs.mailcow.email/#get-support
url: https://docs.mailcow.email/#community-support-and-chat
about: Please use the community forum for questions or assistance
- name: 🔥 Premium Support (Paid)
url: https://www.servercow.de/mailcow?lang=en#support

View File

@@ -15,12 +15,6 @@
"data\/web\/inc\/lib\/vendor\/**"
],
"regexManagers": [
{
"fileMatch": ["^helper-scripts\/nextcloud.sh$"],
"matchStrings": [
"#\\srenovate:\\sdatasource=(?<datasource>.*?) depName=(?<depName>.*?)( versioning=(?<versioning>.*?))?( extractVersion=(?<extractVersion>.*?))?\\s.*?_VERSION=(?<currentValue>.*)"
]
},
{
"fileMatch": ["(^|/)Dockerfile[^/]*$"],
"matchStrings": [

View File

@@ -14,7 +14,7 @@ jobs:
pull-requests: write
steps:
- name: Mark/Close Stale Issues and Pull Requests 🗑️
uses: actions/stale@v9.0.0
uses: actions/stale@v9.1.0
with:
repo-token: ${{ secrets.STALE_ACTION_PAT }}
days-before-stale: 60

View File

@@ -23,7 +23,6 @@ jobs:
- "postfix-mailcow"
- "rspamd-mailcow"
- "sogo-mailcow"
- "solr-mailcow"
- "unbound-mailcow"
- "watchdog-mailcow"
runs-on: ubuntu-latest

1
.gitignore vendored
View File

@@ -23,6 +23,7 @@ data/conf/dovecot/sni.conf
data/conf/dovecot/sogo-sso.conf
data/conf/dovecot/sogo_trusted_ip.conf
data/conf/dovecot/sql
data/conf/dovecot/conf.d/fts.conf
data/conf/nextcloud-*.bak
data/conf/nginx/*.active
data/conf/nginx/*.bak

View File

@@ -4,9 +4,9 @@ exec 5>&1
# Do not attempt to write to slave
if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
export REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}"
export REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning"
else
export REDIS_CMDLINE="redis-cli -h redis -p 6379"
export REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS} --no-auth-warning"
fi
until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do

View File

@@ -124,7 +124,7 @@ case "$SUCCESS" in
;;
*) # non-zero is non-fun
log_f "Failed to obtain certificate ${CERT} for domains '${CERT_DOMAINS[*]}'"
redis-cli -h redis SET ACME_FAIL_TIME "$(date +%s)"
redis-cli -h redis -a ${REDISPASS} --no-auth-warning SET ACME_FAIL_TIME "$(date +%s)"
exit 100${SUCCESS}
;;
esac

View File

@@ -34,9 +34,9 @@ async def lifespan(app: FastAPI):
# Init redis client
if os.environ['REDIS_SLAVEOF_IP'] != "":
redis_client = redis = await aioredis.from_url(f"redis://{os.environ['REDIS_SLAVEOF_IP']}:{os.environ['REDIS_SLAVEOF_PORT']}/0")
redis_client = redis = await aioredis.from_url(f"redis://{os.environ['REDIS_SLAVEOF_IP']}:{os.environ['REDIS_SLAVEOF_PORT']}/0", password=os.environ['REDISPASS'])
else:
redis_client = redis = await aioredis.from_url("redis://redis-mailcow:6379/0")
redis_client = redis = await aioredis.from_url("redis://redis-mailcow:6379/0", password=os.environ['REDISPASS'])
# Init docker clients
sync_docker_client = docker.DockerClient(base_url='unix://var/run/docker.sock', version='auto')

View File

@@ -105,7 +105,6 @@ RUN addgroup -g 5000 vmail \
dovecot-submissiond \
dovecot-pigeonhole-plugin \
dovecot-pop3d \
dovecot-fts-solr \
dovecot-fts-flatcurve \
&& arch=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$arch" \

View File

@@ -2,7 +2,7 @@
source /source_env.sh
MAX_AGE=$(redis-cli --raw -h redis-mailcow GET Q_MAX_AGE)
MAX_AGE=$(redis-cli --raw -h redis-mailcow -a ${REDISPASS} --no-auth-warning GET Q_MAX_AGE)
if [[ -z ${MAX_AGE} ]]; then
echo "Max age for quarantine items not defined"

View File

@@ -14,9 +14,9 @@ done
# Do not attempt to write to slave
if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}"
REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning"
else
REDIS_CMDLINE="redis-cli -h redis -p 6379"
REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS} --no-auth-warning"
fi
until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do
@@ -110,21 +110,16 @@ EOF
echo -n ${ACL_ANYONE} > /etc/dovecot/acl_anyone
if [[ "${FLATCURVE_EXPERIMENTAL}" =~ ^([yY][eE][sS]|[yY]) ]]; then
echo -e "\e[33mActivating Flatcurve as FTS Backend...\e[0m"
echo -e "\e[33mDepending on your previous setup a full reindex might be needed... \e[0m"
echo -e "\e[34mVisit https://docs.mailcow.email/manual-guides/Dovecot/u_e-dovecot-fts/#fts-related-dovecot-commands to learn how to reindex\e[0m"
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify fts fts_flatcurve listescape replication lazy_expunge' > /etc/dovecot/mail_plugins
echo -n 'quota imap_quota imap_acl acl zlib imap_zlib imap_sieve mail_crypt mail_crypt_acl notify mail_log fts fts_flatcurve listescape replication' > /etc/dovecot/mail_plugins_imap
echo -n 'quota sieve acl zlib mail_crypt mail_crypt_acl fts fts_flatcurve notify listescape replication' > /etc/dovecot/mail_plugins_lmtp
elif [[ "${SKIP_SOLR}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
if [[ "${SKIP_FTS}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo -e "\e[33mDetecting SKIP_FTS=y... not enabling Flatcurve (FTS) then...\e[0m"
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify listescape replication lazy_expunge' > /etc/dovecot/mail_plugins
echo -n 'quota imap_quota imap_acl acl zlib imap_zlib imap_sieve mail_crypt mail_crypt_acl notify listescape replication mail_log' > /etc/dovecot/mail_plugins_imap
echo -n 'quota sieve acl zlib mail_crypt mail_crypt_acl notify listescape replication' > /etc/dovecot/mail_plugins_lmtp
else
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify fts fts_solr listescape replication lazy_expunge' > /etc/dovecot/mail_plugins
echo -n 'quota imap_quota imap_acl acl zlib imap_zlib imap_sieve mail_crypt mail_crypt_acl notify mail_log fts fts_solr listescape replication' > /etc/dovecot/mail_plugins_imap
echo -n 'quota sieve acl zlib mail_crypt mail_crypt_acl fts fts_solr notify listescape replication' > /etc/dovecot/mail_plugins_lmtp
echo -e "\e[32mDetecting SKIP_FTS=n... enabling Flatcurve (FTS)\e[0m"
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify fts fts_flatcurve listescape replication lazy_expunge' > /etc/dovecot/mail_plugins
echo -n 'quota imap_quota imap_acl acl zlib imap_zlib imap_sieve mail_crypt mail_crypt_acl notify mail_log fts fts_flatcurve listescape replication' > /etc/dovecot/mail_plugins_imap
echo -n 'quota sieve acl zlib mail_crypt mail_crypt_acl fts fts_flatcurve notify listescape replication' > /etc/dovecot/mail_plugins_lmtp
fi
chmod 644 /etc/dovecot/mail_plugins /etc/dovecot/mail_plugins_imap /etc/dovecot/mail_plugins_lmtp /templates/quarantine.tpl
@@ -247,51 +242,6 @@ function script_deinit()
end
EOF
# Temporarily set FTS depending on user choice inside mailcow.conf. Will be removed as soon as Solr is dropped
if [[ "${FLATCURVE_EXPERIMENTAL}" =~ ^([yY][eE][sS]|[yY])$ ]]; then
cat <<EOF > /etc/dovecot/conf.d/fts.conf
# Autogenerated by mailcow
plugin {
fts_autoindex = yes
fts_autoindex_exclude = \Junk
fts_autoindex_exclude2 = \Trash
fts = flatcurve
# Maximum term length can be set via the 'maxlen' argument (maxlen is
# specified in bytes, not number of UTF-8 characters)
fts_tokenizer_email_address = maxlen=100
fts_tokenizer_generic = algorithm=simple maxlen=30
# These are not flatcurve settings, but required for Dovecot FTS. See
# Dovecot FTS Configuration link above for further information.
fts_languages = en es de
fts_tokenizers = generic email-address
# OPTIONAL: Recommended default FTS core configuration
fts_filters = normalizer-icu snowball stopwords
fts_filters_en = lowercase snowball english-possessive stopwords
}
EOF
elif [[ ! "${SKIP_SOLR}" =~ ^([yY][eE][sS]|[yY])$ ]]; then
cat <<EOF > /etc/dovecot/conf.d/fts.conf
# Autogenerated by mailcow
plugin {
fts = solr
fts_autoindex = yes
fts_autoindex_exclude = \Junk
fts_autoindex_exclude2 = \Trash
fts_solr = url=http://solr:8983/solr/dovecot-fts/
fts_tokenizers = generic email-address
fts_tokenizer_generic = algorithm=simple
fts_filters = normalizer-icu snowball stopwords
fts_filters_en = lowercase snowball english-possessive stopwords
}
EOF
fi
# Replace patterns in app-passdb.lua
sed -i "s/__DBUSER__/${DBUSER}/g" /etc/dovecot/lua/passwd-verify.lua
sed -i "s/__DBPASS__/${DBPASS}/g" /etc/dovecot/lua/passwd-verify.lua
@@ -398,6 +348,15 @@ mail_replica = tcp:${MAILCOW_REPLICA_IP}:${DOVEADM_REPLICA_PORT}
EOF
fi
# Setting variables for indexer-worker inside fts.conf automatically according to mailcow.conf settings
if [[ "${SKIP_FTS}" =~ ^([nN][oO]|[nN])+$ ]]; then
echo -e "\e[94mConfiguring FTS Settings...\e[0m"
echo -e "\e[94mSetting FTS Memory Limit (per process) to ${FTS_HEAP} MB\e[0m"
sed -i "s/vsz_limit\s*=\s*[0-9]*\s*MB*/vsz_limit=${FTS_HEAP} MB/" /etc/dovecot/conf.d/fts.conf
echo -e "\e[94mSetting FTS Process Limit to ${FTS_PROCS}\e[0m"
sed -i "s/process_limit\s*=\s*[0-9]*/process_limit=${FTS_PROCS}/" /etc/dovecot/conf.d/fts.conf
fi
# 401 is user dovecot
if [[ ! -s /mail_crypt/ecprivkey.pem || ! -s /mail_crypt/ecpubkey.pem ]]; then
openssl ecparam -name prime256v1 -genkey | openssl pkey -out /mail_crypt/ecprivkey.pem

View File

@@ -1,7 +1,7 @@
#!/bin/bash
if [[ "${SKIP_SOLR}" =~ ^([yY][eE][sS]|[yY])+$ && ! "${FLATCURVE_EXPERIMENTAL}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
if [[ "${SKIP_FTS}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
exit 0
else
doveadm fts optimize -A
fi
fi

View File

@@ -31,7 +31,7 @@ try:
while True:
try:
r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0)
r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0, password=os.environ['REDISPASS'])
r.ping()
except Exception as ex:
print('%s - trying again...' % (ex))

View File

@@ -23,7 +23,7 @@ else:
while True:
try:
r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0)
r = redis.StrictRedis(host='redis', decode_responses=True, port=6379, db=0, password=os.environ['REDISPASS'])
r.ping()
except Exception as ex:
print('%s - trying again...' % (ex))

View File

@@ -4,9 +4,9 @@ source /source_env.sh
# Do not attempt to write to slave
if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}"
REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning"
else
REDIS_CMDLINE="redis-cli -h redis -p 6379"
REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS} --no-auth-warning"
fi
# Is replication active?

View File

@@ -11,7 +11,7 @@ else
fi
# Deploy
if curl --connect-timeout 15 --retry 10 --max-time 30 https://www.spamassassin.heinlein-support.de/$(dig txt 1.4.3.spamassassin.heinlein-support.de +short | tr -d '"' | tr -dc '0-9').tar.gz --output /tmp/sa-rules-heinlein.tar.gz; then
if curl --connect-timeout 15 --retry 5 --max-time 30 https://www.spamassassin.heinlein-support.de/$(dig txt 1.4.3.spamassassin.heinlein-support.de +short | tr -d '"' | tr -dc '0-9').tar.gz --output /tmp/sa-rules-heinlein.tar.gz; then
if gzip -t /tmp/sa-rules-heinlein.tar.gz; then
tar xfvz /tmp/sa-rules-heinlein.tar.gz -C /tmp/sa-rules-heinlein
cat /tmp/sa-rules-heinlein/*cf > /etc/rspamd/custom/sa-rules

View File

@@ -20,6 +20,7 @@ destination d_redis_ui_log {
host("`REDIS_SLAVEOF_IP`")
persist-name("redis1")
port(`REDIS_SLAVEOF_PORT`)
auth("`REDISPASS`")
command("LPUSH" "DOVECOT_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
);
};
@@ -28,6 +29,7 @@ destination d_redis_f2b_channel {
host("`REDIS_SLAVEOF_IP`")
persist-name("redis2")
port(`REDIS_SLAVEOF_PORT`)
auth("`REDISPASS`")
command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
);
};

View File

@@ -20,6 +20,7 @@ destination d_redis_ui_log {
host("redis-mailcow")
persist-name("redis1")
port(6379)
auth("`REDISPASS`")
command("LPUSH" "DOVECOT_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
);
};
@@ -28,6 +29,7 @@ destination d_redis_f2b_channel {
host("redis-mailcow")
persist-name("redis2")
port(6379)
auth("`REDISPASS`")
command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
);
};

View File

@@ -10,9 +10,9 @@ catch_non_zero() {
source /source_env.sh
# Do not attempt to write to slave
if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}"
REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning"
else
REDIS_CMDLINE="redis-cli -h redis -p 6379"
REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS} --no-auth-warning"
fi
catch_non_zero "${REDIS_CMDLINE} LTRIM ACME_LOG 0 ${LOG_LINES}"
catch_non_zero "${REDIS_CMDLINE} LTRIM POSTFIX_MAILLOG 0 ${LOG_LINES}"

View File

@@ -106,7 +106,7 @@ def get_ip(address):
ip = ip.ipv4_mapped
if ip.is_private or ip.is_loopback:
return False
return ip
def ban(address):
@@ -434,9 +434,9 @@ if __name__ == '__main__':
redis_slaveof_ip = os.getenv('REDIS_SLAVEOF_IP', '')
redis_slaveof_port = os.getenv('REDIS_SLAVEOF_PORT', '')
if "".__eq__(redis_slaveof_ip):
r = redis.StrictRedis(host=os.getenv('IPV4_NETWORK', '172.22.1') + '.249', decode_responses=True, port=6379, db=0)
r = redis.StrictRedis(host=os.getenv('IPV4_NETWORK', '172.22.1') + '.249', decode_responses=True, port=6379, db=0, password=os.environ['REDISPASS'])
else:
r = redis.StrictRedis(host=redis_slaveof_ip, decode_responses=True, port=redis_slaveof_port, db=0)
r = redis.StrictRedis(host=redis_slaveof_ip, decode_responses=True, port=redis_slaveof_port, db=0, password=os.environ['REDISPASS'])
r.ping()
pubsub = r.pubsub()
except Exception as ex:
@@ -452,7 +452,7 @@ if __name__ == '__main__':
# clear bans in redis
r.delete('F2B_ACTIVE_BANS')
r.delete('F2B_PERM_BANS')
refreshF2boptions()
watch_thread = Thread(target=watch)

View File

@@ -0,0 +1,18 @@
FROM nginx:alpine
LABEL maintainer "The Infrastructure Company GmbH <info@servercow.de>"
ENV PIP_BREAK_SYSTEM_PACKAGES=1
RUN apk add --no-cache nginx \
python3 \
py3-pip && \
pip install --upgrade pip && \
pip install Jinja2
RUN mkdir -p /etc/nginx/includes
COPY ./bootstrap.py /
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -0,0 +1,96 @@
import os
import subprocess
from jinja2 import Environment, FileSystemLoader
def includes_conf(env, template_vars):
server_name = "server_name.active"
listen_plain = "listen_plain.active"
listen_ssl = "listen_ssl.active"
server_name_config = f"server_name {template_vars['MAILCOW_HOSTNAME']} autodiscover.* autoconfig.* {template_vars['ADDITIONAL_SERVER_NAMES']};"
listen_plain_config = f"listen {template_vars['HTTP_PORT']};"
listen_ssl_config = f"listen {template_vars['HTTPS_PORT']};"
if not template_vars['DISABLE_IPv6']:
listen_plain_config += f"\nlisten [::]:{template_vars['HTTP_PORT']};"
listen_ssl_config += f"\nlisten [::]:{template_vars['HTTPS_PORT']} ssl;"
listen_ssl_config += "\nhttp2 on;"
with open(f"/etc/nginx/conf.d/{server_name}", "w") as f:
f.write(server_name_config)
with open(f"/etc/nginx/conf.d/{listen_plain}", "w") as f:
f.write(listen_plain_config)
with open(f"/etc/nginx/conf.d/{listen_ssl}", "w") as f:
f.write(listen_ssl_config)
def sites_default_conf(env, template_vars):
config_name = "sites-default.conf"
template = env.get_template(f"{config_name}.j2")
config = template.render(template_vars)
with open(f"/etc/nginx/includes/{config_name}", "w") as f:
f.write(config)
def nginx_conf(env, template_vars):
config_name = "nginx.conf"
template = env.get_template(f"{config_name}.j2")
config = template.render(template_vars)
with open(f"/etc/nginx/{config_name}", "w") as f:
f.write(config)
def prepare_template_vars():
ipv4_network = os.getenv("IPV4_NETWORK", "172.22.1")
template_vars = {
'IPV4_NETWORK': ipv4_network,
'TRUSTED_NETWORK': os.getenv("TRUSTED_NETWORK", False),
'SKIP_RSPAMD': os.getenv("SKIP_RSPAMD", "n").lower() in ("y", "yes"),
'SKIP_SOGO': os.getenv("SKIP_SOGO", "n").lower() in ("y", "yes"),
'NGINX_USE_PROXY_PROTOCOL': os.getenv("NGINX_USE_PROXY_PROTOCOL", "n").lower() in ("y", "yes"),
'MAILCOW_HOSTNAME': os.getenv("MAILCOW_HOSTNAME", ""),
'ADDITIONAL_SERVER_NAMES': os.getenv("ADDITIONAL_SERVER_NAMES", "").replace(',', ' '),
'HTTP_PORT': os.getenv("HTTP_PORT", "80"),
'HTTPS_PORT': os.getenv("HTTPS_PORT", "443"),
'SOGOHOST': os.getenv("SOGOHOST", ipv4_network + ".248"),
'RSPAMDHOST': os.getenv("RSPAMDHOST", "rspamd-mailcow"),
'PHPFPMHOST': os.getenv("PHPFPMHOST", "php-fpm-mailcow"),
'DISABLE_IPv6': os.getenv("DISABLE_IPv6", "n").lower() in ("y", "yes"),
}
ssl_dir = '/etc/ssl/mail/'
template_vars['valid_cert_dirs'] = []
for d in os.listdir(ssl_dir):
full_path = os.path.join(ssl_dir, d)
if not os.path.isdir(full_path):
continue
cert_path = os.path.join(full_path, 'cert.pem')
key_path = os.path.join(full_path, 'key.pem')
domains_path = os.path.join(full_path, 'domains')
if os.path.isfile(cert_path) and os.path.isfile(key_path) and os.path.isfile(domains_path):
with open(domains_path, 'r') as file:
domains = file.read().strip()
domains_list = domains.split()
if domains_list and template_vars["MAILCOW_HOSTNAME"] not in domains_list:
template_vars['valid_cert_dirs'].append({
'cert_path': full_path + '/',
'domains': domains
})
return template_vars
def main():
env = Environment(loader=FileSystemLoader('./etc/nginx/conf.d/templates'))
# Render config
print("Render config")
template_vars = prepare_template_vars()
sites_default_conf(env, template_vars)
nginx_conf(env, template_vars)
includes_conf(env, template_vars)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,26 @@
#!/bin/sh
PHPFPMHOST=${PHPFPMHOST:-"php-fpm-mailcow"}
SOGOHOST=${SOGOHOST:-"$IPV4_NETWORK.248"}
RSPAMDHOST=${RSPAMDHOST:-"rspamd-mailcow"}
until ping ${PHPFPMHOST} -c1 > /dev/null; do
echo "Waiting for PHP..."
sleep 1
done
if printf "%s\n" "${SKIP_SOGO}" | grep -E '^([yY][eE][sS]|[yY])+$' >/dev/null; then
until ping ${SOGOHOST} -c1 > /dev/null; do
echo "Waiting for SOGo..."
sleep 1
done
fi
if printf "%s\n" "${SKIP_RSPAMD}" | grep -E '^([yY][eE][sS]|[yY])+$' >/dev/null; then
until ping ${RSPAMDHOST} -c1 > /dev/null; do
echo "Waiting for Rspamd..."
sleep 1
done
fi
python3 /bootstrap.py
exec "$@"

View File

@@ -77,7 +77,7 @@ RUN apk add -U --no-cache autoconf \
--with-webp \
--with-xpm \
--with-avif \
&& docker-php-ext-install -j 4 exif gd gettext intl ldap opcache pcntl pdo pdo_mysql pspell soap sockets sysvsem zip bcmath gmp \
&& docker-php-ext-install -j 4 exif gd gettext intl ldap opcache pcntl pdo pdo_mysql pspell soap sockets zip bcmath gmp \
&& docker-php-ext-configure imap --with-imap --with-imap-ssl \
&& docker-php-ext-install -j 4 imap \
&& curl --silent --show-error https://getcomposer.org/installer | php -- --version=${COMPOSER_VERSION} \

View File

@@ -16,7 +16,7 @@ else
REDIS_HOST="redis"
REDIS_PORT="6379"
fi
REDIS_CMDLINE="redis-cli -h ${REDIS_HOST} -p ${REDIS_PORT}"
REDIS_CMDLINE="redis-cli -h ${REDIS_HOST} -p ${REDIS_PORT} -a ${REDISPASS} --no-auth-warning"
until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do
echo "Waiting for Redis..."
@@ -26,7 +26,7 @@ done
# Set redis session store
echo -n '
session.save_handler = redis
session.save_path = "tcp://'${REDIS_HOST}':'${REDIS_PORT}'"
session.save_path = "tcp://'${REDIS_HOST}':'${REDIS_PORT}'?auth='${REDISPASS}'"
' > /usr/local/etc/php/conf.d/session_store.ini
# Check mysql_upgrade (master and slave)

View File

@@ -20,6 +20,7 @@ destination d_redis_ui_log {
host("`REDIS_SLAVEOF_IP`")
persist-name("redis1")
port(`REDIS_SLAVEOF_PORT`)
auth("`REDISPASS`")
command("LPUSH" "POSTFIX_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
);
};
@@ -28,6 +29,7 @@ destination d_redis_f2b_channel {
host("`REDIS_SLAVEOF_IP`")
persist-name("redis2")
port(`REDIS_SLAVEOF_PORT`)
auth("`REDISPASS`")
command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
);
};

View File

@@ -20,6 +20,7 @@ destination d_redis_ui_log {
host("redis-mailcow")
persist-name("redis1")
port(6379)
auth("`REDISPASS`")
command("LPUSH" "POSTFIX_MAILLOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
);
};
@@ -28,6 +29,7 @@ destination d_redis_f2b_channel {
host("redis-mailcow")
persist-name("redis2")
port(6379)
auth("`REDISPASS`")
command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
);
};

View File

@@ -56,27 +56,29 @@ if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
cat <<EOF > /etc/rspamd/local.d/redis.conf
read_servers = "redis:6379";
write_servers = "${REDIS_SLAVEOF_IP}:${REDIS_SLAVEOF_PORT}";
password = "${REDISPASS}";
timeout = 10;
EOF
until [[ $(redis-cli -h redis-mailcow PING) == "PONG" ]]; do
until [[ $(redis-cli -h redis-mailcow -a ${REDISPASS} --no-auth-warning PING) == "PONG" ]]; do
echo "Waiting for Redis @redis-mailcow..."
sleep 2
done
until [[ $(redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} PING) == "PONG" ]]; do
until [[ $(redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning PING) == "PONG" ]]; do
echo "Waiting for Redis @${REDIS_SLAVEOF_IP}..."
sleep 2
done
redis-cli -h redis-mailcow SLAVEOF ${REDIS_SLAVEOF_IP} ${REDIS_SLAVEOF_PORT}
redis-cli -h redis-mailcow -a ${REDISPASS} --no-auth-warning SLAVEOF ${REDIS_SLAVEOF_IP} ${REDIS_SLAVEOF_PORT}
else
cat <<EOF > /etc/rspamd/local.d/redis.conf
servers = "redis:6379";
password = "${REDISPASS}";
timeout = 10;
EOF
until [[ $(redis-cli -h redis-mailcow PING) == "PONG" ]]; do
until [[ $(redis-cli -h redis-mailcow -a ${REDISPASS} --no-auth-warning PING) == "PONG" ]]; do
echo "Waiting for Redis slave..."
sleep 2
done
redis-cli -h redis-mailcow SLAVEOF NO ONE
redis-cli -h redis-mailcow -a ${REDISPASS} --no-auth-warning SLAVEOF NO ONE
fi
# Provide additional lua modules

View File

@@ -22,6 +22,7 @@ destination d_redis_ui_log {
host("`REDIS_SLAVEOF_IP`")
persist-name("redis1")
port(`REDIS_SLAVEOF_PORT`)
auth("`REDISPASS`")
command("LPUSH" "SOGO_LOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
);
};
@@ -30,6 +31,7 @@ destination d_redis_f2b_channel {
host("`REDIS_SLAVEOF_IP`")
persist-name("redis2")
port(`REDIS_SLAVEOF_PORT`)
auth("`REDISPASS`")
command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
);
};

View File

@@ -22,6 +22,7 @@ destination d_redis_ui_log {
host("redis-mailcow")
persist-name("redis1")
port(6379)
auth("`REDISPASS`")
command("LPUSH" "SOGO_LOG" "$(format-json time=\"$S_UNIXTIME\" priority=\"$PRIORITY\" program=\"$PROGRAM\" message=\"$MESSAGE\")\n")
);
};
@@ -30,6 +31,7 @@ destination d_redis_f2b_channel {
host("redis-mailcow")
persist-name("redis2")
port(6379)
auth("`REDISPASS`")
command("PUBLISH" "F2B_CHANNEL" "$(sanitize $MESSAGE)")
);
};

View File

@@ -1,31 +0,0 @@
FROM solr:7.7-slim
USER root
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=(?<version>.*)$
ARG GOSU_VERSION=1.17
COPY solr.sh /
COPY solr-config-7.7.0.xml /
COPY solr-schema-7.7.0.xml /
RUN dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch" \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true \
&& apt-get update && apt-get install -y --no-install-recommends \
tzdata \
curl \
bash \
zip \
&& apt-get autoclean \
&& rm -rf /var/lib/apt/lists/* \
&& chmod +x /solr.sh \
&& sync \
&& bash /solr.sh --bootstrap
RUN zip -q -d /opt/solr/server/lib/ext/log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
RUN apt remove zip -y
CMD ["/solr.sh"]

View File

@@ -1,289 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- This is the default config with stuff non-essential to Dovecot removed. -->
<config>
<!-- Controls what version of Lucene various components of Solr
adhere to. Generally, you want to use the latest version to
get all bug fixes and improvements. It is highly recommended
that you fully re-index after changing this setting as it can
affect both how text is indexed and queried.
-->
<luceneMatchVersion>7.7.0</luceneMatchVersion>
<!-- A 'dir' option by itself adds any files found in the directory
to the classpath, this is useful for including all jars in a
directory.
When a 'regex' is specified in addition to a 'dir', only the
files in that directory which completely match the regex
(anchored on both ends) will be included.
If a 'dir' option (with or without a regex) is used and nothing
is found that matches, a warning will be logged.
The examples below can be used to load some solr-contribs along
with their external dependencies.
-->
<lib dir="${solr.install.dir:../../../..}/contrib/extraction/lib" regex=".*\.jar" />
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-cell-\d.*\.jar" />
<lib dir="${solr.install.dir:../../../..}/contrib/clustering/lib/" regex=".*\.jar" />
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-clustering-\d.*\.jar" />
<lib dir="${solr.install.dir:../../../..}/contrib/langid/lib/" regex=".*\.jar" />
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-langid-\d.*\.jar" />
<lib dir="${solr.install.dir:../../../..}/contrib/velocity/lib" regex=".*\.jar" />
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-velocity-\d.*\.jar" />
<!-- Data Directory
Used to specify an alternate directory to hold all index data
other than the default ./data under the Solr home. If
replication is in use, this should match the replication
configuration.
-->
<dataDir>${solr.data.dir:}</dataDir>
<!-- The default high-performance update handler -->
<updateHandler class="solr.DirectUpdateHandler2">
<!-- Enables a transaction log, used for real-time get, durability, and
and solr cloud replica recovery. The log can grow as big as
uncommitted changes to the index, so use of a hard autoCommit
is recommended (see below).
"dir" - the target directory for transaction logs, defaults to the
solr data directory.
"numVersionBuckets" - sets the number of buckets used to keep
track of max version values when checking for re-ordered
updates; increase this value to reduce the cost of
synchronizing access to version buckets during high-volume
indexing, this requires 8 bytes (long) * numVersionBuckets
of heap space per Solr core.
-->
<updateLog>
<str name="dir">${solr.ulog.dir:}</str>
<int name="numVersionBuckets">${solr.ulog.numVersionBuckets:65536}</int>
</updateLog>
<!-- AutoCommit
Perform a hard commit automatically under certain conditions.
Instead of enabling autoCommit, consider using "commitWithin"
when adding documents.
http://wiki.apache.org/solr/UpdateXmlMessages
maxDocs - Maximum number of documents to add since the last
commit before automatically triggering a new commit.
maxTime - Maximum amount of time in ms that is allowed to pass
since a document was added before automatically
triggering a new commit.
openSearcher - if false, the commit causes recent index changes
to be flushed to stable storage, but does not cause a new
searcher to be opened to make those changes visible.
If the updateLog is enabled, then it's highly recommended to
have some sort of hard autoCommit to limit the log size.
-->
<autoCommit>
<maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
<openSearcher>false</openSearcher>
</autoCommit>
<!-- softAutoCommit is like autoCommit except it causes a
'soft' commit which only ensures that changes are visible
but does not ensure that data is synced to disk. This is
faster and more near-realtime friendly than a hard commit.
-->
<autoSoftCommit>
<maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
</autoSoftCommit>
<!-- Update Related Event Listeners
Various IndexWriter related events can trigger Listeners to
take actions.
postCommit - fired after every commit or optimize command
postOptimize - fired after every optimize command
-->
</updateHandler>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Query section - these settings control query time things like caches
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<query>
<!-- Solr Internal Query Caches
There are two implementations of cache available for Solr,
LRUCache, based on a synchronized LinkedHashMap, and
FastLRUCache, based on a ConcurrentHashMap.
FastLRUCache has faster gets and slower puts in single
threaded operation and thus is generally faster than LRUCache
when the hit ratio of the cache is high (> 75%), and may be
faster under other scenarios on multi-cpu systems.
-->
<!-- Filter Cache
Cache used by SolrIndexSearcher for filters (DocSets),
unordered sets of *all* documents that match a query. When a
new searcher is opened, its caches may be prepopulated or
"autowarmed" using data from caches in the old searcher.
autowarmCount is the number of items to prepopulate. For
LRUCache, the autowarmed items will be the most recently
accessed items.
Parameters:
class - the SolrCache implementation LRUCache or
(LRUCache or FastLRUCache)
size - the maximum number of entries in the cache
initialSize - the initial capacity (number of entries) of
the cache. (see java.util.HashMap)
autowarmCount - the number of entries to prepopulate from
and old cache.
maxRamMB - the maximum amount of RAM (in MB) that this cache is allowed
to occupy. Note that when this option is specified, the size
and initialSize parameters are ignored.
-->
<filterCache class="solr.FastLRUCache"
size="512"
initialSize="512"
autowarmCount="0"/>
<!-- Query Result Cache
Caches results of searches - ordered lists of document ids
(DocList) based on a query, a sort, and the range of documents requested.
Additional supported parameter by LRUCache:
maxRamMB - the maximum amount of RAM (in MB) that this cache is allowed
to occupy
-->
<queryResultCache class="solr.LRUCache"
size="512"
initialSize="512"
autowarmCount="0"/>
<!-- Document Cache
Caches Lucene Document objects (the stored fields for each
document). Since Lucene internal document ids are transient,
this cache will not be autowarmed.
-->
<documentCache class="solr.LRUCache"
size="512"
initialSize="512"
autowarmCount="0"/>
<!-- custom cache currently used by block join -->
<cache name="perSegFilter"
class="solr.search.LRUCache"
size="10"
initialSize="0"
autowarmCount="10"
regenerator="solr.NoOpRegenerator" />
<!-- Lazy Field Loading
If true, stored fields that are not requested will be loaded
lazily. This can result in a significant speed improvement
if the usual case is to not load all stored fields,
especially if the skipped fields are large compressed text
fields.
-->
<enableLazyFieldLoading>true</enableLazyFieldLoading>
<!-- Result Window Size
An optimization for use with the queryResultCache. When a search
is requested, a superset of the requested number of document ids
are collected. For example, if a search for a particular query
requests matching documents 10 through 19, and queryWindowSize is 50,
then documents 0 through 49 will be collected and cached. Any further
requests in that range can be satisfied via the cache.
-->
<queryResultWindowSize>20</queryResultWindowSize>
<!-- Maximum number of documents to cache for any entry in the
queryResultCache.
-->
<queryResultMaxDocsCached>200</queryResultMaxDocsCached>
<!-- Use Cold Searcher
If a search request comes in and there is no current
registered searcher, then immediately register the still
warming searcher and use it. If "false" then all requests
will block until the first searcher is done warming.
-->
<useColdSearcher>false</useColdSearcher>
</query>
<!-- Request Dispatcher
This section contains instructions for how the SolrDispatchFilter
should behave when processing requests for this SolrCore.
-->
<requestDispatcher>
<httpCaching never304="true" />
</requestDispatcher>
<!-- Request Handlers
http://wiki.apache.org/solr/SolrRequestHandler
Incoming queries will be dispatched to a specific handler by name
based on the path specified in the request.
If a Request Handler is declared with startup="lazy", then it will
not be initialized until the first request that uses it.
-->
<!-- SearchHandler
http://wiki.apache.org/solr/SearchHandler
For processing Search Queries, the primary Request Handler
provided with Solr is "SearchHandler" It delegates to a sequent
of SearchComponents (see below) and supports distributed
queries across multiple shards
-->
<requestHandler name="/select" class="solr.SearchHandler">
<!-- default values for query parameters can be specified, these
will be overridden by parameters in the request
-->
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
</lst>
</requestHandler>
<initParams path="/update/**,/select">
<lst name="defaults">
<str name="df">_text_</str>
</lst>
</initParams>
<!-- Response Writers
http://wiki.apache.org/solr/QueryResponseWriter
Request responses will be written using the writer specified by
the 'wt' request parameter matching the name of a registered
writer.
The "default" writer is the default and will be used if 'wt' is
not specified in the request.
-->
<queryResponseWriter name="xml"
default="true"
class="solr.XMLResponseWriter" />
</config>

View File

@@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema name="dovecot-fts" version="2.0">
<fieldType name="string" class="solr.StrField" omitNorms="true" sortMissingLast="true"/>
<fieldType name="long" class="solr.LongPointField" positionIncrementGap="0"/>
<fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
<fieldType name="text" class="solr.TextField" autoGeneratePhraseQueries="true" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.EdgeNGramFilterFactory" minGramSize="3" maxGramSize="20"/>
<filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>
<filter class="solr.WordDelimiterGraphFilterFactory" catenateNumbers="1" generateNumberParts="1" splitOnCaseChange="1" generateWordParts="1" splitOnNumerics="1" catenateAll="1" catenateWords="1"/>
<filter class="solr.FlattenGraphFilterFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.SynonymGraphFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/>
<filter class="solr.FlattenGraphFilterFactory"/>
<filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>
<filter class="solr.WordDelimiterGraphFilterFactory" catenateNumbers="1" generateNumberParts="1" splitOnCaseChange="1" generateWordParts="1" splitOnNumerics="1" catenateAll="1" catenateWords="1"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
</fieldType>
<field name="id" type="string" indexed="true" required="true" stored="true"/>
<field name="uid" type="long" indexed="true" required="true" stored="true"/>
<field name="box" type="string" indexed="true" required="true" stored="true"/>
<field name="user" type="string" indexed="true" required="true" stored="true"/>
<field name="hdr" type="text" indexed="true" stored="false"/>
<field name="body" type="text" indexed="true" stored="false"/>
<field name="from" type="text" indexed="true" stored="false"/>
<field name="to" type="text" indexed="true" stored="false"/>
<field name="cc" type="text" indexed="true" stored="false"/>
<field name="bcc" type="text" indexed="true" stored="false"/>
<field name="subject" type="text" indexed="true" stored="false"/>
<!-- Used by Solr internally: -->
<field name="_version_" type="long" indexed="true" stored="true"/>
<uniqueKey>id</uniqueKey>
</schema>

View File

@@ -1,75 +0,0 @@
#!/bin/bash
if [[ "${FLATCURVE_EXPERIMENTAL}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo "FLATCURVE_EXPERIMENTAL=y, skipping Solr but enabling Flatcurve as FTS for Dovecot!"
echo "Solr will be removed in the future!"
sleep 365d
exit 0
elif [[ "${SKIP_SOLR}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
echo "SKIP_SOLR=y, skipping Solr..."
echo "HINT: You could try the newer FTS Backend Flatcurve, which is currently in experimental state..."
echo "Simply set FLATCURVE_EXPERIMENTAL=y inside your mailcow.conf and restart the stack afterwards!"
echo "Solr will be removed in the future!"
sleep 365d
exit 0
fi
MEM_TOTAL=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
if [[ "${1}" != "--bootstrap" ]]; then
if [ ${MEM_TOTAL} -lt "2097152" ]; then
echo "System memory less than 2 GB, skipping Solr..."
sleep 365d
exit 0
fi
fi
set -e
# run the optional initdb
. /opt/docker-solr/scripts/run-initdb
# fixing volume permission
[[ -d /opt/solr/server/solr/dovecot-fts/data ]] && chown -R solr:solr /opt/solr/server/solr/dovecot-fts/data
if [[ "${1}" != "--bootstrap" ]]; then
sed -i '/SOLR_HEAP=/c\SOLR_HEAP="'${SOLR_HEAP:-1024}'m"' /opt/solr/bin/solr.in.sh
else
sed -i '/SOLR_HEAP=/c\SOLR_HEAP="256m"' /opt/solr/bin/solr.in.sh
fi
if [[ "${1}" == "--bootstrap" ]]; then
echo "Creating initial configuration"
echo "Modifying default config set"
cp /solr-config-7.7.0.xml /opt/solr/server/solr/configsets/_default/conf/solrconfig.xml
cp /solr-schema-7.7.0.xml /opt/solr/server/solr/configsets/_default/conf/schema.xml
rm /opt/solr/server/solr/configsets/_default/conf/managed-schema
echo "Starting local Solr instance to setup configuration"
gosu solr start-local-solr
echo "Creating core \"dovecot-fts\""
gosu solr /opt/solr/bin/solr create -c "dovecot-fts"
# See https://github.com/docker-solr/docker-solr/issues/27
echo "Checking core"
while ! wget -O - 'http://localhost:8983/solr/admin/cores?action=STATUS' | grep -q instanceDir; do
echo "Could not find any cores, waiting..."
sleep 3
done
echo "Created core \"dovecot-fts\""
echo "Stopping local Solr"
gosu solr stop-local-solr
exit 0
fi
echo "Starting up Solr..."
echo -e "\e[31mSolr is deprecated! You can try the new FTS System now by enabling FLATCURVE_EXPERIMENTAL=y inside mailcow.conf and restarting the stack\e[0m"
echo -e "\e[31mSolr will be removed completely soon!\e[0m"
sleep 15
exec gosu solr solr-foreground

View File

@@ -40,9 +40,9 @@ done
# Do not attempt to write to slave
if [[ ! -z ${REDIS_SLAVEOF_IP} ]]; then
REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT}"
REDIS_CMDLINE="redis-cli -h ${REDIS_SLAVEOF_IP} -p ${REDIS_SLAVEOF_PORT} -a ${REDISPASS} --no-auth-warning"
else
REDIS_CMDLINE="redis-cli -h redis -p 6379"
REDIS_CMDLINE="redis-cli -h redis -p 6379 -a ${REDISPASS} --no-auth-warning"
fi
until [[ $(${REDIS_CMDLINE} PING) == "PONG" ]]; do
@@ -330,7 +330,7 @@ redis_checks() {
touch /tmp/redis-mailcow; echo "$(tail -50 /tmp/redis-mailcow)" > /tmp/redis-mailcow
host_ip=$(get_container_ip redis-mailcow)
err_c_cur=${err_count}
/usr/lib/nagios/plugins/check_tcp -4 -H redis-mailcow -p 6379 -E -s "PING\n" -q "QUIT" -e "PONG" 2>> /tmp/redis-mailcow 1>&2; err_count=$(( ${err_count} + $? ))
/usr/lib/nagios/plugins/check_tcp -4 -H redis-mailcow -p 6379 -E -s "AUTH ${REDISPASS}\nPING\n" -q "QUIT" -e "PONG" 2>> /tmp/redis-mailcow 1>&2; err_count=$(( ${err_count} + $? ))
[ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1
[ ${err_c_cur} -ne ${err_count} ] && diff_c=$(( ${err_c_cur} - ${err_count} ))
progress "Redis" ${THRESHOLD} $(( ${THRESHOLD} - ${err_count} )) ${diff_c}
@@ -503,12 +503,12 @@ dovecot_repl_checks() {
err_count=0
diff_c=0
THRESHOLD=${DOVECOT_REPL_THRESHOLD}
D_REPL_STATUS=$(redis-cli -h redis -r GET DOVECOT_REPL_HEALTH)
D_REPL_STATUS=$(redis-cli -h redis -a ${REDISPASS} --no-auth-warning -r GET DOVECOT_REPL_HEALTH)
# Reduce error count by 2 after restarting an unhealthy container
trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1
while [ ${err_count} -lt ${THRESHOLD} ]; do
err_c_cur=${err_count}
D_REPL_STATUS=$(redis-cli --raw -h redis GET DOVECOT_REPL_HEALTH)
D_REPL_STATUS=$(redis-cli --raw -h redis -a ${REDISPASS} --no-auth-warning GET DOVECOT_REPL_HEALTH)
if [[ "${D_REPL_STATUS}" != "1" ]]; then
err_count=$(( ${err_count} + 1 ))
fi
@@ -578,19 +578,19 @@ ratelimit_checks() {
err_count=0
diff_c=0
THRESHOLD=${RATELIMIT_THRESHOLD}
RL_LOG_STATUS=$(redis-cli -h redis LRANGE RL_LOG 0 0 | jq .qid)
RL_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} --no-auth-warning LRANGE RL_LOG 0 0 | jq .qid)
# Reduce error count by 2 after restarting an unhealthy container
trap "[ ${err_count} -gt 1 ] && err_count=$(( ${err_count} - 2 ))" USR1
while [ ${err_count} -lt ${THRESHOLD} ]; do
err_c_cur=${err_count}
RL_LOG_STATUS_PREV=${RL_LOG_STATUS}
RL_LOG_STATUS=$(redis-cli -h redis LRANGE RL_LOG 0 0 | jq .qid)
RL_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} --no-auth-warning LRANGE RL_LOG 0 0 | jq .qid)
if [[ ${RL_LOG_STATUS_PREV} != ${RL_LOG_STATUS} ]]; then
err_count=$(( ${err_count} + 1 ))
echo 'Last 10 applied ratelimits (may overlap with previous reports).' > /tmp/ratelimit
echo 'Full ratelimit buckets can be emptied by deleting the ratelimit hash from within mailcow UI (see /debug -> Protocols -> Ratelimit):' >> /tmp/ratelimit
echo >> /tmp/ratelimit
redis-cli --raw -h redis LRANGE RL_LOG 0 10 | jq . >> /tmp/ratelimit
redis-cli --raw -h redis -a ${REDISPASS} --no-auth-warning LRANGE RL_LOG 0 10 | jq . >> /tmp/ratelimit
fi
[ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1
[ ${err_c_cur} -ne ${err_count} ] && diff_c=$(( ${err_c_cur} - ${err_count} ))
@@ -673,7 +673,7 @@ acme_checks() {
err_count=0
diff_c=0
THRESHOLD=${ACME_THRESHOLD}
ACME_LOG_STATUS=$(redis-cli -h redis GET ACME_FAIL_TIME)
ACME_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} --no-auth-warning GET ACME_FAIL_TIME)
if [[ -z "${ACME_LOG_STATUS}" ]]; then
${REDIS_CMDLINE} SET ACME_FAIL_TIME 0
ACME_LOG_STATUS=0
@@ -685,7 +685,7 @@ acme_checks() {
ACME_LOG_STATUS_PREV=${ACME_LOG_STATUS}
ACME_LC=0
until [[ ! -z ${ACME_LOG_STATUS} ]] || [ ${ACME_LC} -ge 3 ]; do
ACME_LOG_STATUS=$(redis-cli -h redis GET ACME_FAIL_TIME 2> /dev/null)
ACME_LOG_STATUS=$(redis-cli -h redis -a ${REDISPASS} --no-auth-warning GET ACME_FAIL_TIME 2> /dev/null)
sleep 3
ACME_LC=$((ACME_LC+1))
done

View File

@@ -1,130 +0,0 @@
map $http_x_forwarded_proto $client_req_scheme_nc {
default $scheme;
https https;
}
server {
include /etc/nginx/conf.d/listen_ssl.active;
include /etc/nginx/conf.d/listen_plain.active;
include /etc/nginx/mime.types;
charset utf-8;
override_charset on;
ssl_certificate /etc/ssl/mail/cert.pem;
ssl_certificate_key /etc/ssl/mail/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_ecdh_curve X25519:X448:secp384r1:secp256k1;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "noindex, nofollow" always;
add_header X-XSS-Protection "1; mode=block" always;
fastcgi_hide_header X-Powered-By;
server_name NC_SUBD;
root /web/nextcloud/;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /.well-known/carddav {
return 301 $client_req_scheme_nc://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $client_req_scheme_nc://$host/remote.php/dav;
}
location = /.well-known/webfinger {
return 301 $client_req_scheme_nc://$host/index.php/.well-known/webfinger;
}
location = /.well-known/nodeinfo {
return 301 $client_req_scheme_nc://$host/index.php/.well-known/nodeinfo;
}
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /web;
}
fastcgi_buffers 64 4K;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
set_real_ip_from fc00::/7;
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 192.168.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
location / {
rewrite ^ /index.php$uri;
}
location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
deny all;
}
location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+)\.php(?:$|\/) {
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
# Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
# Enable pretty urls
fastcgi_param front_controller_active true;
fastcgi_pass phpfpm:9002;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
client_max_body_size 0;
fastcgi_read_timeout 1200;
}
location ~ ^\/(?:updater|ocs-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
access_log off;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {
try_files $uri /index.php$request_uri;
access_log off;
}
}

View File

@@ -1,2 +0,0 @@
#!/bin/bash
docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) php /web/nextcloud/occ ${@}

View File

@@ -0,0 +1,37 @@
# mailcow FTS Flatcurve Settings, change them as you like.
plugin {
fts_autoindex = yes
fts_autoindex_exclude = \Junk
fts_autoindex_exclude2 = \Trash
# Tweak this setting if you only want to ensure big and frequent folders are indexed, not all.
fts_autoindex_max_recent_msgs = 20
fts = flatcurve
# Maximum term length can be set via the 'maxlen' argument (maxlen is
# specified in bytes, not number of UTF-8 characters)
fts_tokenizer_email_address = maxlen=100
fts_tokenizer_generic = algorithm=simple maxlen=30
# These are not flatcurve settings, but required for Dovecot FTS. See
# Dovecot FTS Configuration link above for further information.
fts_languages = en es de
fts_tokenizers = generic email-address
# OPTIONAL: Recommended default FTS core configuration
fts_filters = normalizer-icu snowball stopwords
fts_filters_en = lowercase snowball english-possessive stopwords
fts_index_timeout = 300
}
### THIS PART WILL BE CHANGED BY MODIFYING mailcow.conf AUTOMATICALLY DURING RUNTIME! ###
service indexer-worker {
# Max amount of simultaniously running indexer jobs.
process_limit=1
# Max amount of RAM used by EACH indexer process.
vsz_limit=128 MB
}
### THIS PART WILL BE CHANGED BY MODIFYING mailcow.conf AUTOMATICALLY DURING RUNTIME! ###

View File

@@ -1,3 +0,0 @@
map_hash_max_size 256;
map_hash_bucket_size 256;

View File

@@ -1,19 +0,0 @@
server {
listen 8081;
listen [::]:8081;
index index.php index.html;
server_name _;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /dynmaps;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass phpfpm:9001;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}

View File

@@ -1,242 +0,0 @@
include /etc/nginx/mime.types;
charset utf-8;
override_charset on;
server_tokens off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_ecdh_curve X25519:X448:secp384r1:secp256k1;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=15768000;";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies none;
add_header Referrer-Policy strict-origin;
index index.php index.html;
client_max_body_size 0;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied off;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
location ~ ^/(fonts|js|css|img)/ {
expires max;
add_header Cache-Control public;
}
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
fastcgi_hide_header X-Powered-By;
absolute_redirect off;
root /web;
location / {
try_files $uri $uri/ @strip-ext;
}
location /qhandler {
rewrite ^/qhandler/(.*)/(.*) /qhandler.php?action=$1&hash=$2;
}
location /edit {
rewrite ^/edit/(.*)/(.*) /edit.php?$1=$2;
}
location @strip-ext {
rewrite ^(.*)$ $1.php last;
}
location ~ ^/api/v1/(.*)$ {
try_files $uri $uri/ /json_api.php?query=$1&$args;
}
location ^~ /.well-known/acme-challenge/ {
allow all;
default_type "text/plain";
}
# If behind reverse proxy, forwards the correct IP
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from fc00::/7;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
rewrite ^/.well-known/caldav$ /SOGo/dav/ permanent;
rewrite ^/.well-known/carddav$ /SOGo/dav/ permanent;
location ^~ /principals {
return 301 /SOGo/dav;
}
location ^~ /inc/lib/ {
deny all;
return 403;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass phpfpm:9002;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
}
location /rspamd/ {
location /rspamd/auth {
# proxy_pass is not inherited
proxy_pass http://rspamd:11334/auth;
proxy_intercept_errors on;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
error_page 401 /_rspamderror.php;
}
proxy_pass http://rspamd:11334/;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
}
location ~* ^/Autodiscover/Autodiscover.xml {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass phpfpm:9002;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files /autodiscover.php =404;
}
location ~* ^/Autodiscover/Autodiscover.json {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass phpfpm:9002;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files /autodiscover-json.php =404;
}
location ~ /(?:m|M)ail/(?:c|C)onfig-v1.1.xml {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass phpfpm:9002;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files /autoconfig.php =404;
}
location /sogo-auth-verify {
internal;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header Content-Length "";
proxy_pass http://127.0.0.1:65510/sogo-auth;
proxy_pass_request_body off;
}
location ^~ /Microsoft-Server-ActiveSync {
include /etc/nginx/conf.d/includes/sogo_proxy_auth.conf;
include /etc/nginx/conf.d/sogo_eas.active;
proxy_connect_timeout 75;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_buffer_size 128k;
proxy_buffers 64 512k;
proxy_busy_buffers_size 512k;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
client_body_buffer_size 512k;
client_max_body_size 0;
}
location ^~ /SOGo {
location ~* ^/SOGo/so/.*\.(xml|js|html|xhtml)$ {
include /etc/nginx/conf.d/includes/sogo_proxy_auth.conf;
include /etc/nginx/conf.d/sogo.active;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header x-webobjects-server-protocol HTTP/1.0;
proxy_set_header x-webobjects-remote-host $remote_addr;
proxy_set_header x-webobjects-server-name $server_name;
proxy_set_header x-webobjects-server-url $client_req_scheme://$http_host;
proxy_set_header x-webobjects-server-port $server_port;
proxy_hide_header Content-Type;
add_header Content-Type text/plain;
break;
}
include /etc/nginx/conf.d/includes/sogo_proxy_auth.conf;
include /etc/nginx/conf.d/sogo.active;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header x-webobjects-server-protocol HTTP/1.0;
proxy_set_header x-webobjects-remote-host $remote_addr;
proxy_set_header x-webobjects-server-name $server_name;
proxy_set_header x-webobjects-server-url $client_req_scheme://$http_host;
proxy_set_header x-webobjects-server-port $server_port;
proxy_buffer_size 128k;
proxy_buffers 64 512k;
proxy_busy_buffers_size 512k;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
client_body_buffer_size 128k;
client_max_body_size 0;
break;
}
location ~* /sogo$ {
return 301 $client_req_scheme://$http_host/SOGo;
}
location /SOGo.woa/WebServerResources/ {
alias /usr/lib/GNUstep/SOGo/WebServerResources/;
}
location /.woa/WebServerResources/ {
alias /usr/lib/GNUstep/SOGo/WebServerResources/;
}
location /SOGo/WebServerResources/ {
alias /usr/lib/GNUstep/SOGo/WebServerResources/;
}
location (^/SOGo/so/ControlPanel/Products/[^/]*UI/Resources/.*\.(jpg|png|gif|css|js)$) {
alias /usr/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
}
include /etc/nginx/conf.d/site.*.custom;
error_page 502 @awaitingupstream;
location @awaitingupstream {
rewrite ^(.*)$ /_status.502.html break;
}
location ~ ^/cache/(.*)$ {
try_files $uri $uri/ /resource.php?file=$1;
}

View File

@@ -1,8 +0,0 @@
auth_request /sogo-auth-verify;
auth_request_set $user $upstream_http_x_user;
auth_request_set $auth $upstream_http_x_auth;
auth_request_set $auth_type $upstream_http_x_auth_type;
proxy_set_header x-webobjects-remote-user "$user";
proxy_set_header Authorization "$auth";
proxy_set_header x-webobjects-auth-type "$auth_type";

View File

@@ -1,19 +0,0 @@
server {
listen 9081;
index index.php index.html;
server_name _;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /meta_exporter;
client_max_body_size 10M;
location ~ \.php$ {
client_max_body_size 10M;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass phpfpm:9001;
fastcgi_index pipe.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}

View File

@@ -1,10 +0,0 @@
proxy_cache_path /tmp levels=1:2 keys_zone=sogo:10m inactive=24h max_size=1g;
server_names_hash_max_size 512;
server_names_hash_bucket_size 128;
map $http_x_forwarded_proto $client_req_scheme {
default $scheme;
https https;
}
include /etc/nginx/conf.d/sites.active;

View File

@@ -1,2 +0,0 @@
listen ${HTTP_PORT};
listen [::]:${HTTP_PORT};

View File

@@ -1,3 +0,0 @@
listen ${HTTPS_PORT} ssl;
listen [::]:${HTTPS_PORT} ssl;
http2 on;

View File

@@ -0,0 +1,127 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
# map-size.conf:
map_hash_max_size 256;
map_hash_bucket_size 256;
# site.conf:
proxy_cache_path /tmp levels=1:2 keys_zone=sogo:10m inactive=24h max_size=1g;
server_names_hash_max_size 512;
server_names_hash_bucket_size 128;
map $http_x_forwarded_proto $client_req_scheme {
default $scheme;
https https;
}
# Default
server {
listen 127.0.0.1:65510; # sogo-auth verify internal
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
listen {{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl;
{% if not DISABLE_IPv6 %}
listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
listen [::]:{{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl;
{%endif%}
http2 on;
ssl_certificate /etc/ssl/mail/cert.pem;
ssl_certificate_key /etc/ssl/mail/key.pem;
server_name {{ MAILCOW_HOSTNAME }} autodiscover.* autoconfig.* {{ ADDITIONAL_SERVER_NAMES }};
include /etc/nginx/includes/sites-default.conf;
}
# rspamd dynmaps:
server {
listen 8081;
{% if not DISABLE_IPv6 %}
listen [::]:8081;
{%endif%}
index index.php index.html;
server_name _;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /dynmaps;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass {{ PHPFPMHOST }}:9001;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
# rspamd meta_exporter:
server {
listen 9081;
index index.php index.html;
server_name _;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /meta_exporter;
client_max_body_size 10M;
location ~ \.php$ {
client_max_body_size 10M;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass {{ PHPFPMHOST }}:9001;
fastcgi_index pipe.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
{% for cert in valid_cert_dirs %}
server {
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
listen {{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl;
{% if not DISABLE_IPv6 %}
listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
listen [::]:{{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl;
{%endif%}
http2 on;
ssl_certificate {{ cert.cert_path }}cert.pem;
ssl_certificate_key {{ cert.cert_path }}key.pem;
server_name {{ cert.domains }};
include /etc/nginx/includes/sites-default.conf;
}
{% endfor %}
}

View File

@@ -1 +0,0 @@
echo "server_name ${MAILCOW_HOSTNAME} autodiscover.* autoconfig.* $(echo ${ADDITIONAL_SERVER_NAMES} | tr ',' ' ');"

View File

@@ -0,0 +1,276 @@
include /etc/nginx/mime.types;
charset utf-8;
override_charset on;
server_tokens off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_ecdh_curve X25519:X448:secp384r1:secp256k1;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=15768000;";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies none;
add_header Referrer-Policy strict-origin;
index index.php index.html;
client_max_body_size 0;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied off;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
location ~ ^/(fonts|js|css|img)/ {
expires max;
add_header Cache-Control public;
}
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
fastcgi_hide_header X-Powered-By;
absolute_redirect off;
root /web;
# If behind reverse proxy, forwards the correct IP
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from fc00::/7;
{% if not TRUSTED_NETWORK %}
real_ip_header X-Forwarded-For;
{% else %}
set_real_ip_from {{ TRUSTED_NETWORK }};
real_ip_header proxy_protocol;
{% endif %}
real_ip_recursive on;
location @strip-ext {
rewrite ^(.*)$ $1.php last;
}
location ^~ /inc/lib/ {
deny all;
return 403;
}
location ^~ /.well-known/acme-challenge/ {
allow all;
default_type "text/plain";
}
rewrite ^/.well-known/caldav$ /SOGo/dav/ permanent;
rewrite ^/.well-known/carddav$ /SOGo/dav/ permanent;
location / {
try_files $uri $uri/ @strip-ext;
}
location /qhandler {
rewrite ^/qhandler/(.*)/(.*) /qhandler.php?action=$1&hash=$2;
}
location /edit {
rewrite ^/edit/(.*)/(.*) /edit.php?$1=$2;
}
location ~ ^/api/v1/(.*)$ {
try_files $uri $uri/ /json_api.php?query=$1&$args;
}
location ~ ^/cache/(.*)$ {
try_files $uri $uri/ /resource.php?file=$1;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass {{ PHPFPMHOST }}:9002;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
}
location ~* ^/Autodiscover/Autodiscover.xml {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass {{ PHPFPMHOST }}:9002;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files /autodiscover.php =404;
}
location ~* ^/Autodiscover/Autodiscover.json {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass {{ PHPFPMHOST }}:9002;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files /autodiscover-json.php =404;
}
location ~ /(?:m|M)ail/(?:c|C)onfig-v1.1.xml {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass {{ PHPFPMHOST }}:9002;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files /autoconfig.php =404;
}
{% if not SKIP_RSPAMD %}
location /rspamd/ {
proxy_pass http://{{ RSPAMDHOST }}:11334/;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
proxy_redirect off;
proxy_intercept_errors on;
error_page 401 /_rspamderror.php;
}
{% endif %}
{% if not SKIP_SOGO %}
location ^~ /principals {
return 301 /SOGo/dav;
}
location /sogo-auth-verify {
internal;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header Content-Length "";
proxy_pass http://127.0.0.1:65510/sogo-auth;
proxy_pass_request_body off;
}
location ^~ /Microsoft-Server-ActiveSync {
auth_request /sogo-auth-verify;
auth_request_set $user $upstream_http_x_user;
auth_request_set $auth $upstream_http_x_auth;
auth_request_set $auth_type $upstream_http_x_auth_type;
proxy_set_header x-webobjects-remote-user "$user";
proxy_set_header Authorization "$auth";
proxy_set_header x-webobjects-auth-type "$auth_type";
proxy_pass http://{{ SOGOHOST }}:20000/SOGo/Microsoft-Server-ActiveSync;
proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
proxy_connect_timeout 75;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_buffer_size 128k;
proxy_buffers 64 512k;
proxy_busy_buffers_size 512k;
proxy_set_header Host $http_host;
client_body_buffer_size 512k;
client_max_body_size 0;
}
location ^~ /SOGo {
location ~* ^/SOGo/so/.*\.(xml|js|html|xhtml)$ {
auth_request /sogo-auth-verify;
auth_request_set $user $upstream_http_x_user;
auth_request_set $auth $upstream_http_x_auth;
auth_request_set $auth_type $upstream_http_x_auth_type;
proxy_set_header x-webobjects-remote-user "$user";
proxy_set_header Authorization "$auth";
proxy_set_header x-webobjects-auth-type "$auth_type";
proxy_pass http://{{ SOGOHOST }}:20000;
proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header Host $http_host;
proxy_set_header x-webobjects-server-protocol HTTP/1.0;
proxy_set_header x-webobjects-remote-host $remote_addr;
proxy_set_header x-webobjects-server-name $server_name;
proxy_set_header x-webobjects-server-url $client_req_scheme://$http_host;
proxy_set_header x-webobjects-server-port $server_port;
proxy_hide_header Content-Type;
add_header Content-Type text/plain;
break;
}
auth_request /sogo-auth-verify;
auth_request_set $user $upstream_http_x_user;
auth_request_set $auth $upstream_http_x_auth;
auth_request_set $auth_type $upstream_http_x_auth_type;
proxy_set_header x-webobjects-remote-user "$user";
proxy_set_header Authorization "$auth";
proxy_set_header x-webobjects-auth-type "$auth_type";
proxy_pass http://{{ SOGOHOST }}:20000;
proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header Host $http_host;
proxy_set_header x-webobjects-server-protocol HTTP/1.0;
proxy_set_header x-webobjects-remote-host $remote_addr;
proxy_set_header x-webobjects-server-name $server_name;
proxy_set_header x-webobjects-server-url $client_req_scheme://$http_host;
proxy_set_header x-webobjects-server-port $server_port;
proxy_buffer_size 128k;
proxy_buffers 64 512k;
proxy_busy_buffers_size 512k;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
client_body_buffer_size 128k;
client_max_body_size 0;
break;
}
location ~* /sogo$ {
return 301 $client_req_scheme://$http_host/SOGo;
}
location /SOGo.woa/WebServerResources/ {
alias /usr/lib/GNUstep/SOGo/WebServerResources/;
}
location /.woa/WebServerResources/ {
alias /usr/lib/GNUstep/SOGo/WebServerResources/;
}
location /SOGo/WebServerResources/ {
alias /usr/lib/GNUstep/SOGo/WebServerResources/;
}
location (^/SOGo/so/ControlPanel/Products/[^/]*UI/Resources/.*\.(jpg|png|gif|css|js)$) {
alias /usr/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
}
{% endif %}
include /etc/nginx/conf.d/site.*.custom;
error_page 502 @awaitingupstream;
location @awaitingupstream {
rewrite ^(.*)$ /_status.502.html break;
}
location ~* \.php$ {
return 404;
}
location ~* \.twig$ {
return 404;
}

View File

@@ -1,38 +0,0 @@
echo '
server {
listen 127.0.0.1:65510;
include /etc/nginx/conf.d/listen_plain.active;
include /etc/nginx/conf.d/listen_ssl.active;
ssl_certificate /etc/ssl/mail/cert.pem;
ssl_certificate_key /etc/ssl/mail/key.pem;
include /etc/nginx/conf.d/server_name.active;
include /etc/nginx/conf.d/includes/site-defaults.conf;
}
';
for cert_dir in /etc/ssl/mail/*/ ; do
if [[ ! -f ${cert_dir}domains ]] || [[ ! -f ${cert_dir}cert.pem ]] || [[ ! -f ${cert_dir}key.pem ]]; then
continue
fi
# do not create vhost for default-certificate. the cert is already in the default server listen
domains="$(cat ${cert_dir}domains | sed -e 's/^[[:space:]]*//')"
case "${domains}" in
"") continue;;
"${MAILCOW_HOSTNAME}"*) continue;;
esac
echo -n '
server {
include /etc/nginx/conf.d/listen_ssl.active;
ssl_certificate '${cert_dir}'cert.pem;
ssl_certificate_key '${cert_dir}'key.pem;
';
echo -n '
server_name '${domains}';
include /etc/nginx/conf.d/includes/site-defaults.conf;
}
';
done

View File

@@ -1 +0,0 @@
proxy_pass http://${IPV4_NETWORK}.248:20000;

View File

@@ -1,5 +0,0 @@
if printf "%s\n" "${SKIP_SOGO}" | grep -E '^([yY][eE][sS]|[yY])+$' >/dev/null; then
echo "return 410;"
else
echo "proxy_pass http://${IPV4_NETWORK}.248:20000/SOGo/Microsoft-Server-ActiveSync;"
fi

View File

@@ -1,6 +1,6 @@
# Whitelist generated by Postwhite v3.4 on Fri Nov 1 00:18:49 UTC 2024
# Whitelist generated by Postwhite v3.4 on Wed Jan 1 00:18:52 UTC 2025
# https://github.com/stevejenkins/postwhite/
# 2013 total rules
# 2014 total rules
2a00:1450:4000::/36 permit
2a01:111:f400::/48 permit
2a01:111:f403:8000::/50 permit
@@ -20,7 +20,10 @@
8.25.194.0/23 permit
8.25.196.0/23 permit
8.39.54.0/23 permit
8.39.54.250/31 permit
8.40.222.0/23 permit
8.40.222.250/31 permit
10.162.0.0/16 permit
12.130.86.238 permit
13.110.208.0/21 permit
13.110.209.0/24 permit
@@ -31,9 +34,11 @@
15.200.21.50 permit
15.200.44.248 permit
15.200.201.185 permit
17.41.0.0/16 permit
17.57.155.0/24 permit
17.57.156.0/24 permit
17.58.0.0/16 permit
17.142.0.0/15 permit
17.143.234.140/30 permit
18.156.89.250 permit
18.157.243.190 permit
@@ -116,7 +121,6 @@
40.233.64.216 permit
40.233.83.78 permit
40.233.88.28 permit
43.228.184.0/22 permit
44.206.138.57 permit
44.217.45.156 permit
44.236.56.93 permit
@@ -325,7 +329,6 @@
65.110.161.77 permit
65.123.29.213 permit
65.123.29.220 permit
65.154.166.0/24 permit
65.212.180.36 permit
66.102.0.0/20 permit
66.119.150.192/26 permit
@@ -1114,10 +1117,8 @@
98.139.245.212/31 permit
99.78.197.208/28 permit
99.83.190.102 permit
103.2.140.0/22 permit
103.9.96.0/22 permit
103.28.42.0/24 permit
103.47.204.0/22 permit
103.151.192.0/23 permit
103.168.172.128/27 permit
104.43.243.237 permit
@@ -1285,9 +1286,6 @@
117.120.16.0/21 permit
119.42.242.52/31 permit
119.42.242.156 permit
121.244.91.48 permit
121.244.91.52 permit
122.15.156.182 permit
123.126.78.64/29 permit
124.108.96.24/31 permit
124.108.96.28/31 permit
@@ -1348,19 +1346,7 @@
134.170.141.64/26 permit
134.170.143.0/24 permit
134.170.174.0/24 permit
135.84.80.0/24 permit
135.84.81.0/24 permit
135.84.82.0/24 permit
135.84.83.0/24 permit
135.84.216.0/22 permit
136.143.160.0/24 permit
136.143.161.0/24 permit
136.143.162.0/24 permit
136.143.178.49 permit
136.143.182.0/23 permit
136.143.184.0/24 permit
136.143.188.0/24 permit
136.143.190.0/23 permit
136.147.128.0/20 permit
136.147.135.0/24 permit
136.147.176.0/20 permit
@@ -1375,7 +1361,6 @@
139.138.46.219 permit
139.138.57.55 permit
139.138.58.119 permit
139.167.79.86 permit
139.180.17.0/24 permit
140.238.148.191 permit
141.148.159.229 permit
@@ -1410,6 +1395,7 @@
146.20.215.0/24 permit
146.20.215.182 permit
146.88.28.0/24 permit
147.154.32.0/25 permit
147.243.1.47 permit
147.243.1.48 permit
147.243.1.153 permit
@@ -1450,7 +1436,6 @@
157.151.208.65 permit
157.255.1.64/29 permit
158.101.211.207 permit
158.120.80.0/21 permit
158.247.16.0/20 permit
159.92.154.0/24 permit
159.92.155.0/24 permit
@@ -1478,6 +1463,11 @@
161.38.204.0/22 permit
161.71.32.0/19 permit
161.71.64.0/20 permit
162.88.4.0/23 permit
162.88.8.0/24 permit
162.88.24.0/24 permit
162.88.25.0/24 permit
162.88.36.0/24 permit
162.247.216.0/22 permit
163.47.180.0/22 permit
163.114.130.16 permit
@@ -1487,6 +1477,8 @@
164.152.23.32 permit
164.177.132.168/30 permit
165.173.128.0/24 permit
165.173.180.250/31 permit
165.173.182.250/31 permit
166.78.68.0/22 permit
166.78.68.221 permit
166.78.69.169 permit
@@ -1520,7 +1512,7 @@
169.148.142.10 permit
169.148.144.0/25 permit
169.148.144.10 permit
170.10.68.0/22 permit
169.148.146.0/23 permit
170.10.128.0/24 permit
170.10.129.0/24 permit
170.10.132.56/29 permit
@@ -1626,6 +1618,7 @@
192.18.139.154 permit
192.18.145.36 permit
192.18.152.58 permit
192.29.103.128/25 permit
192.30.252.0/22 permit
192.161.144.0/20 permit
192.162.87.0/24 permit
@@ -1651,14 +1644,6 @@
195.234.109.226 permit
195.245.230.0/23 permit
198.2.128.0/18 permit
198.2.128.0/24 permit
198.2.132.0/22 permit
198.2.136.0/23 permit
198.2.145.0/24 permit
198.2.177.0/24 permit
198.2.178.0/23 permit
198.2.180.0/24 permit
198.2.186.0/23 permit
198.21.0.0/21 permit
198.37.144.0/20 permit
198.37.152.186 permit
@@ -1678,15 +1663,7 @@
199.16.156.0/22 permit
199.33.145.1 permit
199.33.145.32 permit
199.34.22.36 permit
199.59.148.0/22 permit
199.67.80.2 permit
199.67.80.20 permit
199.67.82.2 permit
199.67.82.20 permit
199.67.84.0/24 permit
199.67.86.0/24 permit
199.67.88.0/24 permit
199.101.161.130 permit
199.101.162.0/25 permit
199.122.120.0/21 permit
@@ -1698,7 +1675,6 @@
202.165.102.47 permit
202.177.148.100 permit
202.177.148.110 permit
203.31.36.0/22 permit
203.32.4.25 permit
203.55.21.0/24 permit
203.81.17.0/24 permit
@@ -1744,19 +1720,13 @@
204.92.114.187 permit
204.92.114.203 permit
204.92.114.204/31 permit
204.141.32.0/23 permit
204.141.42.0/23 permit
204.220.160.0/21 permit
204.220.168.0/21 permit
204.220.176.0/20 permit
204.232.168.0/24 permit
205.139.110.0/24 permit
205.201.128.0/20 permit
205.201.131.128/25 permit
205.201.134.128/25 permit
205.201.136.0/23 permit
205.201.137.229 permit
205.201.139.0/24 permit
205.207.104.0/22 permit
205.220.167.17 permit
205.220.167.98 permit
@@ -1784,7 +1754,6 @@
207.46.132.128/27 permit
207.46.198.0/25 permit
207.46.200.0/27 permit
207.58.147.64/28 permit
207.67.38.0/24 permit
207.67.98.192/27 permit
207.68.176.0/26 permit
@@ -1831,6 +1800,8 @@
208.74.204.5 permit
208.74.204.9 permit
208.75.120.0/22 permit
208.76.62.0/24 permit
208.76.63.0/24 permit
208.82.237.96/29 permit
208.82.237.104/31 permit
208.82.238.96/29 permit
@@ -1930,7 +1901,6 @@
213.199.177.0/26 permit
216.17.150.242 permit
216.17.150.251 permit
216.22.15.224/27 permit
216.24.224.0/20 permit
216.39.60.154/31 permit
216.39.60.156/30 permit
@@ -1973,7 +1943,10 @@
216.136.162.65 permit
216.136.162.120/29 permit
216.136.168.80/28 permit
216.139.64.0/19 permit
216.145.221.0/24 permit
216.146.32.0/24 permit
216.146.33.0/24 permit
216.198.0.0/18 permit
216.203.30.55 permit
216.203.33.178/31 permit
@@ -2001,6 +1974,7 @@
2603:1030:c02:8::14 permit
2607:13c0:0001:0000:0000:0000:0000:7000/116 permit
2607:13c0:0002:0000:0000:0000:0000:1000/116 permit
2607:13c0:0004:0000:0000:0000:0000:0000/116 permit
2607:f8b0:4000::/36 permit
2620:109:c003:104::/64 permit
2620:109:c003:104::215 permit

7
data/conf/redis/redis-conf.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
cat <<EOF > /redis.conf
requirepass $REDISPASS
EOF
exec redis-server /redis.conf

View File

@@ -25,6 +25,7 @@ catch (PDOException $e) {
// Init Redis
$redis = new Redis();
$redis->connect('redis-mailcow', 6379);
$redis->auth(getenv("REDISPASS"));
function parse_email($email) {
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) return false;

View File

@@ -4,6 +4,7 @@ ini_set('error_reporting', 0);
$redis = new Redis();
$redis->connect('redis-mailcow', 6379);
$redis->auth(getenv("REDISPASS"));
function in_net($addr, $net) {
$net = explode('/', $net);

View File

@@ -24,6 +24,7 @@ catch (PDOException $e) {
// Init Redis
$redis = new Redis();
$redis->connect('redis-mailcow', 6379);
$redis->auth(getenv("REDISPASS"));
// Functions
function parse_email($email) {
@@ -96,10 +97,10 @@ $rcpt_final_mailboxes = array();
foreach (json_decode($rcpts, true) as $rcpt) {
// Remove tag
$rcpt = preg_replace('/^(.*?)\+.*(@.*)$/', '$1$2', $rcpt);
// Break rcpt into local part and domain part
$parsed_rcpt = parse_email($rcpt);
// Skip if not a mailcow handled domain
try {
if (!$redis->hGet('DOMAIN_MAP', $parsed_rcpt['domain'])) {
@@ -243,7 +244,7 @@ foreach ($rcpt_final_mailboxes as $rcpt_final) {
WHERE `rcpt` = :rcpt2
ORDER BY id DESC
LIMIT :retention_size
) x
) x
);');
$stmt->execute(array(
':rcpt' => $rcpt_final,

View File

@@ -14,6 +14,7 @@ try {
else {
$redis->connect('redis-mailcow', 6379);
}
$redis->auth(getenv("REDISPASS"));
}
catch (Exception $e) {
exit;

View File

@@ -24,6 +24,7 @@ catch (PDOException $e) {
// Init Redis
$redis = new Redis();
$redis->connect('redis-mailcow', 6379);
$redis->auth(getenv("REDISPASS"));
// Functions
function parse_email($email) {

View File

@@ -16,6 +16,9 @@
SOGoFoldersSendEMailNotifications = YES;
SOGoForwardEnabled = YES;
// Fixes "MODIFICATION_FAILED" error (HTTP 412) in Clients when accepting invitations from external services
SOGoDisableOrganizerEventCheck = YES;
// Option to set Users as admin to globally manage calendar permissions etc. Disabled by default
// SOGoSuperUsernames = ("moo@example.com");

View File

@@ -7,6 +7,7 @@ try {
else {
$redis->connect('redis-mailcow', 6379);
}
$redis->auth(getenv("REDISPASS"));
}
catch (Exception $e) {
exit;

View File

@@ -104,7 +104,7 @@ $template_data = [
'all_domains' => $all_domains,
'mailboxes' => $mailboxes,
'f2b_data' => $f2b_data,
'f2b_banlist_url' => getBaseUrl() . "/api/v1/get/fail2ban/banlist/" . $f2b_data['banlist_id'],
'f2b_banlist_url' => getBaseUrl() . "/f2b-banlist?id=" . $f2b_data['banlist_id'],
'q_data' => quarantine('settings'),
'qn_data' => quota_notification('get'),
'pw_reset_data' => reset_password('get_notification'),

View File

@@ -1531,6 +1531,9 @@ paths:
port1:
description: the smtp port of the target mail server
type: string
user1:
description: the username of the mailbox
type: string
password:
description: the password of the mailbox
type: string
@@ -5415,12 +5418,6 @@ paths:
started_at: "2019-12-22T20:59:58.382274592Z"
state: running
type: info
solr-mailcow:
container: solr-mailcow
image: "mailcow/solr:1.7"
started_at: "2019-12-22T20:59:59.635413798Z"
state: running
type: info
unbound-mailcow:
container: unbound-mailcow
image: "mailcow/unbound:1.10"
@@ -5442,30 +5439,6 @@ paths:
hey where started and a few other details.
operationId: Get container status
summary: Get container status
/api/v1/get/status/solr:
get:
responses:
"401":
$ref: "#/components/responses/Unauthorized"
"200":
content:
application/json:
examples:
response:
value:
solr_documents: null
solr_enabled: false
solr_size: null
type: info
description: OK
headers: {}
tags:
- Status
description: >-
Using this endpoint you can get the status of all containers and when
hey where started and a few other details.
operationId: Get solr status
summary: Get solr status
/api/v1/get/status/vmail:
get:
responses:

View File

@@ -16,6 +16,7 @@ try {
else {
$redis->connect('redis-mailcow', 6379);
}
$redis->auth(getenv("REDISPASS"));
}
catch (Exception $e) {
exit;

View File

@@ -8,7 +8,6 @@ if (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != "adm
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php';
$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
$solr_status = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["SKIP_SOLR"])) ? false : solr_status();
$clamd_status = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["SKIP_CLAMD"])) ? false : true;
@@ -25,7 +24,6 @@ $vmail_df = explode(',', (string)json_decode(docker('post', 'dovecot-mailcow', '
// containers
$containers_info = (array) docker('info');
if ($clamd_status === false) unset($containers_info['clamd-mailcow']);
if ($solr_status === false) unset($containers_info['solr-mailcow']);
ksort($containers_info);
$containers = array();
foreach ($containers_info as $container => $container_info) {
@@ -69,8 +67,6 @@ $template_data = [
'timezone' => $timezone,
'gal' => @$_SESSION['gal'],
'license_guid' => license('guid'),
'solr_status' => $solr_status,
'solr_uptime' => round($solr_status['status']['dovecot-fts']['uptime'] / 1000 / 60 / 60),
'clamd_status' => $clamd_status,
'containers' => $containers,
'ip_check' => customize('get', 'ip_check'),

11
data/web/f2b-banlist.php Normal file
View File

@@ -0,0 +1,11 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
if (isset($_GET['id'])) {
header('Content-Type: text/plain');
echo fail2ban('banlist', 'get', $_GET['id']);
} else {
header('HTTP/1.1 404 Not Found');
exit;
}

View File

@@ -4,14 +4,14 @@ header('Content-Type: application/json');
if (!isset($_SESSION['mailcow_cc_role'])) {
exit();
}
if (isset($_GET['script'])) {
if (isset($_REQUEST['script'])) {
$sieve = new Sieve\SieveParser();
try {
if (empty($_GET['script'])) {
if (empty($_REQUEST['script'])) {
echo json_encode(array('type' => 'danger', 'msg' => $lang['danger']['script_empty']));
exit();
}
$sieve->parse($_GET['script']);
$sieve->parse($_REQUEST['script']);
}
catch (Exception $e) {
echo json_encode(array('type' => 'danger', 'msg' => $e->getMessage()));

View File

@@ -26,7 +26,7 @@ function dkim($_action, $_data = null, $privkey = false) {
);
continue;
}
if (!ctype_alnum(str_replace(['-', '_'], '', $dkim_selector))) {
if (!ctype_alnum(str_replace(['-', '_', '.'], '', $dkim_selector))) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),
@@ -188,7 +188,7 @@ function dkim($_action, $_data = null, $privkey = false) {
return false;
}
}
if (!ctype_alnum($dkim_selector)) {
if (!ctype_alnum(str_replace(['-', '_', '.'], '', $dkim_selector))) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),

View File

@@ -1174,7 +1174,7 @@ function user_get_alias_details($username) {
AND `goto` != :username_goto2
AND `address` != :username_address");
$stmt->execute(array(
':username_goto' => '(^|,)'.$username.'($|,)',
':username_goto' => '(^|,)'.preg_quote($username, '/').'($|,)',
':username_goto2' => $username,
':username_address' => $username
));
@@ -1222,7 +1222,7 @@ function user_get_alias_details($username) {
$data['aliases_send_as_all'] = $row['send_as'];
}
$stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '') as `address` FROM `alias` WHERE `goto` REGEXP :username AND `address` LIKE '@%';");
$stmt->execute(array(':username' => '(^|,)'.$username.'($|,)'));
$stmt->execute(array(':username' => '(^|,)'.preg_quote($username, '/').'($|,)'));
$run = $stmt->fetchAll(PDO::FETCH_ASSOC);
while ($row = array_shift($run)) {
$data['is_catch_all'] = $row['address'];
@@ -2908,50 +2908,6 @@ function getGUID() {
.substr($charid,16, 4).$hyphen
.substr($charid,20,12);
}
function solr_status() {
$curl = curl_init();
$endpoint = 'http://solr:8983/solr/admin/cores';
$params = array(
'action' => 'STATUS',
'core' => 'dovecot-fts',
'indexInfo' => 'true'
);
$url = $endpoint . '?' . http_build_query($params);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 0);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$response_core = curl_exec($curl);
if ($response_core === false) {
$err = curl_error($curl);
curl_close($curl);
return false;
}
else {
curl_close($curl);
$curl = curl_init();
$status_core = json_decode($response_core, true);
$url = 'http://solr:8983/solr/admin/info/system';
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 0);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
$response_sysinfo = curl_exec($curl);
if ($response_sysinfo === false) {
$err = curl_error($curl);
curl_close($curl);
return false;
}
else {
curl_close($curl);
$status_sysinfo = json_decode($response_sysinfo, true);
$status = array_merge($status_core, $status_sysinfo);
return (!empty($status['status']['dovecot-fts']) && !empty($status['jvm']['memory'])) ? $status : false;
}
return (!empty($status['status']['dovecot-fts'])) ? $status['status']['dovecot-fts'] : false;
}
return false;
}
function cleanupJS($ignore = '', $folder = '/tmp/*.js') {
$now = time();

View File

@@ -48,6 +48,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$_data["validity"] = 8760;
}
$domain = $_data['domain'];
$description = $_data['description'];
$valid_domains[] = mailbox('get', 'mailbox_details', $username)['domain'];
$valid_alias_domains = user_get_alias_details($username)['alias_domains'];
if (!empty($valid_alias_domains)) {
@@ -62,10 +63,11 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
return false;
}
$validity = strtotime("+" . $_data["validity"] . " hour");
$stmt = $pdo->prepare("INSERT INTO `spamalias` (`address`, `goto`, `validity`) VALUES
(:address, :goto, :validity)");
$stmt = $pdo->prepare("INSERT INTO `spamalias` (`address`, `description`, `goto`, `validity`) VALUES
(:address, :description, :goto, :validity)");
$stmt->execute(array(
':address' => readable_random_string(rand(rand(3, 9), rand(3, 9))) . '.' . readable_random_string(rand(rand(3, 9), rand(3, 9))) . '@' . $domain,
':description' => $description,
':goto' => $username,
':validity' => $validity
));
@@ -3768,7 +3770,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$data['external_sender_aliases'] = array();
// Fixed addresses
$stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` REGEXP :goto AND `address` NOT LIKE '@%'");
$stmt->execute(array(':goto' => '(^|,)'.$_data.'($|,)'));
$stmt->execute(array(':goto' => '(^|,)'.preg_quote($_data, '/').'($|,)'));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
while ($row = array_shift($rows)) {
$data['fixed_sender_aliases'][] = $row['address'];
@@ -4201,6 +4203,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
}
$stmt = $pdo->prepare("SELECT `address`,
`goto`,
`description`,
`validity`,
`created`,
`modified`
@@ -5434,25 +5437,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
'msg' => 'Could not move maildir to garbage collector: variables local_part and/or domain empty'
);
}
if (strtolower(getenv('SKIP_SOLR')) == 'n' && strtolower(getenv('FLATCURVE_EXPERIMENTAL')) != 'y') {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://solr:8983/solr/dovecot-fts/update?commit=true');
curl_setopt($curl, CURLOPT_HTTPHEADER,array('Content-Type: text/xml'));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, '<delete><query>user:' . $username . '</query></delete>');
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
$response = curl_exec($curl);
if ($response === false) {
$err = curl_error($curl);
$_SESSION['return'][] = array(
'type' => 'warning',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => 'Could not remove Solr index: ' . print_r($err, true)
);
}
curl_close($curl);
}
$stmt = $pdo->prepare("DELETE FROM `alias` WHERE `goto` = :username");
$stmt->execute(array(
':username' => $username
@@ -5553,7 +5537,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
));
$stmt = $pdo->prepare("SELECT `address`, `goto` FROM `alias`
WHERE `goto` REGEXP :username");
$stmt->execute(array(':username' => '(^|,)'.$username.'($|,)'));
$stmt->execute(array(':username' => '(^|,)'.preg_quote($username, '/').'($|,)'));
$GotoData = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($GotoData as $gotos) {
$goto_exploded = explode(',', $gotos['goto']);

View File

@@ -1,9 +1,10 @@
<?php
function init_db_schema() {
function init_db_schema()
{
try {
global $pdo;
$db_version = "29072024_1000";
$db_version = "20112024_1105";
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
@@ -111,6 +112,10 @@ function init_db_schema() {
"c_name" => "VARCHAR(255) NOT NULL",
"c_password" => "VARCHAR(255) NOT NULL DEFAULT ''",
"c_cn" => "VARCHAR(255)",
"c_l" => "VARCHAR(255)",
"c_o" => "VARCHAR(255)",
"c_ou" => "VARCHAR(255)",
"c_telephonenumber" => "VARCHAR(255)",
"mail" => "VARCHAR(255) NOT NULL",
// TODO -> use TEXT and check if SOGo login breaks on empty aliases
"aliases" => "TEXT NOT NULL",
@@ -484,7 +489,7 @@ function init_db_schema() {
"quarantine_category" => "TINYINT(1) NOT NULL DEFAULT '1'",
"app_passwds" => "TINYINT(1) NOT NULL DEFAULT '1'",
"pw_reset" => "TINYINT(1) NOT NULL DEFAULT '1'",
),
),
"keys" => array(
"primary" => array(
"" => array("username")
@@ -523,6 +528,7 @@ function init_db_schema() {
"cols" => array(
"address" => "VARCHAR(255) NOT NULL",
"goto" => "TEXT NOT NULL",
"description" => "TEXT NOT NULL",
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
"modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP",
"validity" => "INT(11)"
@@ -674,7 +680,7 @@ function init_db_schema() {
"mailbox_relayhost" => "TINYINT(1) NOT NULL DEFAULT '1'",
"domain_relayhost" => "TINYINT(1) NOT NULL DEFAULT '1'",
"domain_desc" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
),
"keys" => array(
"primary" => array(
"" => array("username")
@@ -1004,7 +1010,7 @@ function init_db_schema() {
)
),
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
),
),
"pushover" => array(
"cols" => array(
"username" => "VARCHAR(255) NOT NULL",
@@ -1147,7 +1153,7 @@ function init_db_schema() {
while ($row = array_shift($rows)) {
$pdo->query($row['FKEY_DROP']);
}
foreach($properties['cols'] as $column => $type) {
foreach ($properties['cols'] as $column => $type) {
$stmt = $pdo->query("SHOW COLUMNS FROM `" . $table . "` LIKE '" . $column . "'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results == 0) {
@@ -1161,12 +1167,11 @@ function init_db_schema() {
}
}
$pdo->query("ALTER TABLE `" . $table . "` ADD `" . $column . "` " . $type);
}
else {
} else {
$pdo->query("ALTER TABLE `" . $table . "` MODIFY COLUMN `" . $column . "` " . $type);
}
}
foreach($properties['keys'] as $key_type => $key_content) {
foreach ($properties['keys'] as $key_type => $key_content) {
if (strtolower($key_type) == 'primary') {
foreach ($key_content as $key_values) {
$fields = "`" . implode("`, `", $key_values) . "`";
@@ -1223,18 +1228,18 @@ function init_db_schema() {
$keys_to_exist = array();
if (isset($properties['keys']['unique']) && is_array($properties['keys']['unique'])) {
foreach ($properties['keys']['unique'] as $key_name => $key_values) {
$keys_to_exist[] = $key_name;
$keys_to_exist[] = $key_name;
}
}
if (isset($properties['keys']['key']) && is_array($properties['keys']['key'])) {
foreach ($properties['keys']['key'] as $key_name => $key_values) {
$keys_to_exist[] = $key_name;
$keys_to_exist[] = $key_name;
}
}
// Index for foreign key must exist
if (isset($properties['keys']['fkey']) && is_array($properties['keys']['fkey'])) {
foreach ($properties['keys']['fkey'] as $key_name => $key_values) {
$keys_to_exist[] = $key_name;
$keys_to_exist[] = $key_name;
}
}
// Step 2: Drop all vanished indexes
@@ -1251,33 +1256,29 @@ function init_db_schema() {
$pdo->query("ALTER TABLE `" . $table . "` DROP PRIMARY KEY");
}
}
}
else {
} else {
// Create table if it is missing
$sql = "CREATE TABLE IF NOT EXISTS `" . $table . "` (";
foreach($properties['cols'] as $column => $type) {
foreach ($properties['cols'] as $column => $type) {
$sql .= "`" . $column . "` " . $type . ",";
}
foreach($properties['keys'] as $key_type => $key_content) {
foreach ($properties['keys'] as $key_type => $key_content) {
if (strtolower($key_type) == 'primary') {
foreach ($key_content as $key_values) {
$fields = "`" . implode("`, `", $key_values) . "`";
$sql .= "PRIMARY KEY (" . $fields . ")" . ",";
}
}
elseif (strtolower($key_type) == 'key') {
} elseif (strtolower($key_type) == 'key') {
foreach ($key_content as $key_name => $key_values) {
$fields = "`" . implode("`, `", $key_values) . "`";
$sql .= "KEY `" . $key_name . "` (" . $fields . ")" . ",";
}
}
elseif (strtolower($key_type) == 'unique') {
} elseif (strtolower($key_type) == 'unique') {
foreach ($key_content as $key_name => $key_values) {
$fields = "`" . implode("`, `", $key_values) . "`";
$sql .= "UNIQUE KEY `" . $key_name . "` (" . $fields . ")" . ",";
}
}
elseif (strtolower($key_type) == 'fkey') {
} elseif (strtolower($key_type) == 'fkey') {
foreach ($key_content as $key_name => $key_values) {
@list($table_ref, $field_ref) = explode('.', $key_values['ref']);
$sql .= "FOREIGN KEY `" . $key_name . "` (" . $key_values['col'] . ") REFERENCES `" . $table_ref . "` (`" . $field_ref . "`)
@@ -1291,7 +1292,6 @@ function init_db_schema() {
}
// Reset table attributes
$pdo->query("ALTER TABLE `" . $table . "` " . $properties['attr'] . ";");
}
// Recreate SQL views
@@ -1318,12 +1318,12 @@ function init_db_schema() {
$stmt = $pdo->query("SELECT NULL FROM `admin`");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results == 0) {
$pdo->query("INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
$pdo->query("INSERT INTO `admin` (`username`, `password`, `superadmin`, `created`, `modified`, `active`)
VALUES ('admin', '{SSHA256}K8eVJ6YsZbQCfuJvSUbaQRLr0HPLz5rC9IAp0PAFl0tmNDBkMDc0NDAyOTAxN2Rk', 1, NOW(), NOW(), 1)");
$pdo->query("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
$pdo->query("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
SELECT `username`, 'ALL', NOW(), 1 FROM `admin`
WHERE superadmin='1' AND `username` NOT IN (SELECT `username` FROM `domain_admins`);");
$pdo->query("DELETE FROM `admin` WHERE `username` NOT IN (SELECT `username` FROM `domain_admins`);");
$pdo->query("DELETE FROM `admin` WHERE `username` NOT IN (SELECT `username` FROM `domain_admins`);");
}
// Insert new DB schema version
$pdo->query("REPLACE INTO `versions` (`application`, `version`) VALUES ('db_schema', '" . $db_version . "');");
@@ -1351,7 +1351,7 @@ function init_db_schema() {
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.mailbox_format', \"maildir:\") WHERE JSON_VALUE(`attributes`, '$.mailbox_format') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.quarantine_notification', \"never\") WHERE JSON_VALUE(`attributes`, '$.quarantine_notification') IS NULL;");
$pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.quarantine_category', \"reject\") WHERE JSON_VALUE(`attributes`, '$.quarantine_category') IS NULL;");
foreach($tls_options as $tls_user => $tls_options) {
foreach ($tls_options as $tls_user => $tls_options) {
$stmt = $pdo->prepare("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.tls_enforce_in', :tls_enforce_in),
`attributes` = JSON_SET(`attributes`, '$.tls_enforce_out', :tls_enforce_out)
WHERE `username` = :username");
@@ -1388,7 +1388,7 @@ function init_db_schema() {
"key_size" => 2048,
"max_quota_for_domain" => 10240 * 1048576,
)
);
);
$default_mailbox_template = array(
"template" => "Default",
"type" => "mailbox",
@@ -1423,37 +1423,37 @@ function init_db_schema() {
"acl_quarantine_category" => 1,
"acl_app_passwds" => 1,
)
);
);
$stmt = $pdo->prepare("SELECT id FROM `templates` WHERE `type` = :type AND `template` = :template");
$stmt->execute(array(
":type" => "domain",
":template" => $default_domain_template["template"]
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (empty($row)){
if (empty($row)) {
$stmt = $pdo->prepare("INSERT INTO `templates` (`type`, `template`, `attributes`)
VALUES (:type, :template, :attributes)");
$stmt->execute(array(
":type" => "domain",
":template" => $default_domain_template["template"],
":attributes" => json_encode($default_domain_template["attributes"])
));
}
));
}
$stmt = $pdo->prepare("SELECT id FROM `templates` WHERE `type` = :type AND `template` = :template");
$stmt->execute(array(
":type" => "mailbox",
":template" => $default_mailbox_template["template"]
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (empty($row)){
if (empty($row)) {
$stmt = $pdo->prepare("INSERT INTO `templates` (`type`, `template`, `attributes`)
VALUES (:type, :template, :attributes)");
$stmt->execute(array(
":type" => "mailbox",
":template" => $default_mailbox_template["template"],
":attributes" => json_encode($default_mailbox_template["attributes"])
));
}
));
}
if (php_sapi_name() == "cli") {
echo "DB initialization completed" . PHP_EOL;
@@ -1464,8 +1464,7 @@ function init_db_schema() {
'msg' => 'db_init_complete'
);
}
}
catch (PDOException $e) {
} catch (PDOException $e) {
if (php_sapi_name() == "cli") {
echo "DB initialization failed: " . print_r($e, true) . PHP_EOL;
} else {
@@ -1504,8 +1503,7 @@ if (php_sapi_name() == "cli") {
SELECT `c_uid`, `domain`, `c_name`, `c_password`, `c_cn`, `mail`, `aliases`, `ad_aliases`, `ext_acl`, `kind`, `multiple_bookings` from sogo_view");
$stmt = $pdo->query("DELETE FROM _sogo_static_view WHERE `c_uid` NOT IN (SELECT `username` FROM `mailbox` WHERE `active` = '1');");
echo "Fixed _sogo_static_view" . PHP_EOL;
}
catch ( Exception $e ) {
} catch (Exception $e) {
// Dunno
}
}
@@ -1513,9 +1511,8 @@ if (php_sapi_name() == "cli") {
$m = new Memcached();
$m->addServer('memcached', 11211);
$m->flush();
echo "Cleaned up memcached". PHP_EOL;
}
catch ( Exception $e ) {
echo "Cleaned up memcached" . PHP_EOL;
} catch (Exception $e) {
// Dunno
}
init_db_schema();

View File

@@ -68,6 +68,7 @@ try {
else {
$redis->connect('redis-mailcow', 6379);
}
$redis->auth(getenv("REDISPASS"));
}
catch (Exception $e) {
// Stop when redis is not available
@@ -321,7 +322,7 @@ $UI_TEXTS = customize('get', 'ui_texts');
if (file_exists('/web/css/themes/'.$UI_THEME.'-bootstrap.css'))
$css_minifier->add('/web/css/themes/'.$UI_THEME.'-bootstrap.css');
else
$css_minifier->add('/web/css/themes/lumen-bootstrap.css');
$css_minifier->add('/web/css/themes/lumen-bootstrap.css');
// minify css build files
foreach ($css_dir as $css_file) {
$css_minifier->add('/web/css/build/' . $css_file);

View File

@@ -4,6 +4,7 @@ if (!empty($_GET['sso_token'])) {
$username = domain_admin_sso('check', $_GET['sso_token']);
if ($username !== false) {
session_regenerate_id();
$_SESSION['mailcow_cc_username'] = $username;
$_SESSION['mailcow_cc_role'] = 'domainadmin';
header('Location: /mailbox');
@@ -87,18 +88,21 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
$as = check_login($login_user, $_POST["pass_user"]);
if ($as == "admin") {
session_regenerate_id();
$_SESSION['mailcow_cc_username'] = $login_user;
$_SESSION['mailcow_cc_role'] = "admin";
header("Location: /debug");
die();
}
elseif ($as == "domainadmin") {
session_regenerate_id();
$_SESSION['mailcow_cc_username'] = $login_user;
$_SESSION['mailcow_cc_role'] = "domainadmin";
header("Location: /mailbox");
die();
}
elseif ($as == "user") {
session_regenerate_id();
$_SESSION['mailcow_cc_username'] = $login_user;
$_SESSION['mailcow_cc_role'] = "user";
$http_parameters = explode('&', $_SESSION['index_query_string']);
@@ -111,8 +115,10 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
header("Location: /mobileconfig.php");
die();
}
header("Location: /user");
die();
if (!isset($_SESSION['oauth2_request'])) {
header("Location: /user");
die();
}
}
elseif ($as != "pending") {
unset($_SESSION['pending_mailcow_cc_username']);
@@ -120,7 +126,9 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
unset($_SESSION['pending_tfa_methods']);
unset($_SESSION['mailcow_cc_username']);
unset($_SESSION['mailcow_cc_role']);
}
} else {
session_regenerate_id();
}
}
if (isset($_SESSION['mailcow_cc_role']) && (isset($_SESSION['acl']['login_as']) && $_SESSION['acl']['login_as'] == "1")) {

View File

@@ -93,6 +93,7 @@ $AVAILABLE_LANGUAGES = array(
'gr-gr' => 'Ελληνικά (Greek)',
'hu-hu' => 'Magyar (Hungarian)',
'it-it' => 'Italiano (Italian)',
'ja-jp' => '日本語 (Japanese)',
'ko-kr' => '한국어 (Korean)',
'lv-lv' => 'latviešu (Latvian)',
'lt-lt' => 'Lietuvių (Lithuanian)',

View File

@@ -179,9 +179,8 @@ $(document).ready(function() {
// Get script_data textarea content from form the button was clicked in
var script = $('textarea[name="script_data"]', $(this).parents('form:first')).val();
$.ajax({
dataType: 'json',
url: "/inc/ajax/sieve_validation.php",
type: "get",
type: "post",
data: { script: script },
complete: function(data) {
var response = (data.responseText);
@@ -693,8 +692,8 @@ jQuery(function($){
} else if (item.attributes.rl_frame === "d"){
item.attributes.rl_frame = lang_rl.day;
}
item.attributes.rl_value = escapeHtml(item.attributes.rl_value);
item.attributes.rl_value = (!item.attributes.rl_value) ? "∞" : escapeHtml(item.attributes.rl_value);
item.attributes.ratelimit = item.attributes.rl_value + " " + item.attributes.rl_frame;
if (item.template.toLowerCase() == "default"){
item.action = '<div class="btn-group">' +
@@ -818,14 +817,8 @@ jQuery(function($){
}
},
{
title: 'rl_frame',
data: 'attributes.rl_frame',
defaultContent: '',
class: 'none',
},
{
title: 'rl_value',
data: 'attributes.rl_value',
title: lang_edit.ratelimit,
data: 'attributes.ratelimit',
defaultContent: '',
class: 'none',
},
@@ -894,7 +887,10 @@ jQuery(function($){
item.quota.value = humanFileSize(item.quota_used) + "/" + item.quota.value;
item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
item.last_mail_login = item.last_imap_login + '/' + item.last_pop3_login + '/' + item.last_smtp_login + '/' + item.last_sso_login;
item.last_mail_login = (item.attributes.imap_access == 1 ? '<div class="text-start badge bg-info mb-2" style="min-width: 70px;">IMAP @ ' + unix_time_format(Number(item.last_imap_login)) + '</div><br>' : '') +
(item.attributes.pop3_access == 1 ? '<div class="text-start badge bg-info mb-2" style="min-width: 70px;">POP3 @ ' + unix_time_format(Number(item.last_pop3_login)) + '</div><br>' : '') +
(item.attributes.smtp_access == 1 ? '<div class="text-start badge bg-info mb-2" style="min-width: 70px;">SMTP @ ' + unix_time_format(Number(item.last_smtp_login)) + '</div><br>' : '') +
'<div class="text-start badge bg-info" style="min-width: 70px;">SSO @ ' + unix_time_format(Number(item.last_sso_login)) + '</div>';
/*
if (!item.rl) {
item.rl = '∞';
@@ -1010,14 +1006,7 @@ jQuery(function($){
data: 'last_mail_login',
searchable: false,
defaultContent: '',
responsivePriority: 7,
render: function (data, type) {
res = data.split("/");
return '<div class="text-start badge bg-info mb-2" style="min-width: 70px;">IMAP @ ' + unix_time_format(Number(res[0])) + '</div><br>' +
'<div class="text-start badge bg-info mb-2" style="min-width: 70px;">POP3 @ ' + unix_time_format(Number(res[1])) + '</div><br>' +
'<div class="text-start badge bg-info mb-2" style="min-width: 70px;">SMTP @ ' + unix_time_format(Number(res[2])) + '</div><br>' +
'<div class="text-start badge bg-info" style="min-width: 70px;">SSO @ ' + unix_time_format(Number(res[3])) + '</div>';
}
responsivePriority: 7
},
{
title: lang.last_pw_change,
@@ -1183,7 +1172,8 @@ jQuery(function($){
} else if (item.attributes.rl_frame === "d"){
item.attributes.rl_frame = lang_rl.day;
}
item.attributes.rl_value = escapeHtml(item.attributes.rl_value);
item.attributes.rl_value = (!item.attributes.rl_value) ? "∞" : escapeHtml(item.attributes.rl_value);
item.attributes.ratelimit = item.attributes.rl_value + " " + item.attributes.rl_frame;
item.attributes.quota = humanFileSize(item.attributes.quota);
@@ -1328,14 +1318,8 @@ jQuery(function($){
}
},
{
title: "rl_frame",
data: 'attributes.rl_frame',
defaultContent: '',
class: 'none',
},
{
title: 'rl_value',
data: 'attributes.rl_value',
title: lang_edit.ratelimit,
data: 'attributes.ratelimit',
defaultContent: '',
class: 'none',
},

View File

@@ -202,6 +202,14 @@ jQuery(function($){
data: 'address',
defaultContent: ''
},
{
title: lang.description,
data: 'description',
defaultContent: '',
render: function (data, type) {
return escapeHtml(data);
}
},
{
title: lang.alias_valid_until,
data: 'validity',

View File

@@ -510,16 +510,6 @@ if (isset($_GET['query'])) {
$_SESSION['challenge'] = $WebAuthn->getChallenge();
return;
break;
case "fail2ban":
if (!isset($_SESSION['mailcow_cc_role'])){
switch ($object) {
case 'banlist':
header('Content-Type: text/plain');
echo fail2ban('banlist', 'get', $extra);
break;
}
}
break;
}
if (isset($_SESSION['mailcow_cc_role'])) {
switch ($category) {
@@ -1077,9 +1067,10 @@ if (isset($_GET['query'])) {
['db' => 'last_mail_login', 'dt' => 4, 'dummy' => true, 'order_subquery' => "SELECT MAX(`datetime`) FROM `sasl_log` WHERE `service` != 'SSO' AND `username` = `m`.`username`"],
['db' => 'last_pw_change', 'dt' => 5, 'dummy' => true, 'order_subquery' => "JSON_EXTRACT(attributes, '$.passwd_update')"],
['db' => 'in_use', 'dt' => 6, 'dummy' => true, 'order_subquery' => "(SELECT SUM(bytes) FROM `quota2` WHERE `quota2`.`username` = `m`.`username`) / `m`.`quota`"],
['db' => 'name', 'dt' => 7],
['db' => 'messages', 'dt' => 17, 'dummy' => true, 'order_subquery' => "SELECT SUM(messages) FROM `quota2` WHERE `quota2`.`username` = `m`.`username`"],
['db' => 'tags', 'dt' => 20, 'dummy' => true, 'search' => ['join' => 'LEFT JOIN `tags_mailbox` AS `tm` ON `tm`.`username` = `m`.`username`', 'where_column' => '`tm`.`tag_name`']],
['db' => 'active', 'dt' => 21]
['db' => 'active', 'dt' => 21],
];
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/lib/ssp.class.php';
@@ -1420,10 +1411,6 @@ if (isset($_GET['query'])) {
break;
case "fail2ban":
switch ($object) {
case 'banlist':
header('Content-Type: text/plain');
echo fail2ban('banlist', 'get', $extra);
break;
default:
$data = fail2ban('get');
process_get_return($data);
@@ -1641,23 +1628,6 @@ if (isset($_GET['query'])) {
);
echo json_encode($temp, JSON_UNESCAPED_SLASHES);
break;
case "solr":
$solr_status = solr_status();
$solr_size = ($solr_status['status']['dovecot-fts']['index']['size']);
$solr_documents = ($solr_status['status']['dovecot-fts']['index']['numDocs']);
if (strtolower(getenv('SKIP_SOLR')) != 'n') {
$solr_enabled = false;
}
else {
$solr_enabled = true;
}
echo json_encode(array(
'type' => 'info',
'solr_enabled' => $solr_enabled,
'solr_size' => $solr_size,
'solr_documents' => $solr_documents
));
break;
case "host":
if (!$extra){
$stats = docker("host_stats");

View File

@@ -493,6 +493,7 @@
"client_configuration": "Guies de configuració per als clients de correu més habituals",
"create_syncjob": "Afegir treball de sincronitzaió",
"day": "Dia",
"description": "Descripció",
"direct_aliases": "Adreces àlies directes",
"direct_aliases_desc": "Els àlies directes sí que es veuen afectat per la configuració de l'usuari",
"eas_reset": "Fer un reset de la cache d'ActiveSync del dispositiu",
@@ -558,4 +559,4 @@
"week": "Setmana",
"weeks": "Setmanes"
}
}
}

View File

@@ -521,7 +521,6 @@
"external_logs": "Externí logy",
"history_all_servers": "Záznam (všechny servery)",
"in_memory_logs": "Logy v paměti",
"jvm_memory_solr": "Spotřeba paměti JVM",
"last_modified": "Naposledy změněn",
"log_info": "<p><b>Logy v paměti</b> jsou shromažďovány v Redis seznamech a jsou oříznuty na LOG_LINES (%d) každou minutu, aby se nepřetěžoval server.\r\n <br>Logy v paměti nemají být trvalé. Všechny aplikace, které logují do paměti, zároveň logují i do Docker služby podle nastavení logging driveru.\r\n <br>Logy v paměti lze použít pro ladění drobných problémů s kontejnery.</p>\r\n <p><b>Externí logy</b> jsou shromažďovány pomocí API dané aplikace.</p>\r\n <p><b>Statické logy</b> jsou většinou logy činností, které nejsou zaznamenávány do Docker služby, ale přesto je dobré je schraňovat (výjimkou jsou logy API).</p>",
"login_time": "Čas",
@@ -530,8 +529,6 @@
"restart_container": "Restartovat",
"service": "Služba",
"size": "Velikost",
"solr_dead": "Solr se spouští, je vypnutý nebo spadl.",
"solr_status": "Stav Solr",
"started_at": "Spuštěn",
"started_on": "Spuštěno",
"static_logs": "Statické logy",
@@ -1164,6 +1161,7 @@
"created_on": "Vytvoreno",
"daily": "Každý den",
"day": "den",
"description": "Popis",
"delete_ays": "Potvrďte odstranění.",
"direct_aliases": "Přímé aliasy",
"direct_aliases_desc": "Na přímé aliasy se uplatňuje filtr spamu a nastavení pravidel TLS",
@@ -1309,4 +1307,4 @@
"session_token": "Token formuláře není platný: Token mismatch",
"session_ua": "Token formuláře není platný: User-Agent validation error"
}
}
}

View File

@@ -444,12 +444,9 @@
"external_logs": "Eksterne logfiler",
"history_all_servers": "Historie (alle servere)",
"in_memory_logs": "In-memory logs",
"jvm_memory_solr": "Brug af JVM-hukommelse",
"log_info": "<p>mailcow <b>in-memory logs</b> er samlet i Redis-lister og trimmet til LOG_LINES (%d) hvert minut for at reducere hamring.\r\n <br>Logbøger i hukommelsen er ikke beregnet til at være vedholdende. Alle applikationer, der logger ind i hukommelsen, logger også på Docker-dæmonen og derfor til standardlogdriveren.\r\n <br>Logtypen i hukommelsen skal bruges til fejlfinding af mindre problemer med containere.</p>\r\n <p><b>Eksterne logfiler</b> indsamles via API for den givne applikation.</p>\r\n <p><b>Statiske logfiler</b> er for det meste aktivitetslogfiler, der ikke er logget på Dockerd, men stadig skal være vedholdende (undtagen API-logfiler).</p>",
"logs": "Logs",
"restart_container": "Genstart",
"solr_dead": "Solr starter, deaktiveres eller døde.",
"solr_status": "Solr-status",
"started_on": "Startede den",
"static_logs": "Statiske logfiler",
"system_containers": "System og Beholdere",
@@ -971,6 +968,7 @@
"create_syncjob": "Opret nyt sync job",
"daily": "Dagligt",
"day": "dag",
"description": "Beskrivelse",
"delete_ays": "Bekræft venligst ønsket om sletning.",
"direct_aliases": "Direkte alias addresser",
"direct_aliases_desc": "Direkte alias-adresser påvirkes af spamfilter og TLS-politiske indstillinger.",
@@ -1091,4 +1089,4 @@
"first": "Først"
}
}
}
}

View File

@@ -539,7 +539,6 @@
"external_logs": "Externe Logs",
"history_all_servers": "History (alle Server)",
"in_memory_logs": "In-memory Logs",
"jvm_memory_solr": "JVM-Speicherauslastung",
"last_modified": "Zuletzt geändert",
"log_info": "<p>mailcow <b>in-memory Logs</b> werden in Redis Listen gespeichert, die maximale Anzahl der Einträge pro Anwendung richtet sich nach LOG_LINES (%d).\r\n <br>In-memory Logs sind vergänglich und nicht zur ständigen Aufbewahrung bestimmt. Alle Anwendungen, die in-memory protokollieren, schreiben ebenso in den Docker Daemon.\r\n <br>Das in-memory Protokoll versteht sich als schnelle Übersicht zum Debugging eines Containers, für komplexere Protokolle sollte der Docker Daemon konsultiert werden.</p>\r\n <p><b>Externe Logs</b> werden via API externer Applikationen bezogen.</p>\r\n <p><b>Statische Logs</b> sind weitestgehend Aktivitätsprotokolle, die nicht in den Docker Daemon geschrieben werden, jedoch permanent verfügbar sein müssen (ausgeschlossen API Logs).</p>",
"login_time": "Zeit",
@@ -550,8 +549,6 @@
"service": "Dienst",
"show_ip": "Zeige öffentliche IP",
"size": "Größe",
"solr_dead": "Solr startet, ist deaktiviert oder temporär nicht erreichbar.",
"solr_status": "Solr Status",
"started_at": "Gestartet am",
"started_on": "Gestartet am",
"static_logs": "Statische Logs",
@@ -1185,6 +1182,7 @@
"created_on": "Erstellt am",
"daily": "Täglich",
"day": "Tag",
"description": "Beschreibung",
"delete_ays": "Soll der Löschvorgang wirklich ausgeführt werden?",
"direct_aliases": "Direkte Alias-Adressen",
"direct_aliases_desc": "Nur direkte Alias-Adressen werden für benutzerdefinierte Einstellungen berücksichtigt.",
@@ -1338,4 +1336,4 @@
"hour": "Nachrichten / Stunde",
"day": "Nachrichten / Tag"
}
}
}

View File

@@ -539,7 +539,6 @@
"external_logs": "External logs",
"history_all_servers": "History (all servers)",
"in_memory_logs": "In-memory logs",
"jvm_memory_solr": "JVM memory usage",
"last_modified": "Last modified",
"log_info": "<p>mailcow <b>in-memory logs</b> are collected in Redis lists and trimmed to LOG_LINES (%d) every minute to reduce hammering.\r\n <br>In-memory logs are not meant to be persistent. All applications that log in-memory, also log to the Docker daemon and therefore to the default logging driver.\r\n <br>The in-memory log type should be used for debugging minor issues with containers.</p>\r\n <p><b>External logs</b> are collected via API of the given application.</p>\r\n <p><b>Static logs</b> are mostly activity logs, that are not logged to the Dockerd but still need to be persistent (except for API logs).</p>",
"login_time": "Time",
@@ -550,8 +549,6 @@
"service": "Service",
"show_ip": "Show public IP",
"size": "Size",
"solr_dead": "Solr is starting, disabled or died.",
"solr_status": "Solr status",
"started_at": "Started at",
"started_on": "Started on",
"static_logs": "Static logs",
@@ -1192,6 +1189,7 @@
"created_on": "Created on",
"daily": "Daily",
"day": "day",
"description": "Description",
"delete_ays": "Please confirm the deletion process.",
"direct_aliases": "Direct alias addresses",
"direct_aliases_desc": "Direct alias addresses are affected by spam filter and TLS policy settings.",
@@ -1338,4 +1336,4 @@
"session_token": "Form token invalid: Token mismatch",
"session_ua": "Form token invalid: User-Agent validation error"
}
}
}

View File

@@ -346,12 +346,10 @@
"log_info": "<p>Los <b>logs en memoria</b> son recopilados en listas de Redis y recortados a LOG_LINES (%d) cada minuto para prevenir sobrecarga en el sistema.\r\n <br>Los logs en memoria no están destinados a ser persistentes. Todas las aplicaciones que logean a la memoria, también logean en el daemon de Docker y, por lo tanto, en el controlador de registro predeterminado.\r\n El log en memoria se debe utilizar para analizar problemas menores con los contenedores.</p>\r\n <p>Los <b>logs externos</b> se recopilan a través de la API de la aplicación dada.</p>\r\n <p>Los <b>logs estáticos</b> son principalmente registros de actividad, que no están registrados en Dockerd pero que aún deben ser persistentes (excepto los registros de API).</p>",
"logs": "Logs",
"restart_container": "Reiniciar",
"solr_dead": "Solr está empezando, deshabilitado o caído.",
"docs": "Docs",
"last_modified": "Última modificación",
"size": "Tamaño",
"started_at": "Iniciado el",
"solr_status": "Solr status",
"uptime": "Uptime",
"static_logs": "Logs estáticos",
"system_containers": "Sistema y Contenedores"
@@ -709,6 +707,7 @@
"create_syncjob": "Crear nuevo trabajo de sincronización",
"daily": "Cada día",
"day": "Día",
"description": "Descripción",
"direct_aliases": "Alias directos",
"direct_aliases_desc": "Los alias directos se ven afectadas por el filtro de correo no deseado y la configuración de la política TLS del usuario.",
"eas_reset": "Resetear el caché ActiveSync",
@@ -778,4 +777,4 @@
"fuzzy_learn_error": "Error aprendiendo hash: %s",
"ip_invalid": "IP inválida omitida: %s"
}
}
}

View File

@@ -380,16 +380,13 @@
"disk_usage": "Levyn käyttö",
"external_logs": "Ulkoiset loki",
"in_memory_logs": "Muistissa olevat lokit",
"jvm_memory_solr": "JVM-muistin käyttö",
"log_info": "<p>mailcow <b>muistissa olevat lokit</b> kerätään Redis-luetteloihin ja leikataan LOG_LINES (%d) joka minuutti lyömisen vähentämiseksi.\r\n <br>Muistissa olevien lokien ei ole tarkoitus olla pysyviä. Kaikki sovellukset, jotka kirjautuvat muistiin, kirjautuvat myös Docker-daemoniin ja siten oletusarvoiseen lokitiedostoon.\r\n <br>Muistin lokityyppiä olisi käytettävä virheiden virheenkorjaukseen säilöissä.</p>\r\n <p><b>Ulkoiset lokit</b> kerätään annetun sovelluksen API: n kautta.</p>\r\n <p><b>Staattiset lokit</b> ovat useimmiten toimintalokkeja, joita ei kirjata Dockerdiin, mutta joiden on silti oltava pysyviä (paitsi API-lokit).</p>",
"logs": "Logit tausta palveluista",
"restart_container": "Uudelleen käynnistä",
"solr_dead": "Solr käynnistyy, on poissa käytöstä tai kuoli.",
"docs": "Docs",
"last_modified": "Viimeksi muokattu",
"size": "Koko",
"started_at": "Käynnistetty",
"solr_status": "Solr-tila",
"uptime": "Päällä",
"started_on": "Aloitettiin",
"static_logs": "Staattiset lokit",
@@ -810,6 +807,7 @@
"create_syncjob": "Luo uusi synkronointi työ",
"daily": "Päivittäin",
"day": "Päivä",
"description": "Kuvaus",
"direct_aliases": "Suorat alias osoitteet",
"direct_aliases_desc": "Roska posti suodatus-ja TLS-käytäntö asetukset vaikuttavat suora aliaksen osoitteisiin.",
"eas_reset": "Tyhjennä ActiveSync-laitteen väli muisti",
@@ -908,4 +906,4 @@
"last": "Edellinen"
}
}
}
}

View File

@@ -3,13 +3,13 @@
"alias_domains": "Ajouter un alias de domaine",
"app_passwds": "Gérer les mots de passe d'application",
"bcc_maps": "Mapping BCC",
"delimiter_action": "Délimitation d'action",
"eas_reset": "Réinitialiser les périphériques EA",
"delimiter_action": "Action du délimiteur",
"eas_reset": "Réinitialiser les périphériques EAS",
"extend_sender_acl": "Autoriser l'extension des ACL par des adresses externes",
"filters": "Filtres",
"login_as": "S'identifier en tant qu'utilisateur",
"prohibited": "Interdit par les ACL",
"protocol_access": "Modifier le protocol d'acces",
"protocol_access": "Modifier le protocole daccès",
"pushover": "Pushover",
"quarantine": "Actions de quarantaine",
"quarantine_attachments": "Pièces jointes en quarantaine",
@@ -20,7 +20,7 @@
"smtp_ip_access": "Changer les hôtes autorisés pour SMTP",
"sogo_access": "Autoriser la gestion des accès à SOGo",
"sogo_profile_reset": "Réinitialiser le profil SOGo",
"spam_alias": "Alias temporaire",
"spam_alias": "Alias temporaires",
"spam_policy": "Liste Noire/Liste Blanche",
"spam_score": "Score SPAM",
"syncjobs": "Tâches de synchronisation",
@@ -43,20 +43,20 @@
"alias_domain_info": "<small>Seulement des noms de domaines valides (séparés par des virgules).</small>",
"app_name": "Nom de l'application",
"app_password": "Mot de passe de l'application",
"automap": "Tenter de cibler automatiquement les dossiers (\"Sent items\", \"Sent\" => \"Sent\" etc.)",
"automap": "Tenter de cibler automatiquement les dossiers (« Sent items », « Sent » => « Sent » etc.)",
"backup_mx_options": "Options de MX secondaire",
"comment_info": "Un commentaire privé n'est pas visible pour l'utilisateur, tandis qu'un commentaire public est affiché sous forme d'info-bulle lorsqu'on le survole dans un aperçu des utilisateurs",
"custom_params": "Paramètres personnalisés",
"custom_params_hint": "Correct : --param=xy, Incorrect : --param xy",
"delete1": "Supprimer à la source lorsque la synchronisation terminée",
"delete2": "Supprimer les messages à destination qui ne sont pas présents à la source",
"delete2duplicates": "Supprimer les doubles à destination",
"custom_params_hint": "Correct : --param=xy, incorrect : --param xy",
"delete1": "Supprimer sur la source lorsque la synchronisation est terminée",
"delete2": "Supprimer les messages sur la destination qui ne sont pas présents sur la source",
"delete2duplicates": "Supprimer les doublons sur la destination",
"description": "Description",
"destination": "Destination",
"disable_login": "Désactiver l'authentification (les courriels entrants resteront acceptés)",
"domain": "domaine",
"domain": "Domaine",
"domain_matches_hostname": "Le domaine %s correspond à la machine (hostname)",
"domain_quota_m": "Quota total du domaine (Mo)",
"domain_quota_m": "Quota total du domaine (Mio)",
"enc_method": "Méthode de chiffrement",
"exclude": "Exclure des objets (expression régulière - regex)",
"full_name": "Nom complet",
@@ -70,7 +70,7 @@
"inactive": "Inactif",
"kind": "Type",
"mailbox_quota_def": "Quota boîte de réception par défaut",
"mailbox_quota_m": "Quota max par boîte de réception (Mo)",
"mailbox_quota_m": "Quota max par boîte de réception (Mio)",
"mailbox_username": "Identifiant (partie gauche d'une adresse de courriel)",
"max_aliases": "Nombre maximal d'alias",
"max_mailboxes": "Nombre maximal de boîtes de réception",
@@ -80,16 +80,16 @@
"password": "Mot de passe",
"password_repeat": "Confirmation du mot de passe (répéter)",
"port": "Port",
"post_domain_add": "le conteneur SOGo, \"sogo-mailcow\", doit être redémarré après l'ajout d'un nouveau domaine!<br><br>De plus, la configuration DNS doit être révisée. Lorsque la configuration DNS est approuvée, redémarrer \"acme-mailcow\" pour générer automatiquement les certificats pour votre nouveau domaine (autoconfig.&lt;domain&gt;, autodiscover.&lt;domain&gt;).<br>Cette étape est optionelle et sera réessayée toutes les 24 heures.",
"post_domain_add": "Le conteneur SOGo, « sogo-mailcow », doit être redémarré après l'ajout d'un nouveau domaine !<br><br>De plus, la configuration DNS doit être révisée. Lorsque la configuration DNS est approuvée, redémarrer « acme-mailcow » pour générer automatiquement les certificats pour votre nouveau domaine (autoconfig.&lt;domain&gt;, autodiscover.&lt;domain&gt;).<br>Cette étape est optionnelle et sera réessayée toutes les 24 heures.",
"private_comment": "Commentaire privé",
"public_comment": "Commentaire public",
"quota_mb": "Quota (Mo)",
"quota_mb": "Quota (Mio)",
"relay_all": "Relayer tous les destinataires",
"relay_all_info": "↪ Si vous choissisez <b>de ne pas</b> relayer tous les destinataires, vous devez ajouter une boîte de réception (\"aveugle\") pour chaque destinataire simple qui doit être relayé.",
"relay_all_info": "↪ Si vous choisissez <b>de ne pas</b> relayer tous les destinataires, vous devez ajouter une boîte de réception (« aveugle ») pour chaque destinataire simple qui doit être relayé.",
"relay_domain": "Relayer ce domaine",
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Info</div> Vous pouvez définir des cartes de transport vers une destination personnalisée pour ce domaine. sinon, une recherche MX sera effectuée.",
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Info</div> Vous pouvez définir des cartes de transport vers une destination personnalisée pour ce domaine. Sinon, une recherche MX sera effectuée.",
"relay_unknown_only": "Relayer uniquement les boîtes de réception inexistantes. Les boîtes de réception existantes seront livrées localement.",
"relayhost_wrapped_tls_info": "Veuillez <b>ne pas</b> utiliser des ports TLS wrappés (généralement utilisés sur le port 465).<br>\r\nUtilisez n'importe quel port non encapsulé et lancez STARTTLS. Une politique TLS pour appliquer TLS peut être créée dans \"Cartes de politique TLS\".",
"relayhost_wrapped_tls_info": "Veuillez <b>ne pas</b> utiliser des ports TLS wrappés (généralement utilisés sur le port 465).<br>\nUtilisez n'importe quel port non encapsulé et lancez STARTTLS. Une politique TLS pour appliquer TLS peut être créée dans « Cartes de politique TLS ».",
"select": "Veuillez sélectionner…",
"select_domain": "Sélectionner d'abord un domaine",
"sieve_desc": "Description courte",
@@ -139,15 +139,15 @@
"api_skip_ip_check": "Passer la vérification d'IP pour l'API",
"app_links": "Liens des applications",
"app_name": "Nom de l'application",
"apps_name": "\"mailcow Apps\" nom",
"apps_name": "Nom « mailcow Apps »",
"arrival_time": "Heure d'arrivée (heure du serveur)",
"authed_user": "Utilisateur autorisé",
"ays": "Voulez-vous vraiment le faire ?",
"ban_list_info": "Consultez la liste des adresses IP bannies ci-dessous : <b>réseau (durée de bannissement restante) - [actions]</b>.<br />Les adresses IP mises en file d'attente pour être dé-bannies seront supprimées de la liste de bannissement dans quelques secondes.<br />Les étiquettes rouges indiquent les bannissement permanent par liste noire.",
"ban_list_info": "Consultez la liste des adresses IP bannies ci-dessous : <b>réseau (durée de bannissement restante) - [actions]</b>.<br />Les adresses IP mises en file d'attente pour être dé-bannies seront supprimées de la liste de bannissement dans quelques secondes.<br />Les étiquettes rouges indiquent les bannissements permanent par liste noire.",
"change_logo": "Changer de logo",
"configuration": "Configuration",
"convert_html_to_text": "Convertir le code HTML en texte brut",
"credentials_transport_warning": "<b>Attention</b> : Lajout dune nouvelle entrée de carte de transport mettra à jour les informations didentification pour toutes les entrées avec une colonne nexthop.",
"credentials_transport_warning": "<b>Attention</b> : Lajout dune nouvelle entrée de carte de transport mettra à jour les informations didentification pour toutes les entrées avec une colonne nexthop.",
"customer_id": "ID client",
"customize": "Personnaliser",
"destination": "Destination",
@@ -184,7 +184,7 @@
"f2b_netban_ipv4": "Taille du sous-réseau IPv4 pour l'application du bannissement (8-32)",
"f2b_netban_ipv6": "Taille du sous-réseau IPv6 pour l'application du bannissement (8-128)",
"f2b_parameters": "Paramètres Fail2ban",
"f2b_regex_info": "Logs pris en compte : SOGo, Postfix, Dovecot, PHP-FPM.",
"f2b_regex_info": "Logs pris en compte : SOGo, Postfix, Dovecot, PHP-FPM.",
"f2b_retry_window": "Fenêtre de nouvel essai pour le nb max. de tentatives",
"f2b_whitelist": "Réseaux/hôtes en liste blanche",
"filter_table": "Table de filtrage",
@@ -200,19 +200,19 @@
"host": "Hôte",
"html": "HTML",
"import": "Importer",
"import_private_key": "Importer la clè privée",
"import_private_key": "Importer la clé privée",
"in_use_by": "Utilisé par",
"inactive": "Inactif",
"include_exclude": "Inclure/Exclure",
"include_exclude_info": "Par défaut - sans sélection - <b>toutes les boîte de réception</b> sont adressées",
"includes": "Inclure ces destinataires",
"last_applied": "Dernière application",
"license_info": "Une licence nest pas requise, mais contribue au développement.<br><a href=\"https://www.servercow.de/mailcow?lang=en#sal\" target=\"_blank\" alt=\"SAL order\">Enregistrer votre GUID ici</a> or <a href=\"https://www.servercow.de/mailcow?lang=en#support\" target=\"_blank\" alt=\"Support order\">acheter le support pour votre intallation Mailcow.</a>",
"license_info": "Une licence nest pas requise, mais contribue au développement.<br><a href=\"https://www.servercow.de/mailcow?lang=en#sal\" target=\"_blank\" alt=\"SAL order\">Enregistrer votre GUID ici</a> ou <a href=\"https://www.servercow.de/mailcow?lang=en#support\" target=\"_blank\" alt=\"Support order\">acheter le support pour votre installation mailcow.</a>",
"link": "Lien",
"loading": "Veuillez patienter…",
"logo_info": "Votre image sera redimensionnée à une hauteur de 40 pixels pour la barre de navigation du haut et à un maximum de 250 pixels en largeur pour la page d'accueil. Un graphique extensible est fortement recommandé.",
"lookup_mx": "Faire correspondre la destination à MX (<code>.*\\.google\\.com</code> pour acheminer tous les messages ciblés vers un MX se terminant par google.com sur ce tronçon)",
"main_name": "\"mailcow UI\" nom",
"main_name": "Nom « mailcow UI »",
"merged_vars_hint": "Les lignes grisées ont été importées depuis <code>vars.(local.)inc.php</code> et ne peuvent pas être modifiées.",
"message": "Message",
"message_size": "Taille du message",
@@ -223,7 +223,7 @@
"no_record": "Aucun enregistrement",
"oauth2_client_id": "Client ID",
"oauth2_client_secret": "Secret client",
"oauth2_info": "L'implémentation OAuth2 prend en charge le type d'autorisation \"Authorization Code\" et émet des jetons d'actualisation.<br>\nLe serveur émet également automatiquement de nouveaux jetons d'actualisation, après qu'un jeton d'actualisation a été utilisé.<br><br>\n→ La portée par défaut est <i>profile</i>. Seuls les utilisateurs d'une boîte de réception peuvent être authentifiés par rapport à OAuth2. Si le paramètre scope est omis, il revient au <i>profile</i>.<br>\n→ Le paramètre <i>state</i> doit être envoyé par le client dans le cadre de la demande d'autorisation.<br><br>\nChemins d'accès aux requêtes vers l'API OAuth <br>\n<ul>\n <li>Point de terminaison d'autorisation : <code>/oauth/authorize</code></li>\n <li>Point de terminaison du jeton : <code>/oauth/token</code></li>\n <li>Page de ressource : <code>/oauth/profile</code></li>\n</ul>\nLa régénération du secret client ne fera pas expirer les codes d'autorisation existants, mais ils ne pourront pas renouveler leur jeton.<br><br>\nLa révocation des jetons clients entraînera la fin immédiate de toutes les sessions actives. Tous les clients doivent se ré-authentifier.",
"oauth2_info": "L'implémentation OAuth2 prend en charge le type d'autorisation « Authorization Code » et émet des jetons d'actualisation.<br>\nLe serveur émet également automatiquement de nouveaux jetons d'actualisation, après qu'un jeton d'actualisation a été utilisé.<br><br>\n→ La portée par défaut est <i>profile</i>. Seuls les utilisateurs d'une boîte de réception peuvent être authentifiés par rapport à OAuth2. Si le paramètre scope est omis, il revient au <i>profile</i>.<br>\n→ Le paramètre <i>state</i> doit être envoyé par le client dans le cadre de la demande d'autorisation.<br><br>\nChemins d'accès aux requêtes vers l'API OAuth <br>\n<ul>\n <li>Point de terminaison d'autorisation : <code>/oauth/authorize</code></li>\n <li>Point de terminaison du jeton : <code>/oauth/token</code></li>\n <li>Page de ressource : <code>/oauth/profile</code></li>\n</ul>\nLa régénération du secret client ne fera pas expirer les codes d'autorisation existants, mais ils ne pourront pas renouveler leur jeton.<br><br>\nLa révocation des jetons clients entraînera la fin immédiate de toutes les sessions actives. Tous les clients doivent se ré-authentifier.",
"oauth2_redirect_uri": "URI de redirection",
"oauth2_renew_secret": "Générer un nouveau secret client",
"oauth2_revoke_tokens": "Révoquer tous les jetons",
@@ -233,19 +233,19 @@
"priority": "Priorité",
"private_key": "Clé privée",
"quarantine": "Quarantaine",
"quarantine_bcc": "Envoyer une copie de toutes les notifications (BCC) à ce destinataire:<br><small>Laisser vide pour le désactiver. <b>Courrier non signé et non coché. Doit être livré en linterne seulement.</b></small>",
"quarantine_bcc": "Envoyer une copie de toutes les notifications (BCC) à ce destinataire :<br><small>Laisser vide pour le désactiver. <b>Courrier non signé et non coché. Doit être livré en interne seulement.</b></small>",
"quarantine_exclude_domains": "Exclure les domaines et les alias de domaine",
"quarantine_max_age": "Âge maximun en jour(s)<br><small>La valeur doit être égale ou supérieure à 1 jour.</small>",
"quarantine_max_size": "Taille maximum en Mo (les éléments plus grands sont mis au rebut):<br><small>0 ne signifie <b>pas</b> illimité.</small>",
"quarantine_max_score": "Ignorer la notification si le score de spam est au dessus de cette valeur :<br><small>Par défaut : 9999.0</small>",
"quarantine_max_size": "Taille maximum en Mio (les éléments plus grands sont mis au rebut) :<br><small>0 ne signifie <b>pas</b> illimité.</small>",
"quarantine_max_score": "Ignorer la notification si le score de spam est au dessus de cette valeur :<br><small>Par défaut : 9999.0</small>",
"quarantine_notification_html": "Modèle de courriel de notification :<br><small>Laisser vide pour restaurer le modèle par défaut.</small>",
"quarantine_notification_sender": "Notification par courriel de lexpéditeur",
"quarantine_notification_subject": "Objet du courriel de notification",
"quarantine_redirect": "<b>Rediriger toutes les notifications</b> vers ce destinataire:<br><small>Laisser vide pour désactiver. <b>Courrier non signé et non coché. Doit être livré en interne seulement.</b></small>",
"quarantine_redirect": "<b>Rediriger toutes les notifications</b> vers ce destinataire :<br><small>Laisser vide pour désactiver. <b>Courrier non signé et non coché. Doit être livré en interne seulement.</b></small>",
"quarantine_release_format": "Format des éléments diffusés",
"quarantine_release_format_att": "En pièce jointe",
"quarantine_release_format_raw": "Original non modifié",
"quarantine_retention_size": "Rétentions par boîte de réception:<br><small>0 indique <b>inactive</b>.</small>",
"quarantine_retention_size": "Rétentions par boîte de réception :<br><small>0 indique <b>inactive</b>.</small>",
"quota_notification_html": "Modèle de courriel de notification :<br><small>Laisser vide pour restaurer le modèle par défaut.</small>",
"quota_notification_sender": "Notification par courriel de lexpéditeur",
"quota_notification_subject": "Objet du courriel de notification",
@@ -263,7 +263,7 @@
"relay_from": "\"De:\" adresse",
"relay_run": "Lancer le test",
"relayhosts": "Transports dépendant de lexpéditeur",
"relayhosts_hint": "Définir les transports dépendant de lexpéditeur pour pouvoir les sélectionner dans un dialogue de configuration de domaines.<br>\n Le service de transport est toujours \"SMTP:\" et va donc essayer TLS lorsquil est proposé. Le TLS encapsulé (SMTPS) nest pas pris en charge. Il est tenu compte de la définition de la politique TLS pour chaque utilisateur sortant.<br>\n Affecte les domaines sélectionnés, y compris les domaines alias.",
"relayhosts_hint": "Définir les transports dépendant de lexpéditeur pour pouvoir les sélectionner dans un dialogue de configuration de domaines.<br>\n Le service de transport est toujours « smtp: » et va donc essayer TLS lorsquil est proposé. Le TLS encapsulé (SMTPS) nest pas pris en charge. Il est tenu compte de la définition de la politique TLS pour chaque utilisateur sortant.<br>\n Affecte les domaines sélectionnés, y compris les domaines alias.",
"remove": "Supprimer",
"remove_row": "Supprimer la ligne",
"reset_default": "Réinitialisation à la valeur par défaut",
@@ -274,7 +274,7 @@
"rsetting_desc": "Description courte",
"rsetting_no_selection": "Veuillez sélectionner une règle",
"rsetting_none": "Pas de règles disponibles",
"rsettings_insert_preset": "Insérer un exemple de préréglage \"%s\"",
"rsettings_insert_preset": "Insérer un exemple de préréglage « %s »",
"rsettings_preset_1": "Désactiver tout sauf DKIM et la limite d'envoi pour les utilisateurs authentifiés",
"rsettings_preset_2": "Les postmasters veulent du spam",
"rsettings_preset_3": "Autoriser uniquement des expéditeurs particuliers pour une boîte de réception (c.-à-d. utilisation comme boîte de réception interne seulement)",
@@ -286,7 +286,7 @@
"rspamd_settings_map": "Carte des paramètres Rspamd",
"sal_level": "Niveau Moo",
"save": "Enregistrer les modifications",
"search_domain_da": "Recherche domaines",
"search_domain_da": "Rechercher des domaines",
"send": "Envoyer",
"sender": "Expéditeur",
"service_id": "ID du service",
@@ -297,11 +297,11 @@
"text": "Texte",
"time": "Heure",
"title": "Titre",
"title_name": "\"mailcow UI\" titre du site web",
"title_name": "Titre du site web « mailcow UI »",
"to_top": "Retour en haut",
"transport_dest_format": "Syntaxe : example.org, .example.org, *, box@example.org (les valeurs multiples peuvent être séparées par des virgules)",
"transport_maps": "Plans de transport",
"transports_hint": "→ Une entrée de carte de transport <b>annule</b> une carte de transport dépendante de lexpéditeur</b>.<br>\n→ Les transports basés sur le MX sont préférables.<br>\n→ Les paramètres de politique TLS sortants par utilisateur sont ignorés et ne peuvent être appliqués que par les entrées de carte de politique TLS.<br>\n→ Pour chaque transports défini, le servie de transports sera \"smtp:\", TLS sera essayé lorsque disponible. Le Wrapped TLS (SMTPS) nest pas pris en charge.<br>\n→ Les adresses qui correspondent à\"/localhost$/\" seront toujours transportées via \"local:\", donc une destination \"*\" ne s'applique pas à ces adresses.<br>\n→ Pour déterminer les informations d'identification dans l'exemple suivant \"[host]:25\", Postfix va <b>toujours</b> faire une requête pour \"host\" avant de chercher \"[host]:25\". Ce comportement rend impossible lutilisation \"host\" et \"[host]:25\" en même temps.",
"transports_hint": "→ Une entrée de carte de transport <b>annule</b> une carte de transport dépendante de lexpéditeur</b>.<br>\n→ Les transports basés sur le MX sont préférables.<br>\n→ Les paramètres de politique TLS sortants par utilisateur sont ignorés et ne peuvent être appliqués que par les entrées de carte de politique TLS.<br>\n→ Pour chaque transports défini, le servie de transports sera « smtp: », TLS sera essayé lorsque disponible. Le Wrapped TLS (SMTPS) nest pas pris en charge.<br>\n→ Les adresses qui correspondent à « /localhost$/ » seront toujours transportées via « local: », donc une destination « * » ne s'applique pas à ces adresses.<br>\n→ Pour déterminer les informations d'identification dans l'exemple suivant « [host]:25 », Postfix va <b>toujours</b> faire une requête pour « host » avant de chercher « [host]:25 ». Ce comportement rend impossible lutilisation de « host » et « [host]:25 » en même temps.",
"ui_footer": "Pied de page (HTML autorisé)",
"ui_header_announcement": "Annonces",
"ui_header_announcement_active": "Définir lannonce active",
@@ -352,7 +352,14 @@
"password_reset_tmpl_html": "Modèle HTML",
"password_reset_tmpl_text": "Modèle en texte",
"restore_template": "Laisser vide pour restaurer le modèle par défaut.",
"admins_ldap": "Si aucune adresse de messagerie de récupération n'est fournie, cette fonction ne peut pas être utilisée."
"admins_ldap": "Administrateurs LDAP",
"options": "Options",
"ip_check_opt_in": "Utiliser le service tiers <strong>ipv4.mailcow.email</strong> et <strong>ipv6.mailcow.email</strong> pour résoudre les adresses IP externes.",
"queue_unban": "débannir",
"service": "Service",
"success": "Succès",
"cors_settings": "Paramètres CORS",
"login_time": "Horodatage de connexion"
},
"danger": {
"access_denied": "Accès refusé ou données de formulaire non valides",
@@ -370,37 +377,37 @@
"comment_too_long": "Le commentaire est trop long, 160 caractère max sont permis",
"defquota_empty": "Le quota par défaut par boîte de réception doit pas être 0.",
"description_invalid": "La description des ressources pour %s est non valide",
"dkim_domain_or_sel_exists": "Une clé DKIM pour \"%s\" existe et ne sera pas écrasée",
"dkim_domain_or_sel_invalid": "Domaine ou sélection DKIM non valide : %s",
"dkim_domain_or_sel_exists": "Une clé DKIM pour « %s » existe et ne sera pas écrasée",
"dkim_domain_or_sel_invalid": "Domaine ou sélecteur DKIM non valide : %s",
"domain_cannot_match_hostname": "Le domaine ne correspond pas au nom dhôte",
"domain_exists": "Le domaine %s exite déjà",
"domain_invalid": "Le mom de domaine est vide ou non valide",
"domain_invalid": "Le nom de domaine est vide ou non valide",
"domain_not_empty": "Impossible de supprimer le domaine non vide %s",
"domain_not_found": "Le domaine %s est introuvable",
"domain_quota_m_in_use": "Le quota de domaine doit être supérieur ou égal à %s Mo",
"extra_acl_invalid": "L'adresse de lexpéditeur externe \"%s\" est non valide",
"extra_acl_invalid_domain": "L'expéditeur externe \"%s\" utilise un domaine non valide",
"domain_quota_m_in_use": "Le quota de domaine doit être supérieur ou égal à %s Mio",
"extra_acl_invalid": "L'adresse de lexpéditeur externe « %s » est non valide",
"extra_acl_invalid_domain": "L'expéditeur externe « %s » utilise un domaine non valide",
"file_open_error": "Le fichier ne peut pas être ouvert pour l'écriture",
"filter_type": "Type de fltre erroné",
"from_invalid": "Expéditeur ne peut pas être vide",
"global_filter_write_error": "Impossible décrire le fichier de filtre : %s",
"global_filter_write_error": "Impossible décrire le fichier de filtre : %s",
"global_map_invalid": "ID de carte globale %s non valide",
"global_map_write_error": "Impossible décrire lID de la carte globale %s : %s",
"global_map_write_error": "Impossible décrire lID de la carte globale %s : %s",
"goto_empty": "Une adresse alias doit contenir au moins une adresse 'goto'valide",
"goto_invalid": "Adresse Goto %s non valide",
"ham_learn_error": "Erreur d'apprentissage Ham : %s",
"imagick_exception": "Erreur : Exception Imagick lors de la lecture de limage",
"ham_learn_error": "Erreur d'apprentissage Ham : %s",
"imagick_exception": "Erreur : Exception Imagick lors de la lecture de limage",
"img_invalid": "Impossible de valider le fichier image",
"img_tmp_missing": "Impossible de valider le fichier image : Fichier temporaire introuvable",
"img_tmp_missing": "Impossible de valider le fichier image : Fichier temporaire introuvable",
"invalid_bcc_map_type": "Type de carte BCC non valide",
"invalid_destination": "Le format de la destination \"%s\" est non valide",
"invalid_destination": "Le format de la destination « %s » est non valide",
"invalid_filter_type": "Type de filtre non valide",
"invalid_host": "Hôte non valide spécifié : %s",
"invalid_host": "Hôte non valide spécifié : %s",
"invalid_mime_type": "Type mime non valide",
"invalid_nexthop": "Le format de saut suivant est non valide",
"invalid_nexthop_authenticated": "Next hop existe avec différents identifiants, veuillez dabord mettre à jour les identifiants existants pour ce prochain saut.",
"invalid_recipient_map_new": "Nouveau destinataire spécifié non valide : %s",
"invalid_recipient_map_old": "Destinataire original spécifié non valide : %s",
"invalid_recipient_map_new": "Nouveau destinataire spécifié non valide : %s",
"invalid_recipient_map_old": "Destinataire original spécifié non valide : %s",
"ip_list_empty": "La liste des adresses IP autorisées ne peut pas être vide",
"is_alias": "%s est déjà connu comme une adresse alias",
"is_alias_or_mailbox": "%s est déjà connu comme un alias, une boîte de réception ou une adresse alias développée à partir dun domaine alias.",
@@ -409,19 +416,19 @@
"login_failed": "La connexion a échoué",
"mailbox_defquota_exceeds_mailbox_maxquota": "Le quota par défaut dépasse la limite maximale du quota",
"mailbox_invalid": "Le nom de la boîte de réception n'est pas valide",
"mailbox_quota_exceeded": "Le quota dépasse la limite du domaine (max. %d Mo)",
"mailbox_quota_exceeded": "Le quota dépasse la limite du domaine (max. %d Mio)",
"mailbox_quota_exceeds_domain_quota": "Le quota maximal dépasse la limite du quota de domaine",
"mailbox_quota_left_exceeded": "Espace libre insuffisant (espace libre : %d Mio)",
"mailbox_quota_left_exceeded": "Espace libre insuffisant (espace libre : %d Mio)",
"mailboxes_in_use": "Le max. des boîtes de réception doit être supérieur ou égal à %d",
"malformed_username": "Nom dutilisateur malformé",
"map_content_empty": "Le contenu de la carte ne peut pas être vide",
"max_alias_exceeded": "Le nombre max. d'aliases est dépassé",
"max_alias_exceeded": "Le nombre max. d'alias est dépassé",
"max_mailbox_exceeded": "Le nombre max. de boîte de réception est dépassé (%d of %d)",
"max_quota_in_use": "Le quota de la boîte de réception doit être supérieur ou égal à %d Mo",
"max_quota_in_use": "Le quota de la boîte de réception doit être supérieur ou égal à %d Mio",
"maxquota_empty": "Le quota maximum par boîte de réception ne doit pas être de 0.",
"mysql_error": "Erreur MySQL : %s",
"nginx_reload_failed": "Le rechargement de Nginx a échoué : %s",
"network_host_invalid": "Réseau ou hôte non valide : %s",
"mysql_error": "Erreur MySQL : %s",
"nginx_reload_failed": "Le rechargement de Nginx a échoué : %s",
"network_host_invalid": "Réseau ou hôte non valide : %s",
"next_hop_interferes": "%s interfère avec le nexthop %s",
"next_hop_interferes_any": "Un saut suivant existant interfère avec %s",
"no_user_defined": "Aucun utilisateur défini",
@@ -432,15 +439,15 @@
"password_mismatch": "Le mot de passe de confirmation ne correspond pas",
"policy_list_from_exists": "Un enregistrement avec ce nom existe déjà",
"policy_list_from_invalid": "Le format de lenregistrement est invalide",
"private_key_error": "Erreur de clé privée : %s",
"private_key_error": "Erreur de clé privée : %s",
"pushover_credentials_missing": "Jeton Pushover ou clé manquante",
"pushover_key": "La clé Pushover a un mauvais format",
"pushover_token": "Le jeton Pushover a un mauvais format",
"quota_not_0_not_numeric": "Le quota doit être numerique et >= 0",
"recipient_map_entry_exists": "Une entrée dans la carte du bénéficiaire \"%s\" existe",
"redis_error": "Erreur Redis : %s",
"recipient_map_entry_exists": "Une entrée dans la carte du destinataire « %s » existe",
"redis_error": "Erreur Redis : %s",
"relayhost_invalid": "La saisie de la carte %s est invalide",
"release_send_failed": "Le message na pas pu être diffusé : %s",
"release_send_failed": "Le message na pas pu être diffusé : %s",
"reset_f2b_regex": "Le filtre regex n'a pas pu être réinitialisé à temps, veuillez réessayer ou attendre quelques secondes de plus et recharger le site web.",
"resource_invalid": "Le nom de la resource %s n'est pas valide",
"rl_timeframe": "Le délai de la limite d'envoi est incorrect",
@@ -449,8 +456,8 @@
"sender_acl_invalid": "La valeur ACL de lexpéditeur %s est invalide",
"set_acl_failed": "Impossible de définir l'ACL",
"settings_map_invalid": "La carte des paramètres %s est invalide",
"sieve_error": "Erreur d'analyse syntaxique Sieve : %s",
"spam_learn_error": "Erreur d'apprentissage du spam : %s",
"sieve_error": "Erreur d'analyse syntaxique Sieve : %s",
"spam_learn_error": "Erreur d'apprentissage du spam : %s",
"subject_empty": "Le sujet ne peut pas être vide",
"target_domain_invalid": "Le domaine cible %s n'est pas valide",
"targetd_not_found": "Le domaine cible %s est introuvable",
@@ -459,19 +466,19 @@
"text_empty": "La zone texte ne peut pas être vide",
"tfa_token_invalid": "Le token TFA est invalide",
"tls_policy_map_dest_invalid": "La politique de destination n'est pas valide",
"tls_policy_map_entry_exists": "Une entrée de carte de politique \"%s\" existe",
"tls_policy_map_entry_exists": "Une entrée de carte de politique « %s » existe",
"tls_policy_map_parameter_invalid": "Le paramètre Policy est invalide",
"totp_verification_failed": "Echec de la vérification TOTP",
"transport_dest_exists": "La destination de transport \"%s\" existe",
"webauthn_verification_failed": "Échec de la vérification WebAuthn : %s",
"fido2_verification_failed": "La vérification FIDO2 a échoué : %s",
"transport_dest_exists": "La destination de transport « %s » existe",
"webauthn_verification_failed": "Échec de la vérification WebAuthn : %s",
"fido2_verification_failed": "La vérification FIDO2 a échoué : %s",
"unknown": "Une erreur inconnue est survenue",
"unknown_tfa_method": "Methode TFA inconnue",
"unlimited_quota_acl": "Quota illimité interdit par les ACL",
"username_invalid": "Le nom d'utilisateur %s ne peut pas être utilisé",
"validity_missing": "Veuillez attribuer une période de validité",
"value_missing": "Veuillez fournir toutes les valeurs",
"yotp_verification_failed": "La vérification Yubico OTP a échoué : %s",
"yotp_verification_failed": "La vérification Yubico OTP a échoué : %s",
"webauthn_authenticator_failed": "L'authentificateur sélectionné est introuvable",
"demo_mode_enabled": "Le mode de démonstration est activé",
"template_exists": "Le modèle %s existe déjà",
@@ -479,7 +486,7 @@
"template_name_invalid": "Le nom du modèle est invalide",
"img_dimensions_exceeded": "L'image dépasse les dimensions maximales",
"img_size_exceeded": "L'image dépasse la taille maximale de fichier",
"webauthn_publickey_failed": "Aucune clé publique n'a été stockée pour l'authentificateur sélectionné.",
"webauthn_publickey_failed": "Aucune clé publique n'a été stockée pour l'authentificateur sélectionné",
"cors_invalid_method": "Allow-Method specifiée invalide",
"cors_invalid_origin": "Allow-Origin spécifiée invalide",
"extended_sender_acl_denied": "ACL manquante pour définir les adresses des expéditeurs externes",
@@ -495,20 +502,17 @@
"chart_this_server": "Graphique (ce serveur)",
"containers_info": "Informations des conteneurs",
"disk_usage": "Utilisation du disque",
"external_logs": "Logs externe",
"external_logs": "Logs externes",
"history_all_servers": "Historique (tous les serveurs)",
"in_memory_logs": "Logs En-mémoire",
"jvm_memory_solr": "Utilisation mémoire JVM",
"log_info": "<p>Les logs <b>En-mémoire</b> Mailcow sont collectés dans des listes Redis et découpées en LOG_LINES (%d) chaque minute pour réduire la charge.\n <br>Les logs En-mémoire ne sont pas destinés à être persistants. Toutes les applications qui se connectent en mémoire, se connectent également au démon Docker, et donc au pilote de journalisation par défaut.\n <br>Le type de journal en mémoire doit être utilisé pour déboguer les problèmes mineurs avec les conteneurs.</p>\n <p><b>Les logs externes</b> sont collectés via l'API de l'application concernée.</p>\n <p>Les journaux <b>statiques</b> sont principalement des journaux dactivité, qui ne sont pas enregistrés dans Dockerd, mais qui doivent toujours être persistants (sauf pour les logs API).</p>",
"logs": "Logs",
"restart_container": "Redémarrer",
"solr_dead": "Solr est en cours de démarrage, désactivé ou mort.",
"docs": "Docs",
"last_modified": "Dernière modification",
"online_users": "Utilisateurs en ligne",
"size": "Taille",
"started_at": "Démarré à",
"solr_status": "Etat Solr",
"uptime": "Disponibilité",
"started_on": "Démarré à",
"static_logs": "Logs statiques",
@@ -518,7 +522,19 @@
"wip": "En cours de réalisation",
"architecture": "Architecture",
"cores": "Cœurs",
"current_time": "Heure du système"
"current_time": "Heure du système",
"container_disabled": "Conteneur arrêté ou désactivé",
"error_show_ip": "Impossible de résoudre les adresses IP publiques",
"no_update_available": "Le système utilise la version la plus récente",
"container_running": "En cours d'exécution",
"container_stopped": "Arrêté",
"memory": "Mémoire",
"login_time": "Horodatage",
"service": "Service",
"success": "Succès",
"update_available": "Une mise à jour est disponible",
"update_failed": "Impossible de vérifier la présence d'une mise à jour",
"show_ip": "Afficher l'IP publique"
},
"diagnostics": {
"cname_from_a": "Valeur dérivée de lenregistrement A/AAAA. Ceci est supporté tant que lenregistrement indique la bonne ressource.",
@@ -529,7 +545,7 @@
"dns_records_name": "Nom",
"dns_records_status": "État courant",
"dns_records_type": "Type",
"optional": "Cet enregistrement est optionel."
"optional": "Cet enregistrement est optionnel."
},
"edit": {
"active": "Actif",
@@ -540,7 +556,7 @@
"allowed_protocols": "Protocoles autorisés",
"app_name": "Nom de l'application",
"app_passwd": "Mot de passe de l'application",
"automap": "Essayer dautomatiser les dossiers (\"Sent items\", \"Sent\" => \"Sent\" etc.)",
"automap": "Tenter de cibler automatiquement les dossiers (« Sent items », « Sent » => « Sent » etc.)",
"backup_mx_options": "Options Backup MX",
"bcc_dest_format": "La destination BCC doit être une seule adresse de courriel valide.",
"client_id": "ID client",
@@ -548,7 +564,7 @@
"comment_info": "Un commentaire privé nest pas visible pour lutilisateur, tandis quun commentaire public est affiché comme infobulle lorsque vous le placez dans un aperçu des utilisateurs",
"delete1": "Supprimer de la source une fois terminé",
"delete2": "Supprimer les messages sur la destination qui ne sont pas sur la source",
"delete2duplicates": "Supprimer les doublons à destination",
"delete2duplicates": "Supprimer les doublons sur la destination",
"delete_ays": "Veuillez confirmer le processus de suppression.",
"description": "Description",
"disable_login": "Refuser louverture de session (le courrier entrant est toujours accepté)",
@@ -577,10 +593,10 @@
"mailbox_quota_def": "Quota par défaut de la boîte de réception",
"max_aliases": "Nombre max. d'alias",
"max_mailboxes": "Nombre max. de boîte de réception possibles",
"max_quota": "Quota max. par boîte de réception (Mo)",
"max_quota": "Quota max. par boîte de réception (Mio)",
"maxage": "Âge maximal en jours des messages qui seront consultés à distance<br><small>(0 = ignorer la durée)</small>",
"maxbytespersecond": "Octets max. par seconde <br><small>(0 = pas de limite)</small>",
"mbox_rl_info": "Cette limite d'envoi est appliquée au nom de connexion SASL, elle correspond à toute adresse \"from\" utilisée par lutilisateur connecté. Une limite d'envoi pour les boîtes de réception remplace une limite d'envoi pour lensemble du domaine.",
"mbox_rl_info": "Cette limite d'envoi est appliquée au nom de connexion SASL, elle correspond à toute adresse « from » utilisée par lutilisateur connecté. Une limite d'envoi pour les boîtes de réception remplace une limite d'envoi pour lensemble du domaine.",
"mins_interval": "Intervalle (min)",
"multiple_bookings": "Réservations multiples",
"nexthop": "Saut suivant",
@@ -598,11 +614,11 @@
"pushover_title": "Titre de la notification",
"pushover_vars": "Lorsque aucun filtre dexpéditeur nest défini, tous les messages seront considérés.<br>Les filtres Regex ainsi que les vérifications exactes de lexpéditeur peuvent être définis individuellement et seront considérés de façon séquentielle. Ils ne dépendent pas les uns des autres.<br>Variables utilisables pour le texte et le titre (veuillez prendre note des politiques de protection des données)",
"pushover_verify": "Vérifier les informations d'identification",
"quota_mb": "Quota (Mo)",
"quota_mb": "Quota (Mio)",
"ratelimit": "Limite d'envoi",
"redirect_uri": "URL de redirection/callback",
"relay_all": "Relayer tous les destinataires",
"relay_all_info": "↪ Si vous <b>ne choisissez pas</b> de relayer tous les destinataires, vous devrez ajouter une boîte de réception (\"aveugle\") pour chaque destinataire qui devrait être relayé.",
"relay_all_info": "↪ Si vous <b>ne choisissez pas</b> de relayer tous les destinataires, vous devrez ajouter une boîte de réception (« aveugle ») pour chaque destinataire qui devrait être relayé.",
"relay_domain": "Relayer ce domaine",
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Info</div> Vous pouvez définir des cartes de transport vers une destination personnalisée pour ce domaine. Si elle nest pas configurée, une recherche MX sera effectuée.",
"relay_unknown_only": "Relais des boîtes de réception non existantes seulement. Les boîtes de réception existantes seront livrées localement.",
@@ -613,7 +629,7 @@
"scope": "Portée",
"sender_acl": "Permettre denvoyer comme",
"sender_acl_disabled": "<span class=\"badge fs-6 bg-danger\">Le contrôle de lexpéditeur est désactivé</span>",
"sender_acl_info": "Si lutilisateur de la boîte de réception A est autorisé à envoyer en tant quutilisateur de la boîte de réception B, ladresse de lexpéditeur nest pas automatiquement affichée comme sélectionnable du champ \"de\" dans SOGo.<br>\n Lutilisateur B de la boîte de réception doit créer une délégation dans Sogo pour permettre à lutilisateur A de la boîte de réception de sélectionner son adresse comme expéditeur. Pour déléguer une boîte de réception dans Sogo, utilisez le menu (trois points) à droite du nom de votre boîte dans le coin supérieur gauche dans la vue de courrier. Ce comportement ne sapplique pas aux adresses alias.",
"sender_acl_info": "Si lutilisateur de la boîte de réception A est autorisé à envoyer en tant quutilisateur de la boîte de réception B, ladresse de lexpéditeur nest pas automatiquement affichée comme sélectionnable du champ « de » dans SOGo.<br>\n Lutilisateur B de la boîte de réception doit créer une délégation dans SOGo pour permettre à lutilisateur A de la boîte de réception de sélectionner son adresse comme expéditeur. Pour déléguer une boîte de réception dans SOGo, utilisez le menu (trois points) à droite du nom de votre boîte dans le coin supérieur gauche dans la vue de courrier. Ce comportement ne sapplique pas aux adresses alias.",
"sieve_desc": "Description courte",
"sieve_type": "Type de filtre",
"skipcrossduplicates": "Ignorer les messages en double dans les dossiers (premier arrivé, premier servi)",
@@ -641,15 +657,15 @@
"domain_footer_info_vars": {
"from_addr": "{= from_addr =} - Partie de l'enveloppe relative à l'adresse de provenance",
"from_domain": "{= from_domain =} - Partie de l'enveloppe provenant du domaine",
"custom": "{= foo =} - Si la boîte de réception possède l'attribut personnalisé \"foo\" avec la valeur \"bar\", elle renvoie \"bar\"",
"custom": "{= foo =} - Si la boîte de réception possède l'attribut personnalisé « foo » avec la valeur « bar », elle renvoie « bar »",
"auth_user": "{= auth_user =} - Nom d'utilisateur authentifié spécifié par un MTA",
"from_user": "{= from_user =} -La partie utilisateur de l'enveloppe, par exemple, pour \"moo@mailcow.tld\", renvoie \"moo\"",
"from_name": "{= from_name =} - À partir du nom de l'enveloppe, par exemple, pour \"Mailcow &lt;moo@mailcow.tld&gt ;\" on obtient \"Mailcow\""
"from_user": "{= from_user =} -La partie utilisateur de l'enveloppe, par exemple, pour « moo@mailcow.tld », renvoie « moo »",
"from_name": "{= from_name =} - À partir du nom de l'enveloppe, par exemple, pour « Mailcow &lt;moo@mailcow.tld&gt ; » on obtient « Mailcow »"
},
"domain_footer_skip_replies": "Ignorer le pied de page des courriels de réponse",
"domain_footer": "Pied de page du domaine",
"domain_footer_html": "Pied de page HTML",
"domain_footer_info": "Les pieds de page du domaine sont ajoutés à tous les courriels sortants associés à une adresse au sein de ce domaine. <br> Les variables suivantes peuvent être utilisées pour le pied de page :",
"domain_footer_info": "Les pieds de page du domaine sont ajoutés à tous les courriels sortants associés à une adresse au sein de ce domaine. <br> Les variables suivantes peuvent être utilisées pour le pied de page :",
"domain_footer_plain": "Pied de page",
"app_passwd_protocols": "Protocoles autorisés pour le mot de passe d'application",
"created_on": "Créé le",
@@ -658,7 +674,15 @@
"quota_warning_bcc_info": "Les avertissements seront envoyés en copies séparées aux destinataires suivants. Le sujet sera précédé du nom d'utilisateur correspondant entre parenthèses, par exemple : <code>Avertissement sur les quotas (user@example.com)</code>.",
"sogo_access_info": "L'authentification unique à partir de l'interface de messagerie reste opérationnelle. Ce paramètre n'affecte pas l'accès à tous les autres services et ne supprime ni, ne modifie le profil SOGo existant d'un utilisateur.",
"admin": "Modifier l'administrateur",
"password_recovery_email": "Adresse email de récupération"
"password_recovery_email": "Adresse email de récupération",
"mailbox_rename_title": "Nouveau nom de la partie locale de la boîte de réception",
"mailbox_rename": "Renommer la boîte de réception",
"mailbox_rename_agree": "J'ai fait une sauvegarde.",
"mailbox_rename_warning": "IMPORTANT ! Faites une sauvegarde avant de renommer la boîte de réception.",
"mailbox_rename_alias": "Créer un alias automatiquement",
"sogo_access": "Autoriser la connexion directe à SOGo",
"pushover": "Pushover",
"pushover_sound": "Son"
},
"footer": {
"cancel": "Annuler",
@@ -672,7 +696,8 @@
"restart_container_info": "<b>Important :</b> Un redémarrage en douceur peut prendre un certain temps, veuillez attendre quil soit terminé.",
"restart_now": "Redémarrer maintenant",
"restarting_container": "Redémarrage du conteneur, cela peut prendre un certain temps",
"nothing_selected": "Rien n'est sélectionné"
"nothing_selected": "Rien n'est sélectionné",
"hibp_check": "Vérifier avec haveibeenpwned.com"
},
"header": {
"administration": "Configuration & détails",
@@ -683,7 +708,8 @@
"quarantine": "Quarantaine",
"restart_netfilter": "Redémarrer Netfilter",
"restart_sogo": "Redémarrer SOGo",
"user_settings": "Paramètres utilisateur"
"user_settings": "Paramètres utilisateur",
"mailcow_system": "Système"
},
"info": {
"awaiting_tfa_confirmation": "En attente de la confirmation de TFA",
@@ -723,9 +749,9 @@
"add_tls_policy_map": "Ajouter la carte de la politique des TLS",
"address_rewriting": "Réécriture de ladresse",
"alias": "Alias",
"alias_domain_alias_hint": "Les alias <b>ne sont pas</b> appliqués automatiquement sur les alias de domaine. Un alias d'adresse <code>my-alias@domain</code> <b>ne couvre pas</b> l'adresse <code>my-alias@alias-domain</code> (où \"alias-domain\" est un alias imaginaire pour \"domain\").<br>Veuillez utiliser un filtre à tamis pour rediriger le courrier vers une boîte de réception externe (voir l'onglet « Filtres » ou utilisez SOGo → Transférer).",
"alias_domain_alias_hint": "Les alias <b>ne sont pas</b> appliqués automatiquement sur les alias de domaine. Un alias d'adresse <code>my-alias@domain</code> <b>ne couvre pas</b> l'adresse <code>my-alias@alias-domain</code> (où « alias-domain » est un alias imaginaire pour « domain »).<br>Veuillez utiliser un filtre sieve pour rediriger le courrier vers une boîte de réception externe (voir l'onglet « Filtres » ou utilisez SOGo → Transférer). Utilisez « Étendre l'alias aux alias de domaine » pour ajouter automatiquement les alias manquants.",
"alias_domain_backupmx": "Alias de domaine inactif pour le domaine relais",
"aliases": "Aliases",
"aliases": "Alias",
"allow_from_smtp": "Restreindre l'utilisation de <b>SMTP</b> à ces adresses IP",
"allow_from_smtp_info": "Laissez vide pour autoriser tous les expéditeurs.<br>Adresses IPv4/IPv6 et réseaux.",
"allowed_protocols": "Protocoles autorisés",
@@ -774,12 +800,12 @@
"hourly": "Toutes les heures",
"in_use": "Utilisé (%)",
"inactive": "Inactif",
"insert_preset": "Insérer un exemple de préréglage \"%s\"",
"insert_preset": "Insérer un exemple de préréglage « %s »",
"kind": "Type",
"last_mail_login": "Dernière connexion mail",
"last_modified": "Dernière modification",
"last_run": "Dernière exécution",
"last_run_reset": "Calendrier suivant",
"last_run_reset": "Exécuter maintenant",
"mailbox": "Boîte de réception",
"mailbox_defquota": "Taille de boîte de réception par défaut",
"mailbox_quota": "Taille max. dune boîte de réception",
@@ -818,7 +844,7 @@
"running": "En fonctionnement",
"set_postfilter": "Marquer comme postfiltre",
"set_prefilter": "Marquer comme préfiltre",
"sieve_info": "Vous pouvez stocker plusieurs filtres par utilisateur, mais un seul préfiltre et un seul postfiltre peuvent être actifs simultanément.<br>\nChaque filtre sera traité dans lordre décrit. Ni un script « rejeter » ni un « garder » narrêtera le traitement des autres scripts. Les modifications apportées aux scripts de tamis globaux déclencheront un redémarrage de Dovecot.<br><br>Préfiltre de tamis global → Préfiltre → Scripts utilisateur → Postfiltre → Postfiltre du tamis global",
"sieve_info": "Vous pouvez stocker plusieurs filtres par utilisateur, mais un seul préfiltre et un seul postfiltre peuvent être actifs simultanément.<br>\nChaque filtre sera traité dans lordre décrit. Ni un script en échec ni un « keep; » narrêtera le traitement des autres scripts. Les modifications apportées aux scripts sieve globaux déclencheront un redémarrage de Dovecot.<br><br>Préfiltre sieve global → Préfiltre → Scripts utilisateur → Postfiltre → Postfiltre sieve global",
"sieve_preset_1": "Jeter le courrier avec les types de fichiers dangereux probables",
"sieve_preset_2": "Toujours marquer l'adresse de courriel dun expéditeur spécifique comme vu",
"sieve_preset_3": "Jeter en silence, arrêter tout traitement supplémentaire par filtre sieve",
@@ -826,7 +852,7 @@
"sieve_preset_5": "Répondeur auto (vacances)",
"sieve_preset_6": "Rejeter le courrier avec réponse",
"sieve_preset_7": "Rediriger et garder/déposer",
"sieve_preset_8": "Rediriger les courriels d'un expéditeur spécifique, les marquer comme lus et les classer dans des sous-dossiers.",
"sieve_preset_8": "Rediriger les courriels d'un expéditeur spécifique, les marquer comme lus et les classer dans des sous-dossiers",
"sieve_preset_header": "Voir les exemples de préréglages ci-dessous. Pour plus de détails, voir <a href=\"https://en.wikipedia.org/wiki/Sieve_(mail_filtering_language)\" target=\"_blank\">Wikipédia</a>.",
"sogo_visible": "Alias visible dans SOGo",
"sogo_visible_n": "Masquer alias dans SOGo",
@@ -864,7 +890,22 @@
"mailbox_templates": "Modèle de boîte de réception",
"relay_unknown": "Relayer les boîtes de réception inconnues",
"all_domains": "Tous les domaines",
"syncjob_EXIT_OVERQUOTA": "Quota dépassé de la boîte de réception cible"
"syncjob_EXIT_OVERQUOTA": "Quota dépassé de la boîte de réception cible",
"domain_templates": "Modèles de domaine",
"syncjob_last_run_result": "Résultat de la dernière exécution",
"sender": "Expéditeur",
"add_template": "Ajouter un modèle",
"syncjob_EX_OK": "Succès",
"syncjob_EXIT_CONNECTION_FAILURE": "Problème de connexion",
"syncjob_EXIT_TLS_FAILURE": "Problème avec le chiffrement de la connexion",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "Problème d'authentification",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Impossible de se connecter au serveur distant",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Utilisateur ou mot de passe erroné",
"templates": "Modèles",
"template": "Modèle",
"syncjob_check_log": "Vérifier le journal",
"recipient": "Destinataire",
"open_logs": "Afficher les journaux"
},
"oauth2": {
"access_denied": "Veuillez vous connecter en tant que propriétaire de la boîte de réception pour accorder laccès via Oauth2.",
@@ -882,9 +923,9 @@
"confirm": "Confirmer",
"confirm_delete": "Confirmer la suppression de cet élément.",
"danger": "Danger",
"deliver_inbox": "Envoyer dans la boîte de reception",
"disabled_by_config": "La configuration actuelle du système désactive la fonctionnalité de quarantaine. Veuillez définir « retentions par boîte » et une « taille maximale » pour les éléments en quarantaine.",
"settings_info": "Quantité maximale d'éléments à mettre en quarantaine : %s<br>Taille maximale des courriels : %s MiB",
"deliver_inbox": "Envoyer dans la boîte de réception",
"disabled_by_config": "La configuration actuelle du système désactive la fonctionnalité de quarantaine. Veuillez définir « retentions par boîte » et une « taille maximale » pour les éléments en quarantaine.",
"settings_info": "Quantité maximale d'éléments à mettre en quarantaine : %s<br>Taille maximale des courriels : %s Mio",
"download_eml": "Télécharger (.eml)",
"empty": "Pas de résultat",
"high_danger": "Haut",
@@ -897,7 +938,7 @@
"notified": "Notifié",
"qhandler_success": "Demande envoyée avec succès au système. Vous pouvez maintenant fermer la fenêtre.",
"qid": "Rspamd QID",
"qinfo": "Le système de quarantaine enregistrera le courrier rejeté dans la base de données (l'expéditeur n'aura <em> pas </em> l'impression d'un courrier remis) ainsi que le courrier, remis sous forme de copie dans le dossier indésirable d'une boîte de réception.\n <br>« Apprendre comme spam et supprimer » apprendra un message comme spam via le théorème Bayésien calculera également des hachages flous pour refuser des messages similaires à l'avenir.\n <br>Veuillez noter que l'apprentissage de plusieurs messages peut prendre du temps, selon votre système. <br> Les éléments figurant sur la liste noire sont exclus de la quarantaine.",
"qinfo": "Le système de quarantaine enregistrera le courrier rejeté dans la base de données (l'expéditeur n'aura <em>pas</em> l'impression d'un courrier remis) ainsi que le courrier, remis sous forme de copie dans le dossier indésirable d'une boîte de réception.\n <br>« Apprendre comme spam et supprimer » apprendra un message comme spam via le théorème Bayésien et calculera également des hachages flous pour refuser des messages similaires à l'avenir.\n <br>Veuillez noter que l'apprentissage de plusieurs messages peut prendre du temps, selon votre système.<br>Les éléments figurant sur la liste noire sont exclus de la quarantaine.",
"qitem": "Élément de quarantaine",
"quarantine": "Quarantaine",
"quick_actions": "Actions",
@@ -913,7 +954,7 @@
"rewrite_subject": "Réécrire le sujet",
"rspamd_result": "Résultat Rspamd",
"sender": "Expéditeur (SMTP)",
"sender_header": "Expéditeur (\"From\" header)",
"sender_header": "Expéditeur (« From » header)",
"type": "Type",
"quick_release_link": "Ouvrir le lien de dégagement rapide",
"quick_delete_link": "Ouvrir le lien de suppression rapide",
@@ -931,13 +972,18 @@
"queue": {
"queue_manager": "Gestion de la file d'attente",
"hold_mail": "Garder",
"legend": "Fonctions d'action de la file d'attente du courrier :",
"legend": "Fonctions d'action de la file d'attente du courrier :",
"info": "La file d'attente contient tous les courriels en attente de livraison. Si un courriel reste longtemps dans la file d'attente, il est automatiquement supprimé par le système.<br>Le message d'erreur du courriel concerné indique pourquoi le courriel n'a pas pu être distribué.",
"deliver_mail_legend": "Tentatives de réexpédition des courriers sélectionnés.",
"hold_mail_legend": "Met en attente les courriers sélectionnés. (Empêche les tentatives de distribution ultérieures)",
"unban": "file d'attente d'unban",
"unhold_mail": "Libérer",
"unhold_mail_legend": "Libère les courriers sélectionnés pour la distribution. (Nécessite une mise en attente préalable)"
"unhold_mail_legend": "Libère les courriers sélectionnés pour la distribution. (Nécessite une mise en attente préalable)",
"show_message": "Afficher le message",
"delete": "Tout supprimer",
"flush": "Vider la file d'attente",
"ays": "Veuillez confirmer que vous souhaitez supprimer tous les éléments de la file d'attente actuelle.",
"deliver_mail": "Délivrer"
},
"start": {
"help": "Afficher/masquer le panneau daide",
@@ -960,14 +1006,14 @@
"app_links": "Modifications enregistrées dans les liens dapplication",
"app_passwd_added": "Ajout dun nouveau mot de passe dapplication",
"app_passwd_removed": "Suppression de lidentifiant du mot de passe de lapplication %s",
"bcc_deleted": "Suppression des entrées de la carte BCC : %s",
"bcc_deleted": "Suppression des entrées de la carte BCC : %s",
"bcc_edited": "Entrée de la carte BCC %s modifiée",
"bcc_saved": "Saisie de carte BCC enregistrée",
"db_init_complete": "Initialisation de la base de données terminée",
"delete_filter": "ID des filtres supprimés %s",
"delete_filters": "Filtres supprimés : %s",
"deleted_syncjob": "ID du travail de synchronisation supprimé : %s",
"deleted_syncjobs": "Travail de synchronisation supprimé : %s",
"delete_filters": "Filtres supprimés : %s",
"deleted_syncjob": "ID de la tâche de synchronisation supprimée : %s",
"deleted_syncjobs": "Tâche de synchronisation supprimée : %s",
"dkim_added": "La clé DKIM %s a été enregistrée",
"dkim_duplicated": "La clé DKIM pour le domaine %s a été copiée vers %s",
"dkim_removed": "La clé DKIM %s a été supprimée",
@@ -1000,7 +1046,7 @@
"qlearn_spam": "Le message ID %s a été appris comme spam et supprimé",
"queue_command_success": "Queue de commande terminée avec succès",
"recipient_map_entry_deleted": "La carte du destinataire ID %s a été effacée",
"recipient_map_entry_saved": "L'entrée de la carte du bénéficiaire \"%s\" a été enregistrée",
"recipient_map_entry_saved": "L'entrée de la carte du destinataire « %s » a été enregistrée",
"relayhost_added": "L'entrée de la carte %s a été ajoutée",
"relayhost_removed": "L'entrée de la carte %s a été supprimée",
"reset_main_logo": "Réinitialisation du logo par défaut",
@@ -1014,7 +1060,7 @@
"settings_map_removed": "Suppression de la carte des paramètres ID %s",
"sogo_profile_reset": "Le profil SOGo profile pour l'utilisateur %s est remis à zéro",
"tls_policy_map_entry_deleted": "La carte de stratégie TLS ID %s a été supprimée",
"tls_policy_map_entry_saved": "La carte de stratégie TLS ID \"%s\" a été enregistrée",
"tls_policy_map_entry_saved": "La carte de stratégie TLS ID « %s » a été enregistrée",
"ui_texts": "Enregistrement des modifications apportées aux textes de linterface utilisateur",
"upload_success": "Fichier téléchargé avec succès",
"verified_totp_login": "Authentification TOTP vérifiée",
@@ -1029,7 +1075,10 @@
"domain_add_dkim_available": "A DKIM key did already exist",
"ip_check_opt_in_modified": "Le contrôle de l'IP a été enregistré avec succès",
"password_changed_success": "Le mot de passe a été modifié avec succès",
"recovery_email_sent": "Email de réinitialisation envoyé à %s"
"recovery_email_sent": "Email de réinitialisation envoyé à %s",
"mailbox_renamed": "La boîte de réception a été renommée de %s à %s",
"template_modified": "Les modifications au modèle %s ont été enregistrées",
"password_policy_saved": "La politique de mot de passe a été enregistrée avec succès"
},
"tfa": {
"api_register": "%s utilise l'API Yubico Cloud. Veuillez obtenir une clé API pour votre clé <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">ici</a>",
@@ -1050,7 +1099,7 @@
"start_webauthn_validation": "Début de la validation",
"tfa": "Authentification à deux facteurs",
"tfa_token_invalid": "Token TFA invalide",
"totp": "OTP (One Time Password = Mot de passe à usage unique : Google Authenticator, Authy, etc.)",
"totp": "OTP (One Time Password = Mot de passe à usage unique : Google Authenticator, Authy, etc.)",
"webauthn": "Authentification WebAuthn",
"waiting_usb_auth": "<i>En attente dun périphérique USB…</i><br><br>Sil vous plaît appuyez maintenant sur le bouton de votre périphérique USB WebAuthn.",
"waiting_usb_register": "<i>En attente dun périphérique USB…</i><br><br>Veuillez entrer votre mot de passe ci-dessus et confirmer votre inscription WebAuthn en appuyant sur le bouton de votre périphérique USB WebAuthn.",
@@ -1089,7 +1138,7 @@
"alias_valid_until": "Valide jusque",
"aliases_also_send_as": "Aussi autorisé à envoyer en tant quutilisateur",
"aliases_send_as_all": "Ne pas vérifier laccès de lexpéditeur pour les domaines suivants et leurs alias",
"app_hint": "Les mots de passe dapplication sont des mots de passe alternatifs pour votre connexion IMAP, SMTP, Caldav, Carddav et EAS. Le nom dutilisateur reste inchangé.<br>SOGo n'est pas disponible au travers des mots de passe d'application.",
"app_hint": "Les mots de passe dapplication sont des mots de passe alternatifs pour votre connexion IMAP, SMTP, CalDAV, CardDAV et EAS. Le nom dutilisateur reste inchangé.<br>Le webmail SOGo n'est pas disponible au travers des mots de passe d'application.",
"app_name": "Nom d'application",
"app_passwds": "Mots de passe d'applications",
"apple_connection_profile": "Profil de connexion Apple",
@@ -1101,11 +1150,12 @@
"create_syncjob": "Créer une tâche de synchronisation",
"daily": "Quotidien",
"day": "jour",
"description": "Description",
"delete_ays": "Veuillez confirmer le processus de suppression.",
"direct_aliases": "Adresses alias directes",
"direct_aliases": "Adresses d'alias directes",
"direct_aliases_desc": "Les adresses dalias directes sont affectées par le filtre anti-spam et les paramètres de politique TLS.",
"eas_reset": "Réinitialiser le cache de lappareil ActiveSync",
"eas_reset_help": "Dans de nombreux cas, une réinitialisation du cache de lappareil aidera à récupérer un profil ActiveSync cassé.<br><b>Attention :</b> Tous les éléments seront de nouveau téléchargés !",
"eas_reset_help": "Dans de nombreux cas, une réinitialisation du cache de lappareil aidera à récupérer un profil ActiveSync cassé.<br><b>Attention :</b> Tous les éléments seront de nouveau téléchargés !",
"eas_reset_now": "Réinitialiser maintenant",
"edit": "Éditer",
"email": "Courriel",
@@ -1138,7 +1188,7 @@
"pushover_evaluate_x_prio": "Acheminement du courrier hautement prioritaire [<code>X-Priority: 1</code>]",
"pushover_info": "Les paramètres de notification push sappliqueront à tout le courrier propre (non spam) livré à <b>%s</b> y compris les alias (partagés, non partagés, étiquetés).",
"pushover_only_x_prio": "Ne tenir compte que du courrier hautement prioritaire [<code>X-Priority: 1</code>]",
"pushover_sender_array": "Tenir compte des adresses de courriel suivantes de lexpéditeur : <small>(comma-separated)</small>",
"pushover_sender_array": "Tenir compte des adresses de courriel de lexpéditeur suivantes : <small>(séparées par des virgules)</small>",
"pushover_sender_regex": "Apparier les expéditeurs par le regex suivant",
"pushover_text": "Texte de notification",
"pushover_title": "Titre de la notification",
@@ -1149,8 +1199,8 @@
"q_reject": "Rejeté",
"quarantine_notification": "Avis de quarantaine",
"quarantine_category": "Catégorie de la notification de quarantaine",
"quarantine_notification_info": "Une fois quun avis a été envoyé, les articles seront marqués comme « notifiés » et aucune autre notification ne sera envoyée pour ce point particulier.",
"quarantine_category_info": "La catégorie de notification « Rejeté » inclut le courrier rejeté, tandis que « Dossier indésirable » informera un utilisateur des courriels placés dans le dossier indésirable.",
"quarantine_notification_info": "Une fois quun avis a été envoyé, les articles seront marqués comme « notifiés » et aucune autre notification ne sera envoyée pour ce point particulier.",
"quarantine_category_info": "La catégorie de notification « Rejeté » inclut le courrier rejeté, tandis que « Dossier indésirable » informera un utilisateur des courriels placés dans le dossier indésirable.",
"remove": "Enlever",
"running": "En fonctionnement",
"save": "Enregistrer les changements",
@@ -1167,11 +1217,11 @@
"spamfilter": "Filtre de spam",
"spamfilter_behavior": "Note",
"spamfilter_bl": "Liste noire (BlackList)",
"spamfilter_bl_desc": "Les adresses de courriel sur la liste noire de <b>toujours</b> peuvent être classées comme des pourriels et rejetées. Des caractères génériques peuvent être utilisés. Un filtre nest appliqué quaux alias directs (alias avec une seule boîte de réception cible), à lexclusion des alias tous azimuts et dune boîte de réception elle-même.",
"spamfilter_bl_desc": "Les adresses de courriel sur liste noire qui doivent <b>toujours</b> être classées comme des pourriels et rejetées. Les messages rejetés ne seront <b>pas</b> copiés dans la quarantaine. Des caractères génériques peuvent être utilisés. Un filtre nest appliqué quaux alias directs (alias avec une seule boîte de réception cible), à lexclusion des alias attrape-tout et dune boîte de réception elle-même.",
"spamfilter_default_score": "Valeurs par défaut",
"spamfilter_green": "Vert : ce message n'est pas un spam",
"spamfilter_hint": "La première valeur indique un « faible score de spam », la seconde représente un « haut score de spam ».",
"spamfilter_red": "Rouge : Ce message est un spam et sera rejeté par le serveur",
"spamfilter_green": "Vert : ce message n'est pas un spam",
"spamfilter_hint": "La première valeur indique un « faible score de spam », la seconde représente un « haut score de spam ».",
"spamfilter_red": "Rouge : Ce message est un spam et sera rejeté par le serveur",
"spamfilter_table_action": "Action",
"spamfilter_table_add": "Ajouter un élément",
"spamfilter_table_domain_policy": "n/a (politique de domaine)",
@@ -1179,13 +1229,13 @@
"spamfilter_table_remove": "supprimer",
"spamfilter_table_rule": "Règle",
"spamfilter_wl": "Liste blanche (WhiteList)",
"spamfilter_wl_desc": "La liste blanche est programmée pour <b> ne jamais</b> classer comme spam les adresses de courriel qu'elle contient. Des caractères génériques peuvent être utilisés. Un filtre nest appliqué quaux alias directs (alias avec une seule boîte de réception cible), à lexclusion des alias catch-all et dune boîte de réception.",
"spamfilter_yellow": "Jaune : ce message est peut être un spam, il sera étiqueté comme spam et déplacé vers votre dossier Pourriel",
"spamfilter_wl_desc": "La liste blanche est programmée pour <b> ne jamais</b> classer comme spam les adresses de courriel qu'elle contient. Des caractères génériques peuvent être utilisés. Un filtre nest appliqué quaux alias directs (alias avec une seule boîte de réception cible), à lexclusion des alias attrape-tout et dune boîte de réception.",
"spamfilter_yellow": "Jaune : ce message est peut-être un spam, il sera étiqueté comme spam et déplacé vers votre dossier Pourriel",
"status": "Statut",
"sync_jobs": "Jobs de synchronisation",
"sync_jobs": "Tâches de synchronisation",
"tag_handling": "Régler la manipulation du courrier étiqueté",
"tag_help_example": "Exemple pour une adresse de courriel étiquetée : me<b>+Facebook</b>@example.org",
"tag_help_explain": "Dans un sous-dossier : un nouveau sous-dossier nommé selon l'étiquette sera créé sous INBOX (\"INBOX/Facebook\").<br>\nDans le sujet : le nom des balises sera ajouté au début du sujet de l'e-mail, exemple : \"[Facebook] My News\".",
"tag_help_example": "Exemple pour une adresse de courriel étiquetée : me<b>+Facebook</b>@example.org",
"tag_help_explain": "Dans un sous-dossier : un nouveau sous-dossier nommé selon l'étiquette sera créé sous INBOX (« INBOX/Facebook »).<br>\nDans le sujet : le nom des balises sera ajouté au début du sujet de l'e-mail, exemple : « [Facebook] My News ».",
"tag_in_none": "Ne rien faire",
"tag_in_subfolder": "Dans un sous dossier",
"tag_in_subject": "Dans le sujet",
@@ -1208,7 +1258,7 @@
"with_app_password": "avec le mot de passe de l'application",
"apple_connection_profile_with_app_password": "Un nouveau mot de passe est généré et ajouté au profil, de sorte qu'aucun mot de passe ne doit être saisi lors de la configuration de votre appareil. Ne partagez pas le fichier car il vous donne un accès complet à votre boîte de réception.",
"attribute": "Attribut",
"direct_protocol_access": "Cet utilisateur de la boîte aux lettres dispose d'un <b>accès externe direct</b> aux protocoles et applications suivants. Votre administrateur contrôle ce paramètre. Il est possible de créer des mots de passe d'application pour accorder l'accès à des protocoles et des applications individuels.<br>Le bouton « Connexion au webmail » permet une connexion unique à SOGo et est toujours disponible.",
"direct_protocol_access": "Cet utilisateur de la boîte aux lettres dispose d'un <b>accès externe direct</b> aux protocoles et applications suivants. Votre administrateur contrôle ce paramètre. Il est possible de créer des mots de passe d'application pour accorder l'accès à des protocoles et des applications individuels.<br>Le bouton « Connexion au webmail » permet une connexion unique à SOGo et est toujours disponible.",
"open_webmail_sso": "Connexion au webmail",
"recent_successful_connections": "Voir les connexions réussies",
"syncjob_EXIT_TLS_FAILURE": "Problème de connexion chiffrée",
@@ -1229,19 +1279,28 @@
"allowed_protocols": "Protocoles autorisés",
"mailbox": "Boîte de réception",
"password_reset_info": "Si aucun email pour la récupération du mot de passe n'est fourni, cette fonction ne peut pas être utilisée.",
"pw_recovery_email": "Email de récupération pour son mot de passe"
"pw_recovery_email": "Email de récupération pour son mot de passe",
"month": "mois",
"from": "de",
"empty": "Aucun résultat",
"fido2_webauthn": "FIDO2/WebAuthn",
"last_pw_change": "Dernier changement de mot de passe",
"open_logs": "Afficher les journaux",
"pushover_sound": "Son",
"mailbox_general": "Général",
"mailbox_settings": "Paramètres"
},
"warning": {
"cannot_delete_self": "Impossible de supprimer lutilisateur connecté",
"domain_added_sogo_failed": "Ajout dun domaine mais échec du redémarrage de Sogo, veuillez vérifier les journaux de votre serveur.",
"dovecot_restart_failed": "Dovecot na pas pu redémarrer, veuillez vérifier les journaux",
"fuzzy_learn_error": "Erreur dapprentissage du hachage flou: %s",
"fuzzy_learn_error": "Erreur dapprentissage du hachage flou : %s",
"hash_not_found": "Hachage non trouvé ou déjà supprimé",
"ip_invalid": "IP non valide ignorée : %s",
"ip_invalid": "IP non valide ignorée : %s",
"no_active_admin": "Impossible de désactiver le dernier administrateur actif",
"quota_exceeded_scope": "Dépassement du quota de domaine : Seules des boîtes de réception illimitées peuvent être créées dans ce domaine.",
"session_token": "Jeton de formulaire invalide : Jeton différent",
"session_ua": "Jeton de formulaire invalide : erreur de validation User-Agent",
"quota_exceeded_scope": "Dépassement du quota de domaine : Seules des boîtes de réception illimitées peuvent être créées dans ce domaine.",
"session_token": "Jeton de formulaire invalide : Jeton différent",
"session_ua": "Jeton de formulaire invalide : erreur de validation User-Agent",
"is_not_primary_alias": "Alias non primaire ignoré %s"
},
"datatables": {
@@ -1250,21 +1309,30 @@
"thousands": ",",
"paginate": {
"first": "Premier",
"last": "Dernier"
"last": "Dernier",
"next": "Suivant",
"previous": "Précédent"
},
"aria": {
"sortAscending": ": activer pour trier les colonnes en ordre croissant",
"sortDescending": ": activer pour trier les colonnes en ordre décroissant"
},
"infoEmpty": "Affichage de 0 à 0 de 0 entrées",
"infoFiltered": "(filtré à partir de _MAX_ entrées totales)",
"infoEmpty": "Affichage de 0 à 0 sur 0 entrée",
"infoFiltered": "(filtré à partir de _MAX_ entrée(s) totale(s))",
"lengthMenu": "Afficher les entrées _MENU_",
"loadingRecords": "Chargement…",
"processing": "Veuillez patienter…",
"collapse_all": "Tout réduire",
"info": "Affichage de _START_ de _END_ sur _TOTAL_ entrées"
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrée(s)",
"search": "Rechercher :",
"emptyTable": "Aucune donnée présente dans la table",
"zeroRecords": "Aucun enregistrement correspondant trouvé"
},
"ratelimit": {
"disabled": "Désactivé"
"disabled": "Désactivé",
"second": "msgs / seconde",
"minute": "msgs / minute",
"hour": "msgs / heure",
"day": "msgs / jour"
}
}
}

View File

@@ -406,6 +406,7 @@
"create_syncjob": "Új szinkronizációs művelet létrehozása",
"daily": "Napi",
"day": "nap",
"description": "Leírás",
"delete_ays": "Erősítse meg a törlést.",
"direct_aliases": "Közvetlen alias címek",
"eas_reset": "ActiveSync eszköz gyorsítótár ürítése",
@@ -591,4 +592,4 @@
"app_name": "Alkalmazás neve",
"app_passwd_protocols": "Engedélyezett protokollok az alkalmazás jelszavához"
}
}
}

View File

@@ -494,7 +494,6 @@
"external_logs": "Log esterni",
"history_all_servers": "Cronologia (tutti i server)",
"in_memory_logs": "In-memory logs",
"jvm_memory_solr": "JVM memory usage",
"last_modified": "Ultima modifica",
"log_info": "<p>mailcow <b>in-memory logs</b> are collected in Redis lists and trimmed to LOG_LINES (%d) every minute to reduce hammering.\r\n <br>In-memory logs are not meant to be persistent. All applications that log in-memory, also log to the Docker daemon and therefore to the default logging driver.\r\n <br>The in-memory log type should be used for debugging minor issues with containers.</p>\r\n <p><b>External logs</b> are collected via API of the given application.</p>\r\n <p><b>Static logs</b> are mostly activity logs, that are not logged to the Dockerd but still need to be persistent (except for API logs).</p>",
"login_time": "Orario",
@@ -503,8 +502,6 @@
"restart_container": "Riavvio",
"service": "Servizio",
"size": "Dimensione",
"solr_dead": "Solr sta partendo, è disabilitato o morto.",
"solr_status": "Stato Solr",
"started_at": "Iniziato alle",
"started_on": "Iniziato",
"static_logs": "Log statici",
@@ -1126,6 +1123,7 @@
"created_on": "Creato il",
"daily": "Giornaliero",
"day": "giorno",
"description": "Descrizione",
"delete_ays": "Please confirm the deletion process.",
"direct_aliases": "Direct alias addresses",
"direct_aliases_desc": "Direct alias addresses are affected by spam filter and TLS policy settings.",
@@ -1308,4 +1306,4 @@
},
"decimal": "."
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -424,16 +424,13 @@
"external_logs": "External logs",
"history_all_servers": "History (all servers)",
"in_memory_logs": "In-memory logs",
"jvm_memory_solr": "JVM memory usage",
"log_info": "<p>mailcow <b>in-memory logs</b> are collected in Redis lists and trimmed to LOG_LINES (%d) every minute to reduce hammering.\r\n <br>In-memory logs are not meant to be persistent. All applications that log in-memory, also log to the Docker daemon and therefore to the default logging driver.\r\n <br>The in-memory log type should be used for debugging minor issues with containers.</p>\r\n <p><b>External logs</b> are collected via API of the given application.</p>\r\n <p><b>Static logs</b> are mostly activity logs, that are not logged to the Dockerd but still need to be persistent (except for API logs).</p>",
"logs": "Logs",
"restart_container": "Restart",
"solr_dead": "Solr is starting, disabled or died.",
"docs": "Docs",
"last_modified": "Last modified",
"size": "Size",
"started_at": "Started at",
"solr_status": "Solr status",
"uptime": "Uptime",
"started_on": "Started on",
"static_logs": "Static logs",
@@ -911,6 +908,7 @@
"create_syncjob": "새 동기화 작업 생성",
"daily": "매일",
"day": "일",
"description": "Description",
"delete_ays": "진짜 삭제하겠습니까?",
"direct_aliases": "Direct alias addresses",
"direct_aliases_desc": "Direct alias addresses are affected by spam filter and TLS policy settings.",
@@ -1020,4 +1018,4 @@
"session_token": "Form token invalid: Token mismatch",
"session_ua": "Form token invalid: User-Agent validation error"
}
}
}

View File

@@ -551,6 +551,7 @@
"client_configuration": "Parādīt konfigurācijas norādes e-pasta klientiem un tālruņiem",
"create_syncjob": "Izveidot jaunu sinhronizācijas darbu",
"day": "Dienas",
"description": "Apraksts",
"direct_aliases": "Tiešas aizstājadreses",
"direct_aliases_desc": "Tiešās aizstājadreses ir surogātpasta atlasīšanas un TLS nosacījumu iestatījumu ietekmētas.",
"eas_reset": "Atiestatīt ActiveSync ierīces kešatmiņu",
@@ -643,7 +644,6 @@
"logs": "Žurnāli",
"architecture": "Arhitektūra",
"disk_usage": "Diska lietojums",
"jvm_memory_solr": "JVM atmiņas lietojums",
"memory": "Atmiņa",
"timezone": "Laika josla",
"uptime": "Darbošanās laiks"
@@ -659,4 +659,4 @@
"fido2": {
"fido2_auth": "Pieteikties ar FIDO2"
}
}
}

View File

@@ -328,12 +328,10 @@
"update_available": "En oppdatering er tilgjengelig",
"service": "Tjeneste",
"show_ip": "Vis offentlig IP",
"solr_dead": "Solr starter, er deaktivert eller døde",
"memory": "Minne",
"online_users": "Tilkoblede brukere",
"restart_container": "Omstart",
"size": "Størrelse",
"solr_status": "Solr-status",
"started_at": "Startet ved",
"started_on": "Startet den",
"static_logs": "Statiske logger",

View File

@@ -472,17 +472,14 @@
"external_logs": "Externe logs",
"history_all_servers": "Geschiedenis (alle servers)",
"in_memory_logs": "Geheugenlogs",
"jvm_memory_solr": "JVM-geheugengebruik",
"log_info": "<p>Mailcows <b>geheugenlogs</b> worden elke minuut afgesneden naar maximaal %d regels (LOG_LINES) om de stabiliteit te garanderen.<br>Geheugenlogs zijn niet bedoeld om bewaard te blijven. Alle applicaties die geheugenlogs schrijven worden ook naar het Docker-proces gelogd.<br>De geheugenlogs kunnen gebruikt worden voor het oplossen van problemen met bepaalde containers.</p><p><b>Externe logs</b> worden verzameld door middel van de API van deze applicaties.</p><p><b>Statische logs</b> zijn activiteitenlogs die niet naar het Docker-proces worden gelogd, maar wel bewaard moeten blijven (uitgezonderd API-logs).</p>",
"logs": "Logs",
"restart_container": "Herstart",
"solr_dead": "Solr is uitgeschakeld, uitgevallen of nog bezig met opstarten.",
"docs": "Documenten",
"last_modified": "Voor het laatst bijgewerkt op",
"online_users": "Gebruikers online",
"size": "Grootte",
"started_at": "Opgestart op",
"solr_status": "Solr-status",
"uptime": "Uptime",
"started_on": "Gestart op",
"static_logs": "Statische logs",
@@ -1028,6 +1025,7 @@
"create_syncjob": "Voeg sync job toe",
"daily": "Dagelijks",
"day": "dag",
"description": "Beschrijving",
"delete_ays": "Bevestig de verwijdering.",
"direct_aliases": "Directe aliasadressen",
"direct_aliases_desc": "Directe aliasadressen worden beïnvloed door spamfilters en het versleutelingsbeleid.",
@@ -1167,4 +1165,4 @@
"search": "Zoeken:",
"zeroRecords": "Geen overeenkomsten gevonden"
}
}
}

View File

@@ -363,6 +363,7 @@
"create_syncjob": "Utwórz nowe polecenie synchronizacji",
"daily": "Co dzień",
"day": "Dzień",
"description": "Opis",
"direct_aliases": "Aliasy bezpośrednie",
"direct_aliases_desc": "Na aliasy bezpośrednie wpływają filtry spamu i ustawienia TLS.",
"eas_reset": "Zresetuj pamięć podręczną urządzenia ActiveSync",
@@ -431,4 +432,4 @@
"weekly": "Co tydzień",
"weeks": "Tygodnie"
}
}
}

View File

@@ -539,7 +539,6 @@
"external_logs": "Registros externos",
"history_all_servers": "Histórico (todos os servidores)",
"in_memory_logs": "Registros na memória",
"jvm_memory_solr": "Uso de memória JVM",
"last_modified": "Última modificação",
"log_info": "<p>Os <b>registros na memória do</b> mailcow são coletados em listas do Redis e reduzidos para LOG_LINES (%d) a cada minuto para reduzir o martelamento.\r\n Os <br>registros na memória não devem ser persistentes. Todos os aplicativos que fazem login na memória também fazem login no daemon do Docker e, portanto, no driver de registro padrão.\r\n </p><br>O tipo de registro na memória deve ser usado para depurar pequenos problemas com contêineres.\r\n <p>Os <b>registros externos</b> são coletados por meio da API do aplicativo em questão.</p>\r\n <p>Os <b>registros estáticos</b> são principalmente registros de atividades, que não são registrados no Dockerd, mas ainda precisam ser persistentes (exceto os registros da API).</p>",
"login_time": "Hora",
@@ -550,8 +549,6 @@
"service": "Serviço",
"show_ip": "Mostrar IP público",
"size": "Tamanho",
"solr_dead": "O Solr está iniciando, desativado ou morreu.",
"solr_status": "Status do solr",
"started_at": "Começou em",
"started_on": "Começou em",
"static_logs": "Registros estáticos",
@@ -1186,6 +1183,7 @@
"created_on": "Criado em",
"daily": "Diariamente",
"day": "dia",
"description": "Descrição",
"delete_ays": "Confirme o processo de exclusão.",
"direct_aliases": "Endereços de alias diretos",
"direct_aliases_desc": "Os endereços de alias diretos são afetados pelo filtro de spam e pelas configurações da política TLS.",
@@ -1332,4 +1330,4 @@
"session_token": "Token de formulário inválido: incompatibilidade de token",
"session_ua": "Token de formulário inválido: erro de validação do agente de usuário"
}
}
}

View File

@@ -236,6 +236,7 @@
"aliases_send_as_all": "Não verificar remetente para os domínios",
"change_password": "Alterar senha",
"day": "Dia",
"description": "Descrição",
"edit": "Editar",
"hour": "Hora",
"hours": "Horas",
@@ -272,4 +273,4 @@
"week": "Semana",
"weeks": "Semanas"
}
}
}

View File

@@ -481,7 +481,6 @@
"external_logs": "Jurnale externe",
"history_all_servers": "Istoric (toate serverele)",
"in_memory_logs": "Jurnale din memorie",
"jvm_memory_solr": "Memorie utilizată de JVM",
"last_modified": "Ultima modificare",
"log_info": "<p><b>jurnalele din memorie</b> pentru mailcow sunt colectate în listele Redis și trimise la LOG_LINES (%d) în fiecare minut pentru a reduce ciocnirea.\n <br>Jurnalele din memorie nu sunt menite a fi persistente. Toate aplicațiile care înregistrează jurnale în memorie, înregistrează de asemenea jurnale în daemonul Docker și, prin urmare, în driverul de jurnale implicit.\n <br>Tipul de jurnal din memorie trebuie utilizat pentru depanarea problemelor minore cu containerele.</p>\n <p><b>Jurnalele externe</b> sunt colectate prin API-ul aplicației respective.</p>\n <p><b>Jurnalele statice</b> sunt, în majoritate, jurnale de activitate care nu sunt înregistrate în Docker, dar trebuie să fie persistente (cu excepția jurnalelor API).</p>",
"login_time": "Moment",
@@ -490,8 +489,6 @@
"restart_container": "Repornire",
"service": "Serviciu",
"size": "Mărime",
"solr_dead": "Solr începe, este invalid sau s-a oprit.",
"solr_status": "Stare Solr",
"started_at": "Pornit la",
"started_on": "Început pe",
"static_logs": "Jurnale statice",
@@ -1064,6 +1061,7 @@
"created_on": "Creat în",
"daily": "Zilnic",
"day": "zi",
"description": "Descriere",
"delete_ays": "Vă rugăm să confirmați stergerea.",
"direct_aliases": "Adrese alias directe",
"direct_aliases_desc": "Adresele alias directe sunt afectate de setările filtrului de spam și ale politicii TLS.",
@@ -1210,4 +1208,4 @@
"expand_all": "Expandează tot",
"decimal": ","
}
}
}

View File

@@ -14,6 +14,7 @@
"prohibited": "Запрещено правилами ACL",
"protocol_access": "Настройка разрешенных протоколов",
"pushover": "Pushover API",
"pw_reset": "Разрешить пользователям mailcow восстановление паролей",
"quarantine": "Карантин - действия",
"quarantine_attachments": "Карантин - вложения",
"quarantine_category": "Категория уведомлений о спаме",
@@ -28,8 +29,7 @@
"spam_score": "Политика фильтрации спама",
"syncjobs": "Задания синхронизации",
"tls_policy": "Политика шифрования",
"unlimited_quota": "Неограниченная квота для почтовых ящиков",
"pw_reset": "Разрешить сброс пароля пользователей mailcow"
"unlimited_quota": "Неограниченная квота для почтовых ящиков"
},
"add": {
"activate_filter_warn": "Активация этого фильтра отключит все остальные фильтры этого типа.",
@@ -42,13 +42,14 @@
"alias_domain": "Псевдоним домена",
"alias_domain_info": "<small>Действительные имена доменов, раздёленные запятыми.</small>",
"app_name": "Название приложения",
"app_passwd_protocols": "Разрешенные протоколы для пароля приложения",
"app_password": "Добавить пароль приложения",
"automap": "Автоматическое слияние папок (\"Sent items\", \"Sent\" => \"Sent\" etc.)",
"backup_mx_options": "Параметры резервного MX",
"bcc_dest_format": "Место назначения BCC должно быть единственным действительным адресом электронной почты.<br>Если вам нужно отправить копию на несколько адресов - используйте псевдоним.",
"comment_info": "Приватный комментарий не виден пользователям, а публичный - отображается рядом с псевдонимом в личном кабинете пользователя.",
"custom_params": "Пользовательские параметры",
"custom_params_hint": "Верно: --param=xy, не верно: --param xy",
"custom_params_hint": "Верно: --param=xy, неверно: --param xy",
"delete1": "Удаление из источника после завершения",
"delete2": "Удаление писем по месту назначения, которые не находятся на исходном",
"delete2duplicates": "Удаление дубликатов по назначению",
@@ -58,6 +59,7 @@
"domain": "Домен",
"domain_matches_hostname": "Домен %s соответствует имени хоста",
"domain_quota_m": "Квота домена (MiB)",
"dry": "Имитировать синхронизацию",
"enc_method": "Метод шифрования",
"exclude": "Исключить объекты (regex)",
"full_name": "Полное имя",
@@ -89,7 +91,7 @@
"relay_all_info": "↪<small>Если вы решите <b>не</b> ретранслировать всех получателей, вам нужно будет добавить (\"слепой\") почтовый адрес для каждого получателя, которого следует ретранслировать.</small>",
"relay_domain": "Ретрансляция этого домена",
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Инфо</div> Вы можете настроить собственный транспорт для домена. Если такой настройки нет, то доставка будет выполнена на основе MX записей.",
"relay_unknown_only": "Ретрансляция только не существующих почтовых ящиков. Почта к существующим почтовым ящикам будут доставляться локально.",
"relay_unknown_only": "Ретрансляция только несуществующих почтовых ящиков. Почта существующих почтовых ящиков будут доставляться локально.",
"relayhost_wrapped_tls_info": "Пожалуйста <b>не</b> используйте TLS порты (в основном это 465 порт).<br>\r\nИспользуйте любой <b>не</b> TLS порт который поддерживает STARTTLS. А для защиты от downgrate атак - настройке принудительную политику TLS.",
"select": "Пожалуйста, выберите...",
"select_domain": "Пожалуйста, сначала выберите домен",
@@ -99,6 +101,7 @@
"subscribeall": "Подписаться на все папки и подпапки",
"syncjob": "Добавить задание синхронизации",
"syncjob_hint": "Пароли к вашему аккаунту будут сохранены на сервере в виде простого текста!",
"tags": "Теги",
"target_address": "Владельцы псевдонима",
"target_address_info": "<small>Адреса почтовых ящиков, разделенные запятыми.</small>",
"target_domain": "Целевой домен",
@@ -106,10 +109,7 @@
"timeout2": "Тайм-аут для подключения к локальному хосту",
"username": "Имя пользователя",
"validate": "Проверить",
"validation_success": "Проверка прошла успешно",
"tags": "Теги",
"app_passwd_protocols": "Разрешенные протоколы для пароля приложения",
"dry": "Имитировать синхронизацию"
"validation_success": "Проверка прошла успешно"
},
"admin": {
"access": "Настройки доступа",
@@ -135,6 +135,8 @@
"admins": "Администраторы",
"admins_ldap": "Администраторы LDAP",
"advanced_settings": "Расширенные настройки",
"allowed_methods": "Access-Control-Allow-Methods",
"allowed_origins": "Access-Control-Allow-Origin",
"api_allow_from": "Список IP-адресов для доступа к API (разделенных запятой или новой строкой)",
"api_info": "API находится в стадии разработки. Документация находится по адресу <a href=\"/api\">/api</a>",
"api_key": "Ключ API",
@@ -151,6 +153,8 @@
"change_logo": "Изменить логотип",
"configuration": "Глобальные настройки",
"convert_html_to_text": "Сконвертировать HTML в обычный текст",
"copy_to_clipboard": "Текст скопирован в буфер обмена!",
"cors_settings": "Настройки CORS",
"credentials_transport_warning": "<b>Предупреждение</b>: добавление новой записи перезапишет учетные данные для всех записей с таким же <i>следующим хостом</i>.",
"customer_id": "ID клиента",
"customize": "Персонализация",
@@ -179,10 +183,14 @@
"empty": "Пусто",
"excludes": "Исключает этих получателей",
"f2b_ban_time": "Время бана (в секундах)",
"f2b_ban_time_increment": "Время бана увеличивается с каждым баном",
"f2b_blacklist": "Черный список подсетей/хостов",
"f2b_filter": "Правила фильтрации с помощью регулярных выражений",
"f2b_list_info": "Хосты или подсети, занесенные в черный список, всегда будут перевешивать объекты из белого списка. <b>Обновление списка займет несколько секунд.</b>",
"f2b_manage_external": "Внешнее управление Fail2Ban",
"f2b_manage_external_info": "Fail2ban по-прежнему будет вести банлист, но не будет активно устанавливать правила для блокировки трафика. Используйте сгенерированный ниже банлист для внешнего блокирования трафика.",
"f2b_max_attempts": "Максимальное количество попыток",
"f2b_max_ban_time": "Максимальное время блокировки",
"f2b_netban_ipv4": "Размер подсети IPv4 для применения бана (8-32)",
"f2b_netban_ipv6": "Размер подсети IPv6 для применения бана (8-128)",
"f2b_parameters": "Настройки Fail2ban",
@@ -208,14 +216,19 @@
"include_exclude": "Включить/Исключить",
"include_exclude_info": "По умолчанию - без выбора - <b>все почтовые ящики</b> адресованы",
"includes": "Включить этих получателей",
"ip_check": "Проверить IP",
"ip_check_disabled": "Проверка IP-адресов отключена. Вы можете включить её в разделе <br> <strong>Система > Конфигурация > Параметры > Персонализация</strong>.",
"ip_check_opt_in": "Согласие на использование сторонних служб <strong>ipv4.mailcow.email</strong> и <strong>ipv6.mailcow.email</strong> для разрешения внешних IP-адресов.",
"is_mx_based": "На основе MX",
"last_applied": "Посл. применение",
"license_info": "Лицензия не обязательна, но её приобретение помогает дальнейшему развитию mailcow.<br><a href=\"https://www.servercow.de/mailcow?lang=en#sal\" target=\"_blank\" alt=\"SAL order\">Зарегистрируйте свой GUID здесь</a> или <a href=\"https://www.servercow.de/mailcow?lang=en#support\" target=\"_blank\" alt=\"Заказать поддержку\">приобретите поддержку для вашей установки mailcow.</a>",
"license_info": "Лицензия необязательна, но её приобретение помогает дальнейшему развитию mailcow.<br><a href=\"https://www.servercow.de/mailcow?lang=en#sal\" target=\"_blank\" alt=\"SAL order\">Зарегистрируйте свой GUID здесь</a> или <a href=\"https://www.servercow.de/mailcow?lang=en#support\" target=\"_blank\" alt=\"Заказать поддержку\">приобретите поддержку для вашей установки mailcow.</a>",
"link": "Ссылка",
"loading": "Пожалуйста, подождите...",
"login_time": "Время входа",
"logo_info": "Ваше изображение будет масштабироваться до высоты 40px для верхней панели навигации и до 250px ширины для стартовой страницы. <br>Рекомендуется использовать векторную графику, на пример: .svg.",
"lookup_mx": "Назначение на основе резовинга MX записи по регулярному выражению (<code>.*\\.example\\.com$</code> для маршрутизации всей почты через этот хост, если MX заканчивающийся на example.com)",
"logo_dark_label": "Инвертированный для темного режима",
"logo_info": "Ваше изображение будет масштабироваться до высоты 40px для верхней панели навигации и до 250px ширины для стартовой страницы. <br>Рекомендуется использовать векторную графику, например: .svg.",
"logo_normal_label": "Обычный",
"lookup_mx": "Назначение - регулярное выражение для сопоставления с именем MX (<code>.*\\.google\\.com</code> для направления всей почты, адресованной MX, заканчивающейся на google.com, через этот хоп)",
"main_name": "Название для \"mailcow UI\"",
"merged_vars_hint": "Серым цветом выделены строки полученные из <code>vars.(local.)inc.php</code>, они не могут быть изменены.",
"message": "Сообщение",
@@ -225,15 +238,16 @@
"no_active_bans": "В данный момент нет забаненных подсетей/хостов",
"no_new_rows": "Нет доступных строк",
"no_record": "Нет записей",
"oauth2_client_id": "ID клиента",
"oauth2_apps": "Приложения OAuth2",
"oauth2_add_client": "Добавить клиента OAuth2",
"oauth2_apps": "Приложения OAuth2",
"oauth2_client_id": "ID клиента",
"oauth2_client_secret": "Секретный ключ пользователя",
"oauth2_info": "Реализация OAuth2 поддерживает предоставления кодов авторизации и выдает токены продления сессии.<br>\r\nСервер также автоматически выдает новый токен продления сессии, после того, как предыдущий был использован.<br><br>\r\n&#8226; Scope по умолчанию: <i>profile</i>. Только пользователи почтовых аккаунтов могут проходить аутентификацию через OAuth2. Если параметр области не указан, он возвращается к <i>profile</i>.<br>\r\n&#8226; Параметр <i>state</i> должен быть отправлен клиентом как часть запроса для авторизации.<br><br>\r\nПути для запросов OAuth2 API: <br>\r\n<ul>\r\n <li>Authorization endpoint: <code>/oauth/authorize</code></li>\r\n <li>Token endpoint: <code>/oauth/token</code></li>\r\n <li>Resource page: <code>/oauth/profile</code></li>\r\n</ul>\r\nГенерирование нового клиентского секрета не приводит к истечению существующих кодов авторизации, но они не смогут обновить свой токен.<br><br>\r\nОтзыв клиентских токенов приведет к немедленному прекращению всех активных сеансов. Все клиенты должны будут пройти повторную аутентификацию.",
"oauth2_redirect_uri": "Переадресация URI",
"oauth2_renew_secret": "Сгенерировать новый ключ клиента",
"oauth2_revoke_tokens": "Отозвать все клиентские токены",
"optional": "опционально",
"options": "Параметры",
"password": "Пароль",
"password_length": "Минимальная длина пароля",
"password_policy": "Политика паролей",
@@ -243,6 +257,11 @@
"password_policy_numbers": "Должен содержать цифру",
"password_policy_special_chars": "Должны содержать специальный символ",
"password_repeat": "Подтверждение пароля (повтор)",
"password_reset_info": "Если получатель не указан, использование данной функции недоступно.",
"password_reset_settings": "Параметры восстановления паролей",
"password_reset_tmpl_html": "Шаблон в виде HTML",
"password_reset_tmpl_text": "Шаблон в виде обычного текста",
"password_settings": "Параметры паролей",
"priority": "Приоритет",
"private_key": "Закрытый ключ",
"quarantine": "Карантин",
@@ -250,7 +269,7 @@
"quarantine_exclude_domains": "Исключить домены и псевдонимы доменов",
"quarantine_max_age": "Максимальный период хранения в днях<br><small>Значение должно быть равно или больше 1 дня.</small>",
"quarantine_max_score": "Не уведомлять о спаме, если оценка письма выше, чем:<br><small>По умолчанию 9999.0</small>",
"quarantine_max_size": "Максимальный размер в MiB (письма большего размера не будет сохранены):<br><small>0 означает, что карантин <b>отключён</b>.</small>",
"quarantine_max_size": "Максимальный размер в MiB (письма большего размера не будут сохранены):<br><small>0 означает, что карантин <b>отключён</b>.</small>",
"quarantine_notification_html": "Шаблон уведомления:<br><small>Оставьте пустым, чтобы восстановить шаблон по умолчанию.</small>",
"quarantine_notification_sender": "Email-адрес для отправки уведомления",
"quarantine_notification_subject": "Тема письма",
@@ -259,6 +278,7 @@
"quarantine_release_format_att": "Как вложение",
"quarantine_release_format_raw": "Оригинальное письмо",
"quarantine_retention_size": "Количество писем, сохраняемых в карантине на аккаунт:<br><small>0 означает, что карантин <b>отключён</b>.</small>",
"queue_unban": "разблокировать",
"quota_notification_html": "Шаблон уведомления:<br><small>Оставьте пустым, чтобы восстановить шаблон по умолчанию.</small>",
"quota_notification_sender": "Email-адрес для отправки уведомления",
"quota_notification_subject": "Тема письма",
@@ -267,7 +287,7 @@
"quota_notifications_vars": "{{percent}} равно текущей квоте пользователя<br>{{username}} - имя почтового аккаунта",
"r_active": "Включенные ограничения",
"r_inactive": "Отключенные ограничения",
"r_info": "Не активные (серые) элементы списка ограничений - это не валидные ограничения, и они не могут быть перемещены. <br>Вы можете добавить новые элементы в <code>inc/vars.local.inc.php</code> чтобы иметь возможность настраивать их.",
"r_info": "Неактивные (серые) элементы списка ограничений - это некорректные ограничения, и они не могут быть перемещены. <br>Вы можете добавить новые элементы в <code>inc/vars.local.inc.php</code> чтобы иметь возможность настраивать их.",
"rate_name": "Название очереди",
"recipients": "Получатели",
"refresh": "Обновить",
@@ -282,6 +302,8 @@
"remove_row": "Удалить строку",
"reset_default": "Восстановить по умолчанию",
"reset_limit": "Удалить хэш",
"reset_password_vars": "<code>{{link}}</code> Сгенерированная ссылка для восстановление пароля<br><code>{{username}}</code> Имя почтового ящика пользователя, запросившего восстановление пароля<br><code>{{username2}}</code> Имя почтового ящика для восстановления<br><code>{{date}}</code> Дата запроса на восстановление пароля<br><code>{{token_lifetime}}</code> Срок действия токена в минутах<br><code>{{hostname}}</code> Имя хоста mailcow",
"restore_template": "Оставьте пустым, чтобы восстановить шаблон по умолчанию.",
"routing": "Маршрутизация",
"rsetting_add_rule": "Добавить правило",
"rsetting_content": "Содержание правила",
@@ -290,14 +312,14 @@
"rsetting_none": "Нет доступных правил",
"rsettings_insert_preset": "Вставить пример \"%s\"",
"rsettings_preset_1": "Отключить все, кроме DKIM и ограничения скорости для аутентифицированных пользователей",
"rsettings_preset_2": "Не проверять письма на спам Postmaster",
"rsettings_preset_2": "Не проверять письма Postmaster на спам",
"rsettings_preset_3": "Разрешить только определённых отправителей для почтового ящика (использование только в качестве внутреннего почтового ящика)",
"rsettings_preset_4": "Отключить Rspamd для домена",
"rspamd_com_settings": "Имена правил будут сгенерированы на основе их ID.<br> Инструкция доступна на сайте <a href=\"https://rspamd.com/doc/configuration/settings.html#settings-structure\" target=\"_blank\">документация Rspamd user settings</a>, заготовленные шаблоны:",
"rspamd_global_filters": "Глобальные правила фильтрации",
"rspamd_global_filters_agree": "Я понимаю, что я делаю, и буду осторожен!",
"rspamd_global_filters_info": "Глобальные правила фильтрации содержат различные виды глобальных черных и белых списков.",
"rspamd_global_filters_regex": "Названия фильтров отражают их предназначение. Все правила должены состоять из регулярных выражений в формате \"/pattern/options\" (на пример: <code>/.+@domain\\.tld/i</code>).<br>\r\nНесмотря на то, что перед сохранением правил выполняется проверка регулярных выражений, функциональность Rspamds может быть нарушена, если будет использован<br>\r\n некорректный синтаксис. Будьте внимательны при написании правил.<br>Электронные письма от адресов электронной почты, проходящие по регулярным выражениям черных списков, будут отклонены без сохранения в карантин.<br>\r\n Rspamd попытается прочитать содержимое правил при их изменении. Но, если что, вы можете <a href=\"\" data-toggle=\"modal\" data-container=\"rspamd-mailcow\" data-target=\"#RestartContainer\">перезапустить Rspamd</a>, чтобы принять последние изменения принудительно.",
"rspamd_global_filters_regex": "Названия фильтров отражают их предназначение. Все правила должены состоять из регулярных выражений в формате \"/pattern/options\" (например: <code>/.+@domain\\.tld/i</code>).<br>\r\nНесмотря на то, что перед сохранением правил выполняется проверка регулярных выражений, функциональность Rspamds может быть нарушена, если будет использован<br>\r\n некорректный синтаксис. Будьте внимательны при написании правил.<br>Электронные письма от адресов электронной почты, проходящие по регулярным выражениям черных списков, будут отклонены без сохранения в карантин.<br>\r\n Rspamd попытается прочитать содержимое правил при их изменении. Но, если что, вы можете <a href=\"\" data-toggle=\"modal\" data-container=\"rspamd-mailcow\" data-target=\"#RestartContainer\">перезапустить Rspamd</a>, чтобы принять последние изменения принудительно.",
"rspamd_settings_map": "Правила Rspamd",
"sal_level": "Уровень Муу",
"save": "Сохранить изменения",
@@ -337,19 +359,7 @@
"username": "Имя пользователя",
"validate_license_now": "Получить лицензию на основе GUID с сервера лицензий",
"verify": "Проверить",
"yes": "&#10003;",
"queue_unban": "разблокировать",
"f2b_ban_time_increment": "Время бана увеличивается с каждым баном",
"f2b_max_ban_time": "Максимальное время блокировки",
"allowed_origins": "Access-Control-Allow-Origin",
"cors_settings": "Настройки CORS",
"allowed_methods": "Access-Control-Allow-Methods",
"ip_check": "Проверить IP",
"ip_check_disabled": "Проверка IP отключена. Вы можете включить его в разделе <br> <strong>Система > Конфигурация > Параметры > Настроить</strong>.",
"ip_check_opt_in": "Согласие на использование сторонних служб <strong>ipv4.mailcow.email</strong> и <strong>ipv6.mailcow.email</strong> для разрешения внешних IP-адресов.",
"f2b_manage_external": "Внешнее управление Fail2Ban",
"f2b_manage_external_info": "Fail2ban по-прежнему будет вести банлист, но не будет активно устанавливать правила для блокировки трафика. Используйте сгенерированный ниже банлист для внешнего блокирования трафика.",
"copy_to_clipboard": "Текст скопирован в буфер обмена!"
"yes": "&#10003;"
},
"danger": {
"access_denied": "Доступ запрещён, или указаны неверные данные",
@@ -365,7 +375,10 @@
"bcc_exists": "Для типов %s уже существует карта BCC %s",
"bcc_must_be_email": "Назначение BCC %s не является правильным адресом электронной почты",
"comment_too_long": "Комментарий слишком длинный, придел 160 символов",
"cors_invalid_method": "Указан недопустимый метод разрешения",
"cors_invalid_origin": "Указан неверный Allow-Origin",
"defquota_empty": "Квота по умолчанию не может быть 0.",
"demo_mode_enabled": "Демонстрационный режим включен",
"description_invalid": "Недопустимое описание ресурса %s",
"dkim_domain_or_sel_exists": "Ключ DKIM для \"%s\" уже существует",
"dkim_domain_or_sel_invalid": "DKIM домен или селектор недопустимы для %s",
@@ -375,20 +388,23 @@
"domain_not_empty": "Нельзя удалить непустой домен %s",
"domain_not_found": "Домен %s не найден",
"domain_quota_m_in_use": "Квота домена должна быть больше или равна %s MiB",
"extra_acl_invalid": "Адрес внешнего отправителя \"%s\" не валидный.",
"extra_acl_invalid_domain": "Адрес внешнего отправителя \"%s\" не валидный домен",
"extended_sender_acl_denied": "отсутствует ACL для установки внешних адресов отправителей",
"extra_acl_invalid": "Адрес внешнего отправителя \"%s\" некорректен",
"extra_acl_invalid_domain": "Адрес внешнего отправителя \"%s\" содержит некорректный домен",
"fido2_verification_failed": "Ошибка валидации FIDO2: %s",
"file_open_error": "Файл не может быть открыт на запись",
"filter_type": "Неверный тип фильтра",
"from_invalid": "Отправитель не может быть пустым",
"global_filter_write_error": "Ошибка записи фильтра в файл: %s",
"global_map_invalid": "Идентификатор глобального правила %s не валидный",
"global_map_invalid": "Недопустимый идентификатор глобального правила %s",
"global_map_write_error": "Не удалось создать глобальное правило ID %s: %s",
"goto_empty": "Псевдоним должен содержать по крайней мере один валидный адрес владельца",
"goto_empty": "Псевдоним должен содержать по крайней мере один действующий адрес владельца",
"goto_invalid": "Недопустимый основной адрес %s",
"ham_learn_error": "Ошибка при обучении полезной почты: %s",
"imagick_exception": "Ошибка в Imagick при чтении изображения",
"img_dimensions_exceeded": "Разрешение изображения превышает допустимое значение",
"img_invalid": "Невозможно проверить файл изображения",
"img_size_exceeded": "Изображение превышает допустимый размер файла",
"img_tmp_missing": "Невозможно проверить файл изображения: временный файл не найден",
"invalid_bcc_map_type": "Неверный тип правила BCC",
"invalid_destination": "Назначение \"%s\" указано неверно",
@@ -397,8 +413,9 @@
"invalid_mime_type": "Неверный mime type",
"invalid_nexthop": "Формат следующего хоста неверен",
"invalid_nexthop_authenticated": "Следующий хост существует с разными данными авторизации, пожалуйста, обновите существующие данные авторизации сначала для этого хоста.",
"invalid_recipient_map_new": "Новый получатель: %s не валидный",
"invalid_recipient_map_old": "Первоначальный получатель: %s не валидный",
"invalid_recipient_map_new": "Недопустимый новый получатель: %s",
"invalid_recipient_map_old": "Недопустимый исходный получатель: %s",
"invalid_reset_token": "Неверный токен восстановления",
"ip_list_empty": "Список разрешенных IP адресов не может быть пустым",
"is_alias": "%s уже известен как псевдоним адреса",
"is_alias_or_mailbox": "%s уже известен как псевдоним или почтовый аккаунт",
@@ -418,7 +435,7 @@
"max_quota_in_use": "Квота почтового аккаунта должна быть больше или равна %d MiB",
"maxquota_empty": "Максимальная квота почтового аккаунта не должна быть 0.",
"mysql_error": "Ошибка в MySQL: %s",
"network_host_invalid": "Сеть или хост: %s не валидный",
"network_host_invalid": "Недопустимые сеть или хост: %s",
"next_hop_interferes": "%s пересекается с %s",
"next_hop_interferes_any": "Существующий хост пересекается с %s",
"nginx_reload_failed": "Обновление конфигурации Nginx не удалось: %s",
@@ -428,6 +445,8 @@
"password_complexity": "Пароль не соответствует требованиям",
"password_empty": "Пароль не может быть пустым",
"password_mismatch": "Введенные пароли не совпадают",
"password_reset_invalid_user": "Почтовый ящик не найден или не задан адрес электронной почты для восстановления",
"password_reset_na": "Восстановление пароля в настоящее время недоступно. Пожалуйста, свяжитесь с вашим администратором.",
"policy_list_from_exists": "Запись с указанным именем уже существует",
"policy_list_from_invalid": "Запись имеет недопустимый формат",
"private_key_error": "Ошибка приватного ключа: %s",
@@ -436,17 +455,19 @@
"pushover_token": "Токен Pushover указан в неверном формате",
"quota_not_0_not_numeric": "Размер квоты должен быть больше или равен нулю",
"recipient_map_entry_exists": "Правило перезаписи \"%s\" уже существует",
"recovery_email_failed": "Не удалось отправить письмо для восстановления. Пожалуйста, свяжитесь с вашим администратором.",
"redis_error": "Ошибка в Redis: %s",
"relayhost_invalid": "Правило %s не валидное",
"relayhost_invalid": "Недопустимое правило %s",
"release_send_failed": "Сообщение не может быть восстановлено: %s",
"reset_f2b_regex": "Сброс фильтров не был выполнен за отведённый промежуток времени, пожалуйста, повторите попытку или подождите еще несколько секунд и перезагрузите веб страницу.",
"reset_token_limit_exceeded": "Превышен лимит запросов на восстановление. Пожалуйста, попробуйте ещё раз позже.",
"resource_invalid": "Недопустимое имя ресурса",
"rl_timeframe": "Не верный временной интервал для лимита отправки",
"rspamd_ui_pw_length": "Длина пароля должна составлять не менее 6 символов для Rspamd UI",
"script_empty": "Скрипт не может быть пустым",
"sender_acl_invalid": "Недопустимое значение ACL для: %s",
"set_acl_failed": "Не удалось установить ACL",
"settings_map_invalid": "Правило ID: %s не валидное",
"settings_map_invalid": "Недопустимое правило ID %s",
"sieve_error": "Ошибка в синтаксисе Sieve: %s",
"spam_learn_error": "Ошибка при обучении спам фильтра: %s",
"subject_empty": "Тема письма не может быть пустой",
@@ -454,56 +475,92 @@
"targetd_not_found": "Основной домен %s не найден",
"targetd_relay_domain": "Целевой домен %s уже является домен ретрансляции",
"temp_error": "Временная ошибка",
"text_empty": "Текст не должен быть пустым",
"template_exists": "Шаблон %s уже существует",
"template_id_invalid": "Недопустимое значение ID шаблона: %s",
"template_name_invalid": "Недопустимое название шаблона",
"text_empty": "Текст не может быть пустым",
"tfa_token_invalid": "Неправильный TFA токен",
"tls_policy_map_dest_invalid": "Недопустимое значение назначения политики",
"tls_policy_map_entry_exists": "Правило политики шифрования \"%s\" уже существует",
"tls_policy_map_parameter_invalid": "Недопустимое значение параметра политики",
"to_invalid": "Получатель не может быть пустым",
"totp_verification_failed": "Ошибка валидации TOTP",
"transport_dest_exists": "Назначение для отправки \"%s\" уже существует",
"webauthn_verification_failed": "Ошибка валидации WebAuthn: %s",
"unknown": "Произошла неизвестная ошибка",
"unknown_tfa_method": "Неизвестный метод TFA",
"unlimited_quota_acl": "Неограниченная квота запрещена политикой доступа",
"username_invalid": "Имя пользователя %s нельзя использовать",
"validity_missing": "Пожалуйста, назначьте срок действия",
"value_missing": "Пожалуйста заполните все поля",
"yotp_verification_failed": "Ошибка валидации Yubico OTP: %s",
"cors_invalid_method": "Указан недопустимый метод разрешения",
"demo_mode_enabled": "Демонстрационный режим включен",
"cors_invalid_origin": "Указан неверный Allow-Origin"
"webauthn_authenticator_failed": "Выбранный аутентификатор не был найден",
"webauthn_publickey_failed": "Для выбранного аутентификатора не был сохранен открытый ключ",
"webauthn_username_failed": "Выбранный аутентификатор принадлежит другой учетной записи",
"webauthn_verification_failed": "Ошибка валидации WebAuthn: %s",
"yotp_verification_failed": "Ошибка валидации Yubico OTP: %s"
},
"datatables": {
"collapse_all": "Свернуть все",
"decimal": ",",
"emptyTable": "В таблице отсутствуют данные",
"expand_all": "Развернуть все",
"info": "Показаны записи с _START_ по _END_ из _TOTAL_",
"infoEmpty": "Показано 0 записей",
"infoFiltered": "(отфильтровано из _MAX_ всех записей)",
"infoPostFix": "",
"lengthMenu": "Показать _MENU_ записей",
"loadingRecords": "Загрузка...",
"processing": "Пожалуйста, подождите...",
"search": "Поиск:",
"thousands": " ",
"zeroRecords": "Не найдено соответствующих записей",
"paginate": {
"first": "Первая",
"last": "Последняя",
"next": "Следующая",
"previous": "Предыдущая"
},
"aria": {
"sortAscending": ": активируйте для сортировки столбца по возрастанию",
"sortDescending": ": активируйте для сортировки столбца по убыванию"
}
},
"debug": {
"architecture": "Архитектура",
"chart_this_server": "Диаграмма (текущий сервер)",
"containers_info": "Статус контейнеров Docker",
"container_running": "Работающий",
"container_disabled": "Контейнер остановлен или отключен",
"container_running": "Работающий",
"container_stopped": "Остановлен",
"containers_info": "Статус контейнеров Docker",
"cores": "яд.",
"current_time": "Системное время",
"disk_usage": "Использование дискового пространства",
"docs": "Проиндексировано объектов",
"error_show_ip": "Не удалось определить публичные IP-адреса",
"external_logs": "Внешние журналы",
"history_all_servers": "История (все серверы)",
"in_memory_logs": "Журналы контейнеров",
"jvm_memory_solr": "Использовано оперативной памяти JVM",
"last_modified": "Последние изменения",
"log_info": "<p><b>Журналы контейнеров</b> mailcow сохраняются в Redis, и раз в минуту строки журнала за пределами <code>LOG_LINES (%d)</code> удаляются, чтобы уменьшить нагрузку на сервер.\r\n <br>Сами журналы контейнеров не сохраняются после перезагрузки контейнера. Все контейнеры дополнительно пишут логи в службу Docker, и, следовательно, используют драйвер логирования по умолчанию. Журналы контейнеров предусмотрены только для отладки мелких проблем. Для других задач, пожалуйста, настройте драйвер логирования Docker самостоятельно.</p>\r\n <p><b>Внешние журналы</b> собираются через API приложений.</p>\r\n <p><b>Статические журналы</b> &ndash; это, в основном, журналы активности, которые не записываются в Dockerd, но все равно должны быть постоянными (за исключением журналов API).</p>",
"login_time": "Время входа",
"logs": "Журналы",
"memory": "Память",
"no_update_available": "Система обновлена до последней версии",
"online_users": "Подключено пользователей",
"restart_container": "Перезапустить",
"service": "Сервис",
"show_ip": "Показать публичные IP-адреса",
"size": "Индексы занимают",
"solr_dead": "Solr не запущен. Если вы включили Solf в файле настроек <code>mailcow.conf</code> и это сообщение отображается более получаса, скорее всего Solr сломан.",
"solr_status": "Состояние Solr",
"started_at": "Запущен",
"started_on": "Запущен в",
"static_logs": "Статические журналы",
"success": "Успех",
"no_update_available": "Система обновлена до последней версии",
"system_containers": "Система и контейнеры",
"timezone": "Часовой пояс",
"update_available": "Доступно обновление",
"update_failed": "Не удалось проверить наличие обновлений",
"uptime": "Время работы",
"username": "Имя пользователя"
"username": "Имя пользователя",
"wip": "В настоящее время идёт разработка"
},
"diagnostics": {
"cname_from_a": "Значение, полученное из записи A/AAAA. Это поддерживается до тех пор, пока запись указывает на правильный ресурс.",
@@ -514,7 +571,7 @@
"dns_records_name": "Название",
"dns_records_status": "Статус",
"dns_records_type": "Тип",
"optional": "Эта запись не обязательна."
"optional": "Эта запись необязательна."
},
"edit": {
"acl": "ACL (Список прав)",
@@ -527,6 +584,7 @@
"allowed_protocols": "Разрешённые протоколы",
"app_name": "Название приложения",
"app_passwd": "Пароль приложения",
"app_passwd_protocols": "Разрешенные протоколы для пароля приложения",
"automap": "Автоматическое слияние папок (\"Sent items\", \"Sent\" => \"Sent\" etc.)",
"backup_mx_options": "Параметры резервного копирования MX",
"bcc_dest_format": "Назначением для правила BCC должен быть единственный действительный адрес электронной почты.",
@@ -534,6 +592,7 @@
"client_secret": "Секретный ключ пользователя",
"comment_info": "Приватный комментарий не виден пользователям, а публичный - отображается рядом с псевдонимом в личном кабинете пользователя",
"created_on": "Дата создания",
"custom_attributes": "Пользовательские атрибуты",
"delete1": "Удаление из источника после завершения",
"delete2": "Удаление писем по месту назначения, которые не находятся на исходном",
"delete2duplicates": "Удаление дубликатов по назначению",
@@ -542,6 +601,19 @@
"disable_login": "Вход в систему запрещен",
"domain": "Изменение домена",
"domain_admin": "Изменение администратора домена",
"domain_footer": "Нижний колонтитул домена",
"domain_footer_html": "HTML нижний колонтитул",
"domain_footer_info": "Нижние колонтитулы на уровне домена добавляются ко всем исходящим электронным письмам, связанным с адресом в этом домене. <br> Для нижнего колонтитула можно использовать следующие переменные:",
"domain_footer_info_vars": {
"auth_user": "{= auth_user =} - Аутентифицированное имя пользователя, указанное MTA",
"custom": "{= foo =} - Если почтовый ящик имеет пользовательский атрибут \"foo\" со значением \"bar\", он возвращает \"bar\".",
"from_addr": "{= from_addr =} - Из адресной части envelope",
"from_domain": "{= from_domain =} - из доменной части envelope",
"from_name": "{= from_name =} - Из названия envelope, например, для \"Mailcow &lt;moo@mailcow.tld&gt;\" возвращается \"Mailcow\"",
"from_user": "{= from_user =} - Из пользовательской части envelope, например, для \"moo@mailcow.tld\" возвращается \"moo\""
},
"domain_footer_plain": "ПРОСТОЙ нижний колонтитул",
"domain_footer_skip_replies": "Ignore footer on reply e-mails",
"domain_quota": "Квота домена",
"domains": "Домены",
"dont_check_sender_acl": "Отключить проверку отправителя для домена %s и псевдонимов домена",
@@ -550,9 +622,9 @@
"exclude": "Исключить объекты (regex)",
"extended_sender_acl": "Внешние адреса почты",
"extended_sender_acl_info": "Для внешних доменов должен быть импортирован или сгенерирован доменный ключ DKIM с соответствующей записью TXT в домене, если внешний домен использует DMARC.<br>\r\n Не забудьте добавить этот сервер к соответствующей записи SPF TXT внешнего домена.<br>\r\n Добавление домена из списка внешних адресов в mailcow автоматически удалит соответствующие записи из внешних адресов пользователей.<br>\r\n Чтобы разрешить пользователю отправку от имени *@domain.tld, укажите @domain.tld.",
"footer_exclude": "Исключить из нижнего колонтитула",
"force_pw_update": "Требовать смены пароля при следующем входе в систему",
"force_pw_update_info": "Пользователь должен будет войти в %s и сменить свой пароль. mailcow OAuth2, SOGo, EAS, IMAP/POP3 и SMTP будут не доступны до смены пароля.",
"footer_exclude": "Исключить из нижнего колонтитула",
"full_name": "Полное имя",
"gal": "GAL - Глобальная адресная книга",
"gal_info": "GAL содержит все объекты домена и не подлежит редактированию. Информация о занятости в SOGo будет отсутствовать для домена, если данная функция будет отключена! <b>Требуется перезапустить SOGo, чтобы применить изменения.</b>",
@@ -566,6 +638,11 @@
"mailbox": "Изменение почтового аккаунта",
"mailbox_quota_def": "Квота по умолчанию",
"mailbox_relayhost_info": "Применяется только к почтовому ящику и личным псевдонимам, вне зависимости от настроек маршрутизации на уровне домена.",
"mailbox_rename": "Переименовать почтовый ящик",
"mailbox_rename_agree": "Я сделал резервную копию.",
"mailbox_rename_alias": "Автоматически создать псевдоним",
"mailbox_rename_title": "Новое имя локального почтового ящика",
"mailbox_rename_warning": "ВАЖНО! Перед переименованием почтового ящика создайте резервную копию.",
"max_aliases": "Максимум псевдонимов",
"max_mailboxes": "Максимум почтовых ящиков",
"max_quota": "Максимальная квота почтового аккаунта (MiB)",
@@ -574,9 +651,10 @@
"mbox_rl_info": "Этот лимит применяется к SASL логину пользователя и соответствует любому адресу отправителя, используемому зарегистрированным пользователем. Лимит скорости почтового аккаунта перекрывает лимит скорости для всего домена.",
"mins_interval": "Интервал (в минутах)",
"multiple_bookings": "Несколько бронирований",
"none_inherit": "Отсутствует / Наследуется",
"nexthop": "Следующий хост",
"none_inherit": "Отсутствует / Наследуется",
"password": "Пароль",
"password_recovery_email": "Адрес для восстановления пароля",
"password_repeat": "Подтверждение пароля (повтор)",
"previous": "Предыдущая страница",
"private_comment": "Приватный комментарий",
@@ -587,6 +665,7 @@
"pushover_only_x_prio": "Получать уведомления только об письмах с высоким приоритетом [<code>X-Priority: 1</code>]",
"pushover_sender_array": "Получать уведомления от списка адресов электронной почты <small>(envelop-from разделенные запятыми)</small>:",
"pushover_sender_regex": "Получать уведомления от отправителей, удовлетворяющих regex-выражению:",
"pushover_sound": "Звук уведомления",
"pushover_text": "Текст уведомления",
"pushover_title": "Заголовок уведомления",
"pushover_vars": "Когда фильтрация по отправителю не определена, уведомления будут доставлятся от всех отправителей.<br>Можно использовать обычный фильтр по отправителю и расширенный regex-фильтр, а также оба сразу.<br>Пожалуйста, ознакомьтесь с <a href=\"https://pushover.net/privacy\">Pushover Privacy Policy</a> перед использованием шаблонов для текста и заголовка",
@@ -600,7 +679,7 @@
"relay_all_info": "↪<small>Если вы решите <b>не</b> ретранслировать всех получателей, вам нужно будет добавить (\"слепой\") почтовый аккаунт для каждого получателя, которого следует ретранслировать.</small>",
"relay_domain": "Ретрансляция этого домена",
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Инфо</div> Вы можете настроить собственный транспорт для домена. Если такой настройки нет, то доставка будет выполнена на основе MX записей.",
"relay_unknown_only": "Ретрансляция только не существующих почтовых ящиков. Почта к существующим почтовым ящикам будут доставляться локально.",
"relay_unknown_only": "Ретрансляция только несуществующих почтовых ящиков. Почта к существующим почтовым ящикам будут доставляться локально.",
"relayhost": "Маршрутизация на основе отправителя",
"remove": "Удалить",
"resource": "Ресурс",
@@ -612,6 +691,8 @@
"sieve_desc": "Краткое описание",
"sieve_type": "Тип фильтра",
"skipcrossduplicates": "Пропускать повторяющиеся сообщения в папках",
"sogo_access": "Предоставить прямой доступ к SOGo",
"sogo_access_info": "Единый вход из интерфейса почты продолжает работать. Эта настройка не влияет на доступ ко всем другим службам, а также не удаляет или изменяет существующий профиль пользователя SOGo.",
"sogo_visible": "Отображать псевдоним в SOGo",
"sogo_visible_info": "Влияет только на объекты, которые могут отображаться в SOGo (персональные или общие псевдонимы, указывающие как минимум на один локальный почтовый аккаунт). Учтите, что если функция отключена, у пользователей не будет возможности выбрать адрес псевдонима в качестве отправителя в SOGo.",
"spam_alias": "Создать или изменить временные (спам) псевдонимы",
@@ -627,22 +708,7 @@
"title": "Изменение объекта",
"unchanged_if_empty": "Если без изменений - оставьте пустым",
"username": "Имя пользователя",
"validate_save": "Подтвердить и сохранить",
"sogo_access_info": "Единый вход из интерфейса почты продолжает работать. Эта настройка не влияет на доступ ко всем другим службам, а также не удаляет или изменяет существующий профиль пользователя SOGo.",
"app_passwd_protocols": "Разрешенные протоколы для пароля приложения",
"domain_footer_info": "Нижние колонтитулы на уровне домена добавляются ко всем исходящим электронным письмам, связанным с адресом в этом домене. <br> Для нижнего колонтитула можно использовать следующие переменные:",
"domain_footer_info_vars": {
"from_name": "{= from_name =} - Из названия envelope, например, для \"Mailcow &lt;moo@mailcow.tld&gt;\" возвращается \"Mailcow\"",
"auth_user": "{= auth_user =} - Аутентифицированное имя пользователя, указанное MTA",
"from_user": "{= from_user =} - Из пользовательской части envelope, например, для \"moo@mailcow.tld\" возвращается \"moo\"",
"from_addr": "{= from_addr =} - Из адресной части envelope",
"from_domain": "{= from_domain =} - из доменной части envelope",
"custom": "{= foo =} - Если почтовый ящик имеет пользовательский атрибут \"foo\" со значением \"bar\", он возвращает \"bar\"."
},
"domain_footer": "Нижний колонтитул домена",
"domain_footer_html": "HTML нижний колонтитул",
"domain_footer_plain": "ПРОСТОЙ нижний колонтитул",
"custom_attributes": "Пользовательские атрибуты"
"validate_save": "Подтвердить и сохранить"
},
"fido2": {
"confirm": "Подтвердить",
@@ -677,10 +743,10 @@
"header": {
"administration": "Настройка сервера",
"apps": "Приложения",
"debug": "Состояние сервера",
"debug": "Информация",
"email": "E-Mail",
"mailcow_system": "Система",
"mailcow_config": "Конфигурация",
"mailcow_system": "Система",
"quarantine": "Карантин",
"restart_netfilter": "Перезапустить netfilter",
"restart_sogo": "Перезапустить SOGo",
@@ -692,12 +758,19 @@
"session_expires": "Ваш сеанс закончится примерно через 15 секунд"
},
"login": {
"back_to_mailcow": "Вернуться к mailcow",
"delayed": "Вход был отложен на %s секунд.",
"fido2_webauthn": "FIDO2/WebAuthn Login",
"forgot_password": "> Забыли пароль?",
"invalid_pass_reset_token": "Токен восстановления пароля недействителен или срок его действия истек.<br>Пожалуйста, запросите новую ссылку для восстановления пароля.",
"login": "Войти",
"mobileconfig_info": "Пожалуйста, войдите в систему как пользователь почтового аккаунта для загрузки профиля подключения Apple.",
"new_password": "Новый пароль",
"new_password_confirm": "Повторите новый пароль",
"other_logins": "Вход с помощью ключа",
"password": "Пароль",
"request_reset_password": "Запросить восстановление пароля",
"reset_password": "Восстановление пароля",
"username": "Имя пользователя"
},
"mailbox": {
@@ -715,6 +788,7 @@
"add_mailbox": "Добавить почтовый аккаунт",
"add_recipient_map_entry": "Добавить перезапись получателя",
"add_resource": "Добавить ресурс",
"add_template": "Добавить шаблон",
"add_tls_policy_map": "Добавить политику TLS",
"address_rewriting": "Перезапись адресов",
"alias": "Псевдоним",
@@ -739,12 +813,12 @@
"bcc_to_rcpt": "Переключиться на тип \"получатель\"",
"bcc_to_sender": "Переключиться на тип \"отправитель\"",
"bcc_type": "Тип BCC",
"booking_null": "Всегда показывать как свободный",
"booking_0_short": "Всегда свободнен",
"booking_custom": "Лимит на количество бронирований",
"booking_custom_short": "Жесткий лимит",
"booking_ltnull": "Неограниченный, занят при бронировании",
"booking_lt0_short": "Неограниченный лимит",
"booking_ltnull": "Неограниченный, занят при бронировании",
"booking_null": "Всегда показывать как свободный",
"catch_all": "Catch-all",
"created_on": "Дата создания",
"daily": "Раз в день",
@@ -759,6 +833,7 @@
"domain_aliases": "Псевдонимы доменов",
"domain_quota": "Квота",
"domain_quota_total": "Квота домена",
"domain_templates": "Шаблоны доменов",
"domains": "Домены",
"edit": "Изменить",
"empty": "Пусто",
@@ -786,6 +861,7 @@
"mailbox_defaults_info": "Установите настройки по умолчанию для новых почтовых аккаунтов.",
"mailbox_defquota": "Квота по умолчанию",
"mailbox_quota": "Макс. квота почт. ящика",
"mailbox_templates": "Шаблоны почтовых ящиков",
"mailboxes": "Почтовые ящики",
"max_aliases": "Максимум псевдонимов",
"max_mailboxes": "Максимум почтовых ящиков",
@@ -813,16 +889,17 @@
"recipient_map_new": "Перезапись на",
"recipient_map_new_info": "Должен быть действующим почтовым ящиком.",
"recipient_map_old": "Получатель",
"recipient_map_old_info": "Должен быть валидный почтовым ящиком или доменом.",
"recipient_map_old_info": "Должен быть действующим почтовым ящиком или доменом.",
"recipient_maps": "Перезапись получателя",
"relay_all": "Ретрансляция всех получателей",
"relay_unknown": "Ретрансляция неизвестных получателей",
"remove": "Удалить",
"resources": "Ресурсы",
"running": "В процессе",
"sender": "Отправитель",
"set_postfilter": "Использовать как постфильтр",
"set_prefilter": "Использовать как предварительный фильтр",
"sieve_info": "Вы можете сохранить несколько фильтров для каждого пользователя, но только один предварительный фильтр и один постфильтр могут быть активными одновременно.<br>\r\n Каждый фильтр будет обработан в описанном порядке. Не сломанный скрипт, не <code>keep;</code> не остановит обработку дальнейших скриптов.<br><br>Global sieve prefilter &#8226; Prefilter &#8226; User scripts &#8226; Postfilter &#8226; Global sieve postfilter",
"sieve_info": "Вы можете сохранить несколько фильтров для каждого пользователя, но только один предварительный фильтр и один постфильтр могут быть активными одновременно.<br>\r\n Каждый фильтр будет обработан в описанном порядке. Ни сломанный скрипт, ни <code>keep;</code> не остановит обработку дальнейших скриптов.<br><br>Global sieve prefilter &#8226; Prefilter &#8226; User scripts &#8226; Postfilter &#8226; Global sieve postfilter",
"sieve_preset_1": "Discard mail with probable dangerous file types",
"sieve_preset_2": "Always mark the e-mail of a specific sender as seen",
"sieve_preset_3": "Discard silently, stop all further sieve processing",
@@ -830,7 +907,7 @@
"sieve_preset_5": "Auto responder (vacation)",
"sieve_preset_6": "Reject mail with response",
"sieve_preset_7": "Redirect and keep/drop",
"sieve_preset_8": "Discard message sent to an alias address the sender is part of",
"sieve_preset_8": "Переслать письмо от определенного отправителя, пометить его как прочитанное и поместить в подпапку",
"sieve_preset_header": "Пожалуйста, ознакомьтесь с примерами ниже. Для более подробной информации прочитайте <a href=\"https://en.wikipedia.org/wiki/Sieve_(mail_filtering_language)\" target=\"_blank\">Sieve Wikipedia</a>.",
"sogo_visible": "Отображать псевдоним в SOGo",
"sogo_visible_n": "Не отображать псевдоним в SOGo",
@@ -839,25 +916,27 @@
"stats": "Статистика",
"status": "Статус",
"sync_jobs": "Задания синхронизации",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "Ошибка авторизации",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Неправильное имя пользователя или пароль",
"syncjob_EXIT_CONNECTION_FAILURE": "Ошибка связи с сервером",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Не удалось подключиться к удаленному серверу",
"syncjob_EXIT_OVERQUOTA": "Целевой почтовый ящик превысил квоту",
"syncjob_EXIT_TLS_FAILURE": "Ошибка установки шифрованного соединения",
"syncjob_EX_OK": "Успешно",
"syncjob_check_log": "Проверить журнал",
"syncjob_last_run_result": "Результат последнего запуска",
"syncjob_EX_OK": "Успешно",
"syncjob_EXIT_CONNECTION_FAILURE": "Ошибка связи с сервером",
"syncjob_EXIT_TLS_FAILURE": "Ошибка установки шифрованного соединения",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "Ошибка авторизации",
"syncjob_EXIT_OVERQUOTA": "Целевой почтовый ящик превысил квоту",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Не удалось подключиться к удаленному серверу",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Неправильное имя пользователя или пароль",
"table_size": "Размер таблицы",
"table_size_show_n": "Отображать %s полей",
"target_address": "Владельцы псевдонима",
"target_domain": "Целевой домен",
"template": "Шаблон",
"templates": "Шаблоны",
"tls_enforce_in": "Принудительный TLS (входящие)",
"tls_enforce_out": "Принудительный TLS (исходящие)",
"tls_map_dest": "Назначение",
"tls_map_dest_info": "пример: example.org, .example.org, [mail.example.org]:25",
"tls_map_parameters": "Параметры",
"tls_map_parameters_info": "Оставьте поле пустым или укажите параметры, на пример: protocols=!SSLv2 ciphers=medium exclude=3DES",
"tls_map_parameters_info": "Оставьте поле пустым или укажите параметры, например: protocols=!SSLv2 ciphers=medium exclude=3DES",
"tls_map_policy": "Политика",
"tls_policy_maps": "Правила TLS",
"tls_policy_maps_enforced_tls": "Для исходящих сообщений от пользователей с включенной принудительной политикой шифрования исходящих соединений не описанные глобальной политикой,<br>\r\n будут применены значения по умолчанию, указанные в <code>smtp_tls_mandatory_protocols</code> и <code>smtp_tls_mandatory_ciphers</code>.",
@@ -932,14 +1011,27 @@
"type": "Тип"
},
"queue": {
"queue_manager": "Очередь на отправку"
"ays": "Пожалуйста, подтвердите, что вы хотите удалить все элементы из текущей очереди.",
"delete": "Удалить все",
"deliver_mail": "Доставить",
"deliver_mail_legend": "Попытаться повторно доставить выбранные письма.",
"flush": "Обработать очередь",
"hold_mail": "Отложить",
"hold_mail_legend": "Удержать выбранные сообщения. (Предотвратить дальнейшие попытки доставки)",
"info": "Очередь отправки почты содержит все письма, которые ожидают доставки. Если письмо надолго задерживается в почтовой очереди, оно автоматически удаляется системой.<br>Сообщение об ошибке в соответствующих письмах содержит информацию о том, почему письмо не удалось доставить.",
"legend": "Описание действий с почтовой очередью:",
"queue_manager": "Очередь на отправку",
"show_message": "Показать сообщение",
"unhold_mail": "Высвободить",
"unhold_mail_legend": "Освобождает выбранные письма для доставки. (Требуется предварительное удержание)",
"unban": "освободить очередь"
},
"ratelimit": {
"day": "сообщений / день",
"disabled": "Отключен",
"second": "сообщений / секунду",
"minute": "сообщений / минуту",
"hour": "сообщений / час",
"day": "сообщений / день"
"minute": "сообщений / минуту",
"second": "сообщений / секунду"
},
"start": {
"help": "Справка",
@@ -965,6 +1057,7 @@
"bcc_deleted": "Правила BCC удалены: %s",
"bcc_edited": "Правило BCC %s отредактировано",
"bcc_saved": "Правило BCC сохранено",
"cors_headers_edited": "Настройки CORS сохранены",
"db_init_complete": "Инициализация базы данных завершена",
"delete_filter": "Фильтр ID %s удалён",
"delete_filters": "Фильтры удалены: %s",
@@ -973,19 +1066,23 @@
"dkim_added": "DKIM ключ сохранён",
"dkim_duplicated": "DKIM ключи для домена %s были скопированы в %s",
"dkim_removed": "DKIM ключ %s удалён",
"domain_add_dkim_available": "DKIM ключ уже существует",
"domain_added": "Добавлен домен %s",
"domain_admin_added": "Администратор домена %s добавлен",
"domain_admin_modified": "Сохранить изменения администратора домена %s",
"domain_admin_removed": "Администратор домена %s удалён",
"domain_footer_modified": "Изменения в нижнем колонтитуле домена %s сохранены",
"domain_modified": "Сохранить изменения домена %s",
"domain_removed": "Домен %s удалён",
"dovecot_restart_success": "Dovecot перезапущен успешно",
"eas_reset": "Кеш ActiveSync для пользователя %s был сброшен",
"f2b_banlist_refreshed": "Идентификатор банлиста был успешно обновлен.",
"f2b_modified": "Изменения параметров Fail2ban сохранены",
"forwarding_host_added": "Перенаправление узла %s добавлено",
"forwarding_host_removed": "Перенаправление узла %s удалено",
"global_filter_written": "Фильтр успешно записан в файл",
"hash_deleted": "Хеш удалён",
"ip_check_opt_in_modified": "Параметры проверки IP успешно обновлены",
"item_deleted": "Обьект %s удалён",
"item_released": "Письмо %s восстановлено из карантина",
"items_deleted": "Обьекты %s удалены",
@@ -996,14 +1093,17 @@
"mailbox_added": "Почтовый аккаунт %s добавлен",
"mailbox_modified": "Изменения почтового аккаунта %s сохранены",
"mailbox_removed": "Почтовый аккаунт %s удалён",
"mailbox_renamed": "Почтовый аккаунт %s был переименован в %s",
"nginx_reloaded": "Обновление конфигурация Nginx закончено",
"object_modified": "Изменения объекта %s сохранены",
"password_changed_success": "Пароль был успешно изменен",
"password_policy_saved": "Политика паролей сохранена",
"pushover_settings_edited": "Настройки сохранены, пожалуйста, выполните проверку доступа",
"qlearn_spam": "Письмо ID %s было изучено как спам и удалено",
"queue_command_success": "Команда выполнена успешно",
"recipient_map_entry_deleted": "Правило перезаписи получателя ID %s было удалено",
"recipient_map_entry_saved": "Правило перезаписи получателя \"%s\" было сохранено",
"recovery_email_sent": "Письмо для восстановления пароля отправлено на %s",
"relayhost_added": "Промежуточный узел %s добавлен",
"relayhost_removed": "Промежуточный узел %s удалён",
"reset_main_logo": "Восстановить логотип по умолчанию",
@@ -1016,6 +1116,9 @@
"settings_map_added": "Правило добавлено",
"settings_map_removed": "Правило ID %s удалено",
"sogo_profile_reset": "Профиль пользователя SOGo %s сброшен",
"template_added": "Шаблон %s добавлен",
"template_modified": "Изменения шаблона %s сохранены",
"template_removed": "Шаблон ID %s удален",
"tls_policy_map_entry_deleted": "Политика TLS ID %s удалено",
"tls_policy_map_entry_saved": "Политика TLS \"%s\" сохранена",
"ui_texts": "Изменения текстов UI сохранены",
@@ -1023,13 +1126,11 @@
"verified_fido2_login": "Авторизация FIDO2 пройдена",
"verified_totp_login": "Авторизация TOTP пройдена",
"verified_webauthn_login": "Авторизация WebAuthn пройдена",
"verified_yotp_login": "Авторизация Yubico OTP пройдена",
"cors_headers_edited": "Настройки CORS сохранены",
"domain_footer_modified": "Изменения в нижнем колонтитуле домена %s сохранены",
"f2b_banlist_refreshed": "Идентификатор банлиста был успешно обновлен."
"verified_yotp_login": "Авторизация Yubico OTP пройдена"
},
"tfa": {
"api_register": "%s использует Yubico Cloud API. Пожалуйста, получите ключ API для вашего ключа <a href=\"https://upgrade.yubico.com/getapikey/\" target=\"_blank\">здесь</a>",
"authenticators": "Аутентификаторы",
"confirm": "Подтвердите",
"confirm_totp_token": "Пожалуйста, подтвердите изменения, введя сгенерированный код",
"delete_tfa": "Отключить TFA",
@@ -1048,11 +1149,12 @@
"tfa": "Двухфакторная проверка подлинности",
"tfa_token_invalid": "Неправильный TFA токен",
"totp": "OTP (Authy, Google Authenticator и др.)",
"webauthn": "WebAuthn аутентификация",
"u2f_deprecated": "Похоже, что ваш ключ был зарегистрирован с использованием устаревшего метода U2F. Мы деактивируем для вас двухфакторную аутентификацию и удалим ваш ключ.",
"u2f_deprecated_important": "Пожалуйста, зарегистрируйте ваш ключ в панели администратора с помощью нового метода WebAuthn.",
"waiting_usb_auth": "<i>Ожидание устройства USB...</i><br><br>Пожалуйста, нажмите кнопку на USB устройстве сейчас.",
"waiting_usb_register": "<i>Ожидание устройства USB...</i><br><br>Пожалуйста, введите пароль выше и подтвердите регистрацию, нажав кнопку на USB устройстве.",
"yubi_otp": "Yubico OTP аутентификация",
"u2f_deprecated": "Похоже, что ваш ключ был зарегистрирован с использованием устаревшего метода U2F. Мы деактивируем для вас двухфакторную аутентификацию и удалим ваш ключ."
"webauthn": "WebAuthn аутентификация",
"yubi_otp": "Yubico OTP аутентификация"
},
"user": {
"action": "Действия",
@@ -1069,13 +1171,17 @@
"alias_valid_until": "Действителен до",
"aliases_also_send_as": "Разрешено отправлять письма от имени",
"aliases_send_as_all": "Разрешено отправлять письма от любого имени для домена и его псевдонимов",
"allowed_protocols": "Разрешенные протоколы",
"app_hint": "Пароли приложений - это альтернативные пароли для авторизации в IMAP, SMTP, CalDAV, CardDAV и EAS. При этом имя пользователя остается неизменным. <br>SOGo недоступен через пароли приложений.",
"app_name": "Название приложения",
"app_passwds": "Пароли приложений",
"apple_connection_profile": "Профиль подключения Apple",
"apple_connection_profile_complete": "Этот профиль включает настройки IMAP и SMTP, а также CalDAV (календарей) и CardDAV (контактов) для устройства Apple.",
"apple_connection_profile_mailonly": "Этот профиль включает только настройки IMAP и SMTP для устройства Apple.",
"apple_connection_profile_with_app_password": "Новый пароль приложения генерируется и добавляется в профиль, поэтому при настройке устройства не требуется вводить пароль. Не предоставляйте доступ к файлу, поскольку он предоставляет полный доступ к вашему почтовому ящику.",
"attribute": "Атрибут",
"change_password": "Изменить пароль",
"change_password_hint_app_passwords": "В вашей учетной записи есть %d паролей приложений, которые не будут изменены. Чтобы управлять ими, перейдите на вкладку \"Пароли приложений\".",
"clear_recent_successful_connections": "Очистить историю успешных подключений",
"client_configuration": "Показать руководство по настройке почтовых клиентов и смартфонов",
"create_app_passwd": "Создать новый пароль",
@@ -1083,9 +1189,11 @@
"created_on": "Дата создания",
"daily": "Раз в день",
"day": "день",
"description": "Описание",
"delete_ays": "Пожалуйста, подтвердите удаление",
"direct_aliases": "Личные псевдонимы",
"direct_aliases_desc": "На личные псевдонимы распространяются фильтры нежелательной почты и параметры политики TLS.",
"direct_protocol_access": "Этот пользователь почтового ящика имеет <b>прямой, внешний доступ</b> к следующим протоколам и приложениям. Эта настройка контролируется вашим администратором. Для предоставления доступа к отдельным протоколам и приложениям могут быть созданы пароли приложений.<br> Кнопка \"Вход в веб-почту\" обеспечивает единый вход в SOGo и всегда доступна.",
"eas_reset": "Сбросить кеш ActiveSync устройств",
"eas_reset_help": "Во многих случаях сброс кеша устройств помогает восстановить повреждённый профиль ActiveSync.<br><b>Внимание:</b> все письма, календари и контакты будут загружены заново на все ваши устройства!",
"eas_reset_now": "Сбросить кеш сейчас",
@@ -1130,15 +1238,18 @@
"password": "Пароль",
"password_now": "Текущий пароль (подтверждение изменения)",
"password_repeat": "Подтверждение пароля (повтор)",
"password_reset_info": "If no email for password recovery is provided, this function cannot be used.",
"pushover_evaluate_x_prio": "Установить высокий приоритет уведомлений для писем с высоким приоритетом [<code>X-Priority: 1</code>]",
"pushover_info": "Настройки Push-уведомления будут применяться ко всей почте <b>%s</b> (за исключением спама), включая псевдонимы (личные, общие и тегированные).",
"pushover_only_x_prio": "Получать уведомления только о письмах с высоким приоритетом [<code>X-Priority: 1</code>]",
"pushover_sender_array": "Получать уведомления от списка адресов электронной почты <small>(envelop-from, разделённые запятыми)</small>:",
"pushover_sender_regex": "Получать уведомления от отправителей, удовлетворяющих regex-выражению:",
"pushover_sound": "Звук уведомления",
"pushover_text": "Текст уведомления",
"pushover_title": "Заголовок уведомления",
"pushover_vars": "Когда фильтрация по отправителю не определена, уведомения будут доставлятся от всех отправителей.<br>Можно использовать обычный фильтр по отправителю и расширенный regex-фильтр, а также оба сразу.<br>Пожалуйста, ознакомьтесь с <a href=\"https://pushover.net/privacy\">Pushover Privacy Policy</a> перед использованием шаблонов для текста и заголовка",
"pushover_verify": "Проверить доступ",
"pw_recovery_email": "Адрес для восстановления пароля",
"q_add_header": "Нежелательная почта",
"q_all": "Все категории",
"q_reject": "Отклонённая почта",
@@ -1179,15 +1290,15 @@
"spamfilter_yellow": "Жёлтый: эти письма могут быть спамом, будут доставлены в папку \"Спам\"",
"status": "Статус",
"sync_jobs": "Задания синхронизации",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "Ошибка авторизации",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Неправильное имя пользователя или пароль",
"syncjob_EXIT_CONNECTION_FAILURE": "Ошибка связи с сервером",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Не удалось подключиться к удаленному серверу",
"syncjob_EXIT_OVERQUOTA": "Целевой почтовый ящик превысил квоту",
"syncjob_EXIT_TLS_FAILURE": "Ошибка установки шифрованного соединения",
"syncjob_EX_OK": "Успешно",
"syncjob_check_log": "Проверить журнал",
"syncjob_last_run_result": "Результат",
"syncjob_EX_OK": "Успешно",
"syncjob_EXIT_CONNECTION_FAILURE": "Ошибка связи с сервером",
"syncjob_EXIT_TLS_FAILURE": "Ошибка установки шифрованного соединения",
"syncjob_EXIT_AUTHENTICATION_FAILURE": "Ошибка авторизации",
"syncjob_EXIT_OVERQUOTA": "Целевой почтовый ящик превысил квоту",
"syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Не удалось подключиться к удаленному серверу",
"syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Неправильное имя пользователя или пароль",
"tag_handling": "Обработка тегированной почты",
"tag_help_example": "Пример тегированного адреса электронной почты: <code>ich<b>+Facebook</b>@example.org</code>",
"tag_help_explain": "Переместить в подпапку: будет создана новая подпапка в INBOX с именем тега, например: \"INBOX/Facebook\".<br>\r\n Добавить к теме письма: имя тега будет добавлено к теме письма, например: \"[Facebook] My News\".",
@@ -1202,20 +1313,15 @@
"tls_policy_warning": "<strong>Предупреждение:</strong> Если вы включите принудительное шифрованние почты, вы можете столкнуться с потерей писем.<br>Сообщения, которые не соответствуют политике, будут отбрасываться с сообщением почтовым сервером о серьёзном сбое.<br>Этот параметр применяется к вашему основному адресу электронной почты (логину), всем личным псевдонимам и псевдонимам доменов. Подразумеваются только псевдонимы <b>с одним почтовым ящиком</b>, как получатель.",
"user_settings": "Настройки пользователя",
"username": "Имя пользователя",
"value": "Значение",
"verify": "Проверить",
"waiting": "В ожидании",
"week": "неделю",
"weekly": "Раз в неделю",
"weeks": "недели",
"year": "год",
"years": "лет",
"allowed_protocols": "Разрешенные протоколы",
"apple_connection_profile_with_app_password": "Новый пароль приложения генерируется и добавляется в профиль, поэтому при настройке устройства не требуется вводить пароль. Не предоставляйте доступ к файлу, поскольку он предоставляет полный доступ к вашему почтовому ящику.",
"direct_protocol_access": "Этот пользователь почтового ящика имеет <b>прямой, внешний доступ</b> к следующим протоколам и приложениям. Эта настройка контролируется вашим администратором. Для предоставления доступа к отдельным протоколам и приложениям могут быть созданы пароли приложений.<br> Кнопка \"Вход в веб-почту\" обеспечивает единый вход в SOGo и всегда доступна.",
"with_app_password": "с паролем приложения",
"change_password_hint_app_passwords": "В вашей учетной записи есть {{number_of_app_passwords}} паролей приложений, которые не будут изменены. Чтобы управлять ими, перейдите на вкладку \"Пароли приложений\".",
"attribute": "Атрибут",
"value": "Значение"
"year": "год",
"years": "лет"
},
"warning": {
"cannot_delete_self": "Вы не можете удалить сами себя",
@@ -1229,10 +1335,5 @@
"quota_exceeded_scope": "Квота домена превышена: могут быть созданы только почтовые ящики без лимита.",
"session_token": "Неверный токен формы: несоответствие токена",
"session_ua": "Неверный токен формы: ошибка проверки User-Agent"
},
"datatables": {
"collapse_all": "Свернуть все",
"expand_all": "Развернуть все",
"infoPostFix": ""
}
}
}

View File

@@ -3,11 +3,11 @@
"app_passwds": "Upravljaj gesla aplikacij",
"bcc_maps": "Preslikave SKP (BCC)",
"delimiter_action": "Dejanje ločila",
"domain_relayhost": "Spremeni gostitelja relay za domeno",
"domain_relayhost": "Spremenite posrednika za domeno",
"eas_reset": "Ponastavi EAS naprave",
"filters": "Filtri",
"login_as": "Prijavi se kot uporabnik poštnega predala",
"mailbox_relayhost": "Spremeni gostitelja relay za poštni predal",
"mailbox_relayhost": "Spremenite posrednika za e-poštni nabiralnik",
"prohibited": "Prepovedano z ACL",
"protocol_access": "Spremeni dostop do protokola",
"pushover": "Pushover",
@@ -17,33 +17,34 @@
"ratelimit": "Omejitev pošiljanja",
"recipient_maps": "Preslikave prejemnikov",
"smtp_ip_access": "Spremeni dovoljene gostitelje za SMTP",
"sogo_access": "Dovoli upravljanje SOGo dostopov",
"sogo_access": "Dovoli upravljanje SOGo dostopa",
"sogo_profile_reset": "Ponastavi SOGo profil",
"spam_alias": "Začasni aliasi",
"spam_policy": "Blacklist/Whitelist",
"spam_alias": "Začasni vzdevki",
"spam_policy": "Črna lista/Bela lista",
"spam_score": "Ocena neželene pošte",
"tls_policy": "Politika TLS",
"unlimited_quota": "Neomejena kvota za poštne predale",
"alias_domains": "Dodaj alias domene",
"alias_domains": "Dodaj vzdevke domen",
"domain_desc": "Spremeni opis domene",
"extend_sender_acl": "Dovoli razširitev pošiljateljevega ACL z zunanjimi e-poštnimi naslovi",
"quarantine_category": "Spremeni kategorijo obvestil o karanteni",
"syncjobs": "Opravila sinhronizacije"
"syncjobs": "Sinhronizacijska opravila",
"pw_reset": "Dovoli ponastavitev uporabniškega gesla mailcow"
},
"add": {
"active": "Aktivno",
"add": "Dodaj",
"add_domain_only": "Dodaj samo domeno",
"add_domain_restart": "Dodaj domeno in ponovno zaženi SOGo",
"alias_address": "Alias naslov/i",
"alias_domain": "Alias domena",
"alias_address": "Naslov/i vzdevk/a/ov",
"alias_domain": "Vzdevek domene",
"alias_domain_info": "<small>Samo veljavne domene (ločene z vejico).</small>",
"app_name": "Ime aplikacije",
"app_password": "Dodaj geslo aplikacije",
"app_passwd_protocols": "Dovoljeni protokoli za geslo aplikacije",
"automap": "Poskusi samodejno preslikati mape (\"Sent items\", \"Sent\" => \"Poslano\" ipd.)",
"backup_mx_options": "Možnosti posredovanja (relay)",
"comment_info": "Zasebni komentarji niso vidni uporabnikom, javni komentarji pa so prikazani kot tooltip, ko se z miško postavimo nad uporabnika v pregledu",
"comment_info": "Zasebni komentarji niso vidni uporabnikom, javni komentarji pa so prikazani kot opis, ko se z miško postavimo nad uporabnika v pregledu",
"custom_params": "Parametri po meri",
"custom_params_hint": "Pravilno: --param=xy, napačno: --param xy",
"delete1": "Izbriši na viru, ko je končano",
@@ -67,7 +68,7 @@
"kind": "Tip",
"mailbox_quota_def": "Privzeta kvota za poštni predal",
"mailbox_username": "Uporabniško ime (levi del e-poštnega naslova)",
"max_aliases": "Največje število dovoljenih aliasov",
"max_aliases": "Največje število dovoljenih vzdevkov",
"max_mailboxes": "Največje dovoljeno število poštnih predalov",
"mins_interval": "Interval preverjanja (minute)",
"multiple_bookings": "Več rezervacij",
@@ -88,25 +89,25 @@
"sieve_type": "Vrsta filtra",
"skipcrossduplicates": "Preskoči podvojena sporočila po mapah (prvi pride, prvi melje)",
"subscribeall": "Prijavi vse mape",
"syncjob": "Dodaj opravilo sinhronizacije",
"syncjob": "Dodaj sinhronizacijsko opravilo",
"tags": "Oznake",
"target_address": "Goto naslov",
"target_address": "Pojdi na naslov",
"target_address_info": "<small>Polni e-poštni naslov/i (ločeni z vejico).</small>",
"target_domain": "Ciljna domena",
"timeout1": "Časovna omejitev za povezavo do oddaljenega gostitelja",
"username": "Uporabniško ime",
"validate": "Preveri",
"validation_success": "Uspešno preverjeno",
"activate_filter_warn": "Ko je aktivni izbran, bodo vsi ostali filtri deaktivirani.",
"alias_address_info": "<small>Polni email naslov/i oziroma @example.com za zajem vseh sporočil domene (ločeno z vejico), <b>samo domene mailcow</b>.</small>",
"bcc_dest_format": "BCC naslov mora biti en veljaven e-poštni naslov.<br>Če morate poslati kopijo na več naslov, ustvarite alias in ga uporabite tukaj.",
"validate": "Potrditev",
"validation_success": "Uspešno potrjeno",
"activate_filter_warn": "Vsi drugi filtri bodo deaktivirani, če je označeno aktivno.",
"alias_address_info": "<small>Polni e-poštni naslov/i oziroma @example.com za zajem vseh sporočil domene (ločeno z vejico), <b>samo domene mailcow</b>.</small>",
"bcc_dest_format": "BCC naslov mora biti en veljaven e-poštni naslov.<br>Če morate poslati kopijo na več naslov, ustvarite vzdevek in ga uporabite tukaj.",
"disable_login": "Prepovej vpis (vhodna e-pošta je še vedno sprejeta)",
"gal_info": "GAL vsebuje vse objekte domene in ga uporabniki ne morejo urejati. Informacija o zasedenosti v SOGo ni na voljo, če je onemogočena! <b>Ponovno zaženi SOGo za uveljavitev sprememb.</b>",
"mailbox_quota_m": "Najvišja kvota na poštni predal (MiB)",
"password": "Geslo",
"post_domain_add": "SOGo container \"sogo-mailcow\" mora biti ponovno zagnan po dodajanju nove domene!<br><br>Dodatno se mora preveriti DNS konfiguracija domene. Ko je DNS konfiguracija domene odobrena, ponovno zaženite \"acme-mailcow\" za samodejno generiranje certifikatov za novo domeno (autoconfig.&lt;domain&gt;, autodiscover.&lt;domain&gt;).<br>Ta korak je opcijski in se ponovno poskuša vsakih 24 ur.",
"post_domain_add": "SOGo zabojnik\"sogo-mailcow\" mora biti ponovno zagnan po dodajanju nove domene!<br><br>Dodatno se mora preveriti DNS konfiguracija domene. Ko je DNS konfiguracija domene odobrena, ponovno zaženite \"acme-mailcow\" za samodejno generiranje certifikatov za novo domeno (autoconfig.&lt;domain&gt;, autodiscover.&lt;domain&gt;).<br>Ta korak je opcijski in se ponovno poskuša vsakih 24 ur.",
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Info</div> Definirate lahko preslikave transportov za cilj po meri za to domeno. Če ni nastavljena, se ustvari MX poizvedba.",
"syncjob_hint": "Pozor! Gesla se morajo shraniti v plain-text!",
"syncjob_hint": "Pozor! Gesla se morajo shraniti v golo besedilo!",
"timeout2": "Časovna omejitev za povezavo do lokalnega gostitelja",
"dry": "Simuliraj sinhronizacijo"
},
@@ -124,7 +125,7 @@
"add_row": "Dodaj vrstico",
"add_settings_rule": "Dodaj pravilo nastavitev",
"add_transport": "Dodaj transport",
"add_transports_hint": "Prosimo zavedajte se, da se podatki za avtentikacijo, če obstajajo, shranijo v plain text.",
"add_transports_hint": "Prosimo zavedajte se, da se podatki za avtentikacijo, če obstajajo, shranijo v golo besedilo.",
"additional_rows": " nove vrstice so bile dodane",
"admin_details": "Uredi podrobnosti skrbnika",
"admin_domains": "Dodeljene domene",
@@ -282,7 +283,7 @@
"rspamd_global_filters_agree": "Previden bom!",
"rspamd_global_filters_info": "Globalne preslikave filtrov vsebujejo različne vrste globalnih blacklist in whitelist.",
"add_admin": "Dodaj skrbnika",
"add_relayhost_hint": "Prosimo zavedajte se, da se podatki za avtentikacijo, če obstajajo, shranijo v plain text.",
"add_relayhost_hint": "Prosimo zavedajte se, da se podatki za avtentikacijo, če obstajajo, shranijo v golo besedilo.",
"admin": "Skrbnik",
"api_allow_from": "Dovoli API dostop s teh IP naslovov / CIDR mrežnih zapisov",
"apps_name": "Ime aplikacije v mailcow",
@@ -500,12 +501,9 @@
"last_modified": "Nazadnje spremenjeno",
"history_all_servers": "Zgodovina (vsi strežniki)",
"in_memory_logs": "In-memory dnevniki",
"jvm_memory_solr": "JVM zasedenost spomina",
"service": "Servis",
"show_ip": "Prikaži javni IP",
"size": "Velikost",
"solr_dead": "Solr se zaganja, je onemogočen ali se je ustavil.",
"solr_status": "Status Solr",
"started_at": "Zagnano ob",
"started_on": "Zagnano na",
"static_logs": "Statični dnevniki",

View File

@@ -499,7 +499,6 @@
"external_logs": "Externé logy",
"history_all_servers": "História (všetky servery)",
"in_memory_logs": "Logy uložené v pamäti",
"jvm_memory_solr": "JVM spotreba pamäte",
"last_modified": "Naposledy upravené",
"log_info": "<b>Logy v pamäti</b> sú zbierané do Redis listu s max. limitom LOG_LINES (%d) riadkov každú minútu, čo bráni nadmernej záťaži servera.\r\n <br>Logy v pamäti nemajú trvalý charakter. Všetky aplikácie ktoré vedú logy v pamäti, tiež logujú do Docker démona a súčasne do nastaveného logging drivera.\r\n <br>Logy v pamäti sa môžu použiť na ladenie menších problémov s kontajnermi.</p>\r\n <p><b>Externé logy</b> sú zbierané cez API danej aplikácie.</p>\r\n <p><b>Statické logy</b> sú väčšinou aktivity, ktoré nie sú logované do Docker démona, ale musia byť trvalo zaznamenané (s výnimkou API záznamov).</p>",
"login_time": "Čas",
@@ -508,8 +507,6 @@
"restart_container": "Reštartovať",
"service": "Služba",
"size": "Veľkosť",
"solr_dead": "Solr štartuje, je vypnutý alebo nebeží.",
"solr_status": "Solr status",
"started_at": "Spustený",
"started_on": "Spustený",
"static_logs": "Statické logy",
@@ -1116,6 +1113,7 @@
"created_on": "Vytvorené",
"daily": "Denne",
"day": "deň",
"description": "Popis",
"delete_ays": "Potvrďte zmazanie.",
"direct_aliases": "Priame alias adresy",
"direct_aliases_desc": "Priame aliasy sú ovplyvnené spam filtrom a nastavením TLS pravidiel.",
@@ -1258,4 +1256,4 @@
"session_token": "Formulárový token neplatný: Tokenová nezhoda",
"session_ua": "Formulárový token neplatný: User-Agent validation error"
}
}
}

View File

@@ -453,17 +453,14 @@
"external_logs": "Externa loggar",
"history_all_servers": "Historik (alla servrar)",
"in_memory_logs": "Loggar sparade i minnet",
"jvm_memory_solr": "JVM minnesanvändning",
"log_info": "<p>mailcow <b>loggar sparade i minnet</b> samlas in i Redis-listor och trimmas till LOG_LINES (%d) varje minut för att minska lasten.\r\n <br>Loggar sparade i minnet är inte tänkta att vara beständiga. Alla applikationer som loggar i minnet loggar också till Docker-demonen och därefter till standardrutinen för loggning.\r\n <br>Loggar sparade i minnet bör användas för felsökning av mindre problem med olika behållare.</p>\r\n <p><b>Externa loggar</b> samlas in via ett API på den givna applikationen.</p>\r\n <p><b>Statiska loggar</b> är mestadels aktivitetsloggar som inte är loggas i Docker, men som fortfarande måste vara beständiga (utom API-loggar).</p>",
"logs": "Loggar",
"restart_container": "Omstart",
"solr_dead": "Solr är i uppstart, har inaktiveras eller är tillfälligt avstängd.",
"online_users": "Användare online",
"docs": "Dokumentation",
"last_modified": "Senast ändrad",
"size": "Storlek",
"started_at": "Startades kl.",
"solr_status": "Solr status",
"uptime": "Upptid",
"started_on": "Startades",
"static_logs": "Statiska loggar",
@@ -993,6 +990,7 @@
"created_on": "Skapad vid",
"daily": "Dagligen",
"day": "dag",
"description": "Beskrivning",
"delete_ays": "Är du säker att du vill ta bort det här objektet?",
"direct_aliases": "Direkta aliasadresser",
"direct_aliases_desc": "Endast direkta aliasadresser påverkas av spamfilter och TLS-policyföreskrifter.",
@@ -1112,4 +1110,4 @@
"session_token": "Formulär-nyckeln är ogiltig: Nyckeln matchar inte",
"session_ua": "Formulär-nyckeln är ogiltig: User-Agenten kunde inte valideras"
}
}
}

Some files were not shown because too many files have changed in this diff Show More