Compare commits
81 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
428b917579 | ||
|
469f959e96 | ||
|
b68e189d97 | ||
|
028ef22878 | ||
|
0194c39bd5 | ||
|
f53ca24bb0 | ||
|
ae46a877d3 | ||
|
400939faf6 | ||
|
fd0205aafd | ||
|
e367a8ce24 | ||
|
096e2a41e9 | ||
|
e010f08143 | ||
|
3d2483ca37 | ||
|
535dd23509 | ||
|
4336a99c6a | ||
|
4cd5f93cdf | ||
|
67955779b0 | ||
|
26c34b484a | ||
|
4021613059 | ||
|
e891bf8411 | ||
|
f7798d1aac | ||
|
d11f00261b | ||
|
22cd12f37b | ||
|
db2fb12837 | ||
|
e808e595eb | ||
|
ce6742c676 | ||
|
cf3dc584d0 | ||
|
62f3603588 | ||
|
9fd4aa93e9 | ||
|
5bc3d93545 | ||
|
c28a6b89f0 | ||
|
1233613bea | ||
|
0206e0886c | ||
|
f6d135fbad | ||
|
f7da314dcf | ||
|
e6ce5e88f7 | ||
|
0f59d4952b | ||
|
7225bd2f55 | ||
|
deb2b80352 | ||
|
ad9dee92be | ||
|
f36bc16ca7 | ||
|
bda5f0ed4a | ||
|
cbe1c97a82 | ||
|
81fcbdd104 | ||
|
1a9294b58f | ||
|
310c01aac2 | ||
|
229303c1f8 | ||
|
fc075bc6b7 | ||
|
d04f0257c2 | ||
|
d11d356803 | ||
|
c54750ef8b | ||
|
510ef5196b | ||
|
04e46f9f5b | ||
|
6c0a5028c0 | ||
|
791bbeeb39 | ||
|
a5b8f1b7f7 | ||
|
af267ff706 | ||
|
46cc022590 | ||
|
f77c65411d | ||
|
1052e13af8 | ||
|
11e1502b12 | ||
|
02afc45a15 | ||
|
3e1cfe0d08 | ||
|
d20df7d73e | ||
|
a8c61daeaf | ||
|
1a4f11209a | ||
|
04403aaf70 | ||
|
7f0dd7d0d7 | ||
|
cd29ad883e | ||
|
e1cd719a17 | ||
|
15bb331a7d | ||
|
6f3179bb8d | ||
|
29e5b87207 | ||
|
4403bc2d18 | ||
|
63e92e0897 | ||
|
aa4d8b1f47 | ||
|
9054ca18be | ||
|
38291d123f | ||
|
ca64ff2c0b | ||
|
dc85f49961 | ||
|
5dca4dac81 |
@@ -14,7 +14,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Mark/Close Stale Issues and Pull Requests 🗑️
|
||||
uses: actions/stale@v7.0.0
|
||||
uses: actions/stale@v8.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.STALE_ACTION_PAT }}
|
||||
days-before-stale: 60
|
||||
|
2
.github/workflows/pr_to_nightly.yml
vendored
2
.github/workflows/pr_to_nightly.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Run the Action
|
||||
uses: devops-infra/action-pull-request@v0.5.3
|
||||
uses: devops-infra/action-pull-request@v0.5.5
|
||||
with:
|
||||
github_token: ${{ secrets.PRTONIGHTLY_ACTION_PAT }}
|
||||
title: Automatic PR to nightly from ${{ github.event.repository.updated_at}}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
FROM clamav/clamav:1.0_base
|
||||
FROM clamav/clamav:1.0.1-1_base
|
||||
|
||||
LABEL maintainer "André Peters <andre.peters@servercow.de>"
|
||||
|
||||
|
@@ -380,7 +380,12 @@ class DockerUtils:
|
||||
if 'maildir' in request_json:
|
||||
for container in self.docker_client.containers.list(filters={"id": container_id}):
|
||||
sane_name = re.sub(r'\W+', '', request_json['maildir'])
|
||||
cmd = ["/bin/bash", "-c", "if [[ -d '/var/vmail/" + request_json['maildir'].replace("'", "'\\''") + "' ]]; then /bin/mv '/var/vmail/" + request_json['maildir'].replace("'", "'\\''") + "' '/var/vmail/_garbage/" + str(int(time.time())) + "_" + sane_name + "'; fi"]
|
||||
vmail_name = request_json['maildir'].replace("'", "'\\''")
|
||||
index_name = request_json['maildir'].split("/")
|
||||
index_name = index_name[1].replace("'", "'\\''") + "@" + index_name[0].replace("'", "'\\''")
|
||||
cmd_vmail = "if [[ -d '/var/vmail/" + vmail_name + "' ]]; then /bin/mv '/var/vmail/" + vmail_name + "' '/var/vmail/_garbage/" + str(int(time.time())) + "_" + sane_name + "'; fi"
|
||||
cmd_vmail_index = "if [[ -d '/var/vmail_index/" + index_name + "' ]]; then /bin/mv '/var/vmail_index/" + index_name + "' '/var/vmail/_garbage/" + str(int(time.time())) + "_" + sane_name + "_index'; fi"
|
||||
cmd = ["/bin/bash", "-c", cmd_vmail + " && " + cmd_vmail_index]
|
||||
maildir_cleanup = container.exec_run(cmd, user='vmail')
|
||||
return exec_run_handler('generic', maildir_cleanup)
|
||||
# api call: container_post - post_action: exec - cmd: rspamd - task: worker_password
|
||||
|
@@ -21,6 +21,7 @@ RUN groupadd -g 5000 vmail \
|
||||
&& touch /etc/default/locale \
|
||||
&& apt-get update \
|
||||
&& apt-get -y --no-install-recommends install \
|
||||
build-essential \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
cpanminus \
|
||||
@@ -61,6 +62,7 @@ RUN groupadd -g 5000 vmail \
|
||||
libproc-processtable-perl \
|
||||
libreadonly-perl \
|
||||
libregexp-common-perl \
|
||||
libssl-dev \
|
||||
libsys-meminfo-perl \
|
||||
libterm-readkey-perl \
|
||||
libtest-deep-perl \
|
||||
@@ -110,6 +112,8 @@ RUN groupadd -g 5000 vmail \
|
||||
&& apt-get autoclean \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& rm -rf /tmp/* /var/tmp/* /root/.cache/
|
||||
# imapsync dependencies
|
||||
RUN cpan Crypt::OpenSSL::PKCS12
|
||||
|
||||
COPY trim_logs.sh /usr/local/bin/trim_logs.sh
|
||||
COPY clean_q_aged.sh /usr/local/bin/clean_q_aged.sh
|
||||
|
@@ -8492,6 +8492,7 @@ sub xoauth2
|
||||
require HTML::Entities ;
|
||||
require JSON ;
|
||||
require JSON::WebToken::Crypt::RSA ;
|
||||
require Crypt::OpenSSL::PKCS12;
|
||||
require Crypt::OpenSSL::RSA ;
|
||||
require Encode::Byte ;
|
||||
require IO::Socket::SSL ;
|
||||
@@ -8532,8 +8533,9 @@ sub xoauth2
|
||||
|
||||
$sync->{ debug } and myprint( "Service account: $iss\nKey file: $keyfile\nKey password: $keypass\n");
|
||||
|
||||
# Get private key from p12 file (would be better in perl...)
|
||||
$key = `openssl pkcs12 -in "$keyfile" -nodes -nocerts -passin pass:$keypass -nomacver`;
|
||||
# Get private key from p12 file
|
||||
my $pkcs12 = Crypt::OpenSSL::PKCS12->new_from_file($keyfile);
|
||||
$key = $pkcs12->private_key($keypass);
|
||||
|
||||
$sync->{ debug } and myprint( "Private key:\n$key\n");
|
||||
}
|
||||
|
@@ -64,28 +64,40 @@ def refreshF2boptions():
|
||||
global f2boptions
|
||||
global quit_now
|
||||
global exit_code
|
||||
|
||||
f2boptions = {}
|
||||
|
||||
if not r.get('F2B_OPTIONS'):
|
||||
f2boptions = {}
|
||||
f2boptions['ban_time'] = int
|
||||
f2boptions['max_attempts'] = int
|
||||
f2boptions['retry_window'] = int
|
||||
f2boptions['netban_ipv4'] = int
|
||||
f2boptions['netban_ipv6'] = int
|
||||
f2boptions['ban_time'] = r.get('F2B_BAN_TIME') or 1800
|
||||
f2boptions['max_attempts'] = r.get('F2B_MAX_ATTEMPTS') or 10
|
||||
f2boptions['retry_window'] = r.get('F2B_RETRY_WINDOW') or 600
|
||||
f2boptions['netban_ipv4'] = r.get('F2B_NETBAN_IPV4') or 32
|
||||
f2boptions['netban_ipv6'] = r.get('F2B_NETBAN_IPV6') or 128
|
||||
r.set('F2B_OPTIONS', json.dumps(f2boptions, ensure_ascii=False))
|
||||
f2boptions['ban_time'] = r.get('F2B_BAN_TIME')
|
||||
f2boptions['max_ban_time'] = r.get('F2B_MAX_BAN_TIME')
|
||||
f2boptions['ban_time_increment'] = r.get('F2B_BAN_TIME_INCREMENT')
|
||||
f2boptions['max_attempts'] = r.get('F2B_MAX_ATTEMPTS')
|
||||
f2boptions['retry_window'] = r.get('F2B_RETRY_WINDOW')
|
||||
f2boptions['netban_ipv4'] = r.get('F2B_NETBAN_IPV4')
|
||||
f2boptions['netban_ipv6'] = r.get('F2B_NETBAN_IPV6')
|
||||
else:
|
||||
try:
|
||||
f2boptions = {}
|
||||
f2boptions = json.loads(r.get('F2B_OPTIONS'))
|
||||
except ValueError:
|
||||
print('Error loading F2B options: F2B_OPTIONS is not json')
|
||||
quit_now = True
|
||||
exit_code = 2
|
||||
|
||||
verifyF2boptions(f2boptions)
|
||||
r.set('F2B_OPTIONS', json.dumps(f2boptions, ensure_ascii=False))
|
||||
|
||||
def verifyF2boptions(f2boptions):
|
||||
verifyF2boption(f2boptions,'ban_time', 1800)
|
||||
verifyF2boption(f2boptions,'max_ban_time', 10000)
|
||||
verifyF2boption(f2boptions,'ban_time_increment', True)
|
||||
verifyF2boption(f2boptions,'max_attempts', 10)
|
||||
verifyF2boption(f2boptions,'retry_window', 600)
|
||||
verifyF2boption(f2boptions,'netban_ipv4', 32)
|
||||
verifyF2boption(f2boptions,'netban_ipv6', 128)
|
||||
|
||||
def verifyF2boption(f2boptions, f2boption, f2bdefault):
|
||||
f2boptions[f2boption] = f2boptions[f2boption] if f2boption in f2boptions and f2boptions[f2boption] is not None else f2bdefault
|
||||
|
||||
def refreshF2bregex():
|
||||
global f2bregex
|
||||
global quit_now
|
||||
@@ -147,6 +159,7 @@ def ban(address):
|
||||
global lock
|
||||
refreshF2boptions()
|
||||
BAN_TIME = int(f2boptions['ban_time'])
|
||||
BAN_TIME_INCREMENT = bool(f2boptions['ban_time_increment'])
|
||||
MAX_ATTEMPTS = int(f2boptions['max_attempts'])
|
||||
RETRY_WINDOW = int(f2boptions['retry_window'])
|
||||
NETBAN_IPV4 = '/' + str(f2boptions['netban_ipv4'])
|
||||
@@ -174,20 +187,16 @@ def ban(address):
|
||||
net = ipaddress.ip_network((address + (NETBAN_IPV4 if type(ip) is ipaddress.IPv4Address else NETBAN_IPV6)), strict=False)
|
||||
net = str(net)
|
||||
|
||||
if not net in bans or time.time() - bans[net]['last_attempt'] > RETRY_WINDOW:
|
||||
bans[net] = { 'attempts': 0 }
|
||||
active_window = RETRY_WINDOW
|
||||
else:
|
||||
active_window = time.time() - bans[net]['last_attempt']
|
||||
if not net in bans:
|
||||
bans[net] = {'attempts': 0, 'last_attempt': 0, 'ban_counter': 0}
|
||||
|
||||
bans[net]['attempts'] += 1
|
||||
bans[net]['last_attempt'] = time.time()
|
||||
|
||||
active_window = time.time() - bans[net]['last_attempt']
|
||||
|
||||
if bans[net]['attempts'] >= MAX_ATTEMPTS:
|
||||
cur_time = int(round(time.time()))
|
||||
logCrit('Banning %s for %d minutes' % (net, BAN_TIME / 60))
|
||||
NET_BAN_TIME = BAN_TIME if not BAN_TIME_INCREMENT else BAN_TIME * 2 ** bans[net]['ban_counter']
|
||||
logCrit('Banning %s for %d minutes' % (net, NET_BAN_TIME / 60 ))
|
||||
if type(ip) is ipaddress.IPv4Address:
|
||||
with lock:
|
||||
chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), 'MAILCOW')
|
||||
@@ -206,7 +215,7 @@ def ban(address):
|
||||
rule.target = target
|
||||
if rule not in chain.rules:
|
||||
chain.insert_rule(rule)
|
||||
r.hset('F2B_ACTIVE_BANS', '%s' % net, cur_time + BAN_TIME)
|
||||
r.hset('F2B_ACTIVE_BANS', '%s' % net, cur_time + NET_BAN_TIME)
|
||||
else:
|
||||
logWarn('%d more attempts in the next %d seconds until %s is banned' % (MAX_ATTEMPTS - bans[net]['attempts'], RETRY_WINDOW, net))
|
||||
|
||||
@@ -238,7 +247,8 @@ def unban(net):
|
||||
r.hdel('F2B_ACTIVE_BANS', '%s' % net)
|
||||
r.hdel('F2B_QUEUE_UNBAN', '%s' % net)
|
||||
if net in bans:
|
||||
del bans[net]
|
||||
bans[net]['attempts'] = 0
|
||||
bans[net]['ban_counter'] += 1
|
||||
|
||||
def permBan(net, unban=False):
|
||||
global lock
|
||||
@@ -332,7 +342,7 @@ def watch():
|
||||
logWarn('%s matched rule id %s (%s)' % (addr, rule_id, item['data']))
|
||||
ban(addr)
|
||||
except Exception as ex:
|
||||
logWarn('Error reading log line from pubsub')
|
||||
logWarn('Error reading log line from pubsub: %s' % ex)
|
||||
quit_now = True
|
||||
exit_code = 2
|
||||
|
||||
@@ -359,21 +369,30 @@ def snat4(snat_target):
|
||||
chain = iptc.Chain(table, 'POSTROUTING')
|
||||
table.autocommit = False
|
||||
new_rule = get_snat4_rule()
|
||||
for position, rule in enumerate(chain.rules):
|
||||
match = all((
|
||||
new_rule.get_src() == rule.get_src(),
|
||||
new_rule.get_dst() == rule.get_dst(),
|
||||
new_rule.target.parameters == rule.target.parameters,
|
||||
new_rule.target.name == rule.target.name
|
||||
))
|
||||
if position == 0:
|
||||
if not match:
|
||||
logInfo(f'Added POSTROUTING rule for source network {new_rule.src} to SNAT target {snat_target}')
|
||||
chain.insert_rule(new_rule)
|
||||
else:
|
||||
if match:
|
||||
logInfo(f'Remove rule for source network {new_rule.src} to SNAT target {snat_target} from POSTROUTING chain at position {position}')
|
||||
chain.delete_rule(rule)
|
||||
|
||||
if not chain.rules:
|
||||
# if there are no rules in the chain, insert the new rule directly
|
||||
logInfo(f'Added POSTROUTING rule for source network {new_rule.src} to SNAT target {snat_target}')
|
||||
chain.insert_rule(new_rule)
|
||||
else:
|
||||
for position, rule in enumerate(chain.rules):
|
||||
if not hasattr(rule.target, 'parameter'):
|
||||
continue
|
||||
match = all((
|
||||
new_rule.get_src() == rule.get_src(),
|
||||
new_rule.get_dst() == rule.get_dst(),
|
||||
new_rule.target.parameters == rule.target.parameters,
|
||||
new_rule.target.name == rule.target.name
|
||||
))
|
||||
if position == 0:
|
||||
if not match:
|
||||
logInfo(f'Added POSTROUTING rule for source network {new_rule.src} to SNAT target {snat_target}')
|
||||
chain.insert_rule(new_rule)
|
||||
else:
|
||||
if match:
|
||||
logInfo(f'Remove rule for source network {new_rule.src} to SNAT target {snat_target} from POSTROUTING chain at position {position}')
|
||||
chain.delete_rule(rule)
|
||||
|
||||
table.commit()
|
||||
table.autocommit = True
|
||||
except:
|
||||
@@ -418,6 +437,8 @@ def autopurge():
|
||||
time.sleep(10)
|
||||
refreshF2boptions()
|
||||
BAN_TIME = int(f2boptions['ban_time'])
|
||||
MAX_BAN_TIME = int(f2boptions['max_ban_time'])
|
||||
BAN_TIME_INCREMENT = bool(f2boptions['ban_time_increment'])
|
||||
MAX_ATTEMPTS = int(f2boptions['max_attempts'])
|
||||
QUEUE_UNBAN = r.hgetall('F2B_QUEUE_UNBAN')
|
||||
if QUEUE_UNBAN:
|
||||
@@ -425,7 +446,9 @@ def autopurge():
|
||||
unban(str(net))
|
||||
for net in bans.copy():
|
||||
if bans[net]['attempts'] >= MAX_ATTEMPTS:
|
||||
if time.time() - bans[net]['last_attempt'] > BAN_TIME:
|
||||
NET_BAN_TIME = BAN_TIME if not BAN_TIME_INCREMENT else BAN_TIME * 2 ** bans[net]['ban_counter']
|
||||
TIME_SINCE_LAST_ATTEMPT = time.time() - bans[net]['last_attempt']
|
||||
if TIME_SINCE_LAST_ATTEMPT > NET_BAN_TIME or TIME_SINCE_LAST_ATTEMPT > MAX_BAN_TIME:
|
||||
unban(net)
|
||||
|
||||
def isIpNetwork(address):
|
||||
|
@@ -1,4 +1,4 @@
|
||||
FROM php:8.1-fpm-alpine3.17
|
||||
FROM php:8.2-fpm-alpine3.17
|
||||
LABEL maintainer "Andre Peters <andre.peters@servercow.de>"
|
||||
|
||||
# renovate: datasource=github-tags depName=krakjoe/apcu versioning=semver-coerced
|
||||
@@ -12,7 +12,7 @@ ARG MEMCACHED_PECL_VERSION=3.2.0
|
||||
# renovate: datasource=github-tags depName=phpredis/phpredis versioning=semver-coerced
|
||||
ARG REDIS_PECL_VERSION=5.3.7
|
||||
# renovate: datasource=github-tags depName=composer/composer versioning=semver-coerced
|
||||
ARG COMPOSER_VERSION=2.5.1
|
||||
ARG COMPOSER_VERSION=2.5.5
|
||||
|
||||
RUN apk add -U --no-cache autoconf \
|
||||
aspell-dev \
|
||||
@@ -52,6 +52,7 @@ RUN apk add -U --no-cache autoconf \
|
||||
libxpm-dev \
|
||||
libzip \
|
||||
libzip-dev \
|
||||
linux-headers \
|
||||
make \
|
||||
mysql-client \
|
||||
openldap-dev \
|
||||
@@ -75,7 +76,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 zip bcmath gmp \
|
||||
&& 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-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} \
|
||||
@@ -99,6 +100,7 @@ RUN apk add -U --no-cache autoconf \
|
||||
libxml2-dev \
|
||||
libxpm-dev \
|
||||
libzip-dev \
|
||||
linux-headers \
|
||||
make \
|
||||
openldap-dev \
|
||||
pcre-dev \
|
||||
|
@@ -24,7 +24,7 @@ server {
|
||||
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-Robots-Tag "noindex, nofollow" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
|
||||
fastcgi_hide_header X-Powered-By;
|
||||
|
@@ -8,7 +8,7 @@ VIRUS_FOUND {
|
||||
}
|
||||
# Bad policy from free mail providers
|
||||
FREEMAIL_POLICY_FAILURE {
|
||||
expression = "-g+:policies & !DMARC_POLICY_ALLOW & !MAILLIST & ( FREEMAIL_ENVFROM | FREEMAIL_FROM ) & !WHITELISTED_FWD_HOST";
|
||||
expression = "FREEMAIL_FROM & !DMARC_POLICY_ALLOW & !MAILLIST& !WHITELISTED_FWD_HOST & -g+:policies";
|
||||
score = 16.0;
|
||||
}
|
||||
# Applies to freemail with undisclosed recipients
|
||||
|
@@ -159,8 +159,8 @@ BAZAAR_ABUSE_CH {
|
||||
}
|
||||
|
||||
URLHAUS_ABUSE_CH {
|
||||
type = "url";
|
||||
filter = "full";
|
||||
type = "selector";
|
||||
selector = "urls";
|
||||
map = "https://urlhaus.abuse.ch/downloads/text_online/";
|
||||
score = 10.0;
|
||||
}
|
||||
|
@@ -62,7 +62,7 @@
|
||||
SOGoFirstDayOfWeek = "1";
|
||||
|
||||
SOGoSieveFolderEncoding = "UTF-8";
|
||||
SOGoPasswordChangeEnabled = YES;
|
||||
SOGoPasswordChangeEnabled = NO;
|
||||
SOGoSentFolderName = "Sent";
|
||||
SOGoMailShowSubscribedFoldersOnly = NO;
|
||||
NGImap4ConnectionStringSeparator = "/";
|
||||
|
@@ -3176,8 +3176,10 @@ paths:
|
||||
example:
|
||||
attr:
|
||||
ban_time: "86400"
|
||||
ban_time_increment: "1"
|
||||
blacklist: "10.100.6.5/32,10.100.8.4/32"
|
||||
max_attempts: "5"
|
||||
max_ban_time: "86400"
|
||||
netban_ipv4: "24"
|
||||
netban_ipv6: "64"
|
||||
retry_window: "600"
|
||||
@@ -3191,11 +3193,17 @@ paths:
|
||||
description: the backlisted ips or hostnames separated by comma
|
||||
type: string
|
||||
ban_time:
|
||||
description: the time a ip should be banned
|
||||
description: the time an ip should be banned
|
||||
type: number
|
||||
ban_time_increment:
|
||||
description: if the time of the ban should increase each time
|
||||
type: boolean
|
||||
max_attempts:
|
||||
description: the maximum numbe of wrong logins before a ip is banned
|
||||
type: number
|
||||
max_ban_time:
|
||||
description: the maximum time an ip should be banned
|
||||
type: number
|
||||
netban_ipv4:
|
||||
description: the networks mask to ban for ipv4
|
||||
type: number
|
||||
@@ -4113,10 +4121,12 @@ paths:
|
||||
response:
|
||||
value:
|
||||
ban_time: 604800
|
||||
ban_time_increment: 1
|
||||
blacklist: |-
|
||||
45.82.153.37/32
|
||||
92.118.38.52/32
|
||||
max_attempts: 1
|
||||
max_ban_time: 604800
|
||||
netban_ipv4: 32
|
||||
netban_ipv6: 128
|
||||
perm_bans:
|
||||
|
@@ -239,7 +239,9 @@ function fail2ban($_action, $_data = null) {
|
||||
$is_now = fail2ban('get');
|
||||
if (!empty($is_now)) {
|
||||
$ban_time = intval((isset($_data['ban_time'])) ? $_data['ban_time'] : $is_now['ban_time']);
|
||||
$ban_time_increment = (isset($_data['ban_time_increment']) && $_data['ban_time_increment'] == "1") ? 1 : 0;
|
||||
$max_attempts = intval((isset($_data['max_attempts'])) ? $_data['max_attempts'] : $is_now['max_attempts']);
|
||||
$max_ban_time = intval((isset($_data['max_ban_time'])) ? $_data['max_ban_time'] : $is_now['max_ban_time']);
|
||||
$retry_window = intval((isset($_data['retry_window'])) ? $_data['retry_window'] : $is_now['retry_window']);
|
||||
$netban_ipv4 = intval((isset($_data['netban_ipv4'])) ? $_data['netban_ipv4'] : $is_now['netban_ipv4']);
|
||||
$netban_ipv6 = intval((isset($_data['netban_ipv6'])) ? $_data['netban_ipv6'] : $is_now['netban_ipv6']);
|
||||
@@ -256,6 +258,8 @@ function fail2ban($_action, $_data = null) {
|
||||
}
|
||||
$f2b_options = array();
|
||||
$f2b_options['ban_time'] = ($ban_time < 60) ? 60 : $ban_time;
|
||||
$f2b_options['ban_time_increment'] = ($ban_time_increment == 1) ? true : false;
|
||||
$f2b_options['max_ban_time'] = ($max_ban_time < 60) ? 60 : $max_ban_time;
|
||||
$f2b_options['netban_ipv4'] = ($netban_ipv4 < 8) ? 8 : $netban_ipv4;
|
||||
$f2b_options['netban_ipv6'] = ($netban_ipv6 < 8) ? 8 : $netban_ipv6;
|
||||
$f2b_options['netban_ipv4'] = ($netban_ipv4 > 32) ? 32 : $netban_ipv4;
|
||||
|
@@ -3,7 +3,7 @@ function init_db_schema() {
|
||||
try {
|
||||
global $pdo;
|
||||
|
||||
$db_version = "06012023_1924";
|
||||
$db_version = "14022023_1000";
|
||||
|
||||
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
@@ -1096,7 +1096,7 @@ function init_db_schema() {
|
||||
$stmt = $pdo->query("SHOW TABLES LIKE '" . $table . "'");
|
||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
if ($num_results != 0) {
|
||||
$stmt = $pdo->prepare("SELECT CONCAT('ALTER TABLE ', `table_schema`, '.', `table_name`, ' DROP FOREIGN KEY ', `constraint_name`, ';') AS `FKEY_DROP` FROM `information_schema`.`table_constraints`
|
||||
$stmt = $pdo->prepare("SELECT CONCAT('ALTER TABLE `', `table_schema`, '`.', `table_name`, ' DROP FOREIGN KEY ', `constraint_name`, ';') AS `FKEY_DROP` FROM `information_schema`.`table_constraints`
|
||||
WHERE `constraint_type` = 'FOREIGN KEY' AND `table_name` = :table;");
|
||||
$stmt->execute(array(':table' => $table));
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
@@ -1181,7 +1181,7 @@ jQuery(function($){
|
||||
|
||||
if (table = $('#' + log_table).DataTable()) {
|
||||
var heading = $('#' + log_table).closest('.card').find('.card-header');
|
||||
var load_rows = (table.page.len() + 1) + '-' + (table.page.len() + new_nrows)
|
||||
var load_rows = (table.data().length + 1) + '-' + (table.data().length + new_nrows)
|
||||
|
||||
$.get('/api/v1/get/logs/' + log_url + '/' + load_rows).then(function(data){
|
||||
if (data.length === undefined) { mailcow_alert_box(lang.no_new_rows, "info"); return; }
|
||||
|
@@ -926,9 +926,12 @@ jQuery(function($){
|
||||
'<a href="#" data-action="delete_selected" data-id="single-mailbox" data-api-url="delete/mailbox" data-item="' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
|
||||
'</div>';
|
||||
}
|
||||
item.in_use = '<div class="progress">' +
|
||||
item.in_use = {
|
||||
sortBy: item.percent_in_use,
|
||||
value: '<div class="progress">' +
|
||||
'<div class="progress-bar-mailbox progress-bar progress-bar-' + item.percent_class + '" role="progressbar" aria-valuenow="' + item.percent_in_use + '" aria-valuemin="0" aria-valuemax="100" ' +
|
||||
'style="min-width:2em;width:' + item.percent_in_use + '%">' + item.percent_in_use + '%' + '</div></div>';
|
||||
'style="min-width:2em;width:' + item.percent_in_use + '%">' + item.percent_in_use + '%' + '</div></div>'
|
||||
};
|
||||
item.username = escapeHtml(item.username);
|
||||
|
||||
if (Array.isArray(item.tags)){
|
||||
@@ -994,10 +997,11 @@ jQuery(function($){
|
||||
},
|
||||
{
|
||||
title: lang.in_use,
|
||||
data: 'in_use',
|
||||
data: 'in_use.value',
|
||||
defaultContent: '',
|
||||
responsivePriority: 9,
|
||||
className: 'dt-data-w100'
|
||||
className: 'dt-data-w100',
|
||||
orderData: 24
|
||||
},
|
||||
{
|
||||
title: lang.fname,
|
||||
@@ -1102,7 +1106,12 @@ jQuery(function($){
|
||||
{
|
||||
title: "",
|
||||
data: 'quota.sortBy',
|
||||
responsivePriority: 8,
|
||||
defaultContent: '',
|
||||
className: "d-none"
|
||||
},
|
||||
{
|
||||
title: "",
|
||||
data: 'in_use.sortBy',
|
||||
defaultContent: '',
|
||||
className: "d-none"
|
||||
},
|
||||
|
@@ -650,7 +650,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "Přihlášení zpožděno o %s sekund.",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Přihlásit",
|
||||
"mobileconfig_info": "Ke stažení profilového souboru se přihlaste jako uživatel schránky.",
|
||||
"other_logins": "Přihlášení klíčem",
|
||||
|
@@ -4,15 +4,15 @@
|
||||
"app_passwds": "Administrer app-adgangskoder",
|
||||
"bcc_maps": "BCC kort",
|
||||
"delimiter_action": "Afgrænsning handling",
|
||||
"eas_reset": "Nulstil EAS endheder",
|
||||
"eas_reset": "Nulstil EAS enheder",
|
||||
"extend_sender_acl": "Tillad at udvide afsenderens ACL med eksterne adresser",
|
||||
"filters": "Filtre",
|
||||
"login_as": "Login som mailboks bruger",
|
||||
"prohibited": "Forbudt af ACL",
|
||||
"protocol_access": "Ændre protokol adgang",
|
||||
"prohibited": "Nægtet af ACL",
|
||||
"protocol_access": "Skift protokol adgang",
|
||||
"pushover": "Pushover",
|
||||
"quarantine": "Karantæneaktioner",
|
||||
"quarantine_attachments": "Karantæne vedhæftede filer",
|
||||
"quarantine": "Karantænehandlinger",
|
||||
"quarantine_attachments": "Karantænevedhæftede filer",
|
||||
"quarantine_notification": "Skift karantænemeddelelser",
|
||||
"ratelimit": "Satsgrænse",
|
||||
"recipient_maps": "Modtagerkort",
|
||||
@@ -20,12 +20,15 @@
|
||||
"sogo_access": "Tillad styring af SOGo-adgang",
|
||||
"sogo_profile_reset": "Nulstil SOGo-profil",
|
||||
"spam_alias": "Midlertidige aliasser",
|
||||
"spam_policy": "Sortliste / hvidliste",
|
||||
"spam_policy": "Sortliste/hvidliste",
|
||||
"spam_score": "Spam-score",
|
||||
"syncjobs": "Synkroniserings job",
|
||||
"tls_policy": "TLS politik",
|
||||
"unlimited_quota": "Ubegrænset plads for mailbokse",
|
||||
"domain_desc": "Skift domæne beskrivelse"
|
||||
"domain_desc": "Skift domæne beskrivelse",
|
||||
"domain_relayhost": "Skift relæ host for et domæne",
|
||||
"mailbox_relayhost": "Skift relæ-host for en postkasse",
|
||||
"quarantine_category": "Skift kategorien for karantænemeddelelse"
|
||||
},
|
||||
"add": {
|
||||
"activate_filter_warn": "Alle andre filtre deaktiveres, når aktiv er markeret.",
|
||||
@@ -59,7 +62,7 @@
|
||||
"gal": "Global adresseliste",
|
||||
"gal_info": "GAL indeholder alle objekter i et domæne og kan ikke redigeres af nogen bruger. Information om ledig / optaget i SOGo mangler, hvis deaktiveret! <b> Genstart SOGo for at anvende ændringer. </b>",
|
||||
"generate": "generere",
|
||||
"goto_ham": "Lær som <span class=\"text-success\"><b>ham</b></span>",
|
||||
"goto_ham": "Lær som <span class=\"text-success\"><b>ønsket</b></span>",
|
||||
"goto_null": "Kassér e-mail i stilhed",
|
||||
"goto_spam": "Lær som <span class=\"text-danger\"><b>spam</b></span>",
|
||||
"hostname": "Vært",
|
||||
@@ -80,7 +83,7 @@
|
||||
"private_comment": "Privat kommentar",
|
||||
"public_comment": "Offentlig kommentar",
|
||||
"quota_mb": "Kvota (Mb)",
|
||||
"relay_all": "Send alle modtagere videre",
|
||||
"relay_all": "Besvar alle modtager",
|
||||
"relay_all_info": "↪ Hvis du vælger <b> ikke </b> at videresende alle modtagere, skal du tilføje et (\"blind\") postkasse til hver enkelt modtager, der skal videresendes.",
|
||||
"relay_domain": "Send dette domæne videre",
|
||||
"relay_transport_info": "<div class=\"badge fs-6 bg-info\">Info</div> Du kan definere transportkort til en tilpasset destination for dette domæne. Hvis ikke indstillet, foretages der et MX-opslag.",
|
||||
@@ -101,7 +104,10 @@
|
||||
"timeout2": "Timeout for forbindelse til lokal vært",
|
||||
"username": "Brugernavn",
|
||||
"validate": "Bekræft",
|
||||
"validation_success": "Valideret med succes"
|
||||
"validation_success": "Valideret med succes",
|
||||
"bcc_dest_format": "BCC-destination skal være en enkelt gyldig e-mail-adresse.<br>Hvis du har brug for at sende en kopi til flere adresser, kan du oprette et alias og bruge det her.",
|
||||
"app_passwd_protocols": "Tilladte protokoller for app adgangskode",
|
||||
"tags": "Tag's"
|
||||
},
|
||||
"admin": {
|
||||
"access": "Adgang",
|
||||
@@ -308,7 +314,10 @@
|
||||
"username": "Brugernavn",
|
||||
"validate_license_now": "Valider GUID mod licensserver",
|
||||
"verify": "Verificere",
|
||||
"yes": "✓"
|
||||
"yes": "✓",
|
||||
"ip_check_opt_in": "Opt-In for brug af tredjepartstjeneste <strong>ipv4.mailcow.email</strong> og <strong>ipv6.mailcow.email</strong> til at finde eksterne IP-adresser.",
|
||||
"queue_unban": "unban",
|
||||
"admins": "Administratorer"
|
||||
},
|
||||
"danger": {
|
||||
"access_denied": "Adgang nægtet eller ugyldig formular data",
|
||||
@@ -425,7 +434,8 @@
|
||||
"username_invalid": "Brugernavn %s kan ikke bruges",
|
||||
"validity_missing": "Tildel venligst en gyldighedsperiode",
|
||||
"value_missing": "Angiv alle værdier",
|
||||
"yotp_verification_failed": "Yubico OTP verifikationen mislykkedes: %s"
|
||||
"yotp_verification_failed": "Yubico OTP verifikationen mislykkedes: %s",
|
||||
"webauthn_publickey_failed": "Der er ikke gemt nogen offentlig nøgle for den valgte autentifikator"
|
||||
},
|
||||
"debug": {
|
||||
"chart_this_server": "Diagram (denne server)",
|
||||
@@ -442,7 +452,8 @@
|
||||
"solr_status": "Solr-status",
|
||||
"started_on": "Startede den",
|
||||
"static_logs": "Statiske logfiler",
|
||||
"system_containers": "System og Beholdere"
|
||||
"system_containers": "System og Beholdere",
|
||||
"error_show_ip": "Kunne ikke finde de offentlige IP-adresser"
|
||||
},
|
||||
"diagnostics": {
|
||||
"cname_from_a": "Værdi afledt af A / AAAA-post. Dette understøttes, så længe posten peger på den korrekte ressource.",
|
||||
@@ -553,7 +564,11 @@
|
||||
"title": "Rediger objekt",
|
||||
"unchanged_if_empty": "Lad være tomt, hvis uændret",
|
||||
"username": "Brugernavn",
|
||||
"validate_save": "Valider og gem"
|
||||
"validate_save": "Valider og gem",
|
||||
"admin": "Rediger administrator",
|
||||
"lookup_mx": "Destination er et regulært udtryk, der matcher MX-navnet (<code>.*google\\.dk</code> for at dirigere al e-mail, der er målrettet til en MX, der ender på google.dk, over dette hop)",
|
||||
"mailbox_relayhost_info": "Anvendt på postkassen og kun direkte aliasser, og overskriver et domæne relæ-host.",
|
||||
"quota_warning_bcc": "Kvoteadvarsel BCC"
|
||||
},
|
||||
"footer": {
|
||||
"cancel": "Afbestille",
|
||||
@@ -571,7 +586,7 @@
|
||||
"header": {
|
||||
"administration": "Konfiguration og detailer",
|
||||
"apps": "Apps",
|
||||
"debug": "Systemoplysninger",
|
||||
"debug": "Information",
|
||||
"email": "E-Mail",
|
||||
"mailcow_config": "Konfiguration",
|
||||
"quarantine": "Karantæne",
|
||||
@@ -586,7 +601,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "Login blev forsinket med% s sekunder.",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Login",
|
||||
"mobileconfig_info": "Log ind som postkassebruger for at downloade den anmodede Apple-forbindelsesprofil.",
|
||||
"other_logins": "Nøgle login",
|
||||
@@ -739,7 +754,10 @@
|
||||
"username": "Brugernavn",
|
||||
"waiting": "Venter",
|
||||
"weekly": "Ugentlig",
|
||||
"yes": "✓"
|
||||
"yes": "✓",
|
||||
"goto_ham": "Lær som <b>ønsket</b>",
|
||||
"catch_all": "Fang-alt",
|
||||
"open_logs": "Åben logfiler"
|
||||
},
|
||||
"oauth2": {
|
||||
"access_denied": "Log ind som mailboks ejer for at give adgang via OAuth2.",
|
||||
@@ -1030,7 +1048,7 @@
|
||||
"spamfilter_table_empty": "Intet data at vise",
|
||||
"spamfilter_table_remove": "slet",
|
||||
"spamfilter_table_rule": "Regl",
|
||||
"spamfilter_wl": "Hvisliste",
|
||||
"spamfilter_wl": "Hvidliste",
|
||||
"spamfilter_wl_desc": "Hvidlistede e-mail-adresser til <b>aldrig</b> at klassificeres som spam. Wildcards kan bruges. Et filter anvendes kun på direkte aliaser (aliaser med en enkelt målpostkasse) eksklusive catch-aliaser og selve en postkasse.",
|
||||
"spamfilter_yellow": "Gul: denne besked kan være spam, vil blive tagget som spam og flyttes til din junk-mappe",
|
||||
"status": "Status",
|
||||
@@ -1066,5 +1084,11 @@
|
||||
"quota_exceeded_scope": "Domænekvote overskredet: Kun ubegrænsede postkasser kan oprettes i dette domæneomfang.",
|
||||
"session_token": "Form nøgle ugyldig: Nøgle passer ikke",
|
||||
"session_ua": "Form nøgle ugyldig: Bruger-Agent gyldighedskontrols fejl"
|
||||
},
|
||||
"datatables": {
|
||||
"lengthMenu": "Vis _MENU_ poster",
|
||||
"paginate": {
|
||||
"first": "Først"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -175,10 +175,12 @@
|
||||
"empty": "Keine Einträge vorhanden",
|
||||
"excludes": "Diese Empfänger ausschließen",
|
||||
"f2b_ban_time": "Bannzeit in Sekunden",
|
||||
"f2b_ban_time_increment": "Bannzeit erhöht sich mit jedem Bann",
|
||||
"f2b_blacklist": "Blacklist für Netzwerke und Hosts",
|
||||
"f2b_filter": "Regex-Filter",
|
||||
"f2b_list_info": "Ein Host oder Netzwerk auf der Blacklist wird immer eine Whitelist-Einheit überwiegen. <b>Die Aktualisierung der Liste dauert einige Sekunden.</b>",
|
||||
"f2b_max_attempts": "Max. Versuche",
|
||||
"f2b_max_ban_time": "Maximale Bannzeit in Sekunden",
|
||||
"f2b_netban_ipv4": "Netzbereich für IPv4-Banns (8-32)",
|
||||
"f2b_netban_ipv6": "Netzbereich für IPv6-Banns (8-128)",
|
||||
"f2b_parameters": "Fail2ban-Parameter",
|
||||
@@ -710,7 +712,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "Login wurde zur Sicherheit um %s Sekunde/n verzögert.",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Anmelden",
|
||||
"mobileconfig_info": "Bitte als Mailbox-Benutzer einloggen, um das Verbindungsprofil herunterzuladen.",
|
||||
"other_logins": "Key Login",
|
||||
|
@@ -177,10 +177,12 @@
|
||||
"empty": "No results",
|
||||
"excludes": "Excludes these recipients",
|
||||
"f2b_ban_time": "Ban time (s)",
|
||||
"f2b_ban_time_increment": "Ban time is incremented with each ban",
|
||||
"f2b_blacklist": "Blacklisted networks/hosts",
|
||||
"f2b_filter": "Regex filters",
|
||||
"f2b_list_info": "A blacklisted host or network will always outweigh a whitelist entity. <b>List updates will take a few seconds to be applied.</b>",
|
||||
"f2b_max_attempts": "Max. attempts",
|
||||
"f2b_max_ban_time": "Max. ban time (s)",
|
||||
"f2b_netban_ipv4": "IPv4 subnet size to apply ban on (8-32)",
|
||||
"f2b_netban_ipv6": "IPv6 subnet size to apply ban on (8-128)",
|
||||
"f2b_parameters": "Fail2ban parameters",
|
||||
@@ -710,7 +712,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "Login was delayed by %s seconds.",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Login",
|
||||
"mobileconfig_info": "Please login as mailbox user to download the requested Apple connection profile.",
|
||||
"other_logins": "Key login",
|
||||
|
@@ -141,9 +141,11 @@
|
||||
"empty": "Sin resultados",
|
||||
"excludes": "Excluye a estos destinatarios",
|
||||
"f2b_ban_time": "Tiempo de restricción (s)",
|
||||
"f2b_ban_time_increment": "Tiempo de restricción se incrementa con cada restricción",
|
||||
"f2b_blacklist": "Redes y hosts en lista negra",
|
||||
"f2b_list_info": "Un host o red en lista negra siempre superará a una entidad de la lista blanca. <b>Las actualizaciones de la lista tardarán unos segundos en aplicarse.</b>",
|
||||
"f2b_max_attempts": "Max num. de intentos",
|
||||
"f2b_max_ban_time": "Max tiempo de restricción (s)",
|
||||
"f2b_netban_ipv4": "Tamaño de subred IPv4 para aplicar la restricción (8-32)",
|
||||
"f2b_netban_ipv6": "Tamaño de subred IPv6 para aplicar la restricción (8-128)",
|
||||
"f2b_parameters": "Parametros Fail2ban",
|
||||
|
@@ -24,7 +24,7 @@
|
||||
"spam_policy": "Liste Noire/Liste Blanche",
|
||||
"spam_score": "Score SPAM",
|
||||
"syncjobs": "Tâches de synchronisation",
|
||||
"tls_policy": "Police TLS",
|
||||
"tls_policy": "Politique TLS",
|
||||
"unlimited_quota": "Quota illimité pour les boites de courriel",
|
||||
"domain_desc": "Modifier la description du domaine",
|
||||
"domain_relayhost": "Changer le relais pour un domaine",
|
||||
@@ -106,7 +106,8 @@
|
||||
"validate": "Valider",
|
||||
"validation_success": "Validation réussie",
|
||||
"bcc_dest_format": "La destination Cci doit être une seule adresse e-mail valide.<br>Si vous avez besoin d'envoyer une copie à plusieurs adresses, créez un alias et utilisez-le ici.",
|
||||
"tags": "Etiquettes"
|
||||
"tags": "Etiquettes",
|
||||
"app_passwd_protocols": "Protocoles autorisés pour le mot de passe de l'application"
|
||||
},
|
||||
"admin": {
|
||||
"access": "Accès",
|
||||
@@ -171,11 +172,13 @@
|
||||
"edit": "Editer",
|
||||
"empty": "Aucun résultat",
|
||||
"excludes": "Exclure ces destinataires",
|
||||
"f2b_ban_time": "Durée du bannissement(s)",
|
||||
"f2b_ban_time": "Durée du bannissement (s)",
|
||||
"f2b_ban_time_increment": "Durée du bannissement est augmentée à chaque bannissement",
|
||||
"f2b_blacklist": "Réseaux/Domaines sur Liste Noire",
|
||||
"f2b_filter": "Filtre(s) Regex",
|
||||
"f2b_list_info": "Un hôte ou un réseau sur liste noire l'emportera toujours sur une entité de liste blanche. <b>L'application des mises à jour de liste prendra quelques secondes.</b>",
|
||||
"f2b_max_attempts": "Nb max. de tentatives",
|
||||
"f2b_max_ban_time": "Max. durée du bannissement (s)",
|
||||
"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",
|
||||
@@ -321,7 +324,9 @@
|
||||
"admins": "Administrateurs",
|
||||
"api_read_only": "Accès lecture-seule",
|
||||
"password_policy_lowerupper": "Doit contenir des caractères minuscules et majuscules",
|
||||
"password_policy_numbers": "Doit contenir au moins un chiffre"
|
||||
"password_policy_numbers": "Doit contenir au moins un chiffre",
|
||||
"ip_check": "Vérification IP",
|
||||
"ip_check_disabled": "La vérification IP est désactivée. Vous pouvez l'activer sous<br> <strong>Système > Configuration > Options > Personnaliser</strong>"
|
||||
},
|
||||
"danger": {
|
||||
"access_denied": "Accès refusé ou données de formulaire non valides",
|
||||
@@ -440,7 +445,12 @@
|
||||
"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 selectionné est introuvable",
|
||||
"demo_mode_enabled": "Le mode de démonstration est activé",
|
||||
"template_exists": "La template %s existe déja",
|
||||
"template_id_invalid": "Le numéro de template %s est invalide",
|
||||
"template_name_invalid": "Le nom de la template est invalide"
|
||||
},
|
||||
"debug": {
|
||||
"chart_this_server": "Graphique (ce serveur)",
|
||||
@@ -578,7 +588,7 @@
|
||||
"unchanged_if_empty": "Si non modifié, laisser en blanc",
|
||||
"username": "Nom d'utilisateur",
|
||||
"validate_save": "Valider et sauver",
|
||||
"lookup_mx": "La destination est une expression régulière qui doit correspondre avec le nom du MX (<code>.*google\\.com</code> pour acheminer tout le courrier destiné à un MX se terminant par google.com via ce saut).",
|
||||
"lookup_mx": "La destination est une expression régulière qui doit correspondre avec le nom du MX (<code>.*google\\.com</code> pour acheminer tout le courrier destiné à un MX se terminant par google.com via ce saut)",
|
||||
"mailbox_relayhost_info": "S'applique uniquement à la boîte aux lettres et aux alias directs, remplace le relayhost du domaine."
|
||||
},
|
||||
"footer": {
|
||||
@@ -612,7 +622,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "La connexion a été retardée de %s secondes.",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Connexion",
|
||||
"mobileconfig_info": "Veuillez vous connecter en tant qu’utilisateur de la boîte pour télécharger le profil de connexion Apple demandé.",
|
||||
"other_logins": "Clé d'authentification",
|
||||
@@ -1081,9 +1091,12 @@
|
||||
"username": "Nom d'utilisateur",
|
||||
"verify": "Vérification",
|
||||
"waiting": "En attente",
|
||||
"week": "Semaine",
|
||||
"week": "semaine",
|
||||
"weekly": "Hebdomadaire",
|
||||
"weeks": "semaines"
|
||||
"weeks": "semaines",
|
||||
"months": "mois",
|
||||
"year": "année",
|
||||
"years": "années"
|
||||
},
|
||||
"warning": {
|
||||
"cannot_delete_self": "Impossible de supprimer l’utilisateur connecté",
|
||||
|
@@ -175,10 +175,12 @@
|
||||
"empty": "Nessun risultato",
|
||||
"excludes": "Esclude questi destinatari",
|
||||
"f2b_ban_time": "Tempo di blocco (s)",
|
||||
"f2b_ban_time_increment": "Tempo di blocco aumenta ad ogni blocco",
|
||||
"f2b_blacklist": "Host/reti in blacklist",
|
||||
"f2b_filter": "Filtri Regex",
|
||||
"f2b_list_info": "Un host oppure una rete in blacklist, avrà sempre un peso maggiore rispetto ad una in whitelist. <b>L'aggiornamento della lista richiede alcuni secondi per la sua entrata in azione.</b>",
|
||||
"f2b_max_attempts": "Tentativi massimi",
|
||||
"f2b_max_ban_time": "Tempo massimo di blocco (s)",
|
||||
"f2b_netban_ipv4": "IPv4 subnet size to apply ban on (8-32)",
|
||||
"f2b_netban_ipv6": "IPv6 subnet size to apply ban on (8-128)",
|
||||
"f2b_parameters": "Parametri Fail2ban",
|
||||
@@ -674,7 +676,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "L'accesso è stato ritardato di %s secondi.",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Login",
|
||||
"mobileconfig_info": "Please login as mailbox user to download the requested Apple connection profile.",
|
||||
"other_logins": "Key login",
|
||||
|
@@ -3,7 +3,8 @@
|
||||
"bcc_maps": "BCC kartes",
|
||||
"filters": "Filtri",
|
||||
"recipient_maps": "Saņēmēja kartes",
|
||||
"syncjobs": "Sinhronizācijas uzdevumi"
|
||||
"syncjobs": "Sinhronizācijas uzdevumi",
|
||||
"spam_score": "Mēstules novērtējums"
|
||||
},
|
||||
"add": {
|
||||
"activate_filter_warn": "Visi pārējie filtri tiks deaktivizēti, kad aktīvs ir atzīmēts.",
|
||||
@@ -104,10 +105,10 @@
|
||||
"host": "Hosts",
|
||||
"import": "Importēt",
|
||||
"import_private_key": "Importēt privātu atslēgu",
|
||||
"in_use_by": "Tiek lietots ar",
|
||||
"in_use_by": "Izmanto",
|
||||
"inactive": "Neaktīvs",
|
||||
"link": "Saite",
|
||||
"loading": "Lūdzu uzgaidiet...",
|
||||
"loading": "Lūgums uzgaidīt...",
|
||||
"logo_info": "Jūsu attēls augšējā navigācijas joslā tiks palielināts līdz 40 pikseļiem un maks. sākumlapas platums par 250 pikseļi. Ir ļoti ieteicama pielāgojama grafikaYour image will be scaled to a height of 40px for the top navigation bar and a max. width of 250px for the start page. Ir ļoti ieteicama pielāgojamā grafika",
|
||||
"main_name": "\"mailcow UI\" nosaukums",
|
||||
"merged_vars_hint": "Pelēkās rindas tika apvienotas <code>vars.(local.)inc.php</code> un nevar tikt modificētas.",
|
||||
@@ -144,7 +145,10 @@
|
||||
"ui_texts": "UI etiķetes un teksti",
|
||||
"unchanged_if_empty": "Ja nav veiktas izmaiņas, atstājiet tukšu",
|
||||
"upload": "Augšupielādēt",
|
||||
"username": "Lietotājvārds"
|
||||
"username": "Lietotājvārds",
|
||||
"generate": "izveidot",
|
||||
"message": "Ziņojums",
|
||||
"last_applied": "Pēdējoreiz pielietots"
|
||||
},
|
||||
"danger": {
|
||||
"access_denied": "Piekļuve liegta, vai nepareizi dati",
|
||||
@@ -170,7 +174,7 @@
|
||||
"is_alias": "%s jau ir zināms alias",
|
||||
"is_alias_or_mailbox": "%s jau ir zināms alias, pastkastes vai alias addrese izvērsta no alias domēna.",
|
||||
"is_spam_alias": "%s ir jau zināms spam alias",
|
||||
"last_key": "Pēdējā atslēga nevar būt dzēsta",
|
||||
"last_key": "Pēdējo atslēgu nevar izdzēst, tā vietā jāatspējo divpakāpju pārbaude.",
|
||||
"login_failed": "Ielogošanās neveiksmīga",
|
||||
"mailbox_invalid": "Pastkastes vārds ir nederīgs",
|
||||
"mailbox_quota_exceeded": "Kvota pārsniedz domēna limitu (max. %d MiB)",
|
||||
@@ -262,7 +266,8 @@
|
||||
"title": "Labot priekšmetu",
|
||||
"unchanged_if_empty": "Ja neizmainīts atstājiet tukšu",
|
||||
"username": "Lietotājvārds",
|
||||
"validate_save": "Apstiprināt un saglabāt"
|
||||
"validate_save": "Apstiprināt un saglabāt",
|
||||
"last_modified": "Pēdējoreiz mainīts"
|
||||
},
|
||||
"footer": {
|
||||
"cancel": "Atcelt",
|
||||
@@ -314,21 +319,21 @@
|
||||
"bcc_destinations": "BCC galamērķi/s",
|
||||
"bcc_info": "BCC kartes tiek izmantotas, lai klusu pārsūtītu visu ziņojumu kopijas uz citu adresi. Saņēmēja kartes tipa ieraksts tiek izmantots, kad vietējais galamērķis darbojas kā pasta adresāts. Sūtītāja kartes atbilst vienam un tam pašam principam. <br/>\r\n Vietējais galamērķis netiks informēts par piegādes neveiksmi. ",
|
||||
"bcc_local_dest": "Vietējais galamērķis",
|
||||
"bcc_map_type": "BCC tips",
|
||||
"bcc_map_type": "BCC veids",
|
||||
"bcc_maps": "BCC kartes",
|
||||
"bcc_rcpt_map": "saņēmēja karte",
|
||||
"bcc_sender_map": "Sūtītāja karte",
|
||||
"bcc_to_rcpt": "Pārslēdzieties uz adresāta kartes tipu",
|
||||
"bcc_to_sender": "Pārslēgties uz sūtītāja kartes tipu",
|
||||
"bcc_type": "BCC tips",
|
||||
"deactivate": "Deaktivizēt",
|
||||
"deactivate": "Deaktivēt",
|
||||
"description": "Apraksts",
|
||||
"dkim_key_length": "DKIM atslēgas garums (bits)",
|
||||
"domain": "Domēns",
|
||||
"domain_admins": "Domēna administratori",
|
||||
"domain_aliases": "Domēna aliases",
|
||||
"domain_quota": "Kvota",
|
||||
"domain_quota_total": "Kopējā domēna kvota",
|
||||
"domain_quota_total": "Kopējais domēna ierobežojums",
|
||||
"domains": "Domēns",
|
||||
"edit": "Labot",
|
||||
"empty": "Nav rezultātu",
|
||||
@@ -341,7 +346,7 @@
|
||||
"inactive": "Neaktīvs",
|
||||
"kind": "Veids",
|
||||
"last_run": "Pēdējā norise",
|
||||
"last_run_reset": "Nākamais grafiks",
|
||||
"last_run_reset": "Ievietot sarakstā kā nākamo",
|
||||
"mailbox_quota": "Maks. pastkastes izmērs",
|
||||
"mailboxes": "Pastkaste",
|
||||
"max_aliases": "Maks. iespejamās aliases",
|
||||
@@ -374,7 +379,13 @@
|
||||
"tls_enforce_out": "Piespiest TLS izejošajiem",
|
||||
"toggle_all": "Pārslēgt visu",
|
||||
"username": "Lietotājvārds",
|
||||
"waiting": "Gaidīšana"
|
||||
"waiting": "Gaidīšana",
|
||||
"last_modified": "Pēdējoreiz mainīts",
|
||||
"booking_0_short": "Vienmēŗ bezmaksas",
|
||||
"daily": "Ik dienu",
|
||||
"hourly": "Ik stundu",
|
||||
"last_mail_login": "Pēdējā pieteikšanās pastkastē",
|
||||
"mailbox": "Pastkaste"
|
||||
},
|
||||
"quarantine": {
|
||||
"action": "Darbības",
|
||||
@@ -547,5 +558,14 @@
|
||||
"waiting": "Waiting",
|
||||
"week": "Nedēļa",
|
||||
"weeks": "Nedēļas"
|
||||
},
|
||||
"datatables": {
|
||||
"paginate": {
|
||||
"first": "Pirmā",
|
||||
"last": "Pēdējā"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"last_modified": "Pēdējoreiz mainīts"
|
||||
}
|
||||
}
|
||||
|
@@ -168,10 +168,12 @@
|
||||
"empty": "Geen resultaten",
|
||||
"excludes": "Exclusief",
|
||||
"f2b_ban_time": "Verbanningstijd (s)",
|
||||
"f2b_ban_time_increment": "Verbanningstijd wordt verhoogd met elk verbanning",
|
||||
"f2b_blacklist": "Netwerken/hosts op de blacklist",
|
||||
"f2b_filter": "Regex-filters",
|
||||
"f2b_list_info": "Een host of netwerk op de blacklist staat altijd boven eenzelfde op de whitelist. <b>Het doorvoeren van wijzigingen kan enkele seconden in beslag nemen.</b>",
|
||||
"f2b_max_attempts": "Maximaal aantal pogingen",
|
||||
"f2b_max_ban_time": "Maximaal verbanningstijd (s)",
|
||||
"f2b_netban_ipv4": "Voer de IPv4-subnetgrootte in waar de verbanning van kracht moet zijn (8-32)",
|
||||
"f2b_netban_ipv6": "Voer de IPv6-subnetgrootte in waar de verbanning van kracht moet zijn (8-128)",
|
||||
"f2b_parameters": "Fail2ban",
|
||||
@@ -598,7 +600,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "Aanmelding vertraagd met %s seconden.",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Aanmelden",
|
||||
"mobileconfig_info": "Log in als mailboxgebruiker om het Apple-verbindingsprofiel te downloaden.",
|
||||
"other_logins": "Meld aan met key",
|
||||
|
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"acl": {
|
||||
"sogo_profile_reset": "Usuń profil SOGo (webmail)",
|
||||
"syncjobs": "Polecenie synchronizacji"
|
||||
"syncjobs": "Polecenie synchronizacji",
|
||||
"alias_domains": "Dodaj aliasy domen"
|
||||
},
|
||||
"add": {
|
||||
"active": "Aktywny",
|
||||
|
@@ -656,7 +656,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "Conectarea a fost întârziată cu %s secunde.",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Autentificare",
|
||||
"mobileconfig_info": "Autentificați-vă cu adresa de email pentru a descărca profilul de conexiune Apple.",
|
||||
"other_logins": "Autentificare cu cheie",
|
||||
|
@@ -37,7 +37,7 @@
|
||||
"add_domain_only": "Только добавить домен",
|
||||
"add_domain_restart": "Добавить домен и перезапустить SOGo",
|
||||
"alias_address": "Псевдоним/ы",
|
||||
"alias_address_info": "<small>Укажите почтовые адреса разделенные запятыми или, если хотите пересылать все сообщения для домена владельцам псевдонима то: <code>@example.com</code>. <b>Только домены mailcow разрешены</b>.</small>",
|
||||
"alias_address_info": "<small>Адрес(а) электронной почты (через запятую) или @example.com (для перехвата всех писем для домена). <b>только домены mailcow</b>.</small>",
|
||||
"alias_domain": "Псевдоним домена",
|
||||
"alias_domain_info": "<small>Действительные имена доменов, раздёленные запятыми.</small>",
|
||||
"app_name": "Название приложения",
|
||||
@@ -335,7 +335,8 @@
|
||||
"username": "Имя пользователя",
|
||||
"validate_license_now": "Получить лицензию на основе GUID с сервера лицензий",
|
||||
"verify": "Проверить",
|
||||
"yes": "✓"
|
||||
"yes": "✓",
|
||||
"queue_unban": "разблокировать"
|
||||
},
|
||||
"danger": {
|
||||
"access_denied": "Доступ запрещён, или указаны неверные данные",
|
||||
@@ -654,7 +655,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "Вход был отложен на %s секунд.",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Войти",
|
||||
"mobileconfig_info": "Пожалуйста, войдите в систему как пользователь почтового аккаунта для загрузки профиля подключения Apple.",
|
||||
"other_logins": "Вход с помощью ключа",
|
||||
|
@@ -657,7 +657,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "Prihlásenie bolo oneskorené o %s sekúnd.",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Prihlásenie",
|
||||
"mobileconfig_info": "Prosím, prihláste sa ako mailový používateľ pre stiahnutie požadovaného Apple profilu.",
|
||||
"other_logins": "Prihlásenie kľúčom",
|
||||
|
@@ -618,7 +618,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "Av säkerhetsskäl har inloggning inaktiverats i %s sekunder.",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Logga in",
|
||||
"mobileconfig_info": "Logga in som en användare av brevlåda för att ladda ner den begärda Apple-anslutningsprofilen.",
|
||||
"other_logins": "Loggain med nyckel",
|
||||
|
@@ -656,7 +656,7 @@
|
||||
"awaiting_tfa_confirmation": "В очікуванні підтвердження TFA"
|
||||
},
|
||||
"login": {
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "Увійти",
|
||||
"other_logins": "Вхід за допомогою ключа",
|
||||
"password": "Пароль",
|
||||
|
@@ -661,7 +661,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "请在 %s 秒后重新登录。",
|
||||
"fido2_webauthn": "使用 FIDO2/WebAuthn 登录",
|
||||
"fido2_webauthn": "使用 FIDO2/WebAuthn Login 登录",
|
||||
"login": "登录",
|
||||
"mobileconfig_info": "请使用邮箱用户登录以下载 Apple 连接描述文件。",
|
||||
"other_logins": "Key 登录",
|
||||
|
@@ -655,7 +655,7 @@
|
||||
},
|
||||
"login": {
|
||||
"delayed": "請在 %s 秒後重新登入。",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn",
|
||||
"fido2_webauthn": "FIDO2/WebAuthn Login",
|
||||
"login": "登入",
|
||||
"mobileconfig_info": "請使用信箱使用者登入以下載 Apple 連接描述檔案。",
|
||||
"other_logins": "金鑰登入",
|
||||
|
@@ -12,6 +12,14 @@
|
||||
<label for="f2b_ban_time">{{ lang.admin.f2b_ban_time }}:</label>
|
||||
<input type="number" class="form-control" id="f2b_ban_time" name="ban_time" value="{{ f2b_data.ban_time }}" required>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="f2b_max_ban_time">{{ lang.admin.f2b_max_ban_time }}:</label>
|
||||
<input type="number" class="form-control" id="f2b_max_ban_time" name="max_ban_time" value="{{ f2b_data.max_ban_time }}" required>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<input class="form-check-input" type="checkbox" value="1" name="ban_time_increment" id="f2b_ban_time_increment" {% if f2b_data.ban_time_increment == 1 %}checked{% endif %}>
|
||||
<label class="form-check-label" for="f2b_ban_time_increment">{{ lang.admin.f2b_ban_time_increment }}</label>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label for="f2b_max_attempts">{{ lang.admin.f2b_max_attempts }}:</label>
|
||||
<input type="number" class="form-control" id="f2b_max_attempts" name="max_attempts" value="{{ f2b_data.max_attempts }}" required>
|
||||
|
@@ -612,7 +612,7 @@
|
||||
<li class="table_collapse_option"><a class="dropdown-item" data-datatables-expand="rl_log" data-table="rl_log" href="#">{{ lang.datatables.expand_all }}</a></li>
|
||||
<li class="table_collapse_option"><a class="dropdown-item" data-datatables-collapse="rl_log" data-table="rl_log" href="#">{{ lang.datatables.collapse_all }}</a></li>
|
||||
</ul>
|
||||
<p class="text-muted">{{ lang.admin.hash_remove_info }}</p>
|
||||
<p class="text-muted">{{ lang.admin.hash_remove_info|raw }}</p>
|
||||
<table id="rl_log" class="table table-striped dt-responsive w-100"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -38,15 +38,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex mt-4" style="position: relative">
|
||||
<div class="btn-group">
|
||||
<div class="btn-group">
|
||||
<button type="submit" class="btn btn-xs-lg btn-success" value="Login">{{ lang.login.login }}</button>
|
||||
<button type="button" class="btn btn-xs-lg btn-success dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="#" id="fido2-login"><i class="bi bi-shield-fill-check"></i> {{ lang.login.fido2_webauthn }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-xs-lg btn-success" value="Login">{{ lang.login.login }}</button>
|
||||
<button type="button" class="btn btn-xs-lg btn-success ms-2" id="fido2-login"><i class="bi bi-shield-fill-check"></i> {{ lang.login.fido2_webauthn }}</button>
|
||||
{% if not oauth2_request %}
|
||||
<button type="button" {% if available_languages|length == 1 %}disabled="true"{% endif %} class="btn btn-xs-lg btn-secondary ms-auto dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="flag-icon flag-icon-{{ mailcow_locale[-2:] }}"></span>
|
||||
|
@@ -19,7 +19,7 @@
|
||||
</li>
|
||||
<li class="nav-item" role="presentation"><button class="nav-link" aria-controls="tab-resources" role="tab" data-bs-toggle="tab" data-bs-target="#tab-resources">{{ lang.mailbox.resources }}</button></li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" data-bs-target="#">{{ lang.mailbox.aliases }}</a>
|
||||
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">{{ lang.mailbox.aliases }}</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li role="presentation"><button class="dropdown-item" aria-selected="false" aria-controls="tab-mbox-aliases" role="tab" data-bs-toggle="tab" data-bs-target="#tab-mbox-aliases">{{ lang.mailbox.aliases }}</button></li>
|
||||
<li role="presentation"><button class="dropdown-item" aria-selected="false" aria-controls="tab-domain-aliases" role="tab" data-bs-toggle="tab" data-bs-target="#tab-domain-aliases">{{ lang.mailbox.domain_aliases }}</button></li>
|
||||
|
@@ -58,7 +58,7 @@ services:
|
||||
- redis
|
||||
|
||||
clamd-mailcow:
|
||||
image: mailcow/clamd:1.60
|
||||
image: mailcow/clamd:1.61
|
||||
restart: always
|
||||
depends_on:
|
||||
- unbound-mailcow
|
||||
@@ -76,7 +76,7 @@ services:
|
||||
- clamd
|
||||
|
||||
rspamd-mailcow:
|
||||
image: mailcow/rspamd:1.92
|
||||
image: mailcow/rspamd:1.93
|
||||
stop_grace_period: 30s
|
||||
depends_on:
|
||||
- dovecot-mailcow
|
||||
@@ -106,7 +106,7 @@ services:
|
||||
- rspamd
|
||||
|
||||
php-fpm-mailcow:
|
||||
image: mailcow/phpfpm:1.82
|
||||
image: mailcow/phpfpm:1.83
|
||||
command: "php-fpm -d date.timezone=${TZ} -d expose_php=0"
|
||||
depends_on:
|
||||
- redis-mailcow
|
||||
@@ -169,7 +169,7 @@ services:
|
||||
- phpfpm
|
||||
|
||||
sogo-mailcow:
|
||||
image: mailcow/sogo:1.115
|
||||
image: mailcow/sogo:1.116
|
||||
environment:
|
||||
- DBNAME=${DBNAME}
|
||||
- DBUSER=${DBUSER}
|
||||
@@ -191,7 +191,7 @@ services:
|
||||
volumes:
|
||||
- ./data/hooks/sogo:/hooks:Z
|
||||
- ./data/conf/sogo/:/etc/sogo/:z
|
||||
- ./data/web/inc/init_db.inc.php:/init_db.inc.php:Z
|
||||
- ./data/web/inc/init_db.inc.php:/init_db.inc.php:z
|
||||
- ./data/conf/sogo/custom-favicon.ico:/usr/lib/GNUstep/SOGo/WebServerResources/img/sogo.ico:z
|
||||
- ./data/conf/sogo/custom-theme.js:/usr/lib/GNUstep/SOGo/WebServerResources/js/theme.js:z
|
||||
- ./data/conf/sogo/custom-sogo.js:/usr/lib/GNUstep/SOGo/WebServerResources/js/custom-sogo.js:z
|
||||
@@ -216,7 +216,7 @@ services:
|
||||
- sogo
|
||||
|
||||
dovecot-mailcow:
|
||||
image: mailcow/dovecot:1.22
|
||||
image: mailcow/dovecot:1.23
|
||||
depends_on:
|
||||
- mysql-mailcow
|
||||
dns:
|
||||
@@ -425,7 +425,7 @@ services:
|
||||
- acme
|
||||
|
||||
netfilter-mailcow:
|
||||
image: mailcow/netfilter:1.50
|
||||
image: mailcow/netfilter:1.52
|
||||
stop_grace_period: 30s
|
||||
depends_on:
|
||||
- dovecot-mailcow
|
||||
@@ -510,7 +510,7 @@ services:
|
||||
- watchdog
|
||||
|
||||
dockerapi-mailcow:
|
||||
image: mailcow/dockerapi:2.01
|
||||
image: mailcow/dockerapi:2.02
|
||||
security_opt:
|
||||
- label=disable
|
||||
restart: always
|
||||
|
@@ -205,8 +205,8 @@ DBUSER=mailcow
|
||||
|
||||
# Please use long, random alphanumeric strings (A-Za-z0-9)
|
||||
|
||||
DBPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 | head -c 28)
|
||||
DBROOT=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 | head -c 28)
|
||||
DBPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)
|
||||
DBROOT=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)
|
||||
|
||||
# ------------------------------
|
||||
# HTTP/S Bindings
|
||||
|
15
helper-scripts/expiry-dates.sh
Normal file → Executable file
15
helper-scripts/expiry-dates.sh
Normal file → Executable file
@@ -3,10 +3,11 @@
|
||||
[[ -f mailcow.conf ]] && source mailcow.conf
|
||||
[[ -f ../mailcow.conf ]] && source ../mailcow.conf
|
||||
|
||||
POSTFIX=$(echo | openssl s_client -connect ${MAILCOW_HOSTNAME}:25 -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -enddate | cut -d "=" -f 2)
|
||||
DOVECOT=$(echo | openssl s_client -connect ${MAILCOW_HOSTNAME}:143 -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -enddate | cut -d "=" -f 2)
|
||||
NGINX=$(echo | openssl s_client -connect ${MAILCOW_HOSTNAME}:443 2>/dev/null | openssl x509 -inform pem -noout -enddate | cut -d "=" -f 2)
|
||||
echo TLS expiry dates:
|
||||
echo Postfix: ${POSTFIX}
|
||||
echo Dovecot: ${DOVECOT}
|
||||
echo Nginx: ${NGINX}
|
||||
POSTFIX=$(echo | openssl s_client -connect ${MAILCOW_HOSTNAME}:${SMTP_PORT} -starttls smtp 2>/dev/null | openssl x509 -inform pem -noout -enddate | cut -d "=" -f 2)
|
||||
DOVECOT=$(echo | openssl s_client -connect ${MAILCOW_HOSTNAME}:${IMAP_PORT} -starttls imap 2>/dev/null | openssl x509 -inform pem -noout -enddate | cut -d "=" -f 2)
|
||||
NGINX=$(echo | openssl s_client -connect ${MAILCOW_HOSTNAME}:${HTTPS_PORT} 2>/dev/null | openssl x509 -inform pem -noout -enddate | cut -d "=" -f 2)
|
||||
|
||||
echo "TLS expiry dates:"
|
||||
echo "Postfix: ${POSTFIX}"
|
||||
echo "Dovecot: ${DOVECOT}"
|
||||
echo "Nginx: ${NGINX}"
|
||||
|
@@ -19,7 +19,7 @@ read -r -p "Are you sure you want to reset the mailcow administrator account? [y
|
||||
response=${response,,} # tolower
|
||||
if [[ "$response" =~ ^(yes|y)$ ]]; then
|
||||
echo -e "\nWorking, please wait..."
|
||||
random=$(</dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-16})
|
||||
random=$(</dev/urandom tr -dc _A-Z-a-z-0-9 2> /dev/null | head -c${1:-16})
|
||||
password=$(docker exec -it $(docker ps -qf name=dovecot-mailcow) doveadm pw -s SSHA256 -p ${random} | tr -d '\r')
|
||||
docker exec -it $(docker ps -qf name=mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM admin WHERE username='admin';"
|
||||
docker exec -it $(docker ps -qf name=mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} -e "DELETE FROM domain_admins WHERE username='admin';"
|
||||
|
@@ -1,10 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
# renovate: datasource=github-releases depName=nextcloud/server versioning=semver extractVersion=^v(?<version>.*)$
|
||||
NEXTCLOUD_VERSION=25.0.3
|
||||
NEXTCLOUD_VERSION=26.0.0
|
||||
|
||||
for bin in curl dirmngr; do
|
||||
if [[ -z $(which ${bin}) ]]; then echo "Cannot find ${bin}, exiting..."; exit 1; fi
|
||||
echo -ne "Checking prerequisites..."
|
||||
sleep 1
|
||||
for bin in curl dirmngr tar bzip2; do
|
||||
if [[ -z $(which ${bin}) ]]; then echo -ne "\r\033[31mCannot find ${bin}, exiting...\033[0m\n"; exit 1; fi
|
||||
done
|
||||
echo -ne "\r\033[32mFound all prerequisites! Continuing...\033[0m\n"
|
||||
|
||||
[[ -z ${1} ]] && NC_HELP=y
|
||||
|
||||
@@ -94,8 +97,12 @@ elif [[ ${NC_UPDATE} == "y" ]]; then
|
||||
echo -e "\033[31mError: Nextcloud occ not found. Is Nextcloud installed?\033[0m"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q 'installed: true' <<<$(docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) bash -c "/web/nextcloud/occ --no-warnings status"); then
|
||||
echo "Nextcloud seems not to be installed."
|
||||
if grep -q 'This version of Nextcloud is not compatible with PHP>=8.2.' <<<$(docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) bash -c "/web/nextcloud/occ --no-warnings status"); then
|
||||
echo -e "\033[31mError: This version of Nextcloud is not compatible with PHP>=8.2, we'll fix it\033[0m"
|
||||
wget -q https://raw.githubusercontent.com/nextcloud/server/v26.0.0/lib/versioncheck.php -O ./data/web/nextcloud/lib/versioncheck.php
|
||||
echo -e "\e[33mPlease restart the update again.\e[0m"
|
||||
elif ! grep -q 'installed: true' <<<$(docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) bash -c "/web/nextcloud/occ --no-warnings status"); then
|
||||
echo -e "\033[31mError: Nextcloud seems not to be installed.\033[0m"
|
||||
exit 1
|
||||
else
|
||||
docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) bash -c "php /web/nextcloud/updater/updater.phar"
|
||||
@@ -119,7 +126,7 @@ elif [[ ${NC_INSTALL} == "y" ]]; then
|
||||
&& chmod +x ./data/web/nextcloud/occ
|
||||
|
||||
echo -e "\033[33mCreating 'nextcloud' database...\033[0m"
|
||||
NC_DBPASS=$(</dev/urandom tr -dc A-Za-z0-9 | head -c 28)
|
||||
NC_DBPASS=$(</dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)
|
||||
NC_DBUSER=nextcloud
|
||||
NC_DBNAME=nextcloud
|
||||
|
||||
@@ -135,7 +142,7 @@ elif [[ ${NC_INSTALL} == "y" ]]; then
|
||||
|
||||
echo ""
|
||||
echo -e "\033[33mInstalling Nextcloud...\033[0m"
|
||||
ADMIN_NC_PASS=$(</dev/urandom tr -dc A-Za-z0-9 | head -c 28)
|
||||
ADMIN_NC_PASS=$(</dev/urandom tr -dc A-Za-z0-9 2> /dev/null | head -c 28)
|
||||
|
||||
echo -ne "[1/4] Setting correct permissions for www-data"
|
||||
docker exec -it $(docker ps -f name=php-fpm-mailcow -q) /bin/bash -c "chown -R www-data:www-data /web/nextcloud"
|
||||
@@ -215,5 +222,4 @@ elif [[ ${NC_RESETPW} == "y" ]]; then
|
||||
read -p "Enter the username: " NC_USER
|
||||
done
|
||||
docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) /web/nextcloud/occ user:resetpassword ${NC_USER}
|
||||
|
||||
fi
|
||||
|
77
update.sh
77
update.sh
@@ -176,18 +176,19 @@ remove_obsolete_nginx_ports() {
|
||||
}
|
||||
|
||||
detect_docker_compose_command(){
|
||||
if ! [ "${DOCKER_COMPOSE_VERSION}" == "native" ] && ! [ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]; then
|
||||
if ! [[ "${DOCKER_COMPOSE_VERSION}" =~ ^(native|standalone)$ ]]; then
|
||||
if docker compose > /dev/null 2>&1; then
|
||||
if docker compose version --short | grep "2." > /dev/null 2>&1; then
|
||||
DOCKER_COMPOSE_VERSION=native
|
||||
COMPOSE_COMMAND="docker compose"
|
||||
echo -e "\e[31mFound Docker Compose Plugin (native).\e[0m"
|
||||
echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to native\e[0m"
|
||||
sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=native/' $SCRIPT_DIR/mailcow.conf
|
||||
sleep 2
|
||||
echo -e "\e[33mNotice: You'll have to update this Compose Version via your Package Manager manually!\e[0m"
|
||||
else
|
||||
echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m"
|
||||
echo -e "\e[31mPlease update/install it manually regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
|
||||
echo -e "\e[31mPlease update/install it manually regarding to this doc site: https://docs.mailcow.email/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
elif docker-compose > /dev/null 2>&1; then
|
||||
@@ -197,26 +198,60 @@ if ! [ "${DOCKER_COMPOSE_VERSION}" == "native" ] && ! [ "${DOCKER_COMPOSE_VERSIO
|
||||
COMPOSE_COMMAND="docker-compose"
|
||||
echo -e "\e[31mFound Docker Compose Standalone.\e[0m"
|
||||
echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable to standalone\e[0m"
|
||||
sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=standalone/' $SCRIPT_DIR/mailcow.conf
|
||||
sleep 2
|
||||
echo -e "\e[33mNotice: For an automatic update of docker-compose please use the update_compose.sh scripts located at the helper-scripts folder.\e[0m"
|
||||
else
|
||||
echo -e "\e[31mCannot find Docker Compose with a Version Higher than 2.X.X.\e[0m"
|
||||
echo -e "\e[31mPlease update/install regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
|
||||
echo -e "\e[31mPlease update/install regarding to this doc site: https://docs.mailcow.email/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
else
|
||||
echo -e "\e[31mCannot find Docker Compose.\e[0m"
|
||||
echo -e "\e[31mPlease install it regarding to this doc site: https://mailcow.github.io/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
|
||||
echo -e "\e[31mPlease install it regarding to this doc site: https://docs.mailcow.email/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
elif [ "${DOCKER_COMPOSE_VERSION}" == "native" ]; then
|
||||
COMPOSE_COMMAND="docker compose"
|
||||
# Check if Native Compose works and has not been deleted
|
||||
if ! $COMPOSE_COMMAND > /dev/null 2>&1; then
|
||||
# IF it not exists/work anymore try the other command
|
||||
COMPOSE_COMMAND="docker-compose"
|
||||
if ! $COMPOSE_COMMAND > /dev/null 2>&1 || ! $COMPOSE_COMMAND --version | grep "^2." > /dev/null 2>&1; then
|
||||
# IF it cannot find Standalone in > 2.X, then script stops
|
||||
echo -e "\e[31mCannot find Docker Compose or the Version is lower then 2.X.X.\e[0m"
|
||||
echo -e "\e[31mPlease install it regarding to this doc site: https://docs.mailcow.email/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
# If it finds the standalone Plugin it will use this instead and change the mailcow.conf Variable accordingly
|
||||
echo -e "\e[31mFound different Docker Compose Version then declared in mailcow.conf!\e[0m"
|
||||
echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable from native to standalone\e[0m"
|
||||
sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=standalone/' $SCRIPT_DIR/mailcow.conf
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
|
||||
elif [ "${DOCKER_COMPOSE_VERSION}" == "standalone" ]; then
|
||||
COMPOSE_COMMAND="docker-compose"
|
||||
# Check if Standalone Compose works and has not been deleted
|
||||
if ! $COMPOSE_COMMAND > /dev/null 2>&1 && ! $COMPOSE_COMMAND --version > /dev/null 2>&1 | grep "^2." > /dev/null 2>&1; then
|
||||
# IF it not exists/work anymore try the other command
|
||||
COMPOSE_COMMAND="docker compose"
|
||||
if ! $COMPOSE_COMMAND > /dev/null 2>&1; then
|
||||
# IF it cannot find Native in > 2.X, then script stops
|
||||
echo -e "\e[31mCannot find Docker Compose.\e[0m"
|
||||
echo -e "\e[31mPlease install it regarding to this doc site: https://docs.mailcow.email/mailcow-dockerized-docs/i_u_m/i_u_m_install/\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
# If it finds the native Plugin it will use this instead and change the mailcow.conf Variable accordingly
|
||||
echo -e "\e[31mFound different Docker Compose Version then declared in mailcow.conf!\e[0m"
|
||||
echo -e "\e[31mSetting the DOCKER_COMPOSE_VERSION Variable from standalone to native\e[0m"
|
||||
sed -i 's/^DOCKER_COMPOSE_VERSION=.*/DOCKER_COMPOSE_VERSION=native/' $SCRIPT_DIR/mailcow.conf
|
||||
sleep 2
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -326,8 +361,12 @@ while (($#)); do
|
||||
echo -e "\e[32mRunning in forced mode...\e[0m"
|
||||
FORCE=y
|
||||
;;
|
||||
-d|--dev)
|
||||
echo -e "\e[32mRunning in Developer mode...\e[0m"
|
||||
DEV=y
|
||||
;;
|
||||
--help|-h)
|
||||
echo './update.sh [-c|--check, --ours, --gc, --nightly, --prefetch, --skip-start, --skip-ping-check, --stable, -f|--force, -h|--help]
|
||||
echo './update.sh [-c|--check, --ours, --gc, --nightly, --prefetch, --skip-start, --skip-ping-check, --stable, -f|--force, -d|--dev, -h|--help]
|
||||
|
||||
-c|--check - Check for updates and exit (exit codes => 0: update available, 3: no updates)
|
||||
--ours - Use merge strategy option "ours" to solve conflicts in favor of non-mailcow code (local changes over remote changes), not recommended!
|
||||
@@ -338,6 +377,7 @@ while (($#)); do
|
||||
--skip-ping-check - Skip ICMP Check to public DNS resolvers (Use it only if you´ve blocked any ICMP Connections to your mailcow machine)
|
||||
--stable - Switch your mailcow updates to the stable (master) branch. Default unless you changed it with --nightly.
|
||||
-f|--force - Force update, do not ask questions
|
||||
-d|--dev - Enables Developer Mode (No Checkout of update.sh for tests)
|
||||
'
|
||||
exit 1
|
||||
esac
|
||||
@@ -597,7 +637,7 @@ for option in ${CONFIG_ARRAY[@]}; do
|
||||
echo "Adding new option \"${option}\" to mailcow.conf"
|
||||
echo '# Password hash algorithm' >> mailcow.conf
|
||||
echo '# Only certain password hash algorithm are supported. For a fully list of supported schemes,' >> mailcow.conf
|
||||
echo '# see https://mailcow.github.io/mailcow-dockerized-docs/models/model-passwd/' >> mailcow.conf
|
||||
echo '# see https://docs.mailcow.email/models/model-passwd/' >> mailcow.conf
|
||||
echo "MAILCOW_PASS_SCHEME=BLF-CRYPT" >> mailcow.conf
|
||||
fi
|
||||
elif [[ ${option} == "ADDITIONAL_SERVER_NAMES" ]]; then
|
||||
@@ -617,7 +657,7 @@ for option in ${CONFIG_ARRAY[@]}; do
|
||||
echo '# Optional: Leave empty for none' >> mailcow.conf
|
||||
echo '# This value is only used on first order!' >> mailcow.conf
|
||||
echo '# Setting it at a later point will require the following steps:' >> mailcow.conf
|
||||
echo '# https://mailcow.github.io/mailcow-dockerized-docs/troubleshooting/debug-reset_tls/' >> mailcow.conf
|
||||
echo '# https://docs.mailcow.email/troubleshooting/debug-reset_tls/' >> mailcow.conf
|
||||
echo 'ACME_CONTACT=' >> mailcow.conf
|
||||
fi
|
||||
elif [[ ${option} == "WEBAUTHN_ONLY_TRUSTED_VENDORS" ]]; then
|
||||
@@ -727,15 +767,17 @@ elif [ $NEW_BRANCH == "nightly" ] && [ $CURRENT_BRANCH != "nightly" ]; then
|
||||
git checkout -f ${BRANCH}
|
||||
fi
|
||||
|
||||
echo -e "\e[32mChecking for newer update script...\e[0m"
|
||||
SHA1_1=$(sha1sum update.sh)
|
||||
git fetch origin #${BRANCH}
|
||||
git checkout origin/${BRANCH} update.sh
|
||||
SHA1_2=$(sha1sum update.sh)
|
||||
if [[ ${SHA1_1} != ${SHA1_2} ]]; then
|
||||
echo "update.sh changed, please run this script again, exiting."
|
||||
chmod +x update.sh
|
||||
exit 2
|
||||
if [ ! $DEV ]; then
|
||||
echo -e "\e[32mChecking for newer update script...\e[0m"
|
||||
SHA1_1=$(sha1sum update.sh)
|
||||
git fetch origin #${BRANCH}
|
||||
git checkout origin/${BRANCH} update.sh
|
||||
SHA1_2=$(sha1sum update.sh)
|
||||
if [[ ${SHA1_1} != ${SHA1_2} ]]; then
|
||||
echo "update.sh changed, please run this script again, exiting."
|
||||
chmod +x update.sh
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! $FORCE ]; then
|
||||
@@ -902,9 +944,6 @@ else
|
||||
echo -e "\e[33mCannot determine current git repository version...\e[0m"
|
||||
fi
|
||||
|
||||
# Set DOCKER_COMPOSE_VERSION
|
||||
sed -i 's/^DOCKER_COMPOSE_VERSION=$/DOCKER_COMPOSE_VERSION='$DOCKER_COMPOSE_VERSION'/g' mailcow.conf
|
||||
|
||||
if [[ ${SKIP_START} == "y" ]]; then
|
||||
echo -e "\e[33mNot starting mailcow, please run \"$COMPOSE_COMMAND up -d --remove-orphans\" to start mailcow.\e[0m"
|
||||
else
|
||||
|
Reference in New Issue
Block a user