commit
700f4ac0db
|
@ -0,0 +1,44 @@
|
|||
FROM debian:latest
|
||||
MAINTAINER https://m-ko.de Markus Kosmal <code@cnfg.io>
|
||||
|
||||
# Debian Base to use
|
||||
ENV DEBIAN_VERSION jessie
|
||||
|
||||
# initial install of av daemon
|
||||
RUN echo "deb http://http.debian.net/debian/ $DEBIAN_VERSION main contrib non-free" > /etc/apt/sources.list && \
|
||||
echo "deb http://http.debian.net/debian/ $DEBIAN_VERSION-updates main contrib non-free" >> /etc/apt/sources.list && \
|
||||
echo "deb http://security.debian.org/ $DEBIAN_VERSION/updates main contrib non-free" >> /etc/apt/sources.list && \
|
||||
apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y -qq \
|
||||
clamav-daemon \
|
||||
clamav-freshclam \
|
||||
libclamunrar7 \
|
||||
wget && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# initial update of av databases
|
||||
RUN wget -O /var/lib/clamav/main.cvd http://db.local.clamav.net/main.cvd && \
|
||||
wget -O /var/lib/clamav/daily.cvd http://db.local.clamav.net/daily.cvd && \
|
||||
wget -O /var/lib/clamav/bytecode.cvd http://db.local.clamav.net/bytecode.cvd && \
|
||||
chown clamav:clamav /var/lib/clamav/*.cvd
|
||||
|
||||
# permission juggling
|
||||
RUN mkdir /var/run/clamav && \
|
||||
chown clamav:clamav /var/run/clamav && \
|
||||
chmod 750 /var/run/clamav
|
||||
|
||||
# av configuration update
|
||||
RUN sed -i 's/^Foreground .*$/Foreground true/g' /etc/clamav/clamd.conf && \
|
||||
echo "TCPSocket 3310" >> /etc/clamav/clamd.conf && \
|
||||
sed -i 's/^Foreground .*$/Foreground true/g' /etc/clamav/freshclam.conf
|
||||
|
||||
# volume provision
|
||||
VOLUME ["/var/lib/clamav"]
|
||||
|
||||
# port provision
|
||||
EXPOSE 3310
|
||||
|
||||
# av daemon bootstrapping
|
||||
ADD bootstrap.sh /
|
||||
CMD ["/bootstrap.sh"]
|
|
@ -0,0 +1,35 @@
|
|||
#!/bin/bash
|
||||
# bootstrap clam av service and clam av database updater shell script
|
||||
# presented by mko (Markus Kosmal<code@cnfg.io>)
|
||||
set -m
|
||||
|
||||
# start clam service itself and the updater in background as daemon
|
||||
freshclam -d &
|
||||
clamd &
|
||||
|
||||
# recognize PIDs
|
||||
pidlist=`jobs -p`
|
||||
|
||||
# initialize latest result var
|
||||
latest_exit=0
|
||||
|
||||
# define shutdown helper
|
||||
function shutdown() {
|
||||
trap "" SUBS
|
||||
|
||||
for single in $pidlist; do
|
||||
if ! kill -0 $pidlist 2>/dev/null; then
|
||||
wait $pidlist
|
||||
exitcode=$?
|
||||
fi
|
||||
done
|
||||
|
||||
kill $pidlist 2>/dev/null
|
||||
}
|
||||
|
||||
# run shutdown
|
||||
trap terminate SUBS
|
||||
wait
|
||||
|
||||
# return received result
|
||||
exit $latest_exit
|
|
@ -1,26 +0,0 @@
|
|||
FROM ubuntu:xenial
|
||||
MAINTAINER Andre Peters <andre.peters@debinux.de>
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
ENV LC_ALL C
|
||||
|
||||
RUN dpkg-divert --local --rename --add /sbin/initctl \
|
||||
&& ln -sf /bin/true /sbin/initctl \
|
||||
&& dpkg-divert --local --rename --add /usr/bin/ischroot \
|
||||
&& ln -sf /bin/true /usr/bin/ischroot
|
||||
|
||||
RUN echo 'deb http://repo.powerdns.com/ubuntu xenial-rec-40 main' > /etc/apt/sources.list.d/pdns.list
|
||||
|
||||
RUN echo 'Package: pdns-*\n\
|
||||
Pin: origin repo.powerdns.com\n\
|
||||
Pin-Priority: 600\n' > /etc/apt/preferences.d/pdns
|
||||
|
||||
RUN apt-key adv --fetch-keys http://repo.powerdns.com/FD380FBB-pub.asc \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --force-yes pdns-recursor
|
||||
|
||||
CMD ["/usr/sbin/pdns_recursor"]
|
||||
|
||||
EXPOSE 53/udp
|
||||
|
||||
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
|
@ -12,13 +12,17 @@ RUN dpkg-divert --local --rename --add /sbin/initctl \
|
|||
RUN apt-key adv --fetch-keys http://rspamd.com/apt-stable/gpg.key \
|
||||
&& echo "deb http://rspamd.com/apt-stable/ xenial main" > /etc/apt/sources.list.d/rspamd.list \
|
||||
&& apt-get update \
|
||||
&& apt-get -y install rspamd ca-certificates
|
||||
&& apt-get -y install rspamd ca-certificates python-pip
|
||||
|
||||
RUN echo '.include $LOCAL_CONFDIR/local.d/rspamd.conf.local' > /etc/rspamd/rspamd.conf.local
|
||||
# "Hardcoded" - we need them
|
||||
RUN echo 'settings = "http://nginx:8081/settings.php";' > /etc/rspamd/modules.d/settings.conf
|
||||
|
||||
CMD ["/usr/bin/rspamd","-f", "-u", "_rspamd", "-g", "_rspamd"]
|
||||
ADD settings.conf /etc/rspamd/modules.d/settings.conf
|
||||
ADD antivirus.conf /etc/rspamd/modules.d/antivirus.conf
|
||||
|
||||
RUN pip install -U oletools
|
||||
|
||||
# Give Nginx/PHP time to restart
|
||||
CMD /bin/sleep 30; /usr/bin/rspamd -f -u _rspamd -g _rspamd
|
||||
|
||||
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
antivirus {
|
||||
.include(try=true,priority=1,duplicate=merge) "$LOCAL_CONFDIR/local.d/antivirus.conf"
|
||||
.include(try=true,priority=10) "$LOCAL_CONFDIR/override.d/antivirus.conf"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
settings = "http://nginx:8081/settings.php";
|
|
@ -7,9 +7,6 @@ redirect_stderr=true
|
|||
autostart=true
|
||||
stdout_syslog=true
|
||||
|
||||
[group:sogo-group]
|
||||
programs=reconf-domains,sogo
|
||||
|
||||
[program:sogo]
|
||||
command=/usr/sbin/sogod
|
||||
user=sogo
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
acl internal_networks {
|
||||
127.0.0.0/8;
|
||||
192.168.0.0/16;
|
||||
172.16.0.0/12;
|
||||
10.0.0.0/8;
|
||||
};
|
||||
|
||||
options {
|
||||
directory "/var/bind";
|
||||
allow-recursion { internal_networks; };
|
||||
listen-on { any; };
|
||||
listen-on-v6 { none; };
|
||||
pid-file "/var/run/named/named.pid";
|
||||
allow-transfer { none; };
|
||||
dnssec-enable yes;
|
||||
dnssec-validation yes;
|
||||
dnssec-lookaside auto;
|
||||
};
|
||||
|
||||
include "/etc/bind/bind.keys";
|
|
@ -0,0 +1 @@
|
|||
server_name logs.servercow.de autodiscover.* autoconfig.*;
|
|
@ -1,6 +1,6 @@
|
|||
proxy_cache_path /tmp levels=1:2 keys_zone=sogo:10m inactive=24h max_size=1g;
|
||||
server {
|
||||
include /etc/nginx/conf.d/listen.active;
|
||||
include /etc/nginx/conf.d/listen_ssl.active;
|
||||
include /etc/nginx/mime.types;
|
||||
charset utf-8;
|
||||
override_charset on;
|
||||
|
@ -13,13 +13,23 @@ server {
|
|||
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains";
|
||||
ssl_ecdh_curve secp384r1;
|
||||
index index.php index.html;
|
||||
server_name _ autodiscover.* autoconfig.*;
|
||||
include /etc/nginx/conf.d/server_name.active;
|
||||
error_log /var/log/nginx/error.log;
|
||||
access_log /var/log/nginx/access.log;
|
||||
root /web;
|
||||
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
allow all;
|
||||
default_type "text/plain";
|
||||
}
|
||||
|
||||
# If behind reverse proxy, forwards the correct IP
|
||||
set_real_ip_from 172.22.1.1;
|
||||
real_ip_header X-Forwarded-For;
|
||||
real_ip_recursive on;
|
||||
|
||||
location = /principals/ {
|
||||
rewrite ^ https://$host/SOGo/dav;
|
||||
rewrite ^ $scheme://$host:$server_port/SOGo/dav;
|
||||
allow all;
|
||||
}
|
||||
|
||||
|
@ -42,6 +52,7 @@ server {
|
|||
proxy_pass http://172.22.1.253:11334/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
|
@ -52,12 +63,20 @@ server {
|
|||
deny all;
|
||||
}
|
||||
|
||||
if ($host ~* autodiscover\.(.*)) {
|
||||
rewrite ^(.*) /autodiscover.php last;
|
||||
location ~ /(?:a|A)utodiscover/(?:a|A)utodiscover.xml {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass phpfpm:9000;
|
||||
include /etc/nginx/fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
try_files /autodiscover.php =404;
|
||||
}
|
||||
|
||||
if ($host ~* autoconfig\.(.*)) {
|
||||
rewrite ^(.*) /autoconfig.php last;
|
||||
location ~ /(?:m|M)ail/(?:c|C)onfig-v1.1.xml {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass phpfpm:9000;
|
||||
include /etc/nginx/fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
try_files /autoconfig.php =404;
|
||||
}
|
||||
|
||||
location ^~ /Microsoft-Server-ActiveSync {
|
||||
|
@ -92,13 +111,6 @@ server {
|
|||
proxy_set_header x-webobjects-server-name $server_name;
|
||||
proxy_set_header x-webobjects-server-url $scheme://$host:$server_port;
|
||||
proxy_set_header x-webobjects-server-port $server_port;
|
||||
#proxy_connect_timeout 90;
|
||||
#proxy_send_timeout 90;
|
||||
#proxy_read_timeout 90;
|
||||
#proxy_buffer_size 4k;
|
||||
#proxy_buffers 4 32k;
|
||||
#proxy_busy_buffers_size 64k;
|
||||
#proxy_temp_file_write_size 64k;
|
||||
client_body_buffer_size 128k;
|
||||
client_max_body_size 100m;
|
||||
break;
|
||||
|
@ -114,6 +126,164 @@ server {
|
|||
allow all;
|
||||
}
|
||||
|
||||
location /.woa/WebServerResources/ {
|
||||
proxy_pass http://172.22.1.252:9192/WebServerResources/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache sogo;
|
||||
proxy_cache_valid 200 1d;
|
||||
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
||||
#alias /usr/lib/GNUstep/SOGo/WebServerResources/;
|
||||
allow all;
|
||||
}
|
||||
|
||||
location /SOGo/WebServerResources/ {
|
||||
proxy_pass http://172.22.1.252:9192/WebServerResources/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache sogo;
|
||||
proxy_cache_valid 200 1d;
|
||||
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
||||
#alias /usr/lib/GNUstep/SOGo/WebServerResources/;
|
||||
allow all;
|
||||
}
|
||||
|
||||
location (^/SOGo/so/ControlPanel/Products/[^/]*UI/Resources/.*\.(jpg|png|gif|css|js)$ {
|
||||
proxy_pass http://172.22.1.252:9192/$1.SOGo/Resources/$2;
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache sogo;
|
||||
proxy_cache_valid 200 1d;
|
||||
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
||||
#alias /usr/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
|
||||
}
|
||||
}
|
||||
server {
|
||||
include /etc/nginx/conf.d/listen_plain.active;
|
||||
include /etc/nginx/mime.types;
|
||||
charset utf-8;
|
||||
override_charset on;
|
||||
index index.php index.html;
|
||||
include /etc/nginx/conf.d/server_name.active;
|
||||
error_log /var/log/nginx/error.log;
|
||||
access_log /var/log/nginx/access.log;
|
||||
root /web;
|
||||
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
allow all;
|
||||
default_type "text/plain";
|
||||
}
|
||||
|
||||
# If behind reverse proxy, forwards the correct IP
|
||||
set_real_ip_from 172.22.1.1;
|
||||
real_ip_header X-Forwarded-For;
|
||||
real_ip_recursive on;
|
||||
|
||||
location = /principals/ {
|
||||
rewrite ^ $scheme://$host:$server_port/SOGo/dav;
|
||||
allow all;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
try_files $uri =404;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass phpfpm:9000;
|
||||
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_param PHP_VALUE "max_execution_time = 1200
|
||||
max_input_time = 1200
|
||||
memory_limit = 64M";
|
||||
fastcgi_read_timeout 1200;
|
||||
}
|
||||
|
||||
rewrite ^(/save.+)$ /rspamd$1 last;
|
||||
location /rspamd/ {
|
||||
proxy_pass http://172.22.1.253:11334/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
}
|
||||
|
||||
location ^~ /inc/init.sql {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location ~ /(?:a|A)utodiscover/(?:a|A)utodiscover.xml {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass phpfpm:9000;
|
||||
include /etc/nginx/fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
try_files /autodiscover.php =404;
|
||||
}
|
||||
|
||||
location ~ /(?:m|M)ail/(?:c|C)onfig-v1.1.xml {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass phpfpm:9000;
|
||||
include /etc/nginx/fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
try_files /autoconfig.php =404;
|
||||
}
|
||||
|
||||
location ^~ /Microsoft-Server-ActiveSync {
|
||||
proxy_pass http://172.22.1.252:20000/SOGo/Microsoft-Server-ActiveSync;
|
||||
proxy_connect_timeout 1000;
|
||||
proxy_next_upstream timeout error;
|
||||
proxy_send_timeout 1000;
|
||||
proxy_read_timeout 1000;
|
||||
proxy_buffer_size 8k;
|
||||
proxy_buffers 4 32k;
|
||||
proxy_temp_file_write_size 64k;
|
||||
proxy_busy_buffers_size 64k;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $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 $scheme://$host:$server_port;
|
||||
proxy_set_header x-webobjects-server-port $server_port;
|
||||
client_body_buffer_size 128k;
|
||||
client_max_body_size 100m;
|
||||
}
|
||||
|
||||
location ^~ /SOGo {
|
||||
proxy_pass http://172.22.1.252:20000;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $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 $scheme://$host:$server_port;
|
||||
proxy_set_header x-webobjects-server-port $server_port;
|
||||
client_body_buffer_size 128k;
|
||||
client_max_body_size 100m;
|
||||
break;
|
||||
}
|
||||
|
||||
location /SOGo.woa/WebServerResources/ {
|
||||
proxy_pass http://172.22.1.252:9192/WebServerResources/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache sogo;
|
||||
proxy_cache_valid 200 1d;
|
||||
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
||||
#alias /usr/lib/GNUstep/SOGo/WebServerResources/;
|
||||
allow all;
|
||||
}
|
||||
|
||||
location /.woa/WebServerResources/ {
|
||||
proxy_pass http://172.22.1.252:9192/WebServerResources/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_cache sogo;
|
||||
proxy_cache_valid 200 1d;
|
||||
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
|
||||
#alias /usr/lib/GNUstep/SOGo/WebServerResources/;
|
||||
allow all;
|
||||
}
|
||||
|
||||
location /SOGo/WebServerResources/ {
|
||||
proxy_pass http://172.22.1.252:9192/WebServerResources/;
|
||||
proxy_set_header Host $host;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
listen ${HTTP_PORT};
|
|
@ -0,0 +1 @@
|
|||
server_name ${MAILCOW_HOSTNAME} autodiscover.* autoconfig.*;
|
|
@ -1 +0,0 @@
|
|||
addNTA("mailcow-network", "nta for local")
|
|
@ -1,41 +0,0 @@
|
|||
allow-from=127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8
|
||||
config-dir=/etc/powerdns
|
||||
daemon=no
|
||||
disable-syslog=yes
|
||||
dnssec=process
|
||||
dnssec-log-bogus=yes
|
||||
dont-query=10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10, 0.0.0.0/8, 192.0.0.0/24, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::/96, ::ffff:0:0/96, 100::/64, 2001:db8::/32
|
||||
export-etc-hosts=off
|
||||
# forward-zones=
|
||||
forward-zones-recurse=mailcow-network.=127.0.0.11
|
||||
local-address=0.0.0.0
|
||||
local-port=53
|
||||
loglevel=6
|
||||
# lowercase-outgoing=no
|
||||
lua-config-file=/etc/powerdns/pdns_custom.lua
|
||||
# max-cache-entries=1000000
|
||||
# max-cache-ttl=86400
|
||||
# max-mthreads=2048
|
||||
# max-negative-ttl=3600
|
||||
# max-packetcache-entries=500000
|
||||
# max-qperq=50
|
||||
# max-tcp-clients=128
|
||||
# max-tcp-per-client=0
|
||||
# max-total-msec=7000
|
||||
# minimum-ttl-override=0
|
||||
# network-timeout=1500
|
||||
# packetcache-servfail-ttl=60
|
||||
# packetcache-ttl=3600
|
||||
quiet=yes
|
||||
# security-poll-suffix=secpoll.powerdns.com.
|
||||
# serve-rfc1918=yes
|
||||
# server-down-max-fails=64
|
||||
# server-down-throttle-time=60
|
||||
setgid=pdns
|
||||
setuid=pdns
|
||||
# spoof-nearmiss-max=20
|
||||
# stack-size=200000
|
||||
# threads=2
|
||||
# trace=off
|
||||
version-string=PowerDNS Recursor
|
||||
webserver=no
|
|
@ -83,7 +83,7 @@ virtual_alias_maps = proxy:mysql:/opt/postfix/conf/sql/mysql_virtual_alias_maps.
|
|||
virtual_gid_maps = static:5000
|
||||
virtual_mailbox_base = /var/vmail/
|
||||
virtual_mailbox_domains = proxy:mysql:/opt/postfix/conf/sql/mysql_virtual_domains_maps.cf
|
||||
virtual_mailbox_maps = proxy:mysql:/opt/postfix/conf/sql/mysql_virtual_mailbox_maps.cf, proxy:mysql:/opt/postfix/conf/sql/mysql_virtual_alias_domain_mailbox_maps.cf
|
||||
virtual_mailbox_maps = proxy:mysql:/opt/postfix/conf/sql/mysql_virtual_mailbox_maps.cf
|
||||
virtual_minimum_uid = 104
|
||||
virtual_transport = lmtp:inet:dovecot:24
|
||||
virtual_uid_maps = static:5000
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
user = mailcow
|
||||
password = mysafepasswd
|
||||
hosts = mysql
|
||||
dbname = mailcow
|
||||
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'
|
|
@ -2,4 +2,4 @@ user = mailcow
|
|||
password = mysafepasswd
|
||||
hosts = mysql
|
||||
dbname = mailcow
|
||||
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
|
||||
query = SELECT username FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'
|
||||
|
|
|
@ -2,4 +2,4 @@ user = mailcow
|
|||
password = mysafepasswd
|
||||
hosts = mysql
|
||||
dbname = mailcow
|
||||
query = SELECT goto FROM alias WHERE address='%s' AND active='1' AND domain IN(SELECT domain FROM domain WHERE domain='%d' AND active='1') UNION SELECT logged_in_as FROM sender_acl WHERE send_as='@%d' OR send_as='%s' OR send_as IN ( SELECT CONCAT ('@',target_domain) FROM alias_domain WHERE alias_domain = '%d') OR send_as IN ( SELECT CONCAT ('%u','@',target_domain) FROM alias_domain WHERE alias_domain = '%d' ) AND logged_in_as NOT IN (SELECT goto FROM alias WHERE address='%s') UNION SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' AND alias.address = CONCAT('%u','@',alias_domain.target_domain) AND alias.active ='1' AND alias_domain.active='1'
|
||||
query = SELECT goto FROM alias WHERE address='%s' AND active='1' AND domain IN(SELECT domain FROM domain WHERE domain='%d' AND active='1') UNION SELECT logged_in_as FROM sender_acl WHERE send_as='@%d' OR send_as='%s' OR send_as IN ( SELECT CONCAT ('@',target_domain) FROM alias_domain WHERE alias_domain = '%d') OR send_as IN ( SELECT CONCAT ('%u','@',target_domain) FROM alias_domain WHERE alias_domain = '%d' ) AND logged_in_as NOT IN (SELECT goto FROM alias WHERE address='%s') UNION SELECT username FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' AND mailbox.username = CONCAT('%u','@',alias_domain.target_domain) AND mailbox.active ='1' AND alias_domain.active='1'
|
||||
|
|
|
@ -1,22 +1,34 @@
|
|||
<?php
|
||||
ini_set('error_reporting', 0);
|
||||
header('Content-Type: text/plain');
|
||||
require_once "vars.inc.php";
|
||||
ini_set('error_reporting', 0);
|
||||
$has_object = 0;
|
||||
header('Content-Type: text/plain');
|
||||
$dsn = $database_type . ':host=' . $database_host . ';dbname=' . $database_name;
|
||||
$opt = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
];
|
||||
try {
|
||||
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
|
||||
$stmt = $pdo->query("SELECT `domain` FROM `domain`");
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($row = array_shift($rows)) {
|
||||
$has_object = 1;
|
||||
echo strtolower(trim($row['domain'])) . PHP_EOL;
|
||||
}
|
||||
$stmt = $pdo->query("SELECT `alias_domain` FROM `alias_domain`");
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($row = array_shift($rows)) {
|
||||
$has_object = 1;
|
||||
echo strtolower(trim($row['alias_domain'])) . PHP_EOL;
|
||||
}
|
||||
if ($has_object == 0) {
|
||||
echo "dummy@domain.local";
|
||||
}
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
echo "dummy@domain.local";
|
||||
exit;
|
||||
}
|
||||
?>
|
|
@ -4,6 +4,11 @@ The match section performs AND operation on different matches: for example, if y
|
|||
then the rule matches only when from AND rcpt match. For similar matches, the OR rule applies: if you have multiple rcpt matches,
|
||||
then any of these will trigger the rule. If a rule is triggered then no more rules are matched.
|
||||
*/
|
||||
function parse_email($email) {
|
||||
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) return false;
|
||||
$a = strrpos($email, '@');
|
||||
return array('local' => substr($email, 0, $a), 'domain' => substr($email, $a));
|
||||
}
|
||||
header('Content-Type: text/plain');
|
||||
require_once "vars.inc.php";
|
||||
|
||||
|
@ -15,7 +20,15 @@ $opt = [
|
|||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
];
|
||||
try {
|
||||
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
|
||||
$stmt = $pdo->query("SELECT * FROM `filterconf`");
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
echo 'settings { }';
|
||||
exit;
|
||||
}
|
||||
|
||||
?>
|
||||
settings {
|
||||
<?php
|
||||
|
@ -48,13 +61,27 @@ while ($row = array_shift($rows)) {
|
|||
<?php
|
||||
}
|
||||
}
|
||||
$local = parse_email($row['object'])['local'];
|
||||
$domain = parse_email($row['object'])['domain'];
|
||||
if (!empty($local) && !empty($local)) {
|
||||
?>
|
||||
rcpt = "/<?=$local;?>\+.*<?=$domain;?>/";
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
rcpt = "<?=$row['object'];?>";
|
||||
<?php
|
||||
$stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` = :object_goto AND `address` NOT LIKE '@%' AND `address` != :object_address");
|
||||
$stmt->execute(array(':object_goto' => $row['object'], ':object_address' => $row['object']));
|
||||
$stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` LIKE :object_goto AND `address` NOT LIKE '@%' AND `address` != :object_address");
|
||||
$stmt->execute(array(':object_goto' => '%' . $row['object'] . '%', ':object_address' => $row['object']));
|
||||
$rows_aliases_1 = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($row_aliases_1 = array_shift($rows_aliases_1)) {
|
||||
$local = parse_email($row_aliases_1['address'])['local'];
|
||||
$domain = parse_email($row_aliases_1['address'])['domain'];
|
||||
if (!empty($local) && !empty($local)) {
|
||||
?>
|
||||
rcpt = "/<?=$local;?>\+.*<?=$domain;?>/";
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
rcpt = "<?=$row_aliases_1['address'];?>";
|
||||
<?php
|
||||
|
@ -67,6 +94,13 @@ while ($row = array_shift($rows)) {
|
|||
array_filter($rows_aliases_2);
|
||||
while ($row_aliases_2 = array_shift($rows_aliases_2)) {
|
||||
if (!empty($row_aliases_2['aliases'])) {
|
||||
$local = parse_email($row_aliases_2['aliases'])['local'];
|
||||
$domain = parse_email($row_aliases_2['aliases'])['domain'];
|
||||
if (!empty($local) && !empty($local)) {
|
||||
?>
|
||||
rcpt = "/<?=$local;?>\+.*<?=$domain;?>/";
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
rcpt = "<?=$row_aliases_2['aliases'];?>";
|
||||
<?php
|
||||
|
@ -123,14 +157,30 @@ while ($row = array_shift($rows)) {
|
|||
else {
|
||||
?>
|
||||
priority = high;
|
||||
<?php
|
||||
$local = parse_email($row['object'])['local'];
|
||||
$domain = parse_email($row['object'])['domain'];
|
||||
if (!empty($local) && !empty($local)) {
|
||||
?>
|
||||
rcpt = "/<?=$local;?>\+.*<?=$domain;?>/";
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
rcpt = "<?=$row['object'];?>";
|
||||
<?php
|
||||
}
|
||||
$stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` = :object_goto AND `address` NOT LIKE '@%' AND `address` != :object_address");
|
||||
$stmt->execute(array(':object_goto' => $row['object'], ':object_address' => $row['object']));
|
||||
$stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` LIKE :object_goto AND `address` NOT LIKE '@%' AND `address` != :object_address");
|
||||
$stmt->execute(array(':object_goto' => '%' . $row['object'] . '%', ':object_address' => $row['object']));
|
||||
$rows_aliases_wl_1 = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
array_filter($rows_aliases_wl_1);
|
||||
while ($row_aliases_wl_1 = array_shift($rows_aliases_wl_1)) {
|
||||
$local = parse_email($row_aliases_wl_1['address'])['local'];
|
||||
$domain = parse_email($row_aliases_wl_1['address'])['domain'];
|
||||
if (!empty($local) && !empty($local)) {
|
||||
?>
|
||||
rcpt = "/<?=$local;?>\+.*<?=$domain;?>/";
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
rcpt = "<?=$row_aliases_wl_1['address'];?>";
|
||||
<?php
|
||||
|
@ -143,6 +193,13 @@ while ($row = array_shift($rows)) {
|
|||
array_filter($rows_aliases_wl_2);
|
||||
while ($row_aliases_wl_2 = array_shift($rows_aliases_wl_2)) {
|
||||
if (!empty($row_aliases_wl_2['aliases'])) {
|
||||
$local = parse_email($row_aliases_wl_2['aliases'])['local'];
|
||||
$domain = parse_email($row_aliases_wl_2['aliases'])['domain'];
|
||||
if (!empty($local) && !empty($local)) {
|
||||
?>
|
||||
rcpt = "/<?=$local;?>\+.*<?=$domain;?>/";
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
rcpt = "<?=$row_aliases_wl_2['aliases'];?>";
|
||||
<?php
|
||||
|
@ -195,14 +252,30 @@ while ($row = array_shift($rows)) {
|
|||
else {
|
||||
?>
|
||||
priority = high;
|
||||
<?php
|
||||
$local = parse_email($row['object'])['local'];
|
||||
$domain = parse_email($row['object'])['domain'];
|
||||
if (!empty($local) && !empty($local)) {
|
||||
?>
|
||||
rcpt = "/<?=$local;?>\+.*<?=$domain;?>/";
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
rcpt = "<?=$row['object'];?>";
|
||||
<?php
|
||||
}
|
||||
$stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` = :object_goto AND `address` NOT LIKE '@%' AND `address` != :object_address");
|
||||
$stmt->execute(array(':object_goto' => $row['object'], ':object_address' => $row['object']));
|
||||
$stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` LIKE :object_goto AND `address` NOT LIKE '@%' AND `address` != :object_address");
|
||||
$stmt->execute(array(':object_goto' => '%' . $row['object'] . '%', ':object_address' => $row['object']));
|
||||
$rows_aliases_bl_1 = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
array_filter($rows_aliases_bl_1);
|
||||
while ($row_aliases_bl_1 = array_shift($rows_aliases_bl_1)) {
|
||||
$local = parse_email($row_aliases_bl_1['address'])['local'];
|
||||
$domain = parse_email($row_aliases_bl_1['address'])['domain'];
|
||||
if (!empty($local) && !empty($local)) {
|
||||
?>
|
||||
rcpt = "/<?=$local;?>\+.*<?=$domain;?>/";
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
rcpt = "<?=$row_aliases_bl_1['address'];?>";
|
||||
<?php
|
||||
|
@ -215,6 +288,13 @@ while ($row = array_shift($rows)) {
|
|||
array_filter($rows_aliases_bl_2);
|
||||
while ($row_aliases_bl_2 = array_shift($rows_aliases_bl_2)) {
|
||||
if (!empty($row_aliases_bl_2['aliases'])) {
|
||||
$local = parse_email($row_aliases_bl_2['aliases'])['local'];
|
||||
$domain = parse_email($row_aliases_bl_2['aliases'])['domain'];
|
||||
if (!empty($local) && !empty($local)) {
|
||||
?>
|
||||
rcpt = "/<?=$local;?>\+.*<?=$domain;?>/";
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
rcpt = "<?=$row_aliases_bl_2['aliases'];?>";
|
||||
<?php
|
||||
|
|
|
@ -1,22 +1,34 @@
|
|||
<?php
|
||||
ini_set('error_reporting', 0);
|
||||
header('Content-Type: text/plain');
|
||||
require_once "vars.inc.php";
|
||||
ini_set('error_reporting', 0);
|
||||
$has_object = 0;
|
||||
header('Content-Type: text/plain');
|
||||
$dsn = $database_type . ':host=' . $database_host . ';dbname=' . $database_name;
|
||||
$opt = [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
];
|
||||
try {
|
||||
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
|
||||
$stmt = $pdo->query("SELECT `username` FROM `mailbox` WHERE `wants_tagged_subject` = '1'");
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($row = array_shift($rows)) {
|
||||
$has_object = 1;
|
||||
echo strtolower(trim($row['username'])) . PHP_EOL;
|
||||
}
|
||||
$stmt = $pdo->query("SELECT CONCAT(mailbox.local_part, '@', alias_domain.alias_domain) as `tag_ad` FROM `mailbox` INNER JOIN `alias_domain` ON mailbox.domain = alias_domain.target_domain WHERE mailbox.wants_tagged_subject='1';");
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($row = array_shift($rows)) {
|
||||
$has_object = 1;
|
||||
echo strtolower(trim($row['tag_ad'])) . PHP_EOL;
|
||||
}
|
||||
if ($has_object == 0) {
|
||||
echo "dummy@domain.local";
|
||||
}
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
echo "dummy@domain.local";
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -11,69 +11,85 @@ rspamd_config.MAILCOW_MOO = function (task)
|
|||
return true
|
||||
end
|
||||
|
||||
local modify_subject_map = rspamd_config:add_map({
|
||||
url = 'http://nginx:8081/tags.php',
|
||||
modify_subject_map = rspamd_config:add_map({
|
||||
url = 'http://172.22.1.251:8081/tags.php',
|
||||
type = 'map',
|
||||
description = 'Map of users to use subject tags for'
|
||||
})
|
||||
|
||||
local auth_domain_map = rspamd_config:add_map({
|
||||
url = 'http://nginx:8081/authoritative.php',
|
||||
auth_domain_map = rspamd_config:add_map({
|
||||
url = 'http://172.22.1.251:8081/authoritative.php',
|
||||
type = 'map',
|
||||
description = 'Map of domains we are authoritative for'
|
||||
})
|
||||
|
||||
rspamd_config.ADD_DELIMITER_TAG = {
|
||||
callback = function(task)
|
||||
tag = nil
|
||||
local tag_env = nil
|
||||
local tag_to = nil
|
||||
|
||||
local tag = nil
|
||||
local util = require("rspamd_util")
|
||||
local rspamd_logger = require "rspamd_logger"
|
||||
|
||||
local user_env_tagged = task:get_recipients(1)[1]['user']
|
||||
local user_to_tagged = task:get_recipients(2)[1]['user']
|
||||
|
||||
local user_tagged = task:get_recipients(2)[1]['user']
|
||||
local domain = task:get_recipients(1)[1]['domain']
|
||||
|
||||
local user_env, tag_env = user_env_tagged:match("([^+]+)+(.*)")
|
||||
local user_to, tag_to = user_to_tagged:match("([^+]+)+(.*)")
|
||||
|
||||
local user, tag = user_tagged:match("([^+]+)+(.*)")
|
||||
local authdomain = auth_domain_map:get_key(domain)
|
||||
|
||||
if tag_env then
|
||||
tag = tag_env
|
||||
user = user_env
|
||||
elseif tag_to then
|
||||
tag = tag_to
|
||||
user = user_env
|
||||
end
|
||||
|
||||
if tag and authdomain then
|
||||
rspamd_logger.infox("Domain %s is part of mailcow, start reading tag settings", domain)
|
||||
rspamd_logger.infox("domain: %1, tag: %2", domain, tag)
|
||||
local user_untagged = user .. '@' .. domain
|
||||
rspamd_logger.infox("Querying tag settings for user %1", user_untagged)
|
||||
rspamd_logger.infox("querying tag settings for user %1", user_untagged)
|
||||
if modify_subject_map:get_key(user_untagged) then
|
||||
rspamd_logger.infox("User wants subject modified for tagged mail")
|
||||
rspamd_logger.infox("found user in map for subject rewrite")
|
||||
local sbj = task:get_header('Subject')
|
||||
if tag then
|
||||
rspamd_logger.infox("Found tag %1, will modify subject header", tag)
|
||||
new_sbj = '=?UTF-8?B?' .. tostring(util.encode_base64('[' .. tag .. '] ' .. sbj)) .. '?='
|
||||
task:set_rmilter_reply({
|
||||
remove_headers = {['Subject'] = 1},
|
||||
add_headers = {['Subject'] = new_sbj}
|
||||
})
|
||||
end
|
||||
else
|
||||
rspamd_logger.infox("Add X-Moo-Tag header")
|
||||
rspamd_logger.infox("add X-Moo-Tag header")
|
||||
task:set_rmilter_reply({
|
||||
add_headers = {['X-Moo-Tag'] = 'YES'}
|
||||
})
|
||||
end
|
||||
else
|
||||
rspamd_logger.infox("Skip delimiter handling for untagged message or authenticated user")
|
||||
rspamd_logger.infox("skip delimiter handling for untagged message or authenticated user")
|
||||
end
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
rspamd_config.MRAPTOR = {
|
||||
callback = function(task)
|
||||
local parts = task:get_parts()
|
||||
local rspamd_logger = require "rspamd_logger"
|
||||
local rspamd_regexp = require "rspamd_regexp"
|
||||
|
||||
if parts then
|
||||
for _,p in ipairs(parts) do
|
||||
local mtype,subtype = p:get_type()
|
||||
local re = rspamd_regexp.create_cached('/(office|word|excel)/i')
|
||||
if re:match(subtype) then
|
||||
local content = tostring(p:get_content())
|
||||
local filename = p:get_filename()
|
||||
|
||||
local file = os.tmpname()
|
||||
f = io.open(file, "a+")
|
||||
f:write(content)
|
||||
f:close()
|
||||
|
||||
local scan = assert(io.popen('PATH=/usr/bin:/usr/local/bin mraptor ' .. file .. '> /dev/null 2>&1; echo $?', 'r'))
|
||||
local result = scan:read('*all')
|
||||
local exit_code = string.match(result, "%d+")
|
||||
rspamd_logger.infox(exit_code)
|
||||
scan:close()
|
||||
|
||||
if exit_code == "20" then
|
||||
rspamd_logger.infox("Reject dangerous macro in office file " .. filename)
|
||||
task:set_pre_result(rspamd_actions['reject'], 'Dangerous macro in office file ' .. filename)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
|
|
@ -6,7 +6,20 @@ if (!isset($_SESSION['mailcow_cc_role']) OR !in_array($_SESSION['mailcow_cc_role
|
|||
exit();
|
||||
}
|
||||
if ($_GET['ACTION'] == "start") {
|
||||
$request = xmlrpc_encode_request("supervisor.startProcessGroup", 'sogo-group', array('encoding'=>'utf-8'));
|
||||
$request = xmlrpc_encode_request("supervisor.startProcess", 'reconf-domains', array('encoding'=>'utf-8'));
|
||||
$context = stream_context_create(array('http' => array(
|
||||
'method' => "POST",
|
||||
'header' => "Content-Length: " . strlen($request),
|
||||
'content' => $request
|
||||
)));
|
||||
$file = @file_get_contents("http://sogo:9191/RPC2", false, $context) or die("Cannot connect to $remote_server:$listener_port");
|
||||
$response = xmlrpc_decode($file);
|
||||
if (isset($response['faultString'])) {
|
||||
echo '<b><span class="pull-right text-warning">' . $response['faultString'] . '</span></b>';
|
||||
}
|
||||
else {
|
||||
sleep(4);
|
||||
$request = xmlrpc_encode_request("supervisor.startProcess", 'sogo', array('encoding'=>'utf-8'));
|
||||
$context = stream_context_create(array('http' => array(
|
||||
'method' => "POST",
|
||||
'header' => "Content-Length: " . strlen($request),
|
||||
|
@ -21,8 +34,22 @@ if ($_GET['ACTION'] == "start") {
|
|||
echo '<b><span class="pull-right text-success">OK</span></b>';
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($_GET['ACTION'] == "stop") {
|
||||
$request = xmlrpc_encode_request("supervisor.stopProcessGroup", 'sogo-group', array('encoding'=>'utf-8'));
|
||||
$request = xmlrpc_encode_request("supervisor.stopProcess", 'sogo', array('encoding'=>'utf-8'));
|
||||
$context = stream_context_create(array('http' => array(
|
||||
'method' => "POST",
|
||||
'header' => "Content-Length: " . strlen($request),
|
||||
'content' => $request
|
||||
)));
|
||||
$file = @file_get_contents("http://sogo:9191/RPC2", false, $context) or die("Cannot connect to $remote_server:$listener_port");
|
||||
$response = xmlrpc_decode($file);
|
||||
if (isset($response['faultString'])) {
|
||||
echo '<b><span class="pull-right text-warning">' . $response['faultString'] . '</span></b>';
|
||||
}
|
||||
else {
|
||||
sleep(1);
|
||||
$request = xmlrpc_encode_request("supervisor.stopProcess", 'reconf-domains', array('encoding'=>'utf-8'));
|
||||
$context = stream_context_create(array('http' => array(
|
||||
'method' => "POST",
|
||||
'header' => "Content-Length: " . strlen($request),
|
||||
|
@ -37,4 +64,5 @@ elseif ($_GET['ACTION'] == "stop") {
|
|||
echo '<b><span class="pull-right text-success">OK</span></b>';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -416,7 +416,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
|
|||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" for="sender_acl"><?=$lang['edit']['sender_acl'];?>:</label>
|
||||
<div class="col-sm-10">
|
||||
<select data-width="50%" style="width:100%" id="sender_acl" name="sender_acl[]" size="10" multiple>
|
||||
<select data-width="100%" style="width:100%" id="sender_acl" name="sender_acl[]" size="10" multiple>
|
||||
<?php
|
||||
$sender_acl_handles = mailbox_get_sender_acl_handles($mailbox);
|
||||
|
||||
|
|
|
@ -253,6 +253,8 @@ function edit_admin_account($postarray) {
|
|||
}
|
||||
$username = $postarray['admin_user'];
|
||||
$username_now = $_SESSION['mailcow_cc_username'];
|
||||
$password = $postarray['admin_pass'];
|
||||
$password2 = $postarray['admin_pass2'];
|
||||
|
||||
if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username)) || empty ($username)) {
|
||||
$_SESSION['return'] = array(
|
||||
|
@ -262,15 +264,22 @@ function edit_admin_account($postarray) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!empty($postarray['admin_pass']) && !empty($postarray['admin_pass2'])) {
|
||||
if ($postarray['admin_pass'] != $postarray['admin_pass2']) {
|
||||
if (!empty($password) && !empty($password2)) {
|
||||
if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
'msg' => sprintf($lang['danger']['password_complexity'])
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if ($password != $password2) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
'msg' => sprintf($lang['danger']['password_mismatch'])
|
||||
);
|
||||
return false;
|
||||
}
|
||||
$password_hashed = hash_password($postarray['admin_pass']);
|
||||
$password_hashed = hash_password($password);
|
||||
try {
|
||||
$stmt = $pdo->prepare("UPDATE `admin` SET
|
||||
`modified` = :modified,
|
||||
|
@ -585,9 +594,7 @@ function edit_user_account($postarray) {
|
|||
);
|
||||
return false;
|
||||
}
|
||||
if (strlen($password_new) < "6" ||
|
||||
!preg_match('/[A-Za-z]/', $password_new) ||
|
||||
!preg_match('/[0-9]/', $password_new)) {
|
||||
if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password_new)) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
'msg' => sprintf($lang['danger']['password_complexity'])
|
||||
|
@ -1459,8 +1466,11 @@ function user_get_alias_details($username) {
|
|||
}
|
||||
try {
|
||||
$data['address'] = $username;
|
||||
$stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '✘') AS `aliases` FROM `alias` WHERE `goto` = :username_goto AND `address` NOT LIKE '@%' AND `address` != :username_address");
|
||||
$stmt->execute(array(':username_goto' => $username, ':username_address' => $username));
|
||||
$stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '✘') AS `aliases` FROM `alias`
|
||||
WHERE `goto` LIKE :username_goto
|
||||
AND `address` NOT LIKE '@%'
|
||||
AND `address` != :username_address");
|
||||
$stmt->execute(array(':username_goto' => '%' . $username . '%', ':username_address' => $username));
|
||||
$run = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($row = array_shift($run)) {
|
||||
$data['aliases'] = $row['aliases'];
|
||||
|
@ -1485,8 +1495,8 @@ function user_get_alias_details($username) {
|
|||
while ($row = array_shift($run)) {
|
||||
$data['aliases_send_as_all'] = $row['send_as'];
|
||||
}
|
||||
$stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '✘') as `address` FROM `alias` WHERE `goto` = :username AND `address` LIKE '@%';");
|
||||
$stmt->execute(array(':username' => $username));
|
||||
$stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '✘') as `address` FROM `alias` WHERE `goto` LIKE :username AND `address` LIKE '@%';");
|
||||
$stmt->execute(array(':username' => '%' . $username . '%'));
|
||||
$run = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
while ($row = array_shift($run)) {
|
||||
$data['is_catch_all'] = $row['address'];
|
||||
|
@ -1571,6 +1581,13 @@ function add_domain_admin($postarray) {
|
|||
}
|
||||
}
|
||||
if (!empty($password) && !empty($password2)) {
|
||||
if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
'msg' => sprintf($lang['danger']['password_complexity'])
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if ($password != $password2) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
|
@ -1711,6 +1728,7 @@ function get_domain_admins() {
|
|||
}
|
||||
function get_domain_admin_details($domain_admin) {
|
||||
global $pdo;
|
||||
|
||||
global $lang;
|
||||
$domainadmindata = array();
|
||||
if (isset($domain_admin) && $_SESSION['mailcow_cc_role'] != "admin") {
|
||||
|
@ -2169,6 +2187,13 @@ function edit_domain_admin($postarray) {
|
|||
}
|
||||
|
||||
if (!empty($password) && !empty($password2)) {
|
||||
if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
'msg' => sprintf($lang['danger']['password_complexity'])
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if ($password != $password2) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
|
@ -2262,9 +2287,7 @@ function edit_domain_admin($postarray) {
|
|||
);
|
||||
return false;
|
||||
}
|
||||
if (strlen($password_new) < "6" ||
|
||||
!preg_match('/[A-Za-z]/', $password_new) ||
|
||||
!preg_match('/[0-9]/', $password_new)) {
|
||||
if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password_new)) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
'msg' => sprintf($lang['danger']['password_complexity'])
|
||||
|
@ -2991,6 +3014,13 @@ function mailbox_add_mailbox($postarray) {
|
|||
}
|
||||
|
||||
if (!empty($password) && !empty($password2)) {
|
||||
if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
'msg' => sprintf($lang['danger']['password_complexity'])
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if ($password != $password2) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
|
@ -3735,6 +3765,13 @@ function mailbox_edit_mailbox($postarray) {
|
|||
}
|
||||
}
|
||||
if (!empty($password) && !empty($password2)) {
|
||||
if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
'msg' => sprintf($lang['danger']['password_complexity'])
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if ($password != $password2) {
|
||||
$_SESSION['return'] = array(
|
||||
'type' => 'danger',
|
||||
|
@ -4313,9 +4350,13 @@ function mailbox_get_mailbox_details($mailbox) {
|
|||
$DomainQuota = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$stmt = $pdo->prepare("SELECT COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` = :domain AND `username` != :username");
|
||||
$stmt->execute(array(':domain' => $row['domain'], ':username' => $row['username']));
|
||||
$stmt->execute(array(':domain' => $row['domain'], ':username' => $mailbox));
|
||||
$MailboxUsage = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$stmt = $pdo->prepare("SELECT IFNULL(COUNT(`address`), 0) AS `sa_count` FROM `spamalias` WHERE `goto` = :address AND `validity` >= :unixnow");
|
||||
$stmt->execute(array(':address' => $mailbox, ':unixnow' => time()));
|
||||
$SpamaliasUsage = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$mailboxdata['max_new_quota'] = ($DomainQuota['quota'] * 1048576) - $MailboxUsage['in_use'];
|
||||
if ($mailboxdata['max_new_quota'] > ($DomainQuota['maxquota'] * 1048576)) {
|
||||
$mailboxdata['max_new_quota'] = ($DomainQuota['maxquota'] * 1048576);
|
||||
|
@ -4331,6 +4372,7 @@ function mailbox_get_mailbox_details($mailbox) {
|
|||
$mailboxdata['quota_used'] = intval($row['bytes']);
|
||||
$mailboxdata['percent_in_use'] = round((intval($row['bytes']) / intval($row['quota'])) * 100);
|
||||
$mailboxdata['messages'] = $row['messages'];
|
||||
$mailboxdata['spam_aliases'] = $SpamaliasUsage['sa_count'];
|
||||
if ($mailboxdata['percent_in_use'] >= 90) {
|
||||
$mailboxdata['percent_class'] = "danger";
|
||||
}
|
||||
|
|
|
@ -35,4 +35,6 @@ $DEFAULT_LANG = "en";
|
|||
// See https://bootswatch.com/
|
||||
$DEFAULT_THEME = "lumen";
|
||||
|
||||
// Password complexity as regular expression
|
||||
$PASSWD_REGEP = '.{4,}';
|
||||
?>
|
||||
|
|
|
@ -57,7 +57,7 @@ $lang['danger']['exit_code_not_null'] = 'Fehler: Exit-Code ist %d';
|
|||
$lang['danger']['mailbox_not_available'] = 'Mailbox nicht verfügbar';
|
||||
$lang['danger']['username_invalid'] = 'Benutzername kann nicht verwendet werden';
|
||||
$lang['danger']['password_mismatch'] = 'Passwort-Wiederholung stimmt nicht überein';
|
||||
$lang['danger']['password_complexity'] = 'Passwort entspricht nicht den Vorgaben (Klein- und Großschreibung und mindestens eine Ziffer, mindestens 6 Zeichen lang)';
|
||||
$lang['danger']['password_complexity'] = 'Passwort entspricht nicht den Richtlinien';
|
||||
$lang['danger']['password_empty'] = 'Passwort darf nicht leer sein';
|
||||
$lang['danger']['login_failed'] = 'Anmeldung fehlgeschlagen';
|
||||
$lang['danger']['mailbox_invalid'] = 'Mailboxname ist ungültig';
|
||||
|
@ -92,6 +92,8 @@ $lang['danger']['spam_alias_max_exceeded'] = 'Maximale Anzahl an Spam-Alias-Adre
|
|||
$lang['danger']['validity_missing'] = 'Bitte geben Sie eine Gültigkeitsdauer an';
|
||||
$lang['user']['on'] = 'Ein';
|
||||
$lang['user']['off'] = 'Aus';
|
||||
$lang['user']['messages'] = "Nachrichten";
|
||||
$lang['user']['in_use'] = "Verwendet";
|
||||
$lang['user']['user_change_fn'] = '';
|
||||
$lang['user']['user_settings'] = 'Benutzereinstellungen';
|
||||
$lang['user']['mailbox_settings'] = 'Mailbox-Einstellungen';
|
||||
|
@ -108,8 +110,8 @@ $lang['user']['alias'] = 'Alias';
|
|||
$lang['user']['aliases'] = 'Aliasse';
|
||||
$lang['user']['domain_aliases'] = 'Domain-Alias Adressen';
|
||||
$lang['user']['is_catch_all'] = 'Ist Catch-All Adresse für Domain(s)';
|
||||
$lang['user']['aliases_also_send_as'] = 'Darf außerdem versenden als';
|
||||
$lang['user']['aliases_send_as_all'] = 'Absender für folgende Domains nicht prüfen';
|
||||
$lang['user']['aliases_also_send_as'] = 'Darf außerdem versenden als Benutzer';
|
||||
$lang['user']['aliases_send_as_all'] = 'Absender für folgende Domains und zugehörige Alias-Domains nicht prüfen';
|
||||
$lang['user']['alias_create_random'] = 'Zufälligen Alias generieren';
|
||||
$lang['user']['alias_extend_all'] = 'Gültigkeit +1h';
|
||||
$lang['user']['alias_valid_until'] = 'Gültig bis';
|
||||
|
@ -207,6 +209,7 @@ $lang['header']['logged_in_as_logout'] = 'Eingeloggt als <b>%s</b> (abmelden)';
|
|||
$lang['header']['logged_in_as_logout_dual'] = 'Eingeloggt als <b>%s <span class="text-info">[%s]</span></b>';
|
||||
$lang['header']['locale'] = 'Sprache';
|
||||
$lang['mailbox']['domain'] = 'Domain';
|
||||
$lang['mailbox']['spam_aliases'] = 'Temp. Alias';
|
||||
$lang['mailbox']['alias'] = 'Alias';
|
||||
$lang['mailbox']['aliases'] = 'Aliasse';
|
||||
$lang['mailbox']['multiple_bookings'] = 'Mehrfachbuchen';
|
||||
|
@ -307,7 +310,7 @@ $lang['edit']['dkim_txt_name'] = 'TXT-Record Name:';
|
|||
$lang['edit']['dkim_txt_value'] = 'TXT-Record Wert:';
|
||||
$lang['edit']['previous'] = 'Vorherige Seite';
|
||||
$lang['edit']['unchanged_if_empty'] = 'Unverändert, wenn leer';
|
||||
$lang['edit']['dont_check_sender_acl'] = 'Absender für Domain %s nicht prüfen';
|
||||
$lang['edit']['dont_check_sender_acl'] = 'Absender für Domain %s u. Alias-Dom. nicht prüfen';
|
||||
$lang['edit']['multiple_bookings'] = 'Mehrfaches Buchen';
|
||||
$lang['edit']['kind'] = 'Art';
|
||||
$lang['edit']['resource'] = 'Ressource';
|
||||
|
|
|
@ -59,7 +59,7 @@ $lang['danger']['exit_code_not_null'] = "Error: Exit code was %d";
|
|||
$lang['danger']['mailbox_not_available'] = "Mailbox not available";
|
||||
$lang['danger']['username_invalid'] = "Username cannot be used";
|
||||
$lang['danger']['password_mismatch'] = "Confirmation password is not identical";
|
||||
$lang['danger']['password_complexity'] = "Password does not meet requirements (upper and lowercase letters and at least one number, min. 6 characters long)";
|
||||
$lang['danger']['password_complexity'] = "Password does not meet the policy";
|
||||
$lang['danger']['password_empty'] = "Password must not be empty";
|
||||
$lang['danger']['login_failed'] = "Login failed";
|
||||
$lang['danger']['mailbox_invalid'] = "Mailbox name is invalid";
|
||||
|
@ -94,6 +94,8 @@ $lang['danger']['spam_alias_max_exceeded'] = "Max. allowed spam alias addresses
|
|||
$lang['danger']['validity_missing'] = 'Please assign a period of validity';
|
||||
$lang['user']['on'] = "On";
|
||||
$lang['user']['off'] = "Off";
|
||||
$lang['user']['messages'] = "messages"; // "123 messages"
|
||||
$lang['user']['in_use'] = "Used";
|
||||
$lang['user']['user_change_fn'] = "";
|
||||
$lang['user']['user_settings'] = 'User settings';
|
||||
$lang['user']['mailbox_settings'] = 'Mailbox settings';
|
||||
|
@ -110,8 +112,8 @@ $lang['user']['alias'] = 'Alias';
|
|||
$lang['user']['aliases'] = 'Aliases';
|
||||
$lang['user']['domain_aliases'] = 'Domain alias addresses';
|
||||
$lang['user']['is_catch_all'] = 'Catch-all for domain/s';
|
||||
$lang['user']['aliases_also_send_as'] = 'Also allowed to send as';
|
||||
$lang['user']['aliases_send_as_all'] = 'Do not check sender access for following domain/s';
|
||||
$lang['user']['aliases_also_send_as'] = 'Also allowed to send as user';
|
||||
$lang['user']['aliases_send_as_all'] = 'Do not check sender access for the following domain(s) and its alias domains';
|
||||
$lang['user']['alias_create_random'] = 'Generate random alias';
|
||||
$lang['user']['alias_extend_all'] = 'Extend aliases by 1 hour';
|
||||
$lang['user']['alias_valid_until'] = 'Valid until';
|
||||
|
@ -209,6 +211,7 @@ $lang['header']['logged_in_as_logout'] = 'Logged in as <b>%s</b> (logout)';
|
|||
$lang['header']['logged_in_as_logout_dual'] = 'Logged in as <b>%s <span class="text-info">[%s]</span></b>';
|
||||
$lang['header']['locale'] = 'Language';
|
||||
$lang['mailbox']['domain'] = 'Domain';
|
||||
$lang['mailbox']['spam_aliases'] = 'Temp. alias';
|
||||
$lang['mailbox']['multiple_bookings'] = 'Multiple bookings';
|
||||
$lang['mailbox']['kind'] = 'Kind';
|
||||
$lang['mailbox']['description'] = 'Description';
|
||||
|
@ -245,6 +248,7 @@ $lang['mailbox']['add_domain_alias'] = 'Add domain alias';
|
|||
$lang['mailbox']['add_mailbox'] = 'Add mailbox';
|
||||
$lang['mailbox']['add_resource'] = 'Add resource';
|
||||
$lang['mailbox']['add_alias'] = 'Add alias';
|
||||
$lang['mailbox']['add_domain_record_first'] = 'Please add a domain first';
|
||||
|
||||
$lang['info']['no_action'] = 'No action applicable';
|
||||
|
||||
|
@ -310,7 +314,7 @@ $lang['edit']['dkim_txt_name'] = 'TXT record name:';
|
|||
$lang['edit']['dkim_txt_value'] = 'TXT record value:';
|
||||
$lang['edit']['previous'] = 'Previous page';
|
||||
$lang['edit']['unchanged_if_empty'] = 'If unchanged leave blank';
|
||||
$lang['edit']['dont_check_sender_acl'] = 'Do not check sender for domain %s';
|
||||
$lang['edit']['dont_check_sender_acl'] = "Disable sender check for domain %s + alias domains";
|
||||
$lang['edit']['multiple_bookings'] = 'Multiple bookings';
|
||||
$lang['edit']['kind'] = 'Kind';
|
||||
$lang['edit']['resource'] = 'Resource';
|
||||
|
|
|
@ -91,7 +91,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
endforeach;
|
||||
else:
|
||||
?>
|
||||
<tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record_single'];?></td></tr>
|
||||
<tr id="no-data"><td colspan="999" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['no_record_single'];?></td></tr>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
|
@ -101,7 +101,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
?>
|
||||
<tfoot>
|
||||
<tr id="no-data">
|
||||
<td colspan="8" style="text-align: center; font-style: normal; border-top: 1px solid #e7e7e7;">
|
||||
<td colspan="999" style="text-align: center; font-style: normal; border-top: 1px solid #e7e7e7;">
|
||||
<a href="/add.php?domain"><?=$lang['mailbox']['add_domain'];?></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -137,6 +137,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
<th class="sort-table" style="min-width: 98px;"><?=$lang['mailbox']['fname'];?></th>
|
||||
<th class="sort-table" style="min-width: 86px;"><?=$lang['mailbox']['domain'];?></th>
|
||||
<th class="sort-table" style="min-width: 75px;"><?=$lang['mailbox']['quota'];?></th>
|
||||
<th class="sort-table" style="min-width: 75px;"><?=$lang['mailbox']['spam_aliases'];?></th>
|
||||
<th class="sort-table" style="min-width: 99px;"><?=$lang['mailbox']['in_use'];?></th>
|
||||
<th class="sort-table" style="min-width: 100px;"><?=$lang['mailbox']['msg_num'];?></th>
|
||||
<th class="sort-table" style="min-width: 76px;"><?=$lang['mailbox']['active'];?></th>
|
||||
|
@ -145,6 +146,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
if (!empty($domains)) {
|
||||
foreach (mailbox_get_domains() as $domain) {
|
||||
$mailboxes = mailbox_get_mailboxes($domain);
|
||||
if (!empty($mailboxes)) {
|
||||
|
@ -156,6 +158,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
<td><?=htmlspecialchars($mailboxdata['name'], ENT_QUOTES, 'UTF-8');?></td>
|
||||
<td><?=htmlspecialchars($mailboxdata['domain']);?></td>
|
||||
<td><?=formatBytes($mailboxdata['quota_used'], 2);?> / <?=formatBytes($mailboxdata['quota'], 2);?></td>
|
||||
<td><?=$mailboxdata['spam_aliases'];?></td>
|
||||
<td style="min-width:120px;">
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-<?=$mailboxdata['percent_class'];?>" role="progressbar" aria-valuenow="<?=$mailboxdata['percent_in_use'];?>" aria-valuemin="0" aria-valuemax="100" style="min-width:2em;width: <?=$mailboxdata['percent_in_use'];?>%;">
|
||||
|
@ -180,15 +183,20 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
}
|
||||
else {
|
||||
?>
|
||||
<tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=sprintf($lang['mailbox']['no_record'], $domain);?></td></tr>
|
||||
<tr id="no-data"><td colspan="999" style="text-align: center; font-style: italic;"><?=sprintf($lang['mailbox']['no_record'], $domain);?></td></tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
} else {
|
||||
?>
|
||||
<tr id="no-data"><td colspan="999" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['add_domain_record_first'];?></td></tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr id="no-data">
|
||||
<td colspan="8" style="text-align: center; border-top: 1px solid #e7e7e7;">
|
||||
<td colspan="999" style="text-align: center; border-top: 1px solid #e7e7e7;">
|
||||
<a href="/add.php?mailbox"><?=$lang['mailbox']['add_mailbox'];?></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -227,6 +235,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
if (!empty($domains)) {
|
||||
foreach (mailbox_get_domains() as $domain) {
|
||||
$resources = mailbox_get_resources($domain);
|
||||
if (!empty($resources)) {
|
||||
|
@ -251,15 +260,20 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
}
|
||||
else {
|
||||
?>
|
||||
<tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=sprintf($lang['mailbox']['no_record'], $domain);?></td></tr>
|
||||
<tr id="no-data"><td colspan="999" style="text-align: center; font-style: italic;"><?=sprintf($lang['mailbox']['no_record'], $domain);?></td></tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
} else {
|
||||
?>
|
||||
<tr id="no-data"><td colspan="999" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['add_domain_record_first'];?></td></tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr id="no-data">
|
||||
<td colspan="8" style="text-align: center; border-top: 1px solid #e7e7e7;">
|
||||
<td colspan="999" style="text-align: center; border-top: 1px solid #e7e7e7;">
|
||||
<a href="/add.php?resource"><?=$lang['mailbox']['add_resource'];?></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -296,6 +310,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
if (!empty($domains)) {
|
||||
foreach (mailbox_get_domains() as $domain) {
|
||||
$alias_domains = mailbox_get_alias_domains($domain);
|
||||
if (!empty($alias_domains)) {
|
||||
|
@ -318,15 +333,20 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
}
|
||||
else {
|
||||
?>
|
||||
<tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=sprintf($lang['mailbox']['no_record'], $domain);?></td></tr>
|
||||
<tr id="no-data"><td colspan="999" style="text-align: center; font-style: italic;"><?=sprintf($lang['mailbox']['no_record'], $domain);?></td></tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
} else {
|
||||
?>
|
||||
<tr id="no-data"><td colspan="999" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['add_domain_record_first'];?></td></tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr id="no-data">
|
||||
<td colspan="8" style="text-align: center; border-top: 1px solid #e7e7e7;">
|
||||
<td colspan="999" style="text-align: center; border-top: 1px solid #e7e7e7;">
|
||||
<a href="/add.php?aliasdomain"><?=$lang['mailbox']['add_domain_alias'];?></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -365,6 +385,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
if (!empty($domains)) {
|
||||
foreach (array_merge(mailbox_get_domains(), mailbox_get_alias_domains()) as $domain) {
|
||||
$aliases = mailbox_get_aliases($domain);
|
||||
if (!empty($aliases)) {
|
||||
|
@ -396,15 +417,20 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
|||
}
|
||||
else {
|
||||
?>
|
||||
<tr id="no-data"><td colspan="8" style="text-align: center; font-style: italic;"><?=sprintf($lang['mailbox']['no_record'], $domain);?></td></tr>
|
||||
<tr id="no-data"><td colspan="999" style="text-align: center; font-style: italic;"><?=sprintf($lang['mailbox']['no_record'], $domain);?></td></tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
} else {
|
||||
?>
|
||||
<tr id="no-data"><td colspan="999" style="text-align: center; font-style: italic;"><?=$lang['mailbox']['add_domain_record_first'];?></td></tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr id="no-data">
|
||||
<td colspan="8" style="text-align: center; border-top: 1px solid #e7e7e7;">
|
||||
<td colspan="999" style="text-align: center; border-top: 1px solid #e7e7e7;">
|
||||
<a href="/add.php?alias"><?=$lang['mailbox']['add_alias'];?></a>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -31,7 +31,7 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'doma
|
|||
foreach ($tfa_data['additional'] as $key_info): ?>
|
||||
<form style="display:inline;" method="post">
|
||||
<input type="hidden" name="unset_tfa_key" value="<?=$key_info['id'];?>" />
|
||||
<div class="label label-default">🔑 <?=$key_info['key_id'];?> <a href="#" style="font-weight:bold;color:white" onClick="$(this).closest('form').submit()">[<?=strtolower($lang['admin']['remove']);?>]</a></div>
|
||||
<div class="label label-default">?? <?=$key_info['key_id'];?> <a href="#" style="font-weight:bold;color:white" onClick="$(this).closest('form').submit()">[<?=strtolower($lang['admin']['remove']);?>]</a></div>
|
||||
</form>
|
||||
<?php endforeach;
|
||||
endif;?>
|
||||
|
@ -63,6 +63,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
$_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
||||
$username = $_SESSION['mailcow_cc_username'];
|
||||
$get_tls_policy = get_tls_policy($_SESSION['mailcow_cc_username']);
|
||||
$mailboxdata = mailbox_get_mailbox_details($username);
|
||||
?>
|
||||
<div class="container">
|
||||
<h3><?=$lang['user']['user_settings'];?></h3>
|
||||
|
@ -109,6 +110,18 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-xs-5 text-right"><?=$lang['user']['in_use'];?>:</div>
|
||||
<div class="col-md-5 col-xs-7">
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-<?=$mailboxdata['percent_class'];?>" role="progressbar" aria-valuenow="<?=$mailboxdata['percent_in_use'];?>" aria-valuemin="0" aria-valuemax="100" style="min-width:2em;width: <?=$mailboxdata['percent_in_use'];?>%;">
|
||||
<?=$mailboxdata['percent_in_use'];?>%
|
||||
</div>
|
||||
</div>
|
||||
<p><?=formatBytes($mailboxdata['quota_used'], 2);?> / <?=formatBytes($mailboxdata['quota'], 2);?>, <?=$mailboxdata['messages'];?> <?=$lang['user']['messages'];?></p>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<?php // Show tagging options ?>
|
||||
<form class="form-horizontal" role="form" method="post">
|
||||
<?php $get_tagging_options = get_delimiter_action()['wants_tagged_subject'];?>
|
||||
|
@ -402,7 +415,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
|
|||
<th class="sort-table" style="min-width: 35px;"><?=$lang['user']['interval'];?></th>
|
||||
<th class="sort-table" style="min-width: 35px;"><?=$lang['user']['last_run'];?></th>
|
||||
<th class="sort-table" style="min-width: 35px;">Log</th>
|
||||
<th class="sort-table" style="max-width: 35px;"><?=$lang['user']['active'];?></th>
|
||||
<th class="sort-table" style="max-width: 95px;"><?=$lang['user']['active'];?></th>
|
||||
<th style="text-align: right; min-width: 200px;" data-sortable="false"><?=$lang['user']['action'];?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
version: '2.1'
|
||||
|
||||
services:
|
||||
pdns-mailcow:
|
||||
image: andryyy/mailcow-dockerized:pdns
|
||||
bind9-mailcow:
|
||||
image: resystit/bind9
|
||||
command: "named -c /etc/bind/named.conf -g -u named -4"
|
||||
depends_on:
|
||||
mysql-mailcow:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ./data/conf/pdns/:/etc/powerdns/
|
||||
- ./data/conf/bind9/named.conf:/etc/bind/named.conf
|
||||
restart: always
|
||||
networks:
|
||||
mailcow-network:
|
||||
ipv4_address: 172.22.1.254
|
||||
aliases:
|
||||
- pdns
|
||||
- bind9
|
||||
|
||||
mysql-mailcow:
|
||||
image: mariadb:10.1
|
||||
|
@ -42,7 +43,7 @@ services:
|
|||
redis-mailcow:
|
||||
image: redis
|
||||
depends_on:
|
||||
- pdns-mailcow
|
||||
- bind9-mailcow
|
||||
volumes:
|
||||
- redis-vol-1:/data/
|
||||
restart: always
|
||||
|
@ -56,8 +57,10 @@ services:
|
|||
|
||||
rspamd-mailcow:
|
||||
image: andryyy/mailcow-dockerized:rspamd
|
||||
build: ./data/Dockerfiles/rspamd
|
||||
depends_on:
|
||||
- nginx-mailcow
|
||||
nginx-mailcow:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ./data/conf/rspamd/override.d/:/etc/rspamd/override.d:ro
|
||||
- ./data/conf/rspamd/local.d/:/etc/rspamd/local.d:ro
|
||||
|
@ -76,9 +79,10 @@ services:
|
|||
|
||||
php-fpm-mailcow:
|
||||
image: andryyy/mailcow-dockerized:phpfpm
|
||||
build: ./data/Dockerfiles/php-fpm
|
||||
command: "php-fpm -d date.timezone=${TZ}"
|
||||
depends_on:
|
||||
- pdns-mailcow
|
||||
- bind9-mailcow
|
||||
volumes:
|
||||
- ./data/web:/web:ro
|
||||
- ./data/conf/rspamd/dynmaps:/dynmaps:ro
|
||||
|
@ -99,8 +103,9 @@ services:
|
|||
|
||||
sogo-mailcow:
|
||||
image: andryyy/mailcow-dockerized:sogo
|
||||
build: ./data/Dockerfiles/sogo
|
||||
depends_on:
|
||||
- pdns-mailcow
|
||||
- bind9-mailcow
|
||||
environment:
|
||||
- DBNAME=${DBNAME}
|
||||
- DBUSER=${DBUSER}
|
||||
|
@ -121,8 +126,9 @@ services:
|
|||
|
||||
rmilter-mailcow:
|
||||
image: andryyy/mailcow-dockerized:rmilter
|
||||
build: ./data/Dockerfiles/rmilter
|
||||
depends_on:
|
||||
- pdns-mailcow
|
||||
- bind9-mailcow
|
||||
volumes:
|
||||
- ./data/conf/rmilter/:/etc/rmilter.conf.d/:ro
|
||||
restart: always
|
||||
|
@ -136,8 +142,9 @@ services:
|
|||
|
||||
dovecot-mailcow:
|
||||
image: andryyy/mailcow-dockerized:dovecot
|
||||
build: ./data/Dockerfiles/dovecot
|
||||
depends_on:
|
||||
- pdns-mailcow
|
||||
- bind9-mailcow
|
||||
volumes:
|
||||
- ./data/conf/dovecot:/etc/dovecot
|
||||
- ./data/assets/ssl:/etc/ssl/mail/:ro
|
||||
|
@ -165,11 +172,13 @@ services:
|
|||
|
||||
postfix-mailcow:
|
||||
image: andryyy/mailcow-dockerized:postfix
|
||||
build: ./data/Dockerfiles/postfix
|
||||
depends_on:
|
||||
- pdns-mailcow
|
||||
- bind9-mailcow
|
||||
volumes:
|
||||
- ./data/conf/postfix:/opt/postfix/conf
|
||||
- ./data/assets/ssl:/etc/ssl/mail/:ro
|
||||
- postfix-vol-1:/var/spool/postfix
|
||||
environment:
|
||||
- DBNAME=${DBNAME}
|
||||
- DBUSER=${DBUSER}
|
||||
|
@ -191,7 +200,7 @@ services:
|
|||
memcached-mailcow:
|
||||
image: memcached
|
||||
depends_on:
|
||||
- pdns-mailcow
|
||||
- bind9-mailcow
|
||||
restart: always
|
||||
dns:
|
||||
- 172.22.1.254
|
||||
|
@ -206,9 +215,19 @@ services:
|
|||
- sogo-mailcow
|
||||
- php-fpm-mailcow
|
||||
image: nginx:mainline
|
||||
command: /bin/bash -c "envsubst < /etc/nginx/conf.d/listen.template > /etc/nginx/conf.d/listen.active && nginx -g 'daemon off;'"
|
||||
healthcheck:
|
||||
test: ["CMD", "ping", "php-fpm-mailcow", "-c", "10"]
|
||||
interval: 10s
|
||||
timeout: 30s
|
||||
retries: 5
|
||||
command: /bin/bash -c "envsubst < /etc/nginx/conf.d/templates/listen_plain.template > /etc/nginx/conf.d/listen_plain.active &&
|
||||
envsubst < /etc/nginx/conf.d/templates/listen_ssl.template > /etc/nginx/conf.d/listen_ssl.active &&
|
||||
envsubst < /etc/nginx/conf.d/templates/server_name.template > /etc/nginx/conf.d/server_name.active &&
|
||||
nginx -g 'daemon off;'"
|
||||
environment:
|
||||
- HTTPS_PORT=${HTTPS_PORT:-443}
|
||||
- HTTP_PORT=${HTTP_PORT:-80}
|
||||
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||
volumes:
|
||||
- ./data/web:/web:ro
|
||||
- ./data/conf/rspamd/dynmaps:/dynmaps:ro
|
||||
|
@ -218,10 +237,12 @@ services:
|
|||
- 172.22.1.254
|
||||
dns_search: mailcow-network
|
||||
ports:
|
||||
- "${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
|
||||
- "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
|
||||
- "${HTTP_BIND:-127.0.0.1}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
|
||||
restart: always
|
||||
networks:
|
||||
mailcow-network:
|
||||
ipv4_address: 172.22.1.251
|
||||
aliases:
|
||||
- nginx
|
||||
|
||||
|
@ -239,3 +260,4 @@ volumes:
|
|||
dkim-vol-1:
|
||||
redis-vol-1:
|
||||
rspamd-vol-1:
|
||||
postfix-vol-1:
|
||||
|
|
|
@ -16,8 +16,11 @@ if [ -z "$MAILCOW_HOSTNAME" ]; then
|
|||
read -p "Hostname (FQDN): " -ei "mx.example.org" MAILCOW_HOSTNAME
|
||||
fi
|
||||
|
||||
[[ -a /etc/timezone ]] && TZ=$(cat /etc/timezone)
|
||||
if [ -z "$TZ" ]; then
|
||||
read -p "Timezone: " -ei "Europe/Berlin" TZ
|
||||
else
|
||||
read -p "Timezone: " -ei ${TZ} TZ
|
||||
fi
|
||||
|
||||
cat << EOF > mailcow.conf
|
||||
|
@ -40,11 +43,23 @@ DBPASS=$(</dev/urandom tr -dc A-Za-z0-9 | head -c 28)
|
|||
DBROOT=$(</dev/urandom tr -dc A-Za-z0-9 | head -c 28)
|
||||
|
||||
# ------------------------------
|
||||
# Misc configuration
|
||||
# HTTP/S Bindings
|
||||
# ------------------------------
|
||||
|
||||
# You should use HTTPS, but in case of SSL offloaded reverse proxies:
|
||||
HTTP_PORT=8080
|
||||
HTTP_BIND=0.0.0.0
|
||||
|
||||
HTTPS_PORT=443
|
||||
HTTPS_BIND=0.0.0.0
|
||||
|
||||
# ------------------------------
|
||||
# Other bindings
|
||||
# ------------------------------
|
||||
# You should leave that alone
|
||||
# Can also be 11.22.33.44:25 or 0.0.0.0:465 etc. for specific bindings
|
||||
HTTPS_PORT=443
|
||||
# Format: 11.22.33.44:25 or 0.0.0.0:465 etc.
|
||||
# Do _not_ use IP:PORT in HTTPS_BIND or HTTPS_PORT
|
||||
|
||||
SMTP_PORT=25
|
||||
SMTPS_PORT=465
|
||||
SUBMISSION_PORT=587
|
||||
|
|
Loading…
Reference in New Issue