2017-03-02 18:23:23 +08:00
#!/bin/bash
set -e
2018-06-04 01:22:44 +08:00
# Wait for MySQL to warm-up
2018-10-11 17:53:22 +08:00
while ! mysqladmin status --socket= /var/run/mysqld/mysqld.sock -u${ DBUSER } -p${ DBPASS } --silent; do
2018-06-04 01:22:44 +08:00
echo "Waiting for database to come up..."
sleep 2
done
2021-04-01 21:24:55 +08:00
until dig +short mailcow.email > /dev/null; do
2020-07-11 19:22:48 +08:00
echo "Waiting for DNS..."
sleep 1
done
2020-04-14 23:32:15 +08:00
# Do not attempt to write to slave
if [ [ ! -z ${ REDIS_SLAVEOF_IP } ] ] ; then
REDIS_CMDLINE = " redis-cli -h ${ REDIS_SLAVEOF_IP } -p ${ REDIS_SLAVEOF_PORT } "
else
REDIS_CMDLINE = "redis-cli -h redis -p 6379"
fi
until [ [ $( ${ REDIS_CMDLINE } PING) = = "PONG" ] ] ; do
echo "Waiting for Redis..."
sleep 2
done
${ REDIS_CMDLINE } SET DOVECOT_REPL_HEALTH 1 > /dev/null
2017-04-06 04:25:16 +08:00
# Create missing directories
2019-07-29 03:34:42 +08:00
[ [ ! -d /etc/dovecot/sql/ ] ] && mkdir -p /etc/dovecot/sql/
2019-12-06 17:20:06 +08:00
[ [ ! -d /etc/dovecot/lua/ ] ] && mkdir -p /etc/dovecot/lua/
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
[ [ ! -d /var/vmail/_garbage ] ] && mkdir -p /var/vmail/_garbage
2017-04-04 02:06:49 +08:00
[ [ ! -d /var/vmail/sieve ] ] && mkdir -p /var/vmail/sieve
[ [ ! -d /etc/sogo ] ] && mkdir -p /etc/sogo
2018-11-12 16:49:23 +08:00
[ [ ! -d /var/volatile ] ] && mkdir -p /var/volatile
2017-03-09 00:58:00 +08:00
2017-03-06 17:33:44 +08:00
# Set Dovecot sql config parameters, escape " in db password
2017-03-02 18:23:23 +08:00
DBPASS = $( echo ${ DBPASS } | sed 's/"/\\"/g' )
2017-03-06 17:33:44 +08:00
2017-04-04 02:06:49 +08:00
# Create quota dict for Dovecot
2020-01-29 17:30:06 +08:00
if [ [ " ${ MASTER } " = ~ ^( [ yY] [ eE] [ sS] | [ yY] ) +$ ] ] ; then
QUOTA_TABLE = quota2
else
QUOTA_TABLE = quota2replica
fi
2019-07-29 03:34:42 +08:00
cat <<EOF > /etc/dovecot/sql/dovecot-dict-sql-quota.conf
2019-07-08 13:56:41 +08:00
# Autogenerated by mailcow
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
connect = " host=/var/run/mysqld/mysqld.sock dbname= ${ DBNAME } user= ${ DBUSER } password= ${ DBPASS } "
2017-03-06 17:33:44 +08:00
map {
pattern = priv/quota/storage
2020-01-29 17:30:06 +08:00
table = ${ QUOTA_TABLE }
2017-03-06 17:33:44 +08:00
username_field = username
value_field = bytes
}
map {
pattern = priv/quota/messages
2020-01-29 17:30:06 +08:00
table = ${ QUOTA_TABLE }
2017-03-06 17:33:44 +08:00
username_field = username
value_field = messages
}
EOF
2017-11-04 03:25:38 +08:00
# Create dict used for sieve pre and postfilters
2019-07-29 03:34:42 +08:00
cat <<EOF > /etc/dovecot/sql/dovecot-dict-sql-sieve_before.conf
2019-07-08 13:56:41 +08:00
# Autogenerated by mailcow
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
connect = " host=/var/run/mysqld/mysqld.sock dbname= ${ DBNAME } user= ${ DBUSER } password= ${ DBPASS } "
2017-11-04 03:25:38 +08:00
map {
pattern = priv/sieve/name/\$ script_name
table = sieve_before
username_field = username
value_field = id
fields {
script_name = \$ script_name
}
}
map {
pattern = priv/sieve/data/\$ id
table = sieve_before
username_field = username
value_field = script_data
fields {
id = \$ id
}
}
EOF
2019-07-29 03:34:42 +08:00
cat <<EOF > /etc/dovecot/sql/dovecot-dict-sql-sieve_after.conf
2019-07-08 13:56:41 +08:00
# Autogenerated by mailcow
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
connect = " host=/var/run/mysqld/mysqld.sock dbname= ${ DBNAME } user= ${ DBUSER } password= ${ DBPASS } "
2017-11-04 03:25:38 +08:00
map {
pattern = priv/sieve/name/\$ script_name
table = sieve_after
username_field = username
value_field = id
fields {
script_name = \$ script_name
}
}
map {
pattern = priv/sieve/data/\$ id
table = sieve_after
username_field = username
value_field = script_data
fields {
id = \$ id
}
}
EOF
2019-07-29 03:34:42 +08:00
echo -n ${ ACL_ANYONE } > /etc/dovecot/acl_anyone
2017-11-04 03:25:38 +08:00
2019-01-29 07:11:12 +08:00
if [ [ " ${ SKIP_SOLR } " = ~ ^( [ yY] [ eE] [ sS] | [ yY] ) +$ ] ] ; then
2021-06-23 20:17:39 +08:00
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify listescape replication' > /etc/dovecot/mail_plugins
echo -n 'quota imap_quota imap_acl acl zlib imap_zlib imap_sieve mail_crypt mail_crypt_acl notify listescape replication mail_log' > /etc/dovecot/mail_plugins_imap
echo -n 'quota sieve acl zlib mail_crypt mail_crypt_acl notify listescape replication' > /etc/dovecot/mail_plugins_lmtp
2019-01-29 07:11:12 +08:00
else
2021-06-23 20:17:39 +08:00
echo -n 'quota acl zlib mail_crypt mail_crypt_acl mail_log notify fts fts_solr listescape replication' > /etc/dovecot/mail_plugins
echo -n 'quota imap_quota imap_acl acl zlib imap_zlib imap_sieve mail_crypt mail_crypt_acl notify mail_log fts fts_solr listescape replication' > /etc/dovecot/mail_plugins_imap
echo -n 'quota sieve acl zlib mail_crypt mail_crypt_acl fts fts_solr notify listescape replication' > /etc/dovecot/mail_plugins_lmtp
2019-01-29 07:11:12 +08:00
fi
2019-07-29 03:34:42 +08:00
chmod 644 /etc/dovecot/mail_plugins /etc/dovecot/mail_plugins_imap /etc/dovecot/mail_plugins_lmtp /templates/quarantine.tpl
2019-01-29 07:11:12 +08:00
2019-07-29 03:34:42 +08:00
cat <<EOF > /etc/dovecot/sql/dovecot-dict-sql-userdb.conf
2019-07-08 13:56:41 +08:00
# Autogenerated by mailcow
2017-03-06 17:33:44 +08:00
driver = mysql
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
connect = " host=/var/run/mysqld/mysqld.sock dbname= ${ DBNAME } user= ${ DBUSER } password= ${ DBPASS } "
2020-09-23 17:20:00 +08:00
user_query = SELECT CONCAT( JSON_UNQUOTE( JSON_VALUE( attributes, '$.mailbox_format' ) ) , mailbox_path_prefix, '%d/%n/${MAILDIR_SUB}:VOLATILEDIR=/var/volatile/%u:INDEX=/var/vmail_index/%u' ) AS mail, '%s' AS protocol, 5000 AS uid, 5000 AS gid, concat( '*:bytes=' , quota) AS quota_rule FROM mailbox WHERE username = '%u' AND ( active = '1' OR active = '2' )
2020-04-29 16:58:47 +08:00
iterate_query = SELECT username FROM mailbox WHERE active = '1' OR active = '2' ;
2017-03-06 17:33:44 +08:00
EOF
2017-03-02 18:23:23 +08:00
2021-06-04 20:27:33 +08:00
cat <<EOF > /etc/dovecot/lua/passwd-verify.lua
2019-12-04 01:50:45 +08:00
function auth_password_verify( req, pass)
2021-06-04 20:27:33 +08:00
2019-12-05 04:47:25 +08:00
if req.domain = = nil then
return dovecot.auth.PASSDB_RESULT_USER_UNKNOWN, "No such user"
end
2021-06-04 20:27:33 +08:00
2020-02-21 00:48:57 +08:00
if cur = = nil then
script_init( )
end
2021-06-04 20:27:33 +08:00
if req.user = = nil then
req.user = ''
end
respbody = { }
-- check against mailbox passwds
local cur,errorString = con:execute( string.format( [ [ SELECT password FROM mailbox
WHERE username = '%s'
AND active = '1'
2021-06-08 19:15:14 +08:00
AND domain IN ( SELECT domain FROM domain WHERE domain = '%s' AND active = '1' )
2021-06-09 13:25:38 +08:00
AND IFNULL( JSON_UNQUOTE( JSON_VALUE( mailbox.attributes, '$.force_pw_update' ) ) , 0) != '1'
2021-06-08 19:15:14 +08:00
AND IFNULL( JSON_UNQUOTE( JSON_VALUE( attributes, '$.%s_access' ) ) , 1) = '1' ] ] , con:escape( req.user) , con:escape( req.domain) , con:escape( req.service) ) )
2021-06-04 20:27:33 +08:00
local row = cur:fetch ( { } , "a" )
while row do
if req.password_verify( req, row.password, pass) = = 1 then
cur:close( )
2021-07-01 12:44:37 +08:00
con:execute( string.format( [ [ REPLACE INTO sasl_log ( service, app_password, username, real_rip)
2021-06-30 16:11:37 +08:00
VALUES ( "%s" , 0, "%s" , "%s" ) ] ] , con:escape( req.service) , con:escape( req.user) , con:escape( req.real_rip) ) )
2021-06-04 20:27:33 +08:00
return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass
end
row = cur:fetch ( row, "a" )
end
-- check against app passwds
2021-06-08 19:15:14 +08:00
local cur,errorString = con:execute( string.format( [ [ SELECT app_passwd.id, app_passwd.password FROM app_passwd
INNER JOIN mailbox ON mailbox.username = app_passwd.mailbox
2019-12-04 01:50:45 +08:00
WHERE mailbox = '%s'
2021-06-08 19:15:14 +08:00
AND IFNULL( JSON_UNQUOTE( JSON_VALUE( mailbox.attributes, '$.%s_access' ) ) , 1) = '1'
2021-06-09 13:22:48 +08:00
AND IFNULL( JSON_UNQUOTE( JSON_VALUE( mailbox.attributes, '$.force_pw_update' ) ) , 0) != '1'
2021-06-08 19:15:14 +08:00
AND app_passwd.active = '1'
AND mailbox.active = '1'
AND app_passwd.domain IN ( SELECT domain FROM domain WHERE domain = '%s' AND active = '1' ) ] ] , con:escape( req.user) , con:escape( req.service) , con:escape( req.domain) ) )
2019-12-04 01:50:45 +08:00
local row = cur:fetch ( { } , "a" )
while row do
if req.password_verify( req, row.password, pass) = = 1 then
cur:close( )
2021-07-01 12:44:37 +08:00
con:execute( string.format( [ [ REPLACE INTO sasl_log ( service, app_password, username, real_rip)
2021-06-30 16:11:37 +08:00
VALUES ( "%s" , %d, "%s" , "%s" ) ] ] , con:escape( req.service) , row.id, con:escape( req.user) , con:escape( req.real_rip) ) )
2019-12-04 01:50:45 +08:00
return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass
end
row = cur:fetch ( row, "a" )
end
2021-06-04 20:27:33 +08:00
return dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH, "Failed to authenticate"
-- PoC
-- local reqbody = string.format( [ [ {
-- "success" :0,
-- "service" :"%s" ,
-- "app_password" :false,
-- "username" :"%s" ,
-- "real_rip" :"%s"
-- } ] ] , con:escape( req.service) , con:escape( req.user) , con:escape( req.real_rip) )
-- http.request {
-- method = "POST" ,
2021-07-01 12:44:37 +08:00
-- url = "http://nginx:8081/sasl_log.php" ,
2021-06-04 20:27:33 +08:00
-- source = ltn12.source.string( reqbody) ,
-- headers = {
-- [ "content-type" ] = "application/json" ,
-- [ "content-length" ] = tostring( #reqbody)
-- } ,
-- sink = ltn12.sink.table( respbody)
-- }
2019-12-04 01:50:45 +08:00
end
2020-02-05 17:56:44 +08:00
function auth_passdb_lookup( req)
return dovecot.auth.PASSDB_RESULT_USER_UNKNOWN, ""
end
2019-12-04 01:50:45 +08:00
function script_init( )
mysql = require "luasql.mysql"
2021-06-04 20:27:33 +08:00
http = require "socket.http"
http.TIMEOUT = 5
ltn12 = require "ltn12"
2019-12-04 01:50:45 +08:00
env = mysql.mysql( )
2020-01-29 17:30:06 +08:00
con = env:connect( "__DBNAME__" ,"__DBUSER__" ,"__DBPASS__" ,"localhost" )
2019-12-04 01:50:45 +08:00
return 0
end
function script_deinit( )
con:close( )
env:close( )
end
2019-12-02 17:53:25 +08:00
EOF
2021-04-17 02:38:09 +08:00
# Replace patterns in app-passdb.lua
2021-06-04 20:27:33 +08:00
sed -i " s/__DBUSER__/ ${ DBUSER } /g " /etc/dovecot/lua/passwd-verify.lua
sed -i " s/__DBPASS__/ ${ DBPASS } /g " /etc/dovecot/lua/passwd-verify.lua
sed -i " s/__DBNAME__/ ${ DBNAME } /g " /etc/dovecot/lua/passwd-verify.lua
2021-04-17 02:38:09 +08:00
2019-06-01 19:53:24 +08:00
# Migrate old sieve_after file
2019-07-29 03:34:42 +08:00
[ [ -f /etc/dovecot/sieve_after ] ] && mv /etc/dovecot/sieve_after /etc/dovecot/global_sieve_after
2019-06-01 19:53:24 +08:00
# Create global sieve scripts
2019-07-29 03:34:42 +08:00
cat /etc/dovecot/global_sieve_after > /var/vmail/sieve/global_sieve_after.sieve
cat /etc/dovecot/global_sieve_before > /var/vmail/sieve/global_sieve_before.sieve
2017-04-04 02:06:49 +08:00
2020-09-23 17:20:00 +08:00
# Check permissions of vmail/index/garbage directories.
2017-03-02 18:23:23 +08:00
# Do not do this every start-up, it may take a very long time. So we use a stat check here.
if [ [ $( stat -c %U /var/vmail/) != "vmail" ] ] ; then chown -R vmail:vmail /var/vmail ; fi
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
if [ [ $( stat -c %U /var/vmail/_garbage) != "vmail" ] ] ; then chown -R vmail:vmail /var/vmail/_garbage ; fi
2020-09-23 17:20:00 +08:00
if [ [ $( stat -c %U /var/vmail_index) != "vmail" ] ] ; then chown -R vmail:vmail /var/vmail_index ; fi
2017-03-02 18:23:23 +08:00
2019-03-27 23:37:15 +08:00
# Cleanup random user maildirs
rm -rf /var/vmail/mailcow.local/*
2021-01-28 22:48:59 +08:00
# Cleanup PIDs
[ [ -f /tmp/quarantine_notify.pid ] ] && rm /tmp/quarantine_notify.pid
2019-03-27 23:37:15 +08:00
2019-10-19 18:48:56 +08:00
# create sni configuration
echo "" > /etc/dovecot/sni.conf
for cert_dir in /etc/ssl/mail/*/ ; do
if [ [ ! -f ${ cert_dir } domains ] ] || [ [ ! -f ${ cert_dir } cert.pem ] ] || [ [ ! -f ${ cert_dir } key.pem ] ] ; then
continue
fi
domains = ( $( cat ${ cert_dir } domains) )
for domain in ${ domains [@] } ; do
echo 'local_name ' ${ domain } ' {' >> /etc/dovecot/sni.conf;
echo ' ssl_cert = <' ${ cert_dir } 'cert.pem' >> /etc/dovecot/sni.conf;
echo ' ssl_key = <' ${ cert_dir } 'key.pem' >> /etc/dovecot/sni.conf;
echo '}' >> /etc/dovecot/sni.conf;
done
done
2019-03-27 23:37:15 +08:00
2017-03-02 18:23:23 +08:00
# Create random master for SOGo sieve features
RAND_USER = $( cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 16 | head -n 1)
RAND_PASS = $( cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 24 | head -n 1)
2018-08-28 23:14:05 +08:00
2020-10-20 21:43:02 +08:00
if [ [ ! -z ${ DOVECOT_MASTER_USER } ] ] && [ [ ! -z ${ DOVECOT_MASTER_PASS } ] ] ; then
RAND_USER = ${ DOVECOT_MASTER_USER }
RAND_PASS = ${ DOVECOT_MASTER_PASS }
fi
2020-02-05 17:56:44 +08:00
echo ${ RAND_USER } @mailcow.local:{ SHA1} $( echo -n ${ RAND_PASS } | sha1sum | awk '{print $1}' ) :::::: > /etc/dovecot/dovecot-master.passwd
2019-07-29 03:34:42 +08:00
echo ${ RAND_USER } @mailcow.local::5000:5000:::: > /etc/dovecot/dovecot-master.userdb
2018-08-28 23:14:05 +08:00
echo ${ RAND_USER } @mailcow.local:${ RAND_PASS } > /etc/sogo/sieve.creds
2017-03-02 18:23:23 +08:00
2019-05-19 05:01:05 +08:00
if [ [ -z ${ MAILDIR_SUB } ] ] ; then
MAILDIR_SUB_SHARED =
else
MAILDIR_SUB_SHARED = /${ MAILDIR_SUB }
fi
2019-07-29 03:34:42 +08:00
cat <<EOF > /etc/dovecot/shared_namespace.conf
2019-07-08 13:56:41 +08:00
# Autogenerated by mailcow
2019-05-19 05:01:05 +08:00
namespace {
type = shared
separator = /
prefix = Shared/%%u/
2019-12-25 17:34:08 +08:00
location = maildir:%%h${ MAILDIR_SUB_SHARED } :INDEX= ~${ MAILDIR_SUB_SHARED } /Shared/%%u
2019-05-19 05:01:05 +08:00
subscriptions = no
list = children
}
EOF
2020-07-11 19:22:48 +08:00
cat <<EOF > /etc/dovecot/sogo_trusted_ip.conf
# Autogenerated by mailcow
remote ${ IPV4_NETWORK } .248 {
disable_plaintext_auth = no
}
EOF
2021-06-23 20:11:23 +08:00
# Create random master Password for SOGo SSO
RAND_PASS = $( cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 32 | head -n 1)
echo -n ${ RAND_PASS } > /etc/phpfpm/sogo-sso.pass
cat <<EOF > /etc/dovecot/sogo-sso.conf
2019-07-08 13:56:41 +08:00
# Autogenerated by mailcow
2019-02-26 16:02:35 +08:00
passdb {
driver = static
args = allow_real_nets = ${ IPV4_NETWORK } .248/32 password = { plain} ${ RAND_PASS }
}
EOF
2021-04-17 02:38:09 +08:00
2020-02-05 17:56:44 +08:00
if [ [ " ${ MASTER } " = ~ ^( [ nN] [ oO] | [ nN] ) +$ ] ] ; then
2021-04-17 02:38:09 +08:00
# Toggling MASTER will result in a rebuild of containers, so the quota script will be recreated
cat <<'EOF' > /usr/local/bin/quota_notify.py
2020-01-29 17:30:06 +08:00
#!/usr/bin/python3
import sys
sys.exit( )
EOF
fi
2019-12-04 01:50:45 +08:00
2017-04-06 04:25:16 +08:00
# 401 is user dovecot
2018-10-07 21:09:21 +08:00
if [ [ ! -s /mail_crypt/ecprivkey.pem || ! -s /mail_crypt/ecpubkey.pem ] ] ; then
2017-04-04 02:06:49 +08:00
openssl ecparam -name prime256v1 -genkey | openssl pkey -out /mail_crypt/ecprivkey.pem
openssl pkey -in /mail_crypt/ecprivkey.pem -pubout -out /mail_crypt/ecpubkey.pem
2017-04-06 04:25:16 +08:00
chown 401 /mail_crypt/ecprivkey.pem /mail_crypt/ecpubkey.pem
else
chown 401 /mail_crypt/ecprivkey.pem /mail_crypt/ecpubkey.pem
2017-04-04 02:06:49 +08:00
fi
2017-04-06 04:25:16 +08:00
# Compile sieve scripts
2019-06-01 19:53:24 +08:00
sievec /var/vmail/sieve/global_sieve_before.sieve
sievec /var/vmail/sieve/global_sieve_after.sieve
2019-07-29 03:34:42 +08:00
sievec /usr/lib/dovecot/sieve/report-spam.sieve
sievec /usr/lib/dovecot/sieve/report-ham.sieve
2017-04-06 04:25:16 +08:00
# Fix permissions
2019-07-29 03:34:42 +08:00
chown root:root /etc/dovecot/sql/*.conf
2021-06-04 20:27:33 +08:00
chown root:dovecot /etc/dovecot/sql/dovecot-dict-sql-sieve* /etc/dovecot/sql/dovecot-dict-sql-quota* /etc/dovecot/lua/passwd-verify.lua
chmod 640 /etc/dovecot/sql/*.conf /etc/dovecot/lua/passwd-verify.lua
2017-04-06 04:25:16 +08:00
chown -R vmail:vmail /var/vmail/sieve
2018-11-12 16:49:23 +08:00
chown -R vmail:vmail /var/volatile
2020-09-23 17:20:00 +08:00
chown -R vmail:vmail /var/vmail_index
2018-11-12 16:49:23 +08:00
adduser vmail tty
chmod g+rw /dev/console
2019-05-30 00:02:14 +08:00
chown root:tty /dev/console
2019-07-29 03:34:42 +08:00
chmod +x /usr/lib/dovecot/sieve/rspamd-pipe-ham \
/usr/lib/dovecot/sieve/rspamd-pipe-spam \
2021-04-17 02:38:09 +08:00
/usr/local/bin/imapsync_runner.pl \
2019-01-29 07:11:12 +08:00
/usr/local/bin/imapsync \
/usr/local/bin/trim_logs.sh \
/usr/local/bin/sa-rules.sh \
2019-06-02 03:23:43 +08:00
/usr/local/bin/clean_q_aged.sh \
2019-01-29 07:11:12 +08:00
/usr/local/bin/maildir_gc.sh \
2019-02-05 07:00:22 +08:00
/usr/local/sbin/stop-supervisor.sh \
2020-04-14 18:48:57 +08:00
/usr/local/bin/quota_notify.py \
/usr/local/bin/repl_health.sh
2019-01-29 07:11:12 +08:00
2020-05-04 13:49:30 +08:00
# Prepare environment file for cronjobs
printenv | sed 's/^\(.*\)$/export \1/g' > /source_env.sh
2017-07-31 14:17:56 +08:00
# Clean old PID if any
2019-07-29 03:34:42 +08:00
[ [ -f /var/run/dovecot/master.pid ] ] && rm /var/run/dovecot/master.pid
2017-07-31 14:17:56 +08:00
2018-06-04 01:22:44 +08:00
# Clean stopped imapsync jobs
2018-07-28 04:19:14 +08:00
rm -f /tmp/imapsync_busy.lock
[Docker API] Use TLS encryption for communication with "on-the-fly" created key paris (non-exposed)
[Docker API] Create pipe to pass Rspamd UI worker password
[Dovecot] Pull Spamassassin ruleset to be read by Rspamd (MANY THANKS to Peer Heinlein!)
[Dovecot] Garbage collector for deleted maildirs (set keep time via MAILDIR_GC_TIME which defaults to 1440 minutes)
[Web] Flush memcached after mailbox item changes, fixes #1808
[Web] Fix duplicate IDs, fixes #1792
[Compose] Use SQL sockets
[PHP-FPM] Update APCu and Redis libs
[Dovecot] Encrypt maildir with global key pair in crypt-vol-1 (BACKUP!), also fixes #1791
[Web] Fix deletion of spam aliases
[Helper] Add "crypt" to backup script
[Helper] Override file for external SQL socket (not supported!)
[Compose] New images for Rspamd, PHP-FPM, SOGo, Dovecot, Docker API, Watchdog, ACME, Postfix
2018-09-30 04:01:23 +08:00
IMAPSYNC_TABLE = $( mysql --socket= /var/run/mysqld/mysqld.sock -u ${ DBUSER } -p${ DBPASS } ${ DBNAME } -e "SHOW TABLES LIKE 'imapsync'" -Bs)
[ [ ! -z ${ IMAPSYNC_TABLE } ] ] && mysql --socket= /var/run/mysqld/mysqld.sock -u ${ DBUSER } -p${ DBPASS } ${ DBNAME } -e "UPDATE imapsync SET is_running='0'"
2018-06-04 01:22:44 +08:00
2018-11-26 16:11:22 +08:00
# Envsubst maildir_gc
2019-02-13 00:11:04 +08:00
echo " $( envsubst < /usr/local/bin/maildir_gc.sh) " > /usr/local/bin/maildir_gc.sh
2018-11-26 16:11:22 +08:00
2020-02-05 17:56:44 +08:00
# GUID generation
2020-03-08 23:51:30 +08:00
while [ [ ${ VERSIONS_OK } != 'OK' ] ] ; do
if [ [ ! -z $( mysql --socket= /var/run/mysqld/mysqld.sock -u ${ DBUSER } -p${ DBPASS } ${ DBNAME } -B -e " SELECT 'OK' FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = \" ${ DBNAME } \" AND TABLE_NAME = 'versions' " ) ] ] ; then
VERSIONS_OK = OK
else
echo "Waiting for versions table to be created..."
sleep 3
fi
done
2020-04-23 15:35:22 +08:00
PUBKEY_MCRYPT = $( doveconf -P 2> /dev/null | grep -i mail_crypt_global_public_key | cut -d '<' -f2)
2019-08-09 20:11:36 +08:00
if [ -f ${ PUBKEY_MCRYPT } ] ; then
2019-08-11 03:03:18 +08:00
GUID = $( cat <( echo ${ MAILCOW_HOSTNAME } ) /mail_crypt/ecpubkey.pem | sha256sum | cut -d ' ' -f1 | tr -cd "[a-fA-F0-9.:/] " )
2019-08-09 20:11:36 +08:00
if [ ${# GUID } -eq 64 ] ; then
mysql --socket= /var/run/mysqld/mysqld.sock -u ${ DBUSER } -p${ DBPASS } ${ DBNAME } << EOF
REPLACE INTO versions ( application, version) VALUES ( "GUID" , " ${ GUID } " ) ;
EOF
else
mysql --socket= /var/run/mysqld/mysqld.sock -u ${ DBUSER } -p${ DBPASS } ${ DBNAME } << EOF
REPLACE INTO versions ( application, version) VALUES ( "GUID" , "INVALID" ) ;
EOF
fi
fi
2018-10-02 15:32:51 +08:00
# Collect SA rules once now
/usr/local/bin/sa-rules.sh
2019-10-18 18:01:47 +08:00
# Run hooks
for file in /hooks/*; do
if [ -x " ${ file } " ] ; then
echo " Running hook ${ file } "
" ${ file } "
fi
done
2019-12-05 17:14:41 +08:00
# For some strange, unknown and stupid reason, Dovecot may run into a race condition, when this file is not touched before it is read by dovecot/auth
# May be related to something inside Docker, I seriously don't know
2021-06-04 20:27:33 +08:00
touch /etc/dovecot/lua/passwd-verify.lua
2019-12-05 17:14:41 +08:00
2017-03-02 18:23:23 +08:00
exec " $@ "