diff --git a/data/Dockerfiles/olefy/olefy.py b/data/Dockerfiles/olefy/olefy.py index 776e78648..7c6880929 100644 --- a/data/Dockerfiles/olefy/olefy.py +++ b/data/Dockerfiles/olefy/olefy.py @@ -32,6 +32,13 @@ import time import magic import re +skip_olefy = os.getenv('SKIP_OLEFY', '') + +if skip_olefy.lower() in ['yes', 'y']: + print("SKIP_OLEFY=y, skipping Olefy...") + time.sleep(365 * 24 * 60 * 60) + sys.exit(0) + # merge variables from /etc/olefy.conf and the defaults olefy_listen_addr_string = os.getenv('OLEFY_BINDADDRESS', '127.0.0.1,::1') olefy_listen_port = int(os.getenv('OLEFY_BINDPORT', '10050')) @@ -113,7 +120,7 @@ def oletools( stream, tmp_file_name, lid ): out = bytes(out.decode('utf-8', 'ignore').replace(' ', ' ').replace('\t', '').replace('\n', '').replace('XLMMacroDeobfuscator: pywin32 is not installed (only is required if you want to use MS Excel)', ''), encoding="utf-8") failed = False if out.__len__() < 30: - logger.error('{} olevba returned <30 chars - rc: {!r}, response: {!r}, error: {!r}'.format(lid,cmd_tmp.returncode, + logger.error('{} olevba returned <30 chars - rc: {!r}, response: {!r}, error: {!r}'.format(lid,cmd_tmp.returncode, out.decode('utf-8', 'ignore'), err.decode('utf-8', 'ignore'))) out = b'[ { "error": "Unhandled error - too short olevba response" } ]' failed = True diff --git a/data/Dockerfiles/rspamd/docker-entrypoint.sh b/data/Dockerfiles/rspamd/docker-entrypoint.sh index cf44c3063..7385488b0 100755 --- a/data/Dockerfiles/rspamd/docker-entrypoint.sh +++ b/data/Dockerfiles/rspamd/docker-entrypoint.sh @@ -81,6 +81,27 @@ EOF redis-cli -h redis-mailcow -a ${REDISPASS} --no-auth-warning SLAVEOF NO ONE fi +if [[ "${SKIP_OLEFY}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then + if [[ -f /etc/rspamd/local.d/external_services.conf ]]; then + rm /etc/rspamd/local.d/external_services.conf + fi +else + cat < /etc/rspamd/local.d/external_services.conf +oletools { + # default olefy settings + servers = "olefy:10055"; + # needs to be set explicitly for Rspamd < 1.9.5 + scan_mime_parts = true; + # mime-part regex matching in content-type or filename + # block all macros + extended = true; + max_size = 3145728; + timeout = 20.0; + retransmits = 1; +} +EOF +fi + # Provide additional lua modules ln -s /usr/lib/$(uname -m)-linux-gnu/liblua5.1-cjson.so.0.0.0 /usr/lib/rspamd/cjson.so diff --git a/data/Dockerfiles/watchdog/watchdog.sh b/data/Dockerfiles/watchdog/watchdog.sh index 9d6f6609f..d1c659ce8 100755 --- a/data/Dockerfiles/watchdog/watchdog.sh +++ b/data/Dockerfiles/watchdog/watchdog.sh @@ -994,6 +994,7 @@ PID=$! echo "Spawned cert_checks with PID ${PID}" BACKGROUND_TASKS+=(${PID}) +if [[ "${SKIP_OLEFY}" =~ ^([nN][oO]|[nN])+$ ]]; then ( while true; do if ! olefy_checks; then @@ -1005,6 +1006,7 @@ done PID=$! echo "Spawned olefy_checks with PID ${PID}" BACKGROUND_TASKS+=(${PID}) +fi ( while true; do diff --git a/data/conf/rspamd/local.d/external_services.conf b/data/conf/rspamd/local.d/external_services.conf deleted file mode 100644 index 2b091ff23..000000000 --- a/data/conf/rspamd/local.d/external_services.conf +++ /dev/null @@ -1,12 +0,0 @@ -oletools { - # default olefy settings - servers = "olefy:10055"; - # needs to be set explicitly for Rspamd < 1.9.5 - scan_mime_parts = true; - # mime-part regex matching in content-type or filename - # block all macros - extended = true; - max_size = 3145728; - timeout = 20.0; - retransmits = 1; -} diff --git a/data/web/admin/dashboard.php b/data/web/admin/dashboard.php index 473f28de2..443c2ea2a 100644 --- a/data/web/admin/dashboard.php +++ b/data/web/admin/dashboard.php @@ -18,6 +18,7 @@ elseif (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php'; $_SESSION['return_to'] = $_SERVER['REQUEST_URI']; $clamd_status = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["SKIP_CLAMD"])) ? false : true; +$olefy_status = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["SKIP_OLEFY"])) ? false : true; if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CACHE')) { @@ -33,6 +34,7 @@ $vmail_df = explode(',', (string)json_decode(docker('post', 'dovecot-mailcow', ' // containers $containers_info = (array) docker('info'); if ($clamd_status === false) unset($containers_info['clamd-mailcow']); +if ($olefy_status === false) unset($containers_info['olefy-mailcow']); ksort($containers_info); $containers = array(); foreach ($containers_info as $container => $container_info) { @@ -77,6 +79,7 @@ $template_data = [ 'gal' => @$_SESSION['gal'], 'license_guid' => license('guid'), 'clamd_status' => $clamd_status, + 'olefy_status' => $olefy_status, 'containers' => $containers, 'ip_check' => customize('get', 'ip_check'), 'lang_admin' => json_encode($lang['admin']), diff --git a/docker-compose.yml b/docker-compose.yml index 0cd4491d7..3b27a09a9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -176,6 +176,7 @@ services: - COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized} - SKIP_FTS=${SKIP_FTS:-y} - SKIP_CLAMD=${SKIP_CLAMD:-n} + - SKIP_OLEFY=${SKIP_OLEFY:-n} - SKIP_SOGO=${SKIP_SOGO:-n} - ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n} - MASTER=${MASTER:-y} @@ -538,6 +539,7 @@ services: - IP_BY_DOCKER_API=${IP_BY_DOCKER_API:-0} - CHECK_UNBOUND=${CHECK_UNBOUND:-1} - SKIP_CLAMD=${SKIP_CLAMD:-n} + - SKIP_OLEFY=${SKIP_OLEFY:-n} - SKIP_LETS_ENCRYPT=${SKIP_LETS_ENCRYPT:-n} - SKIP_SOGO=${SKIP_SOGO:-n} - HTTPS_PORT=${HTTPS_PORT:-443} @@ -601,6 +603,7 @@ services: - OLEFY_LOGLVL=20 - OLEFY_MINLENGTH=500 - OLEFY_DEL_TMP=1 + - SKIP_OLEFY=${SKIP_OLEFY:-n} networks: mailcow-network: aliases: diff --git a/generate_config.sh b/generate_config.sh index c7a7cb64f..c4396a9ce 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -382,6 +382,10 @@ SKIP_UNBOUND_HEALTHCHECK=n SKIP_CLAMD=${SKIP_CLAMD} +# Skip Olefy (olefy-mailcow) anti-virus for Office documents (Rspamd will auto-detect a missing Olefy container) - y/n + +SKIP_OLEFY=n + # Skip SOGo: Will disable SOGo integration and therefore webmail, DAV protocols and ActiveSync support (experimental, unsupported, not fully implemented) - y/n SKIP_SOGO=n diff --git a/update.sh b/update.sh index ea2fcf17f..e4e88afb3 100755 --- a/update.sh +++ b/update.sh @@ -323,6 +323,7 @@ adapt_new_options() { "WATCHDOG_EXTERNAL_CHECKS" "WATCHDOG_SUBJECT" "SKIP_CLAMD" + "SKIP_OLEFY" "SKIP_IP_CHECK" "ADDITIONAL_SAN" "DOVEADM_PORT" @@ -967,6 +968,7 @@ CONFIG_ARRAY=( "WATCHDOG_EXTERNAL_CHECKS" "WATCHDOG_SUBJECT" "SKIP_CLAMD" + "SKIP_OLEFY" "SKIP_IP_CHECK" "ADDITIONAL_SAN" "AUTODISCOVER_SAN" @@ -1278,6 +1280,18 @@ for option in "${CONFIG_ARRAY[@]}"; do echo '# CAUTION: Disabling this may expose container ports to other neighbors on the same subnet, even if the ports are bound to localhost' >> mailcow.conf echo 'DISABLE_NETFILTER_ISOLATION_RULE=n' >> mailcow.conf fi + elif [[ "${option}" == "SKIP_CLAMD" ]]; then + if ! grep -q "${option}" mailcow.conf; then + echo "Adding new option \"${option}\" to mailcow.conf" + echo '# Skip ClamAV (clamd-mailcow) anti-virus (Rspamd will auto-detect a missing ClamAV container) - y/n' >> mailcow.conf + echo 'SKIP_CLAMD=n' >> mailcow.conf + fi + elif [[ "${option}" == "SKIP_OLEFY" ]]; then + if ! grep -q "${option}" mailcow.conf; then + echo "Adding new option \"${option}\" to mailcow.conf" + echo '# Skip Olefy (olefy-mailcow) anti-virus for Office documents (Rspamd will auto-detect a missing Olefy container) - y/n' >> mailcow.conf + echo 'SKIP_OLEFY=n' >> mailcow.conf + fi elif [[ "${option}" == "REDISPASS" ]]; then if ! grep -q "${option}" mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf"