forked from GNUsocial/gnu-social
[DOCKER][MAIL] Setup docker mail server
This commit is contained in:
parent
250235b1be
commit
bc1d85de56
13
dockermail/.env
Normal file
13
dockermail/.env
Normal file
@ -0,0 +1,13 @@
|
||||
MYSQL_DATABASE=mailserver
|
||||
MYSQL_USER=mailserver
|
||||
MYSQL_PASSWORD=changeme
|
||||
MYSQL_ROOT_PASSWORD=changeme
|
||||
MAILNAME=mail.example.com
|
||||
POSTMASTER=postmaster@example.com
|
||||
RELAYHOST=false
|
||||
FILTER_MIME=false
|
||||
FILTER_VIRUS=true
|
||||
ENABLE_IMAP=true
|
||||
ENABLE_POP3=true
|
||||
CONTROLLER_PASSWORD=changeme
|
||||
WAITSTART_TIMEOUT=2m
|
21
dockermail/LICENSE
Normal file
21
dockermail/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Jeffrey Boehm
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,6 +1,9 @@
|
||||
To start, run setup.sh choose name and domain and create the first email account. Then open mailserver/ and run 'docker-compose up'
|
||||
To change settings read mailserver/env-mailserver
|
||||
|
||||
To update, run update.sh
|
||||
|
||||
Add more accounts with add_account.sh and send mails with send_mail.sh
|
||||
POP3 STARTTLS 127.0.0.1:110
|
||||
POP3S 127.0.0.1:995
|
||||
IMAP STARTTLS 127.0.0.1:143
|
||||
IMAPS 127.0.0.1:993
|
||||
SMTP 127.0.0.1:25
|
||||
Mail Submission STARTTLS 127.0.0.1:587
|
||||
Management Interface 127.0.0.1:81/manager/
|
||||
Webmail 127.0.0.1:81/webmail/
|
||||
Rspamd interface 127.0.0.1:81/rspamd/
|
@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
read -p "EMAIL: " user
|
||||
read -s -p "PASS: " password
|
||||
printf "\n"
|
||||
|
||||
bash mailserver/setup.sh email add "$user" "$password"
|
||||
|
10
dockermail/db/Dockerfile
Normal file
10
dockermail/db/Dockerfile
Normal file
@ -0,0 +1,10 @@
|
||||
FROM mysql:5.7
|
||||
LABEL maintainer="jeff@ressourcenkonflikt.de"
|
||||
|
||||
ENV MYSQL_DATABASE=mailserver \
|
||||
MYSQL_USER=mailserver \
|
||||
MYSQL_PASSWORD=changeme \
|
||||
MYSQL_ROOT_PASSWORD=changeme
|
||||
|
||||
COPY rootfs/ /
|
||||
VOLUME /run/mysqld
|
@ -0,0 +1,82 @@
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
|
||||
# Export von Tabelle mail_aliases
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `mail_aliases`;
|
||||
|
||||
CREATE TABLE `mail_aliases` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`domain_id` int(11) DEFAULT NULL,
|
||||
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`destination` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `alias_idx` (`domain_id`,`name`,`destination`),
|
||||
KEY `IDX_85AF3A56115F0EE5` (`domain_id`),
|
||||
CONSTRAINT `FK_5F12BB39115F0EE5` FOREIGN KEY (`domain_id`) REFERENCES `mail_domains` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
# Export von Tabelle mail_domains
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `mail_domains`;
|
||||
|
||||
CREATE TABLE `mail_domains` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `UNIQ_56C63EF25E237E06` (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
# Export von Tabelle mail_users
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `mail_users`;
|
||||
|
||||
CREATE TABLE `mail_users` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`domain_id` int(11) DEFAULT NULL,
|
||||
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `user_idx` (`name`,`domain_id`),
|
||||
KEY `IDX_20400786115F0EE5` (`domain_id`),
|
||||
CONSTRAINT `FK_1483A5E9115F0EE5` FOREIGN KEY (`domain_id`) REFERENCES `mail_domains` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
# Export von Tabelle migration_versions
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `migration_versions`;
|
||||
|
||||
CREATE TABLE `migration_versions` (
|
||||
`version` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`version`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
LOCK TABLES `migration_versions` WRITE;
|
||||
/*!40000 ALTER TABLE `migration_versions` DISABLE KEYS */;
|
||||
|
||||
INSERT INTO `migration_versions` (`version`)
|
||||
VALUES
|
||||
('20180320164351'),
|
||||
('20180320171339');
|
||||
|
||||
/*!40000 ALTER TABLE `migration_versions` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
||||
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
226
dockermail/db/rootfs/docker-entrypoint-initdb.d/002_webmail.sql
Normal file
226
dockermail/db/rootfs/docker-entrypoint-initdb.d/002_webmail.sql
Normal file
@ -0,0 +1,226 @@
|
||||
-- Roundcube Webmail initial database structure
|
||||
|
||||
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=0 */;
|
||||
|
||||
-- Table structure for table `session`
|
||||
|
||||
CREATE TABLE `session` (
|
||||
`sess_id` varchar(128) NOT NULL,
|
||||
`changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
|
||||
`ip` varchar(40) NOT NULL,
|
||||
`vars` mediumtext NOT NULL,
|
||||
PRIMARY KEY(`sess_id`),
|
||||
INDEX `changed_index` (`changed`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
|
||||
-- Table structure for table `users`
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`user_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(128) BINARY NOT NULL,
|
||||
`mail_host` varchar(128) NOT NULL,
|
||||
`created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
|
||||
`last_login` datetime DEFAULT NULL,
|
||||
`failed_login` datetime DEFAULT NULL,
|
||||
`failed_login_counter` int(10) UNSIGNED DEFAULT NULL,
|
||||
`language` varchar(5),
|
||||
`preferences` longtext,
|
||||
PRIMARY KEY(`user_id`),
|
||||
UNIQUE `username` (`username`, `mail_host`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
|
||||
-- Table structure for table `cache`
|
||||
|
||||
CREATE TABLE `cache` (
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`cache_key` varchar(128) BINARY NOT NULL,
|
||||
`expires` datetime DEFAULT NULL,
|
||||
`data` longtext NOT NULL,
|
||||
PRIMARY KEY (`user_id`, `cache_key`),
|
||||
CONSTRAINT `user_id_fk_cache` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
INDEX `expires_index` (`expires`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
|
||||
-- Table structure for table `cache_shared`
|
||||
|
||||
CREATE TABLE `cache_shared` (
|
||||
`cache_key` varchar(255) BINARY NOT NULL,
|
||||
`expires` datetime DEFAULT NULL,
|
||||
`data` longtext NOT NULL,
|
||||
PRIMARY KEY (`cache_key`),
|
||||
INDEX `expires_index` (`expires`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
|
||||
-- Table structure for table `cache_index`
|
||||
|
||||
CREATE TABLE `cache_index` (
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`mailbox` varchar(255) BINARY NOT NULL,
|
||||
`expires` datetime DEFAULT NULL,
|
||||
`valid` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`data` longtext NOT NULL,
|
||||
CONSTRAINT `user_id_fk_cache_index` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
INDEX `expires_index` (`expires`),
|
||||
PRIMARY KEY (`user_id`, `mailbox`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
|
||||
-- Table structure for table `cache_thread`
|
||||
|
||||
CREATE TABLE `cache_thread` (
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`mailbox` varchar(255) BINARY NOT NULL,
|
||||
`expires` datetime DEFAULT NULL,
|
||||
`data` longtext NOT NULL,
|
||||
CONSTRAINT `user_id_fk_cache_thread` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
INDEX `expires_index` (`expires`),
|
||||
PRIMARY KEY (`user_id`, `mailbox`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
|
||||
-- Table structure for table `cache_messages`
|
||||
|
||||
CREATE TABLE `cache_messages` (
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`mailbox` varchar(255) BINARY NOT NULL,
|
||||
`uid` int(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`expires` datetime DEFAULT NULL,
|
||||
`data` longtext NOT NULL,
|
||||
`flags` int(11) NOT NULL DEFAULT '0',
|
||||
CONSTRAINT `user_id_fk_cache_messages` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
INDEX `expires_index` (`expires`),
|
||||
PRIMARY KEY (`user_id`, `mailbox`, `uid`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
|
||||
-- Table structure for table `contacts`
|
||||
|
||||
CREATE TABLE `contacts` (
|
||||
`contact_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
|
||||
`del` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`name` varchar(128) NOT NULL DEFAULT '',
|
||||
`email` text NOT NULL,
|
||||
`firstname` varchar(128) NOT NULL DEFAULT '',
|
||||
`surname` varchar(128) NOT NULL DEFAULT '',
|
||||
`vcard` longtext NULL,
|
||||
`words` text NULL,
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
PRIMARY KEY(`contact_id`),
|
||||
CONSTRAINT `user_id_fk_contacts` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
INDEX `user_contacts_index` (`user_id`,`del`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
-- Table structure for table `contactgroups`
|
||||
|
||||
CREATE TABLE `contactgroups` (
|
||||
`contactgroup_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
|
||||
`del` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`name` varchar(128) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY(`contactgroup_id`),
|
||||
CONSTRAINT `user_id_fk_contactgroups` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
INDEX `contactgroups_user_index` (`user_id`,`del`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
CREATE TABLE `contactgroupmembers` (
|
||||
`contactgroup_id` int(10) UNSIGNED NOT NULL,
|
||||
`contact_id` int(10) UNSIGNED NOT NULL,
|
||||
`created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
|
||||
PRIMARY KEY (`contactgroup_id`, `contact_id`),
|
||||
CONSTRAINT `contactgroup_id_fk_contactgroups` FOREIGN KEY (`contactgroup_id`)
|
||||
REFERENCES `contactgroups`(`contactgroup_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `contact_id_fk_contacts` FOREIGN KEY (`contact_id`)
|
||||
REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
INDEX `contactgroupmembers_contact_index` (`contact_id`)
|
||||
) /*!40000 ENGINE=INNODB */;
|
||||
|
||||
|
||||
-- Table structure for table `identities`
|
||||
|
||||
CREATE TABLE `identities` (
|
||||
`identity_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
|
||||
`del` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`standard` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`name` varchar(128) NOT NULL,
|
||||
`organization` varchar(128) NOT NULL DEFAULT '',
|
||||
`email` varchar(128) NOT NULL,
|
||||
`reply-to` varchar(128) NOT NULL DEFAULT '',
|
||||
`bcc` varchar(128) NOT NULL DEFAULT '',
|
||||
`signature` longtext,
|
||||
`html_signature` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY(`identity_id`),
|
||||
CONSTRAINT `user_id_fk_identities` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
INDEX `user_identities_index` (`user_id`, `del`),
|
||||
INDEX `email_identities_index` (`email`, `del`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
|
||||
-- Table structure for table `dictionary`
|
||||
|
||||
CREATE TABLE `dictionary` (
|
||||
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, -- redundant, for compat. with Galera Cluster
|
||||
`user_id` int(10) UNSIGNED DEFAULT NULL, -- NULL here is for "shared dictionaries"
|
||||
`language` varchar(5) NOT NULL,
|
||||
`data` longtext NOT NULL,
|
||||
CONSTRAINT `user_id_fk_dictionary` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
UNIQUE `uniqueness` (`user_id`, `language`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
|
||||
-- Table structure for table `searches`
|
||||
|
||||
CREATE TABLE `searches` (
|
||||
`search_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`type` int(3) NOT NULL DEFAULT '0',
|
||||
`name` varchar(128) NOT NULL,
|
||||
`data` text,
|
||||
PRIMARY KEY(`search_id`),
|
||||
CONSTRAINT `user_id_fk_searches` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
UNIQUE `uniqueness` (`user_id`, `type`, `name`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
-- Table structure for table `filestore`
|
||||
|
||||
CREATE TABLE `filestore` (
|
||||
`file_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`context` varchar(32) NOT NULL,
|
||||
`filename` varchar(128) NOT NULL,
|
||||
`mtime` int(10) NOT NULL,
|
||||
`data` longtext NOT NULL,
|
||||
PRIMARY KEY (`file_id`),
|
||||
CONSTRAINT `user_id_fk_filestore` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
UNIQUE `uniqueness` (`user_id`, `context`, `filename`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
-- Table structure for table `system`
|
||||
|
||||
CREATE TABLE `system` (
|
||||
`name` varchar(64) NOT NULL,
|
||||
`value` mediumtext,
|
||||
PRIMARY KEY(`name`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=1 */;
|
||||
|
||||
INSERT INTO `system` (`name`, `value`) VALUES ('roundcube-version', '2019092900');
|
125
dockermail/docker-compose.yml
Normal file
125
dockermail/docker-compose.yml
Normal file
@ -0,0 +1,125 @@
|
||||
version: '3.5'
|
||||
|
||||
services:
|
||||
# Creates self signed tls certificates. Remove if you
|
||||
# use your own.
|
||||
ssl:
|
||||
image: jeboehm/mailserver-ssl:latest
|
||||
build: ./ssl
|
||||
env_file: .env
|
||||
volumes:
|
||||
- data-tls:/media/tls:rw
|
||||
|
||||
# Responsible for storing users and their aliases. Remove
|
||||
# if you already have a MySQL server.
|
||||
db:
|
||||
image: jeboehm/mailserver-db:latest
|
||||
build: ./db
|
||||
restart: on-failure:5
|
||||
env_file: .env
|
||||
volumes:
|
||||
- data-db:/var/lib/mysql
|
||||
|
||||
# The Mail Transfer Agent (Postfix) receives incoming mail
|
||||
# on TCP port 25.
|
||||
mta:
|
||||
image: jeboehm/mailserver-mta:latest
|
||||
build: ./mta
|
||||
restart: on-failure:5
|
||||
env_file: .env
|
||||
volumes:
|
||||
- data-tls:/media/tls:ro
|
||||
# For using external certificates uncomment the following lines
|
||||
# and change the path on the left side of the colon.
|
||||
# - /home/user/certs/mail.example.com.crt:/media/tls/mailserver.crt:ro
|
||||
# - /home/user/certs/mail.example.com.key:/media/tls/mailserver.key:ro
|
||||
ports:
|
||||
- "0.0.0.0:25:25"
|
||||
|
||||
# The Mail Delivery Agent (Dovecot) is responsible for storing
|
||||
# incoming mail into a users mailbox and also delivers them
|
||||
# via POP3 or IMAP4.
|
||||
mda:
|
||||
image: jeboehm/mailserver-mda:latest
|
||||
build: ./mda
|
||||
restart: on-failure:5
|
||||
env_file: .env
|
||||
volumes:
|
||||
- data-mail:/var/vmail
|
||||
- data-tls:/media/tls:ro
|
||||
# For using external certificates uncomment the following lines
|
||||
# and change the path on the left side of the colon.
|
||||
# - /home/user/certs/mail.example.com.crt:/media/tls/mailserver.crt:ro
|
||||
# - /home/user/certs/mail.example.com.key:/media/tls/mailserver.key:ro
|
||||
ports:
|
||||
- "0.0.0.0:143:143"
|
||||
- "0.0.0.0:993:993"
|
||||
- "0.0.0.0:110:110"
|
||||
- "0.0.0.0:995:995"
|
||||
- "0.0.0.0:587:587"
|
||||
|
||||
# The admin (mailserver-admin) and webmail (roundcube) interfaces
|
||||
# live here. Can be removed if not needed.
|
||||
web:
|
||||
image: jeboehm/mailserver-web:latest
|
||||
build: ./web
|
||||
restart: on-failure:5
|
||||
env_file: .env
|
||||
volumes:
|
||||
- data-dkim:/media/dkim
|
||||
# For use with jwilder/nginx-proxy.
|
||||
# environment:
|
||||
# - VIRTUAL_HOST=mail.example.com
|
||||
ports:
|
||||
- "0.0.0.0:81:80"
|
||||
|
||||
# Incoming spam is (hopefully) filtered by rspamd which runs
|
||||
# in this service.
|
||||
filter:
|
||||
image: jeboehm/mailserver-filter:latest
|
||||
build: ./filter
|
||||
restart: on-failure:5
|
||||
env_file: .env
|
||||
volumes:
|
||||
- data-filter:/var/lib/rspamd
|
||||
- data-dkim:/media/dkim
|
||||
links:
|
||||
- virus:virus.local
|
||||
|
||||
# Incoming viruses or malware is detected and rejected by
|
||||
# this service. Can be removed if FILTER_VIRUS is set to false.
|
||||
virus:
|
||||
image: jeboehm/mailserver-virus:latest
|
||||
build: ./virus
|
||||
restart: on-failure:5
|
||||
env_file: .env
|
||||
volumes:
|
||||
- data-virusdb:/var/lib/clamav
|
||||
|
||||
# If you want unhealthy containers to be restarted automatically
|
||||
# just uncomment the following lines.
|
||||
# autoheal:
|
||||
# image: willfarrell/autoheal:latest
|
||||
# restart: always
|
||||
# networks: []
|
||||
# volumes:
|
||||
# - /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
# environment:
|
||||
# - AUTOHEAL_CONTAINER_LABEL=de.ressourcenkonflikt.docker-mailserver.autoheal
|
||||
|
||||
# Optional service: extend ClamAV (used in the virus service)
|
||||
# by downloading additional databases provided by different
|
||||
# companys. Run it regulary.
|
||||
# virus_unof_sig_updater:
|
||||
# build: ./virus/contrib/unofficial-sigs
|
||||
# env_file: .env
|
||||
# volumes:
|
||||
# - data-virusdb:/var/lib/clamav
|
||||
|
||||
volumes:
|
||||
data-db:
|
||||
data-dkim:
|
||||
data-mail:
|
||||
data-tls:
|
||||
data-filter:
|
||||
data-virusdb:
|
45
dockermail/filter/Dockerfile
Normal file
45
dockermail/filter/Dockerfile
Normal file
@ -0,0 +1,45 @@
|
||||
ARG DOCKERIZE_VER=0.6.0
|
||||
ARG ALPINE_VER=3.9
|
||||
|
||||
FROM jwilder/dockerize:${DOCKERIZE_VER} AS dockerize
|
||||
FROM alpine:${ALPINE_VER}
|
||||
|
||||
LABEL maintainer="jeff@ressourcenkonflikt.de"
|
||||
LABEL vendor="https://github.com/jeboehm/docker-mailserver"
|
||||
LABEL de.ressourcenkonflikt.docker-mailserver.autoheal="true"
|
||||
|
||||
ENV FILTER_VIRUS=false \
|
||||
FILTER_VIRUS_HOST=virus.local \
|
||||
WAITSTART_TIMEOUT=1m \
|
||||
CONTROLLER_PASSWORD=changeme
|
||||
|
||||
RUN apk --no-cache add \
|
||||
openssl \
|
||||
rspamd \
|
||||
rspamd-client \
|
||||
rspamd-controller \
|
||||
rspamd-proxy && \
|
||||
mkdir /run/rspamd && \
|
||||
touch \
|
||||
/etc/rspamd/local.d/antivirus.conf \
|
||||
/etc/rspamd/local.d/worker-controller.inc && \
|
||||
chown -R rspamd \
|
||||
/run/rspamd \
|
||||
/var/lib/rspamd \
|
||||
/etc/rspamd/local.d/antivirus.conf \
|
||||
/etc/rspamd/local.d/worker-controller.inc && \
|
||||
wget -O /usr/share/rspamd/bayes.spam.sqlite https://rspamd.com/rspamd_statistics/bayes.spam.sqlite && \
|
||||
wget -O /usr/share/rspamd/bayes.ham.sqlite https://rspamd.com/rspamd_statistics/bayes.ham.sqlite && \
|
||||
apk --no-cache del \
|
||||
openssl
|
||||
|
||||
COPY --from=dockerize /usr/local/bin/dockerize /usr/local/bin
|
||||
COPY rootfs/ /
|
||||
|
||||
EXPOSE 11332 11334
|
||||
USER rspamd
|
||||
|
||||
VOLUME ["/var/lib/rspamd"]
|
||||
|
||||
HEALTHCHECK CMD wget -O- -T 10 http://127.0.0.1:11334/stat
|
||||
CMD ["/usr/local/bin/entrypoint.sh"]
|
@ -0,0 +1,11 @@
|
||||
{{ $filter_virus := eq (or ($.Env.FILTER_VIRUS) "") "true" }}
|
||||
|
||||
{{ if $filter_virus }}
|
||||
clamav {
|
||||
scan_mime_parts = false;
|
||||
symbol = "CLAM_VIRUS";
|
||||
type = "clamav";
|
||||
action = "reject";
|
||||
servers = "{{$.Env.FILTER_VIRUS_HOST}}:3310";
|
||||
}
|
||||
{{ end }}
|
@ -0,0 +1 @@
|
||||
autolearn = true;
|
@ -0,0 +1,2 @@
|
||||
path = "/media/dkim/$domain.$selector.key";
|
||||
selector_map = "/media/dkim/dkim_selectors.map";
|
1
dockermail/filter/rootfs/etc/rspamd/local.d/logging.inc
Normal file
1
dockermail/filter/rootfs/etc/rspamd/local.d/logging.inc
Normal file
@ -0,0 +1 @@
|
||||
type = console
|
11
dockermail/filter/rootfs/etc/rspamd/local.d/metrics.conf
Normal file
11
dockermail/filter/rootfs/etc/rspamd/local.d/metrics.conf
Normal file
@ -0,0 +1,11 @@
|
||||
group "rbl" {
|
||||
symbol "RBL_NIXSPAM_BAD" {
|
||||
weight = 7.0;
|
||||
description = "From address is listed in ix.dnsbl.manitu.net BL";
|
||||
}
|
||||
|
||||
symbol "RBL_NIXSPAM" {
|
||||
weight = 0.0;
|
||||
description = "Unrecognised result from ix.dnsbl.manitu.net BL";
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
extended_spam_headers = true;
|
7
dockermail/filter/rootfs/etc/rspamd/local.d/options.inc
Normal file
7
dockermail/filter/rootfs/etc/rspamd/local.d/options.inc
Normal file
@ -0,0 +1,7 @@
|
||||
dns {
|
||||
timeout = 1s;
|
||||
sockets = 16;
|
||||
retransmits = 2;
|
||||
nameserver = [ "8.8.8.8:53", "8.8.4.4:53", "1.1.1.1:53", "1.0.0.1:53" ];
|
||||
}
|
||||
|
9
dockermail/filter/rootfs/etc/rspamd/local.d/rbl.conf
Normal file
9
dockermail/filter/rootfs/etc/rspamd/local.d/rbl.conf
Normal file
@ -0,0 +1,9 @@
|
||||
rbls {
|
||||
nixspam {
|
||||
symbol = "RBL_NIXSPAM";
|
||||
rbl = "ix.dnsbl.manitu.net";
|
||||
returncodes {
|
||||
RBL_NIXSPAM_BAD = "127.0.0.2";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
bind_socket = "*:11334";
|
||||
secure_ip = "127.0.0.1";
|
||||
secure_ip = "::1";
|
||||
secure_ip = "172.16.0.0/12";
|
||||
password = "{{$.Env.CONTROLLER_PASSWORD_ENC}}"
|
@ -0,0 +1 @@
|
||||
bind_socket = "*:11332";
|
32
dockermail/filter/rootfs/usr/local/bin/entrypoint.sh
Normal file
32
dockermail/filter/rootfs/usr/local/bin/entrypoint.sh
Normal file
@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
FILTER_VIRUS_ARGS=""
|
||||
if [ ${FILTER_VIRUS} == "true" ]
|
||||
then
|
||||
FILTER_VIRUS_ARGS="-wait tcp://${FILTER_VIRUS_HOST}:3310"
|
||||
fi
|
||||
|
||||
if ! [ -f /var/lib/rspamd/bayes.spam.sqlite ]
|
||||
then
|
||||
cp /usr/share/rspamd/bayes.spam.sqlite /var/lib/rspamd/bayes.spam.sqlite
|
||||
fi
|
||||
|
||||
if ! [ -f /var/lib/rspamd/bayes.ham.sqlite ]
|
||||
then
|
||||
cp /usr/share/rspamd/bayes.ham.sqlite /var/lib/rspamd/bayes.ham.sqlite
|
||||
fi
|
||||
|
||||
if [ "${CONTROLLER_PASSWORD}" == "changeme" ]
|
||||
then
|
||||
# q1 is disabled in rspamd.
|
||||
export CONTROLLER_PASSWORD_ENC="q1"
|
||||
else
|
||||
export CONTROLLER_PASSWORD_ENC=`rspamadm pw -e -p ${CONTROLLER_PASSWORD}`
|
||||
fi
|
||||
|
||||
dockerize \
|
||||
-template /etc/rspamd/local.d/antivirus.conf.templ:/etc/rspamd/local.d/antivirus.conf \
|
||||
-template /etc/rspamd/local.d/worker-controller.inc.templ:/etc/rspamd/local.d/worker-controller.inc \
|
||||
${FILTER_VIRUS_ARGS} \
|
||||
-timeout ${WAITSTART_TIMEOUT} \
|
||||
/usr/sbin/rspamd -c /etc/rspamd/rspamd.conf -f
|
47
dockermail/mda/Dockerfile
Normal file
47
dockermail/mda/Dockerfile
Normal file
@ -0,0 +1,47 @@
|
||||
ARG DOCKERIZE_VER=0.6.0
|
||||
ARG ALPINE_VER=3.9
|
||||
|
||||
FROM jwilder/dockerize:${DOCKERIZE_VER} AS dockerize
|
||||
|
||||
FROM alpine:${ALPINE_VER}
|
||||
LABEL maintainer="jeff@ressourcenkonflikt.de"
|
||||
LABEL vendor="https://github.com/jeboehm/docker-mailserver"
|
||||
LABEL de.ressourcenkonflikt.docker-mailserver.autoheal="true"
|
||||
|
||||
ENV MYSQL_HOST=db \
|
||||
MYSQL_USER=root \
|
||||
MYSQL_PASSWORD=changeme \
|
||||
MYSQL_DATABASE=mailserver \
|
||||
MAILNAME=mail.example.com \
|
||||
POSTMASTER=postmaster@example.com \
|
||||
SUBMISSION_HOST=mta \
|
||||
ENABLE_POP3=true \
|
||||
ENABLE_IMAP=true \
|
||||
SSL_CERT=/media/tls/mailserver.crt \
|
||||
SSL_KEY=/media/tls/mailserver.key \
|
||||
WAITSTART_TIMEOUT=1m
|
||||
|
||||
RUN apk --no-cache add \
|
||||
curl \
|
||||
dovecot \
|
||||
dovecot-lmtpd \
|
||||
dovecot-mysql \
|
||||
dovecot-pigeonhole-plugin \
|
||||
dovecot-pop3d \
|
||||
dovecot-submissiond && \
|
||||
adduser -h /var/vmail -u 5000 -D vmail && \
|
||||
rm -rf /etc/ssl/dovecot && \
|
||||
openssl dhparam -out /etc/dovecot/dh.pem 2048
|
||||
|
||||
COPY --from=dockerize /usr/local/bin/dockerize /usr/local/bin
|
||||
COPY rootfs/ /
|
||||
|
||||
RUN sievec /etc/dovecot/sieve/global/spam-to-folder.sieve && \
|
||||
sievec /etc/dovecot/sieve/global/learn-ham.sieve && \
|
||||
sievec /etc/dovecot/sieve/global/learn-spam.sieve
|
||||
|
||||
EXPOSE 2003 4190 143 110 993 995
|
||||
VOLUME ["/var/vmail"]
|
||||
|
||||
HEALTHCHECK CMD echo "? LOGOUT" | nc 127.0.0.1 143 | grep "Dovecot ready."
|
||||
CMD ["/usr/local/bin/entrypoint.sh"]
|
3
dockermail/mda/rootfs/etc/dovecot/conf.d/10-auth.conf
Normal file
3
dockermail/mda/rootfs/etc/dovecot/conf.d/10-auth.conf
Normal file
@ -0,0 +1,3 @@
|
||||
auth_mechanisms = plain login
|
||||
|
||||
!include auth-sql.conf.ext
|
2
dockermail/mda/rootfs/etc/dovecot/conf.d/10-logging.conf
Normal file
2
dockermail/mda/rootfs/etc/dovecot/conf.d/10-logging.conf
Normal file
@ -0,0 +1,2 @@
|
||||
log_path = /dev/stderr
|
||||
info_log_path = /dev/stdout
|
10
dockermail/mda/rootfs/etc/dovecot/conf.d/10-mail.conf
Normal file
10
dockermail/mda/rootfs/etc/dovecot/conf.d/10-mail.conf
Normal file
@ -0,0 +1,10 @@
|
||||
mail_location = maildir:/var/vmail/%d/%n/Maildir
|
||||
mail_home = /var/vmail/%d/%n
|
||||
mail_uid = vmail
|
||||
mail_gid = vmail
|
||||
mail_privileged_group = vmail
|
||||
mail_plugins = $mail_plugins quota
|
||||
|
||||
namespace inbox {
|
||||
inbox = yes
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
protocols = lmtp submission
|
||||
|
||||
{{ $enable_pop3 := eq (or ($.Env.ENABLE_POP3) "") "true" }}
|
||||
{{ $enable_imap := eq (or ($.Env.ENABLE_IMAP) "") "true" }}
|
||||
|
||||
{{ if $enable_imap }}
|
||||
service imap-login {
|
||||
inet_listener imap {
|
||||
#port = 143
|
||||
}
|
||||
|
||||
inet_listener imaps {
|
||||
#port = 993
|
||||
#ssl = yes
|
||||
}
|
||||
}
|
||||
|
||||
service imap {
|
||||
}
|
||||
|
||||
protocols = $protocols imap
|
||||
{{ end }}
|
||||
|
||||
{{ if $enable_pop3 }}
|
||||
service pop3-login {
|
||||
inet_listener pop3 {
|
||||
#port = 110
|
||||
}
|
||||
|
||||
inet_listener pop3s {
|
||||
#port = 995
|
||||
#ssl = yes
|
||||
}
|
||||
}
|
||||
|
||||
service pop3 {
|
||||
}
|
||||
|
||||
protocols = $protocols pop3
|
||||
{{ end }}
|
||||
|
||||
service submission-login {
|
||||
inet_listener submission {
|
||||
#port = 587
|
||||
}
|
||||
}
|
||||
|
||||
service submission {
|
||||
#process_limit = 1024
|
||||
}
|
||||
|
||||
service lmtp {
|
||||
inet_listener lmtp {
|
||||
port = 2003
|
||||
}
|
||||
}
|
4
dockermail/mda/rootfs/etc/dovecot/conf.d/10-ssl.conf
Normal file
4
dockermail/mda/rootfs/etc/dovecot/conf.d/10-ssl.conf
Normal file
@ -0,0 +1,4 @@
|
||||
ssl = yes
|
||||
ssl_cert = </media/tls/mailserver.crt
|
||||
ssl_key = </media/tls/mailserver.key
|
||||
ssl_dh = </etc/dovecot/dh.pem
|
@ -0,0 +1,5 @@
|
||||
postmaster_address = {{ .Env.POSTMASTER }}
|
||||
hostname = {{ .Env.MAILNAME }}
|
||||
submission_host = {{ .Env.SUBMISSION_HOST }}
|
||||
lda_mailbox_autosubscribe = yes
|
||||
recipient_delimiter = -
|
24
dockermail/mda/rootfs/etc/dovecot/conf.d/15-mailboxes.conf
Normal file
24
dockermail/mda/rootfs/etc/dovecot/conf.d/15-mailboxes.conf
Normal file
@ -0,0 +1,24 @@
|
||||
namespace inbox {
|
||||
mailbox Drafts {
|
||||
auto = subscribe
|
||||
special_use = \Drafts
|
||||
}
|
||||
|
||||
mailbox Junk {
|
||||
auto = subscribe
|
||||
special_use = \Junk
|
||||
}
|
||||
|
||||
mailbox Trash {
|
||||
auto = subscribe
|
||||
special_use = \Trash
|
||||
}
|
||||
|
||||
mailbox Sent {
|
||||
special_use = \Sent
|
||||
}
|
||||
|
||||
mailbox "Sent Messages" {
|
||||
special_use = \Sent
|
||||
}
|
||||
}
|
3
dockermail/mda/rootfs/etc/dovecot/conf.d/20-imap.conf
Normal file
3
dockermail/mda/rootfs/etc/dovecot/conf.d/20-imap.conf
Normal file
@ -0,0 +1,3 @@
|
||||
protocol imap {
|
||||
mail_plugins = $mail_plugins imap_sieve imap_quota
|
||||
}
|
3
dockermail/mda/rootfs/etc/dovecot/conf.d/20-lmtp.conf
Normal file
3
dockermail/mda/rootfs/etc/dovecot/conf.d/20-lmtp.conf
Normal file
@ -0,0 +1,3 @@
|
||||
protocol lmtp {
|
||||
mail_plugins = $mail_plugins sieve
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
protocols = $protocols sieve
|
||||
|
||||
service managesieve-login {
|
||||
inet_listener sieve {
|
||||
port = 4190
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
submission_relay_host = {{ .Env.SUBMISSION_HOST }}
|
||||
submission_relay_port = 25
|
||||
submission_relay_trusted = yes
|
||||
|
||||
protocol submission {
|
||||
}
|
4
dockermail/mda/rootfs/etc/dovecot/conf.d/90-quota.conf
Normal file
4
dockermail/mda/rootfs/etc/dovecot/conf.d/90-quota.conf
Normal file
@ -0,0 +1,4 @@
|
||||
plugin {
|
||||
quota = maildir:User quota
|
||||
quota_exceeded_message = "Benutzer %u hat das Speichervolumen überschritten. / User %u has exhausted allowed storage space."
|
||||
}
|
20
dockermail/mda/rootfs/etc/dovecot/conf.d/90-sieve.conf
Normal file
20
dockermail/mda/rootfs/etc/dovecot/conf.d/90-sieve.conf
Normal file
@ -0,0 +1,20 @@
|
||||
plugin {
|
||||
sieve_plugins = sieve_imapsieve sieve_extprograms
|
||||
sieve_global_extensions = +vnd.dovecot.pipe
|
||||
sieve = file:~/sieve;active=~/.dovecot.sieve
|
||||
sieve_before = /etc/dovecot/sieve/global/spam-to-folder.sieve
|
||||
sieve_pipe_bin_dir = /usr/lib/dovecot/sieve
|
||||
sieve_pipe_exec_timeout = 60s
|
||||
recipient_delimiter = -
|
||||
|
||||
# From somewhere to junk folder
|
||||
imapsieve_mailbox1_name = Junk
|
||||
imapsieve_mailbox1_causes = COPY
|
||||
imapsieve_mailbox1_before = file:/etc/dovecot/sieve/global/learn-spam.sieve
|
||||
|
||||
# From junk folder to elsewhere
|
||||
imapsieve_mailbox2_name = *
|
||||
imapsieve_mailbox2_from = Junk
|
||||
imapsieve_mailbox2_causes = COPY
|
||||
imapsieve_mailbox2_before = file:/etc/dovecot/sieve/global/learn-ham.sieve
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
passdb {
|
||||
driver = sql
|
||||
args = /etc/dovecot/dovecot-sql.conf.ext
|
||||
}
|
||||
|
||||
userdb {
|
||||
driver = sql
|
||||
args = /etc/dovecot/dovecot-sql.conf.ext
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
driver = mysql
|
||||
connect = host={{ .Env.MYSQL_HOST }} dbname={{ .Env.MYSQL_DATABASE }} user={{ .Env.MYSQL_USER }} password={{ .Env.MYSQL_PASSWORD }}
|
||||
default_pass_scheme = SHA256-CRYPT
|
||||
password_query = SELECT mail_users.name AS user, mail_domains.name AS domain, password FROM mail_users JOIN mail_domains ON mail_users.domain_id = mail_domains.id WHERE mail_users.name = '%n' AND mail_domains.name = '%d' AND enabled = 1 AND NOT (send_only = 1 AND "%s" in ('imap', 'pop3'));
|
||||
user_query = SELECT concat('*:storage=', quota, 'M') AS quota_rule FROM mail_users JOIN mail_domains ON mail_users.domain_id = mail_domains.id WHERE mail_users.name = '%n' AND mail_domains.name = '%d';
|
||||
iterate_query = SELECT mail_users.name AS username, mail_domains.name AS domain FROM mail_users JOIN mail_domains ON mail_users.domain_id = mail_domains.id;
|
@ -0,0 +1,2 @@
|
||||
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
|
||||
pipe :copy "rspamc" ["learnham"];
|
@ -0,0 +1,2 @@
|
||||
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
|
||||
pipe :copy "rspamc" ["learnspam"];
|
@ -0,0 +1,6 @@
|
||||
require ["fileinto","mailbox"];
|
||||
|
||||
if header :contains "X-Spam" "YES" {
|
||||
fileinto :create "Junk";
|
||||
stop;
|
||||
}
|
5
dockermail/mda/rootfs/usr/lib/dovecot/sieve/rspamc
Normal file
5
dockermail/mda/rootfs/usr/lib/dovecot/sieve/rspamc
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
ACTION=${1}
|
||||
|
||||
curl -q -s --connect-timeout 60 --data-binary @- http://filter:11334/${ACTION}
|
11
dockermail/mda/rootfs/usr/local/bin/dh.sh
Normal file
11
dockermail/mda/rootfs/usr/local/bin/dh.sh
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
openssl dhparam -out /etc/dovecot/dh.pem.tmp 4096
|
||||
mv /etc/dovecot/dh.pem.tmp /etc/dovecot/dh.pem
|
||||
touch /etc/dovecot/dh.pem.created
|
||||
|
||||
echo "The Diffie Hellman file was generated."
|
||||
echo "YOU SHOULD RESTART THIS CONTAINER NOW."
|
||||
|
||||
exit 0
|
20
dockermail/mda/rootfs/usr/local/bin/entrypoint.sh
Normal file
20
dockermail/mda/rootfs/usr/local/bin/entrypoint.sh
Normal file
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
|
||||
if ! [ -r /etc/dovecot/dh.pem.created ]
|
||||
then
|
||||
echo "Using pre-generated Diffie Hellman parameters until the new one is generated."
|
||||
/usr/local/bin/dh.sh &
|
||||
fi
|
||||
|
||||
rm -f /run/dovecot/master.pid
|
||||
|
||||
dockerize \
|
||||
-template /etc/dovecot/conf.d/10-master.conf.templ:/etc/dovecot/conf.d/10-master.conf \
|
||||
-template /etc/dovecot/conf.d/15-lda.conf.templ:/etc/dovecot/conf.d/15-lda.conf \
|
||||
-template /etc/dovecot/conf.d/20-submission.conf.templ:/etc/dovecot/conf.d/20-submission.conf \
|
||||
-template /etc/dovecot/dovecot-sql.conf.ext.templ:/etc/dovecot/dovecot-sql.conf.ext \
|
||||
-wait tcp://${MYSQL_HOST}:3306 \
|
||||
-wait file://${SSL_CERT} \
|
||||
-wait file://${SSL_KEY} \
|
||||
-timeout ${WAITSTART_TIMEOUT} \
|
||||
/usr/sbin/dovecot -F
|
66
dockermail/mta/Dockerfile
Normal file
66
dockermail/mta/Dockerfile
Normal file
@ -0,0 +1,66 @@
|
||||
ARG DOCKERIZE_VER=0.6.0
|
||||
ARG ALPINE_VER=3.9
|
||||
|
||||
FROM jwilder/dockerize:${DOCKERIZE_VER} AS dockerize
|
||||
FROM alpine:${ALPINE_VER}
|
||||
|
||||
LABEL maintainer="jeff@ressourcenkonflikt.de"
|
||||
LABEL vendor="https://github.com/jeboehm/docker-mailserver"
|
||||
LABEL de.ressourcenkonflikt.docker-mailserver.autoheal="true"
|
||||
|
||||
ENV MAILNAME=mail.example.com \
|
||||
MYNETWORKS=127.0.0.0/8\ 10.0.0.0/8\ 172.16.0.0/12\ 192.168.0.0/16 \
|
||||
MYSQL_HOST=db \
|
||||
MYSQL_USER=root \
|
||||
MYSQL_PASSWORD=changeme \
|
||||
MYSQL_DATABASE=mailserver \
|
||||
FILTER_MIME=false \
|
||||
RSPAMD_HOST=filter \
|
||||
MDA_HOST=mda \
|
||||
MTA_HOST=mta \
|
||||
RELAYHOST=false \
|
||||
SSL_CERT=/media/tls/mailserver.crt \
|
||||
SSL_KEY=/media/tls/mailserver.key \
|
||||
WAITSTART_TIMEOUT=1m
|
||||
|
||||
RUN apk --no-cache add \
|
||||
postfix-mysql \
|
||||
postfix \
|
||||
supervisor && \
|
||||
postconf virtual_mailbox_domains=mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf && \
|
||||
postconf virtual_mailbox_maps=mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf && \
|
||||
postconf virtual_alias_maps=mysql:/etc/postfix/mysql-virtual-alias-maps.cf,mysql:/etc/postfix/mysql-email2email.cf && \
|
||||
postconf smtpd_recipient_restrictions="check_recipient_access mysql:/etc/postfix/mysql-recipient-access.cf" && \
|
||||
postconf smtputf8_enable=no && \
|
||||
postconf smtpd_milters="inet:${RSPAMD_HOST}:11332" && \
|
||||
postconf non_smtpd_milters="inet:${RSPAMD_HOST}:11332" && \
|
||||
postconf milter_protocol=6 && \
|
||||
postconf milter_mail_macros="i {mail_addr} {client_addr} {client_name} {auth_authen}" && \
|
||||
postconf milter_default_action=accept && \
|
||||
postconf virtual_transport="lmtp:${MDA_HOST}:2003" && \
|
||||
postconf smtp_tls_security_level=may && \
|
||||
postconf smtpd_tls_security_level=may && \
|
||||
postconf smtpd_tls_auth_only=yes && \
|
||||
postconf smtpd_tls_cert_file="${SSL_CERT}" && \
|
||||
postconf smtpd_tls_key_file="${SSL_KEY}" && \
|
||||
postconf smtpd_discard_ehlo_keywords="silent-discard, dsn" && \
|
||||
postconf soft_bounce=no && \
|
||||
postconf message_size_limit=52428800 && \
|
||||
postconf mailbox_size_limit=0 && \
|
||||
postconf recipient_delimiter=- && \
|
||||
postconf mynetworks="$MYNETWORKS" && \
|
||||
postconf maximal_queue_lifetime=1h && \
|
||||
postconf bounce_queue_lifetime=1h && \
|
||||
postconf maximal_backoff_time=15m && \
|
||||
postconf minimal_backoff_time=5m && \
|
||||
postconf queue_run_delay=5m && \
|
||||
newaliases
|
||||
|
||||
COPY --from=dockerize /usr/local/bin/dockerize /usr/local/bin
|
||||
COPY rootfs/ /
|
||||
|
||||
EXPOSE 25
|
||||
VOLUME ["/var/spool/postfix"]
|
||||
|
||||
HEALTHCHECK CMD postfix status || exit 1
|
||||
CMD ["/usr/local/bin/entrypoint.sh"]
|
1
dockermail/mta/rootfs/etc/postfix/mime_header_checks
Normal file
1
dockermail/mta/rootfs/etc/postfix/mime_header_checks
Normal file
@ -0,0 +1 @@
|
||||
/name=[^>]*\.(bat|com|exe|dll|vbs|docm|doc|dzip)/ REJECT
|
@ -0,0 +1,5 @@
|
||||
user = {{ .Env.MYSQL_USER }}
|
||||
password = {{ .Env.MYSQL_PASSWORD }}
|
||||
hosts = {{ .Env.MYSQL_HOST }}
|
||||
dbname = {{ .Env.MYSQL_DATABASE }}
|
||||
query = SELECT CONCAT(mail_users.name, '@', mail_domains.name) AS email FROM mail_users JOIN mail_domains ON mail_users.domain_id = mail_domains.id HAVING email='%s'
|
@ -0,0 +1,5 @@
|
||||
user = {{ .Env.MYSQL_USER }}
|
||||
password = {{ .Env.MYSQL_PASSWORD }}
|
||||
hosts = {{ .Env.MYSQL_HOST }}
|
||||
dbname = {{ .Env.MYSQL_DATABASE }}
|
||||
query = SELECT IF(send_only = true, 'REJECT', 'OK') AS access FROM mail_users JOIN mail_domains ON mail_users.domain_id = mail_domains.id WHERE mail_users.name = '%u' AND mail_domains.name = '%d'
|
@ -0,0 +1,5 @@
|
||||
user = {{ .Env.MYSQL_USER }}
|
||||
password = {{ .Env.MYSQL_PASSWORD }}
|
||||
hosts = {{ .Env.MYSQL_HOST }}
|
||||
dbname = {{ .Env.MYSQL_DATABASE }}
|
||||
query = SELECT destination FROM mail_aliases JOIN mail_domains ON mail_aliases.domain_id = mail_domains.id WHERE CONCAT(mail_aliases.name, '@', mail_domains.name) = '%s'
|
@ -0,0 +1,5 @@
|
||||
user = {{ .Env.MYSQL_USER }}
|
||||
password = {{ .Env.MYSQL_PASSWORD }}
|
||||
hosts = {{ .Env.MYSQL_HOST }}
|
||||
dbname = {{ .Env.MYSQL_DATABASE }}
|
||||
query = SELECT 1 FROM mail_domains WHERE name='%s'
|
@ -0,0 +1,5 @@
|
||||
user = {{ .Env.MYSQL_USER }}
|
||||
password = {{ .Env.MYSQL_PASSWORD }}
|
||||
hosts = {{ .Env.MYSQL_HOST }}
|
||||
dbname = {{ .Env.MYSQL_DATABASE }}
|
||||
query = SELECT 1 FROM mail_users JOIN mail_domains ON mail_users.domain_id = mail_domains.id WHERE mail_users.name = '%u' AND mail_domains.name = '%d' AND enabled = 1
|
18
dockermail/mta/rootfs/etc/supervisord.conf
Normal file
18
dockermail/mta/rootfs/etc/supervisord.conf
Normal file
@ -0,0 +1,18 @@
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
logfile=/dev/stderr
|
||||
logfile_maxbytes=0
|
||||
pidfile=/tmp/supervisord.pid
|
||||
user=root
|
||||
|
||||
[program:syslogd]
|
||||
command=/bin/busybox syslogd -n -O - -S
|
||||
redirect_stderr=true
|
||||
stdout_logfile=/dev/stderr
|
||||
stdout_logfile_maxbytes=0
|
||||
|
||||
[program:postfix]
|
||||
command=/usr/libexec/postfix/master -d
|
||||
redirect_stderr=true
|
||||
stdout_logfile=/dev/stderr
|
||||
stdout_logfile_maxbytes=0
|
29
dockermail/mta/rootfs/usr/local/bin/entrypoint.sh
Normal file
29
dockermail/mta/rootfs/usr/local/bin/entrypoint.sh
Normal file
@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
postconf myhostname="${MAILNAME}"
|
||||
postconf mynetworks="${MYNETWORKS}"
|
||||
|
||||
if [ "${FILTER_MIME}" == "true" ]
|
||||
then
|
||||
postconf mime_header_checks=regexp:/etc/postfix/mime_header_checks
|
||||
fi
|
||||
|
||||
if [ "${RELAYHOST}" != "false" ]
|
||||
then
|
||||
postconf relayhost=${RELAYHOST}
|
||||
fi
|
||||
|
||||
dockerize \
|
||||
-template /etc/postfix/mysql-email2email.cf.templ:/etc/postfix/mysql-email2email.cf \
|
||||
-template /etc/postfix/mysql-virtual-alias-maps.cf.templ:/etc/postfix/mysql-virtual-alias-maps.cf \
|
||||
-template /etc/postfix/mysql-virtual-mailbox-domains.cf.templ:/etc/postfix/mysql-virtual-mailbox-domains.cf \
|
||||
-template /etc/postfix/mysql-virtual-mailbox-maps.cf.templ:/etc/postfix/mysql-virtual-mailbox-maps.cf \
|
||||
-template /etc/postfix/mysql-recipient-access.cf.templ:/etc/postfix/mysql-recipient-access.cf \
|
||||
-wait tcp://${MYSQL_HOST}:3306 \
|
||||
-wait tcp://${MDA_HOST}:2003 \
|
||||
-wait tcp://${RSPAMD_HOST}:11332 \
|
||||
-wait file://${SSL_CERT} \
|
||||
-wait file://${SSL_KEY} \
|
||||
-timeout ${WAITSTART_TIMEOUT} \
|
||||
/usr/bin/supervisord
|
@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! command -v swaks &> /dev/null
|
||||
then
|
||||
echo "SWAKS not found."
|
||||
exit
|
||||
fi
|
||||
|
||||
read -p "TO: " to_input
|
||||
read -p "FROM: " from_input
|
||||
read -s -p "PASS: " pass_input
|
||||
printf "\n"
|
||||
read -p "SERVER: " host_input
|
||||
read -p "HEADER: " header_input
|
||||
read -p "BODY: " body_input
|
||||
|
||||
swaks -t "$to_input" -f "$from_input" -s "$host_input" -au "$from_input" -ap "$pass_input" --header "$header_input" --body "$body_input" -tlso
|
@ -1,23 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
mkdir ./mailserver
|
||||
pushd ./mailserver || exit
|
||||
curl -o setup.sh https://raw.githubusercontent.com/tomav/docker-mailserver/master/setup.sh && chmod a+x ./setup.sh
|
||||
curl -o docker-compose.yml https://raw.githubusercontent.com/tomav/docker-mailserver/master/docker-compose.yml.dist
|
||||
curl -o env-mailserver https://raw.githubusercontent.com/tomav/docker-mailserver/master/env-mailserver.dist
|
||||
|
||||
if [ -f .env ]; then
|
||||
rm ./.env
|
||||
fi
|
||||
|
||||
echo "CONTAINER_NAME=mail" >> .env
|
||||
read -r -p "HOSTNAME: "
|
||||
echo "HOSTNAME=$REPLY" >> .env
|
||||
read -r -p "DOMAIN: "
|
||||
echo "DOMAINNAME=$REPLY" >> .env
|
||||
|
||||
printf "\nSetup the first account.\n"
|
||||
read -r -p "Enter Email: " user
|
||||
|
||||
bash ./setup.sh email add "$user"
|
||||
bash ./setup.sh config dkim
|
20
dockermail/ssl/Dockerfile
Normal file
20
dockermail/ssl/Dockerfile
Normal file
@ -0,0 +1,20 @@
|
||||
ARG ALPINE_VER=3.9
|
||||
|
||||
FROM alpine:${ALPINE_VER}
|
||||
|
||||
LABEL maintainer="jeff@ressourcenkonflikt.de"
|
||||
LABEL vendor="https://github.com/jeboehm/docker-mailserver"
|
||||
|
||||
ENV SSL_CERT=/media/tls/mailserver.crt \
|
||||
SSL_KEY=/media/tls/mailserver.key \
|
||||
SSL_CSR=/media/tls/mailserver.csr \
|
||||
SSL_SUBJ_COUNTRY=DE \
|
||||
SSL_SUBJ_STATE=Northrhine-Westfalia \
|
||||
SSL_SUBJ_LOCALITY=Duesseldorf \
|
||||
SSL_SUBJ_ORGANIZATION=Mail \
|
||||
SSL_SUBJ_ORGANIZATIONAL_UNIT=Mail
|
||||
|
||||
RUN apk --no-cache add openssl
|
||||
COPY create_tls.sh /usr/local/bin
|
||||
|
||||
CMD ["/usr/local/bin/create_tls.sh"]
|
17
dockermail/ssl/create_tls.sh
Normal file
17
dockermail/ssl/create_tls.sh
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ -r ${SSL_CERT} ]
|
||||
then
|
||||
echo "SSL certificate found. Exiting..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "No SSL certificate found. Creating a new one..."
|
||||
|
||||
openssl req -nodes -newkey rsa:2048 -keyout ${SSL_KEY} -out ${SSL_CSR} -subj "/C=${SSL_SUBJ_COUNTRY}/ST=${SSL_SUBJ_STATE}/L=${SSL_SUBJ_LOCALITY}/O=${SSL_SUBJ_ORGANIZATION}/OU=${SSL_SUBJ_ORGANIZATIONAL_UNIT}/CN=${MAILNAME}"
|
||||
openssl x509 -req -days 3000 -in ${SSL_CSR} -signkey ${SSL_KEY} -out ${SSL_CERT}
|
||||
|
||||
echo "SSL certificate was successfully created! Exiting..."
|
||||
|
||||
exit 0
|
46
dockermail/test/Dockerfile
Normal file
46
dockermail/test/Dockerfile
Normal file
@ -0,0 +1,46 @@
|
||||
ARG DOCKERIZE_VER=0.6.0
|
||||
ARG ALPINE_VER=3.9
|
||||
|
||||
FROM jwilder/dockerize:${DOCKERIZE_VER} AS dockerize
|
||||
FROM alpine:${ALPINE_VER}
|
||||
|
||||
LABEL maintainer="jeff@ressourcenkonflikt.de"
|
||||
LABEL vendor="https://github.com/jeboehm/docker-mailserver"
|
||||
|
||||
ENV MYSQL_HOST=db \
|
||||
MYSQL_USER=root \
|
||||
MYSQL_PASSWORD=changeme \
|
||||
MYSQL_DATABASE=mailserver \
|
||||
WAITSTART_TIMEOUT=1m
|
||||
|
||||
# Iconv fix: https://github.com/docker-library/php/issues/240#issuecomment-305038173
|
||||
RUN apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/community/ gnu-libiconv
|
||||
ENV LD_PRELOAD=/usr/lib/preloadable_libiconv.so
|
||||
|
||||
RUN apk --no-cache add \
|
||||
bash \
|
||||
bats \
|
||||
curl \
|
||||
docker \
|
||||
jq \
|
||||
mariadb-client \
|
||||
openssl \
|
||||
perl \
|
||||
perl-net-ssleay \
|
||||
php7 \
|
||||
php7-imap \
|
||||
php7-phar \
|
||||
php7-iconv \
|
||||
php7-openssl \
|
||||
&& wget -q -O /usr/local/bin/swaks https://www.jetmore.org/john/code/swaks/files/swaks-20130209.0/swaks \
|
||||
&& chmod +x /usr/local/bin/swaks \
|
||||
&& wget -q -O /usr/local/bin/imap-tester https://github.com/jeboehm/imap-tester/releases/download/v0.2.1/imap-tester.phar \
|
||||
&& chmod +x /usr/local/bin/imap-tester \
|
||||
&& mkdir -p /usr/share/fixtures \
|
||||
&& wget -q -O /usr/share/fixtures/gtube.txt https://spamassassin.apache.org/gtube/gtube.txt \
|
||||
&& wget -q -O /usr/share/fixtures/eicar.com https://secure.eicar.org/eicar.com
|
||||
|
||||
COPY --from=dockerize /usr/local/bin/dockerize /usr/local/bin
|
||||
COPY rootfs/ /
|
||||
|
||||
CMD ["/usr/local/bin/run-tests.sh"]
|
10
dockermail/test/rootfs/usr/local/bin/run-tests.sh
Normal file
10
dockermail/test/rootfs/usr/local/bin/run-tests.sh
Normal file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
dockerize \
|
||||
-wait tcp://db:3306 \
|
||||
-wait tcp://mta:25 \
|
||||
-wait tcp://web:80 \
|
||||
-wait tcp://mda:143 \
|
||||
-wait tcp://filter:11334 \
|
||||
-timeout ${WAITSTART_TIMEOUT} \
|
||||
bats /usr/share/tests/*.bats
|
30
dockermail/test/rootfs/usr/share/tests/001_tls.bats
Normal file
30
dockermail/test/rootfs/usr/share/tests/001_tls.bats
Normal file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "certificates were created" {
|
||||
[ -f /media/tls/mailserver.crt ]
|
||||
}
|
||||
|
||||
@test "connection to imaps" {
|
||||
true | openssl s_client -showcerts -connect mda:993
|
||||
[ "$?" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "connection to pop3s" {
|
||||
true | openssl s_client -showcerts -connect mda:995
|
||||
[ "$?" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "connection to pop3 with starttls" {
|
||||
true | openssl s_client -showcerts -connect mda:110 -starttls pop3
|
||||
[ "$?" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "connection to imap with starttls" {
|
||||
true | openssl s_client -showcerts -connect mda:143 -starttls imap
|
||||
[ "$?" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "connection to smtp with starttls" {
|
||||
true | openssl s_client -showcerts -connect mta:25 -starttls smtp
|
||||
[ "$?" -eq 0 ]
|
||||
}
|
16
dockermail/test/rootfs/usr/share/tests/002_database.bats
Normal file
16
dockermail/test/rootfs/usr/share/tests/002_database.bats
Normal file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "user table exists" {
|
||||
run mysql --batch -u "${MYSQL_USER}" --password="${MYSQL_PASSWORD}" -h "${MYSQL_HOST}" "${MYSQL_DATABASE}" -e "select * from mail_users;"
|
||||
[ "$status" = 0 ]
|
||||
}
|
||||
|
||||
@test "alias table exists" {
|
||||
run mysql --batch -u "${MYSQL_USER}" --password="${MYSQL_PASSWORD}" -h "${MYSQL_HOST}" "${MYSQL_DATABASE}" -e "select * from mail_aliases;"
|
||||
[ "$status" = 0 ]
|
||||
}
|
||||
|
||||
@test "domain table exists" {
|
||||
run mysql --batch -u "${MYSQL_USER}" --password="${MYSQL_PASSWORD}" -h "${MYSQL_HOST}" "${MYSQL_DATABASE}" -e "select * from mail_domains;"
|
||||
[ "$status" = 0 ]
|
||||
}
|
131
dockermail/test/rootfs/usr/share/tests/003_mta.bats
Normal file
131
dockermail/test/rootfs/usr/share/tests/003_mta.bats
Normal file
@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "send mail to local account address" {
|
||||
run swaks -s mta --to admin@example.com --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "send mail to local address with extension" {
|
||||
run swaks -s mta --to admin-test@example.com --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "authentification on smtp with disabled account should fail" {
|
||||
run swaks -s mta --to admin@example.com --from disabled@example.com -a -au disabled@example.com -ap test1234 -tls --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 28 ]
|
||||
}
|
||||
|
||||
@test "authentification on smtp with disabled and send only account should fail" {
|
||||
run swaks -s mta --to admin@example.com --from disabledsendonly@example.com -a -au disabled@example.com -ap test1234 -tls --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 28 ]
|
||||
}
|
||||
|
||||
@test "send mail to mda with smtp authentification (submission service)" {
|
||||
run swaks -s mda --port 587 --to admin@example.com --from admin@example.com -a -au admin@example.com -ap changeme -tls --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "send mail to mda with smtp authentification, with address extension (submission service)" {
|
||||
run swaks -s mda --port 587 --to admin@example.com --from admin-extension@example.com -a -au admin@example.com -ap changeme -tls --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "send mail to mda from sendonly account with smtp authentification (submission service)" {
|
||||
run swaks -s mda --port 587 --to admin@example.com --from sendonly@example.com -a -au sendonly@example.com -ap test1234 -tls --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "send mail to local alias" {
|
||||
run swaks -s mta --to foo@example.com --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "send junk mail to local address" {
|
||||
run swaks -s mta --to admin@example.com --body "$BATS_TEST_DESCRIPTION" --header "X-Spam: Yes"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "send mail with too big attachment to quota user" {
|
||||
dd if=/dev/urandom of=/tmp/bigfile bs=1M count=5
|
||||
run swaks -s mta --to quota@example.com --body "$BATS_TEST_DESCRIPTION" --attach /tmp/bigfile
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "send mail to disabled user" {
|
||||
run swaks -s mta --to disabled@example.com --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "maildir was created" {
|
||||
sleep 10 # MTA + MDA need some time. :)
|
||||
[ -d /var/vmail/example.com/admin/Maildir/new/ ]
|
||||
}
|
||||
|
||||
@test "mail to local account address is stored" {
|
||||
run grep -r "send mail to local account address" /var/vmail/example.com/admin/Maildir/
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "mail to local alias is stored" {
|
||||
run grep -r "send mail to local alias" /var/vmail/example.com/admin/Maildir/
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "mail to local address with extension is stored" {
|
||||
run grep -r "send mail to local address with extension" /var/vmail/example.com/admin/Maildir/
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "mail to mda with smtp authentification (submission service) is stored" {
|
||||
run grep -r "send mail to mda with smtp authentification (submission service)" /var/vmail/example.com/admin/Maildir/
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "send mail to mda with smtp authentification, with address extension (submission service) is stored" {
|
||||
run grep -r "send mail to mda with smtp authentification, with address extension (submission service)" /var/vmail/example.com/admin/Maildir/
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "send mail to mda from sendonly account with smtp authentification (submission service) is stored" {
|
||||
run grep -r "send mail to mda from sendonly account with smtp authentification (submission service)" /var/vmail/example.com/admin/Maildir/
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "junk mail is assorted to the junk folder" {
|
||||
run grep -r "send junk mail to local address" /var/vmail/example.com/admin/Maildir/.Junk/
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "mail with too big attachment is not found" {
|
||||
run grep -r "send mail with too big attachment to quota user" /var/vmail/example.com/quota/Maildir/
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "mail to disabled user is stored anyway" {
|
||||
run grep -r "send mail to disabled user" /var/vmail/example.com/disabled/Maildir/
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "send gtube mail is rejected" {
|
||||
run swaks -s mta --to admin@example.com --data /usr/share/fixtures/gtube.txt
|
||||
[ "$status" -eq 26 ]
|
||||
}
|
||||
|
||||
@test "mail to send only mailbox is rejected" {
|
||||
run swaks -s mta --to sendonly@example.com --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 24 ]
|
||||
}
|
||||
|
||||
@test "mail to disabled and send only mailbox is rejected anyway" {
|
||||
run swaks -s mta --to disabledsendonly@example.com --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 24 ]
|
||||
}
|
||||
|
||||
@test "virus is rejected" {
|
||||
if [ ${FILTER_VIRUS} = "false" ]; then
|
||||
skip
|
||||
fi
|
||||
|
||||
run swaks -s mta --to admin@example.com --attach - < /usr/share/fixtures/eicar.com
|
||||
[ "$status" -eq 26 ]
|
||||
}
|
16
dockermail/test/rootfs/usr/share/tests/004_web.bats
Normal file
16
dockermail/test/rootfs/usr/share/tests/004_web.bats
Normal file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "http connection to manager web interface" {
|
||||
curl -L http://web/manager/ | grep "Email address"
|
||||
[ "$?" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "http connection to webmail interface" {
|
||||
curl http://web/webmail/ | grep "jeboehm"
|
||||
[ "$?" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "http connection to rspamd interface" {
|
||||
curl http://web/rspamd/ | grep "Rspamd Web Interface"
|
||||
[ "$?" -eq 0 ]
|
||||
}
|
72
dockermail/test/rootfs/usr/share/tests/005_mda.bats
Normal file
72
dockermail/test/rootfs/usr/share/tests/005_mda.bats
Normal file
@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "send mail to mda from disabled account with smtp authentification (submission service)" {
|
||||
run swaks -s mda --port 587 --to admin@example.com --from disabled@example.com -a -au disabled@example.com -ap test1234 -tls --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 28 ]
|
||||
}
|
||||
|
||||
@test "send mail to mda without authentification (submission service)" {
|
||||
run swaks -s mda --port 587 --to admin@example.com --from disabled@example.com -tls --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 23 ]
|
||||
}
|
||||
|
||||
@test "send mail to mda without tls (submission service)" {
|
||||
run swaks -s mda --port 587 --to admin@example.com --from admin@example.com -a -au admin@example.com -ap changeme --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 28 ]
|
||||
}
|
||||
|
||||
@test "count mails in inbox via imap" {
|
||||
run imap-tester test:count mda 143 admin@example.com changeme INBOX
|
||||
[ "$output" -gt 3 ]
|
||||
}
|
||||
|
||||
@test "count mails in inbox via imaps" {
|
||||
run imap-tester test:count mda 993 admin@example.com changeme INBOX
|
||||
[ "$output" -gt 3 ]
|
||||
}
|
||||
|
||||
@test "count mails in inbox via pop3" {
|
||||
run imap-tester test:count mda 110 admin@example.com changeme INBOX
|
||||
[ "$output" -gt 3 ]
|
||||
}
|
||||
|
||||
@test "count mails in inbox via pop3s" {
|
||||
run imap-tester test:count mda 995 admin@example.com changeme INBOX
|
||||
[ "$output" -gt 3 ]
|
||||
}
|
||||
|
||||
@test "imap login to send only mailbox is not possible" {
|
||||
run imap-tester test:count mda 143 sendonly@example.com test1234 INBOX
|
||||
[ "$status" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "pop3 login to send only mailbox is not possible" {
|
||||
run imap-tester test:count mda 110 sendonly@example.com test1234 INBOX
|
||||
[ "$status" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "pop3 login to quota mailbox is possible" {
|
||||
run imap-tester test:count mda 110 quota@example.com test1234 INBOX
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "imap login to quota mailbox is possible" {
|
||||
run imap-tester test:count mda 143 quota@example.com test1234 INBOX
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "pop3 login to disabled mailbox is not possible" {
|
||||
run imap-tester test:count mda 110 disabled@example.com test1234 INBOX
|
||||
[ "$status" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "imap login to disabled mailbox is not possible" {
|
||||
run imap-tester test:count mda 143 disabled@example.com test1234 INBOX
|
||||
[ "$status" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "mails are owned by vmail" {
|
||||
run find /var/vmail/example.com/ -not -user 5000
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$output" = "" ]
|
||||
}
|
18
dockermail/test/rootfs/usr/share/tests/006_docker.bats
Normal file
18
dockermail/test/rootfs/usr/share/tests/006_docker.bats
Normal file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "no unhealthy containers exist" {
|
||||
run docker ps -q --filter health=unhealthy
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$output" = "" ]
|
||||
}
|
||||
|
||||
@test "Virus container is not running when filtering is disabled" {
|
||||
if [ ${FILTER_VIRUS} = "true" ]; then
|
||||
echo '# Filtering is disabled, skipping test' >&3
|
||||
skip
|
||||
fi
|
||||
|
||||
run docker ps -q --filter name=docker-mailserver_virus_1
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$output" = "" ]
|
||||
}
|
34
dockermail/test/rootfs/usr/share/tests/007_relayhost.bats
Normal file
34
dockermail/test/rootfs/usr/share/tests/007_relayhost.bats
Normal file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "check mailhog api for messages" {
|
||||
if [ ${RELAYHOST} = "false" ]; then
|
||||
echo '# Relayhost is disabled, skipping test' >&3
|
||||
skip
|
||||
fi
|
||||
|
||||
run curl "http://mailhog:8025/api/v2/messages"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "send mail to mda with smtp authentification, external recipient" {
|
||||
if [ ${RELAYHOST} = "false" ]; then
|
||||
echo '# Relayhost is disabled, skipping test' >&3
|
||||
skip
|
||||
fi
|
||||
|
||||
run swaks -s mda --port 587 --to nobody@ressourcenkonflikt.de --from admin@example.com -a -au admin@example.com -ap changeme -tls --body "$BATS_TEST_DESCRIPTION"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "check mailhog api for outgoing message" {
|
||||
if [ ${RELAYHOST} = "false" ]; then
|
||||
echo '# Relayhost is disabled, skipping test' >&3
|
||||
skip
|
||||
fi
|
||||
|
||||
sleep 5 # Give mailhog some time
|
||||
|
||||
RESULT=$(curl -s "http://mailhog:8025/api/v2/messages" | jq -cr .items[0].Content.Body | tr -d '[:space:]')
|
||||
|
||||
[ "$RESULT" = "sendmailtomdawithsmtpauthentification,externalrecipient" ]
|
||||
}
|
9
dockermail/test/rootfs/usr/share/tests/008_dkim.bats
Normal file
9
dockermail/test/rootfs/usr/share/tests/008_dkim.bats
Normal file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "check DKIM selector map exists" {
|
||||
[ -r /media/dkim/dkim_selectors.map ]
|
||||
}
|
||||
|
||||
@test "check DKIM key for example.com exists" {
|
||||
[ -r /media/dkim/example.com.1337.key ]
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#|/bin/bash
|
||||
|
||||
pushd ./mailserver || exit
|
||||
docker-compose down
|
||||
docker pull tvial/docker-mailserver:latest
|
||||
docker-compose up -d mail
|
26
dockermail/virus/Dockerfile
Normal file
26
dockermail/virus/Dockerfile
Normal file
@ -0,0 +1,26 @@
|
||||
ARG ALPINE_VER=3.11
|
||||
|
||||
FROM alpine:${ALPINE_VER}
|
||||
|
||||
LABEL maintainer="jeff@ressourcenkonflikt.de"
|
||||
LABEL vendor="https://github.com/jeboehm/docker-mailserver"
|
||||
LABEL de.ressourcenkonflikt.docker-mailserver.autoheal="true"
|
||||
|
||||
ENV FILTER_VIRUS=true
|
||||
|
||||
RUN apk --no-cache add \
|
||||
clamav-daemon \
|
||||
clamav-libunrar && \
|
||||
rm -rf /var/log/clamav
|
||||
|
||||
COPY rootfs/ /
|
||||
|
||||
EXPOSE 3310
|
||||
USER clamav
|
||||
|
||||
RUN /usr/bin/freshclam -l /dev/null
|
||||
|
||||
VOLUME ["/var/lib/clamav"]
|
||||
|
||||
HEALTHCHECK CMD echo PING | nc 127.0.0.1 3310 | grep PONG
|
||||
CMD ["/usr/local/bin/entrypoint.sh"]
|
35
dockermail/virus/contrib/unofficial-sigs/Dockerfile
Normal file
35
dockermail/virus/contrib/unofficial-sigs/Dockerfile
Normal file
@ -0,0 +1,35 @@
|
||||
ARG ALPINE_VER=3.9
|
||||
|
||||
FROM alpine:${ALPINE_VER}
|
||||
|
||||
LABEL maintainer="jeff@ressourcenkonflikt.de"
|
||||
LABEL vendor="https://github.com/jeboehm/docker-mailserver"
|
||||
|
||||
# hadolint ignore=DL3003
|
||||
RUN apk --no-cache add \
|
||||
bash \
|
||||
bind-tools \
|
||||
clamav-scanner \
|
||||
gnupg \
|
||||
ncurses \
|
||||
rsync \
|
||||
wget && \
|
||||
wget -q -O /tmp/master.tar.gz https://github.com/extremeshok/clamav-unofficial-sigs/archive/master.tar.gz && \
|
||||
cd /tmp && \
|
||||
tar -xvf master.tar.gz && \
|
||||
cd clamav-unofficial-sigs-master && \
|
||||
cp clamav-unofficial-sigs.sh /usr/local/bin/ && \
|
||||
chmod +x /usr/local/bin/clamav-unofficial-sigs.sh && \
|
||||
cp -r config /etc/clamav-unofficial-sigs && \
|
||||
mkdir /var/lib/clamav-unofficial-sigs && \
|
||||
chown clamav /var/lib/clamav-unofficial-sigs && \
|
||||
cp /etc/clamav-unofficial-sigs/os/os.ubuntu.conf /etc/clamav-unofficial-sigs/os.conf && \
|
||||
echo "user_configuration_complete=\"yes\"" >> /etc/clamav-unofficial-sigs/user.conf && \
|
||||
echo "logging_enabled=\"no\"" >> /etc/clamav-unofficial-sigs/user.conf && \
|
||||
echo "enable_random=\"no\"" >> /etc/clamav-unofficial-sigs/user.conf && \
|
||||
echo "reload_dbs=\"no\"" >> /etc/clamav-unofficial-sigs/user.conf && \
|
||||
rm -rf /tmp/* /var/log/* /etc/clamav-unofficial-sigs/os/
|
||||
|
||||
USER clamav
|
||||
|
||||
CMD ["/usr/local/bin/clamav-unofficial-sigs.sh"]
|
2
dockermail/virus/rootfs/etc/clamav/clamd.conf
Normal file
2
dockermail/virus/rootfs/etc/clamav/clamd.conf
Normal file
@ -0,0 +1,2 @@
|
||||
TCPSocket 3310
|
||||
Foreground true
|
4
dockermail/virus/rootfs/etc/clamav/freshclam.conf
Normal file
4
dockermail/virus/rootfs/etc/clamav/freshclam.conf
Normal file
@ -0,0 +1,4 @@
|
||||
DatabaseOwner clamav
|
||||
DatabaseMirror database.clamav.net
|
||||
ScriptedUpdates yes
|
||||
NotifyClamd /etc/clamav/clamd.conf
|
10
dockermail/virus/rootfs/usr/local/bin/entrypoint.sh
Normal file
10
dockermail/virus/rootfs/usr/local/bin/entrypoint.sh
Normal file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "${FILTER_VIRUS}" = "false" ]
|
||||
then
|
||||
echo "Virus filtering is disabled, exiting."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
/usr/bin/freshclam -d -l /dev/stdout &
|
||||
/usr/sbin/clamd
|
50
dockermail/web/Dockerfile
Normal file
50
dockermail/web/Dockerfile
Normal file
@ -0,0 +1,50 @@
|
||||
ARG ROUNDCUBE_VER=1.4.x-fpm
|
||||
ARG PHP_VER=7.4
|
||||
ARG DOCKERIZE_VER=0.6.0
|
||||
|
||||
FROM jwilder/dockerize:${DOCKERIZE_VER} AS dockerize
|
||||
|
||||
FROM roundcube/roundcubemail:${ROUNDCUBE_VER} AS roundcube
|
||||
|
||||
FROM jeboehm/php-nginx-base:${PHP_VER}
|
||||
|
||||
ARG ADMIN_VER=1.6.1
|
||||
|
||||
LABEL maintainer="jeff@ressourcenkonflikt.de"
|
||||
LABEL vendor="https://github.com/jeboehm/docker-mailserver"
|
||||
LABEL de.ressourcenkonflikt.docker-mailserver.autoheal="true"
|
||||
|
||||
ENV MYSQL_HOST=db \
|
||||
MYSQL_DATABASE=mailserver \
|
||||
MYSQL_USER=mailserver \
|
||||
MYSQL_PASSWORD=changeme \
|
||||
MTA_HOST=mta \
|
||||
MDA_HOST=mda \
|
||||
FILTER_HOST=filter \
|
||||
SUPPORT_URL=https://github.com/jeboehm/docker-mailserver \
|
||||
APP_ENV=prod \
|
||||
TRUSTED_PROXIES=172.16.0.0/12 \
|
||||
WAITSTART_TIMEOUT=1m \
|
||||
ADMIN_VER=${ADMIN_VER}
|
||||
|
||||
COPY --from=roundcube /usr/src/roundcubemail/ /var/www/html/webmail/
|
||||
COPY --from=dockerize /usr/local/bin/dockerize /usr/local/bin
|
||||
COPY rootfs/ /
|
||||
|
||||
WORKDIR /opt/manager
|
||||
|
||||
RUN wget -O /tmp/admin.tar.gz -q https://github.com/jeboehm/mailserver-admin/archive/${ADMIN_VER}.tar.gz && \
|
||||
tar -xf /tmp/admin.tar.gz -C /opt/manager --strip=1 && \
|
||||
rm /tmp/admin.tar.gz && \
|
||||
composer install --no-dev -o
|
||||
|
||||
RUN ln -s /opt/manager/public /var/www/html/manager && \
|
||||
chown -R www-data \
|
||||
/opt/manager/var/cache/ \
|
||||
/opt/manager/var/log/ \
|
||||
/var/www/html/webmail/temp/ \
|
||||
/var/www/html/webmail/logs/
|
||||
|
||||
WORKDIR /var/www/html
|
||||
HEALTHCHECK CMD curl -s http://127.0.0.1/login | grep docker-mailserver
|
||||
CMD ["/usr/local/bin/entrypoint.sh"]
|
6
dockermail/web/README.md
Normal file
6
dockermail/web/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# mailserver-web
|
||||
|
||||
This image contains
|
||||
|
||||
[roundcube](https://roundcube.net)
|
||||
and [mailserver-admin](https://github.com/jeboehm/mailserver-admin).
|
68
dockermail/web/rootfs/etc/nginx/sites-enabled/10-docker.conf
Normal file
68
dockermail/web/rootfs/etc/nginx/sites-enabled/10-docker.conf
Normal file
@ -0,0 +1,68 @@
|
||||
server {
|
||||
listen 80;
|
||||
absolute_redirect off;
|
||||
|
||||
root /var/www/html/manager;
|
||||
|
||||
location = /favicon.ico {
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
location /manager {
|
||||
return 301 /;
|
||||
}
|
||||
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
location ~ \.(tpl|yml|ini|log)$ {
|
||||
deny all;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri /index.php$is_args$args;
|
||||
}
|
||||
|
||||
location /webmail {
|
||||
alias /var/www/html/webmail;
|
||||
index index.php;
|
||||
try_files $uri $uri/ @webmail;
|
||||
|
||||
location ~ \.php$ {
|
||||
include fastcgi_params;
|
||||
# Mitigate httpoxy vulnerability, see: https://httpoxy.org/
|
||||
fastcgi_param HTTP_PROXY "";
|
||||
|
||||
fastcgi_buffers 8 16k;
|
||||
fastcgi_buffer_size 32k;
|
||||
|
||||
client_max_body_size 24M;
|
||||
client_body_buffer_size 128k;
|
||||
fastcgi_param SCRIPT_FILENAME $request_filename;
|
||||
fastcgi_pass php-fpm;
|
||||
}
|
||||
}
|
||||
|
||||
location @webmail {
|
||||
rewrite /webmail/(.*)$ /webmail/index.php?/$1 last;
|
||||
}
|
||||
|
||||
location ~ ^/index\.php(/|$) {
|
||||
fastcgi_pass php-fpm;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.*)$;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
fastcgi_param DOCUMENT_ROOT $realpath_root;
|
||||
internal;
|
||||
}
|
||||
|
||||
location /rspamd/ {
|
||||
proxy_pass http://filter:11334/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
42
dockermail/web/rootfs/usr/local/bin/entrypoint.sh
Normal file
42
dockermail/web/rootfs/usr/local/bin/entrypoint.sh
Normal file
@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
manager_init() {
|
||||
cd /opt/manager
|
||||
|
||||
bin/console doctrine:migrations:migrate -n
|
||||
bin/console doctrine:schema:update --force
|
||||
}
|
||||
|
||||
roundcube_init() {
|
||||
cd /var/www/html/webmail
|
||||
PWD=`pwd`
|
||||
|
||||
bin/initdb.sh --dir=$PWD/SQL || bin/updatedb.sh --dir=$PWD/SQL --package=roundcube || echo "Failed to initialize databse. Please run $PWD/bin/initdb.sh manually."
|
||||
}
|
||||
|
||||
permissions() {
|
||||
chown -R www-data /media/dkim
|
||||
chmod 777 /media/dkim
|
||||
}
|
||||
|
||||
dkim_refresh() {
|
||||
cd /opt/manager
|
||||
|
||||
bin/console dkim:refresh
|
||||
}
|
||||
|
||||
dockerize \
|
||||
-wait tcp://${MYSQL_HOST}:3306 \
|
||||
-wait tcp://${MDA_HOST}:143 \
|
||||
-wait tcp://${MTA_HOST}:25 \
|
||||
-wait tcp://${FILTER_HOST}:11334 \
|
||||
-wait file:///media/dkim/ \
|
||||
-timeout ${WAITSTART_TIMEOUT}
|
||||
|
||||
manager_init
|
||||
roundcube_init
|
||||
permissions
|
||||
dkim_refresh
|
||||
|
||||
/usr/bin/supervisord
|
7
dockermail/web/rootfs/usr/local/bin/fixtures.sh
Normal file
7
dockermail/web/rootfs/usr/local/bin/fixtures.sh
Normal file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
dockerize \
|
||||
-wait tcp://web:80 \
|
||||
-wait tcp://${MYSQL_HOST}:3306 \
|
||||
-timeout ${WAITSTART_TIMEOUT} \
|
||||
${@}
|
4
dockermail/web/rootfs/usr/local/bin/setup.sh
Normal file
4
dockermail/web/rootfs/usr/local/bin/setup.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
/usr/local/bin/fixtures.sh \
|
||||
/opt/manager/bin/console init:setup
|
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
$config = [];
|
||||
$config['smtp_log'] = false;
|
||||
$config['log_dir'] = '/tmp/';
|
||||
$config['temp_dir'] = '/tmp/';
|
||||
$config['imap_cache'] = 'apc';
|
||||
$config['db_dsnw'] = sprintf(
|
||||
'mysql://%s:%s@%s/%s',
|
||||
getenv('MYSQL_USER'),
|
||||
getenv('MYSQL_PASSWORD'),
|
||||
getenv('MYSQL_HOST'),
|
||||
getenv('MYSQL_DATABASE')
|
||||
);
|
||||
$config['default_host'] = 'tls://' . getenv('MDA_HOST');
|
||||
$config['smtp_server'] = 'tls://' . getenv('MDA_HOST');
|
||||
$config['smtp_port'] = 587;
|
||||
$config['smtp_user'] = '%u';
|
||||
$config['smtp_pass'] = '%p';
|
||||
$config['support_url'] = getenv('SUPPORT_URL');
|
||||
$config['plugins'] = [
|
||||
'archive',
|
||||
'zipdownload',
|
||||
'managesieve',
|
||||
'password',
|
||||
];
|
||||
$config['imap_conn_options'] = [
|
||||
'ssl' => [
|
||||
'verify_peer' => false,
|
||||
'verify_peer_name' => false,
|
||||
'allow_self_signed' => false,
|
||||
],
|
||||
];
|
||||
$config['smtp_conn_options'] = [
|
||||
'ssl' => [
|
||||
'verify_peer' => false,
|
||||
'verify_peer_name' => false,
|
||||
'allow_self_signed' => false,
|
||||
],
|
||||
];
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
$config['managesieve_port'] = 4190;
|
||||
$config['managesieve_host'] = '%h';
|
||||
$config['managesieve_auth_type'] = 'PLAIN';
|
||||
$config['managesieve_auth_cid'] = null;
|
||||
$config['managesieve_auth_pw'] = null;
|
||||
$config['managesieve_usetls'] = true;
|
||||
$config['managesieve_conn_options'] = [
|
||||
'ssl' => [
|
||||
'verify_peer' => false,
|
||||
'verify_peer_name' => false,
|
||||
'allow_self_signed' => false,
|
||||
],
|
||||
];
|
||||
$config['managesieve_default'] = '/etc/dovecot/sieve/global';
|
||||
$config['managesieve_script_name'] = 'managesieve';
|
||||
$config['managesieve_mbox_encoding'] = 'UTF-8';
|
||||
$config['managesieve_replace_delimiter'] = '';
|
||||
$config['managesieve_disabled_extensions'] = [];
|
||||
$config['managesieve_debug'] = false;
|
||||
$config['managesieve_kolab_master'] = false;
|
||||
$config['managesieve_filename_extension'] = '.sieve';
|
||||
$config['managesieve_filename_exceptions'] = [];
|
||||
$config['managesieve_domains'] = [];
|
||||
$config['managesieve_vacation'] = 0;
|
||||
$config['managesieve_vacation_interval'] = 0;
|
||||
$config['managesieve_vacation_addresses_init'] = false;
|
||||
$config['managesieve_notify_methods'] = ['mailto'];
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
$config['password_driver'] = 'sql';
|
||||
$config['password_confirm_current'] = true;
|
||||
$config['password_minimum_length'] = 6;
|
||||
$config['password_require_nonalpha'] = false;
|
||||
$config['password_log'] = false;
|
||||
$config['password_login_exceptions'] = null;
|
||||
$config['password_hosts'] = null;
|
||||
$config['password_force_save'] = true;
|
||||
$config['password_force_new_user'] = false;
|
||||
$config['password_algorithm'] = 'clear';
|
||||
$config['password_algorithm_prefix'] = '';
|
||||
$config['password_blowfish_cost'] = 12;
|
||||
$config['password_disabled'] = false;
|
||||
$config['password_db_dsn'] = sprintf(
|
||||
'mysql://%s:%s@%s/%s',
|
||||
getenv('MYSQL_USER'),
|
||||
getenv('MYSQL_PASSWORD'),
|
||||
getenv('MYSQL_HOST'),
|
||||
getenv('MYSQL_DATABASE')
|
||||
);
|
||||
$config['password_query'] = "UPDATE mail_users JOIN mail_domains ON mail_users.domain_id = mail_domains.id SET password=CONCAT('{SHA256-CRYPT}', ENCRYPT (%p, CONCAT('$5$', SUBSTRING(SHA(RAND()), -16)))) WHERE CONCAT(mail_users.name, '@', mail_domains.name)=%u;";
|
||||
$config['password_crypt_hash'] = 'md5';
|
||||
$config['password_idn_ascii'] = false;
|
||||
$config['password_dovecotpw_with_method'] = false;
|
||||
$config['password_hash_algorithm'] = 'sha1';
|
||||
$config['password_hash_base64'] = false;
|
Loading…
Reference in New Issue
Block a user