├── .gitignore ├── README.md ├── autoconfig ├── autoconfig.php ├── autodiscover.php ├── install.sh └── nginx_config ├── dovecot ├── 10-master.conf └── install.sh ├── event ├── after-install.sh └── before-install.sh ├── install.sh ├── mysql └── install.sh ├── postfix └── install.sh ├── roundcube ├── config ├── install.sh ├── nginx_config └── password_plugin_config ├── spamassassin └── install.sh └── tests.sh /.gitignore: -------------------------------------------------------------------------------- 1 | /.* 2 | !.gitignore -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EasyMail - easy way for installing mail server 2 | This script install: 3 | - Dovecot 4 | - Postfix 5 | - Roundcube 6 | - SpamAssassin 7 | - Nginx 8 | - MySQL 9 | 10 | ## Configuration 11 | - Dedicated machine or Virtual private server (VPS) and parametres not lower than: 12 | - RAM 512 MB 13 | - HDD/SSD 10 GB. 14 | - Fresh installed Debian or Ubuntu server with 14.04 or newer. 15 | 16 | ## (optional) Using with Docker container 17 | Example configuration for Docker usage: 18 | ``` 19 | docker run -it -p=110:110 -p=25:25 -p=995:995 -p=80:80 -p=443:443 -p=587:587 -p=993:993 -p=143:143 -h "your-hostname.here" --name="easymail" ubuntu:14.04 /bin/sh -c "if [ -f /run.sh ]; then bash /run.sh; fi; exec /bin/bash" 20 | ``` 21 | 22 | ## Instalation 23 | To run installation we have to: 24 | - Update the package lists from the repositories ```apt-get update``` 25 | - Install git if we don't have it ```apt-get install git -y ``` 26 | - Clone the "easymail" repository ```git clone https://github.com/mailjet/easymail.git /easymail``` 27 | - Run bash script ```bash /easymail/install.sh``` 28 | 29 | or just run: 30 | ``` 31 | apt-get update && apt-get install git -y && git clone https://github.com/mailjet/easymail.git /easymail && bash /easymail/install.sh 32 | ``` 33 | -------------------------------------------------------------------------------- /autoconfig/autoconfig.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | {$domain} 14 | {$mail} 15 | {$mail} 16 | 17 | {$host} 18 | 143 19 | STARTTLS 20 | {$mail} 21 | password-cleartext 22 | 23 | 24 | {$host} 25 | 587 26 | STARTTLS 27 | password-cleartext 28 | {$mail} 29 | 30 | 31 | 32 | EOP; 33 | 34 | 35 | -------------------------------------------------------------------------------- /autoconfig/autodiscover.php: -------------------------------------------------------------------------------- 1 | (.*?)\<\/EMailAddress\>/", $data, $matches); 5 | //set Content-Type 6 | header("Content-Type: application/xml"); 7 | $host = '__EASYMAIL_HOSTNAME__'; 8 | 9 | echo ''; ?> 10 | 11 | 12 | 13 | 14 | email 15 | settings 16 | 17 | IMAP 18 | 19 | 993 20 | off 21 | 22 | off 23 | on 24 | on 25 | 26 | 27 | POP3 28 | 29 | 995 30 | off 31 | 32 | off 33 | on 34 | on 35 | 36 | 37 | SMTP 38 | 39 | 587 40 | off 41 | 42 | off 43 | on 44 | off 45 | off 46 | TLS 47 | on 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /autoconfig/install.sh: -------------------------------------------------------------------------------- 1 | # Install autoconfig and autodiscover 2 | 3 | AUTOCONFIG_DIR="$CURRENT_DIR/autoconfig" 4 | 5 | mkdir /usr/share/nginx/autoconfig_and_autodiscover 6 | 7 | cp $AUTOCONFIG_DIR/autoconfig.php /usr/share/nginx/autoconfig_and_autodiscover/ 8 | set_hostname /usr/share/nginx/autoconfig_and_autodiscover/autoconfig.php 9 | 10 | cp $AUTOCONFIG_DIR/autodiscover.php /usr/share/nginx/autoconfig_and_autodiscover/ 11 | set_hostname /usr/share/nginx/autoconfig_and_autodiscover/autodiscover.php 12 | 13 | cp $AUTOCONFIG_DIR/nginx_config /etc/nginx/sites-enabled/autoconfig_and_autodiscover 14 | sed -i "s#__EASYMAIL_SSL_CA_BUNDLE_FILE__#$SSL_CA_Bundle_File#g" /etc/nginx/sites-enabled/roundcube 15 | sed -i "s#__EASYMAIL_SSL_PRIVATE_KEY_FILE__#$SSL_Private_Key_File#g" /etc/nginx/sites-enabled/roundcube 16 | 17 | service nginx reload -------------------------------------------------------------------------------- /autoconfig/nginx_config: -------------------------------------------------------------------------------- 1 | server { 2 | listen 443; 3 | server_name autoconfig.* autodiscover.*; 4 | 5 | root /usr/share/nginx/autoconfig_and_autodiscover; 6 | index index.php index.html index.htm; 7 | error_log /var/log/nginx/error.log; 8 | 9 | ssl on; 10 | ssl_certificate __EASYMAIL_SSL_CA_BUNDLE_FILE__; 11 | ssl_certificate_key __EASYMAIL_SSL_PRIVATE_KEY_FILE__; 12 | ssl_session_timeout 5m; 13 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # don't use SSLv3 ref: POODLE 14 | ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; 15 | ssl_prefer_server_ciphers on; 16 | 17 | location /autodiscover/autodiscover.xml { 18 | try_files $uri /autodiscover.php?$args; 19 | rewrite ^(.+)$ /autodiscover.php?$1 last; 20 | } 21 | 22 | location ~ \.php$ { 23 | try_files $uri =404; 24 | fastcgi_pass unix:/var/run/php5-fpm.sock; 25 | fastcgi_index index.php; 26 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 27 | include fastcgi_params; 28 | } 29 | } 30 | 31 | server { 32 | listen 80; 33 | server_name autoconfig.* autodiscover.*; 34 | 35 | root /usr/share/nginx/autoconfig_and_autodiscover; 36 | index index.php index.html index.htm; 37 | error_log /var/log/nginx/error.log; 38 | 39 | location /mail/config-v1.1.xml { 40 | try_files $uri /autoconfig.php?$args; 41 | rewrite ^(.+)$ /autoconfig.php?$1 last; 42 | } 43 | 44 | location /autodiscover/autodiscover.xml { 45 | try_files $uri /autodiscover.php?$args; 46 | rewrite ^(.+)$ /autodiscover.php?$1 last; 47 | } 48 | 49 | location ~ \.php$ { 50 | try_files $uri =404; 51 | fastcgi_pass unix:/var/run/php5-fpm.sock; 52 | fastcgi_index index.php; 53 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 54 | include fastcgi_params; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /dovecot/10-master.conf: -------------------------------------------------------------------------------- 1 | #default_process_limit = 100 2 | #default_client_limit = 1000 3 | 4 | # Default VSZ (virtual memory size) limit for service processes. This is mainly 5 | # intended to catch and kill processes that leak memory before they eat up 6 | # everything. 7 | #default_vsz_limit = 256M 8 | 9 | # Login user is internally used by login processes. This is the most untrusted 10 | # user in Dovecot system. It shouldn't have access to anything at all. 11 | #default_login_user = dovenull 12 | 13 | # Internal user is used by unprivileged processes. It should be separate from 14 | # login user, so that login processes can't disturb other processes. 15 | #default_internal_user = dovecot 16 | 17 | service imap-login { 18 | inet_listener imap { 19 | #port = 143 20 | } 21 | inet_listener imaps { 22 | #port = 993 23 | #ssl = yes 24 | } 25 | 26 | # Number of connections to handle before starting a new process. Typically 27 | # the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0 28 | # is faster. 29 | #service_count = 1 30 | 31 | # Number of processes to always keep waiting for more connections. 32 | #process_min_avail = 0 33 | 34 | # If you set service_count=0, you probably need to grow this. 35 | #vsz_limit = $default_vsz_limit 36 | } 37 | 38 | service pop3-login { 39 | inet_listener pop3 { 40 | #port = 110 41 | } 42 | inet_listener pop3s { 43 | #port = 995 44 | #ssl = yes 45 | } 46 | } 47 | 48 | service lmtp { 49 | unix_listener /var/spool/postfix/private/dovecot-lmtp { 50 | mode = 0600 51 | user = postfix 52 | group = postfix 53 | } 54 | } 55 | 56 | service imap { 57 | # Most of the memory goes to mmap()ing files. You may need to increase this 58 | # limit if you have huge mailboxes. 59 | #vsz_limit = $default_vsz_limit 60 | 61 | # Max. number of IMAP processes (connections) 62 | #process_limit = 1024 63 | } 64 | 65 | service pop3 { 66 | # Max. number of POP3 processes (connections) 67 | #process_limit = 1024 68 | } 69 | 70 | service auth { 71 | # auth_socket_path points to this userdb socket by default. It's typically 72 | # used by dovecot-lda, doveadm, possibly imap process, etc. Its default 73 | # permissions make it readable only by root, but you may need to relax these 74 | # permissions. Users that have access to this socket are able to get a list 75 | # of all usernames and get results of everyone's userdb lookups. 76 | unix_listener /var/spool/postfix/private/auth { 77 | mode = 0666 78 | user = postfix 79 | group = postfix 80 | } 81 | 82 | unix_listener auth-userdb { 83 | mode = 0600 84 | user = vmail 85 | #group = 86 | } 87 | 88 | # Postfix smtp-auth 89 | #unix_listener /var/spool/postfix/private/auth { 90 | # mode = 0666 91 | #} 92 | 93 | # Auth process is run as this user. 94 | user = dovecot 95 | } 96 | 97 | service auth-worker { 98 | # Auth worker process is run as root by default, so that it can access 99 | # /etc/shadow. If this isn't necessary, the user should be changed to 100 | # $default_internal_user. 101 | user = vmail 102 | } 103 | 104 | service dict { 105 | # If dict proxy is used, mail processes should have access to its socket. 106 | # For example: mode=0660, group=vmail and global mail_access_groups=vmail 107 | unix_listener dict { 108 | #mode = 0600 109 | #user = 110 | #group = 111 | } 112 | } -------------------------------------------------------------------------------- /dovecot/install.sh: -------------------------------------------------------------------------------- 1 | DOVECOT_DIR="$CURRENT_DIR/dovecot" 2 | 3 | debconf-set-selections <<< "dovecot-core dovecot-core/ssl-cert-exists string error" 4 | debconf-set-selections <<< "dovecot-core dovecot-core/ssl-cert-name string localhost" 5 | debconf-set-selections <<< "dovecot-core dovecot-core/create-ssl-cert boolean true" 6 | 7 | apt-get install dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-mysql -y 8 | 9 | cp /etc/postfix/master.cf /etc/postfix/master.cf.orig 10 | cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig 11 | cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.orig 12 | cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.orig 13 | cp /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.orig 14 | cp /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.orig 15 | cp /etc/dovecot/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext.orig 16 | 17 | echo " 18 | #Automatic added by script for auto install mail server. 19 | smtps inet n - - - - smtpd 20 | submission inet n - - - - smtpd 21 | -o smtpd_tls_security_level=encrypt 22 | -o smtpd_sasl_auth_enable=yes 23 | -o smtpd_client_restrictions=permit_sasl_authenticated,reject 24 | " >> /etc/postfix/master.cf 25 | 26 | echo " 27 | #Automatic added by script for auto install mail server. 28 | protocols = imap pop3 lmtp 29 | " >> /etc/dovecot/dovecot.conf 30 | 31 | sed -i "s/mail_location = .*/mail_location = maildir:\/var\/mail\/vhosts\/%d\/\%n/g" /etc/dovecot/conf.d/10-mail.conf 32 | sed -i "s/#mail_privileged_group =/mail_privileged_group = mail/g" /etc/dovecot/conf.d/10-mail.conf 33 | 34 | mkdir -p /var/mail/vhosts/$HOSTNAME 35 | groupadd -g 5000 vmail 36 | useradd -g vmail -u 5000 vmail -d /var/mail 37 | chown -R vmail:vmail /var/mail 38 | 39 | sed -i "s/^#disable_plaintext_auth = .*/disable_plaintext_auth = yes/g" /etc/dovecot/conf.d/10-auth.conf 40 | sed -i "s/^auth_mechanisms = .*/auth_mechanisms = plain login/g" /etc/dovecot/conf.d/10-auth.conf 41 | sed -i "s/\!include auth-system.conf.ext/#\!include auth-system.conf.ext/g" /etc/dovecot/conf.d/10-auth.conf 42 | sed -i "s/#\!include auth-sql.conf.ext/\!include auth-sql.conf.ext/g" /etc/dovecot/conf.d/10-auth.conf 43 | sed -i "s/#ssl = .*/ssl = required/g" /etc/dovecot/conf.d/10-ssl.conf 44 | sed -i "s#ssl_cert =.*#ssl_cert = <$SSL_CA_Bundle_File#g" /etc/dovecot/conf.d/10-ssl.conf 45 | sed -i "s#ssl_key =.*#ssl_key = <$SSL_Private_Key_File#g" /etc/dovecot/conf.d/10-ssl.conf 46 | 47 | echo ' 48 | passdb { 49 | driver = sql 50 | args = /etc/dovecot/dovecot-sql.conf.ext 51 | } 52 | userdb { 53 | driver = static 54 | args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n 55 | } 56 | ' > /etc/dovecot/conf.d/auth-sql.conf.ext 57 | 58 | echo " 59 | driver = mysql 60 | connect = host=$MYSQL_HOSTNAME dbname=$MYSQL_DATABASE user=$MYSQL_USERNAME password=$MYSQL_PASSWORD 61 | default_pass_scheme = CRYPT 62 | password_query = SELECT email as user, password FROM virtual_users WHERE email='%u'; 63 | " >> /etc/dovecot/dovecot-sql.conf.ext 64 | 65 | chown -R vmail:dovecot /etc/dovecot 66 | chmod -R o-rwx /etc/dovecot 67 | 68 | cp $DOVECOT_DIR/10-master.conf /etc/dovecot/conf.d/10-master.conf 69 | 70 | if [ $IS_ON_DOCKER == true ]; then 71 | /usr/sbin/dovecot 72 | /etc/init.d/postfix restart 73 | else 74 | service dovecot reload 75 | service postfix reload 76 | fi 77 | -------------------------------------------------------------------------------- /event/after-install.sh: -------------------------------------------------------------------------------- 1 | echo "Begin Mailjet configurator. " 2 | echo "You can find you API and SECRET key at https://app.mailjet.com/account/setup" 3 | 4 | MAILJET_APIKEY="" 5 | MAILJET_SECRETKEY="" 6 | 7 | MAILJET_WRONG_DATA_MSG=false 8 | while [ ${#MAILJET_APIKEY} != 32 ]; do 9 | if [ $MAILJET_WRONG_DATA_MSG == true ]; then 10 | echo "Not valid API key try again." 11 | fi 12 | MAILJET_WRONG_DATA_MSG=true; 13 | read -p "Please insert you API key: " MAILJET_APIKEY 14 | done 15 | 16 | MAILJET_WRONG_DATA_MSG=false 17 | while [ ${#MAILJET_SECRETKEY} != 32 ]; do 18 | if [ $MAILJET_WRONG_DATA_MSG == true ]; then 19 | echo "Not valid SECRET key try again." 20 | fi 21 | MAILJET_WRONG_DATA_MSG=true; 22 | read -p "Please insert you SECRET key: " MAILJET_SECRETKEY 23 | done 24 | 25 | cd /etc/postfix/ 26 | cp main.cf main.cf_backup_before_mailjet_configurator 27 | sed -i "s/relayhost =.*/relayhost = in-v3.mailjet.com/" main.cf 28 | echo " 29 | smtp_sasl_auth_enable = yes 30 | smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd 31 | " >> main.cf 32 | echo "in-v3.mailjet.com $MAILJET_APIKEY:$MAILJET_SECRETKEY" > /etc/postfix/sasl_passwd 33 | chown root:root sasl_passwd 34 | chmod 600 sasl_passwd 35 | postmap sasl_passwd && postfix reload 36 | -------------------------------------------------------------------------------- /event/before-install.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/EasyMail/5305b5c7062c1e30c588424f70583c79ccdb74fa/event/before-install.sh -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | export CURRENT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 2 | export HOSTNAME 3 | export IS_ON_DOCKER 4 | export SSL_CA_Bundle_File 5 | export SSL_Private_Key_File 6 | 7 | function is_installed { 8 | is_installed=$(dpkg -l | grep $1 | wc -c) 9 | 10 | if [ $is_installed != "0" ]; then 11 | is_installed=1 12 | fi 13 | 14 | echo $is_installed 15 | } 16 | 17 | bash $CURRENT_DIR/event/before-install.sh 18 | 19 | if [ $(is_installed php) == 1 ]; then 20 | echo "PHP is already installed, installation aborted"; exit 21 | elif [ $(is_installed nginx) == 1 ]; then 22 | echo "Nginx is already installed, installation aborted"; exit 23 | elif [ $(is_installed postfix) == 1 ]; then 24 | echo "Postfix is already installed, installation aborted"; exit 25 | elif [ $(is_installed dovecot) == 1 ]; then 26 | echo "Dovecot is already installed, installation aborted"; exit 27 | elif [ $(is_installed mysql) == 1 ]; then 28 | echo "MySQL is already installed, installation aborted"; exit 29 | elif [ $(is_installed spamassassin) == 1 ]; then 30 | echo "SpamAssassin is already installed, installation aborted"; exit 31 | fi 32 | 33 | read -p "Type hostname: " HOSTNAME 34 | read -s -p "Type admin's email password: " PASSWORD && echo -e 35 | read -e -p "Do you want to install your own ssl certificates? [n/Y] " SSL_INSTALL_OWN 36 | 37 | if [ "$SSL_INSTALL_OWN" == "n" ] || [ "$SSL_INSTALL_OWN" == "N" ]; then 38 | #by default use dovecot's self-signed certificate 39 | SSL_CA_Bundle_File=/etc/dovecot/dovecot.pem 40 | SSL_Private_Key_File=/etc/dovecot/private/dovecot.pem 41 | else 42 | while [ ! -f "$SSL_CA_Bundle_File" ]; do 43 | read -p "[SSL] CA Bundle file path: " SSL_CA_Bundle_File 44 | done 45 | 46 | while [ ! -f "$SSL_Private_Key_File" ]; do 47 | read -p "[SSL] Private key file path: " SSL_Private_Key_File 48 | done 49 | fi 50 | 51 | read -e -p "Is this installation is on Docker? [N/y] " IS_ON_DOCKER 52 | 53 | if [ "$IS_ON_DOCKER" == "y" ] || [ "$IS_ON_DOCKER" == "Y" ]; then 54 | IS_ON_DOCKER=true 55 | else 56 | IS_ON_DOCKER=false 57 | fi 58 | 59 | function set_hostname { 60 | sed -i "s/__EASYMAIL_HOSTNAME__/$HOSTNAME/g" $1 61 | } 62 | export -f set_hostname 63 | 64 | function get_rand_password() { 65 | openssl rand 32 | md5sum | awk '{print $1;}' 66 | } 67 | 68 | export ADMIN_EMAIL="admin@$HOSTNAME" 69 | export ADMIN_PASSWORD=$(openssl passwd -1 $PASSWORD) 70 | 71 | export ROOT_MYSQL_USERNAME='root' 72 | export ROOT_MYSQL_PASSWORD=$(get_rand_password) 73 | 74 | export MYSQL_DATABASE='mailserver' 75 | export MYSQL_HOSTNAME='127.0.0.1' 76 | export MYSQL_USERNAME='mailuser' 77 | export MYSQL_PASSWORD=$(get_rand_password) 78 | 79 | export ROUNDCUBE_MYSQL_DATABASE='roundcube_dbname' 80 | export ROUNDCUBE_MYSQL_USERNAME='roundcube_user' 81 | export ROUNDCUBE_MYSQL_PASSWORD=$(get_rand_password) 82 | 83 | apt-get update 84 | 85 | bash $CURRENT_DIR/mysql/install.sh 86 | bash $CURRENT_DIR/postfix/install.sh 87 | bash $CURRENT_DIR/dovecot/install.sh 88 | bash $CURRENT_DIR/roundcube/install.sh 89 | bash $CURRENT_DIR/autoconfig/install.sh 90 | bash $CURRENT_DIR/spamassassin/install.sh 91 | 92 | echo "Root MySQL username: $ROOT_MYSQL_USERNAME | password: $ROOT_MYSQL_PASSWORD" 93 | echo "Easymail MySQL db: $MYSQL_DATABASE | username: $MYSQL_USERNAME | password: $MYSQL_PASSWORD" 94 | echo "Roundcube MySQL db: $ROUNDCUBE_MYSQL_DATABASE | username: $ROUNDCUBE_MYSQL_USERNAME | password: $ROUNDCUBE_MYSQL_PASSWORD" 95 | 96 | echo "Installation has finished" 97 | if [ $IS_ON_DOCKER == true ]; then 98 | echo "After stop this docker container you must start this services manually: 99 | ========== 100 | service mysql start 101 | service nginx start 102 | service php5-fpm start 103 | /etc/init.d/postfix start 104 | /usr/sbin/dovecot 105 | service spamassassin start 106 | ========== 107 | " 108 | fi 109 | 110 | bash $CURRENT_DIR/event/after-install.sh 111 | 112 | -------------------------------------------------------------------------------- /mysql/install.sh: -------------------------------------------------------------------------------- 1 | debconf-set-selections <<< "mysql-server mysql-server/root_password password $ROOT_MYSQL_PASSWORD" 2 | debconf-set-selections <<< "mysql-server mysql-server/root_password_again password $ROOT_MYSQL_PASSWORD" 3 | 4 | apt-get install expect mysql-server -y 5 | 6 | if [ $IS_ON_DOCKER == true ]; then 7 | service mysql start 8 | fi 9 | 10 | mysql_install_db 11 | expect -c " 12 | 13 | set timeout 10 14 | spawn mysql_secure_installation 15 | 16 | expect \"Enter current password for root (enter for none):\" 17 | send \"$ROOT_MYSQL_PASSWORD\r\" 18 | 19 | expect \"Change the root password?\" 20 | send \"n\r\" 21 | 22 | expect \"Remove anonymous users?\" 23 | send \"y\r\" 24 | 25 | expect \"Disallow root login remotely?\" 26 | send \"y\r\" 27 | 28 | expect \"Remove test database and access to it?\" 29 | send \"y\r\" 30 | 31 | expect \"Reload privilege tables now?\" 32 | send \"y\r\" 33 | 34 | expect eof" 35 | -------------------------------------------------------------------------------- /postfix/install.sh: -------------------------------------------------------------------------------- 1 | debconf-set-selections <<< "postfix postfix/mailname string $HOSTNAME" 2 | debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Internet Site'" 3 | 4 | apt-get install postfix postfix-mysql -y 5 | 6 | mysqladmin -u$ROOT_MYSQL_USERNAME -p$ROOT_MYSQL_PASSWORD create $MYSQL_DATABASE 7 | mysql -h $MYSQL_HOSTNAME -u$ROOT_MYSQL_USERNAME -p$ROOT_MYSQL_PASSWORD << EOF 8 | GRANT SELECT ON $MYSQL_DATABASE.* TO '$MYSQL_USERNAME'@'$MYSQL_HOSTNAME' IDENTIFIED BY '$MYSQL_PASSWORD'; 9 | FLUSH PRIVILEGES; 10 | USE $MYSQL_DATABASE; 11 | CREATE TABLE \`virtual_domains\` ( 12 | \`id\` int(11) NOT NULL auto_increment, 13 | \`name\` varchar(50) NOT NULL, 14 | PRIMARY KEY (\`id\`) 15 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 16 | 17 | CREATE TABLE \`virtual_users\` ( 18 | \`id\` int(11) NOT NULL auto_increment, 19 | \`domain_id\` int(11) NOT NULL, 20 | \`password\` varchar(106) NOT NULL, 21 | \`email\` varchar(100) NOT NULL, 22 | PRIMARY KEY (\`id\`), 23 | UNIQUE KEY \`email\` (\`email\`), 24 | FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE 25 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 26 | 27 | CREATE TABLE \`virtual_aliases\` ( 28 | \`id\` int(11) NOT NULL auto_increment, 29 | \`domain_id\` int(11) NOT NULL, 30 | \`source\` varchar(100) NOT NULL, 31 | \`destination\` varchar(100) NOT NULL, 32 | PRIMARY KEY (\`id\`), 33 | FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE 34 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 35 | 36 | INSERT INTO \`virtual_domains\` (\`id\` ,\`name\`) 37 | VALUES('1', '$HOSTNAME'); 38 | 39 | INSERT INTO \`virtual_users\` (\`id\`, \`domain_id\`, \`password\` , \`email\`) 40 | VALUES ('1', '1', '$ADMIN_PASSWORD', '$ADMIN_EMAIL'); 41 | EOF 42 | 43 | cp /etc/postfix/main.cf /etc/postfix/main.cf.orig 44 | 45 | postconf -e mydestination=localhost 46 | postconf -# smtpd_tls_session_cache_database 47 | postconf -# smtp_tls_session_cache_database 48 | postconf -e smtpd_tls_cert_file=$SSL_CA_Bundle_File 49 | postconf -e smtpd_tls_key_file=$SSL_Private_Key_File 50 | postconf -e smtpd_use_tls=yes 51 | postconf -e smtpd_tls_auth_only=yes 52 | postconf -e smtpd_sasl_type=dovecot 53 | postconf -e smtpd_sasl_path=private/auth 54 | postconf -e smtpd_sasl_auth_enable=yes 55 | postconf -e smtpd_recipient_restrictions=permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination 56 | postconf -e virtual_transport=lmtp:unix:private/dovecot-lmtp 57 | postconf -e virtual_mailbox_domains=mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf 58 | postconf -e virtual_mailbox_maps=mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf 59 | postconf -e virtual_alias_maps=mysql:/etc/postfix/mysql-virtual-alias-maps.cf 60 | 61 | # increase message limit to 25 MB 62 | postconf -e message_size_limit=26214400 63 | 64 | function postfix_mysql_file { 65 | echo "user = $MYSQL_USERNAME 66 | password = $MYSQL_PASSWORD 67 | hosts = $MYSQL_HOSTNAME 68 | dbname = $MYSQL_DATABASE 69 | $1 " > $2 70 | } 71 | 72 | cd /etc/postfix/ 73 | postfix_mysql_file "query = SELECT 1 FROM virtual_domains WHERE name='%s'" mysql-virtual-mailbox-domains.cf 74 | postfix_mysql_file "query = SELECT 1 FROM virtual_users WHERE email='%s'" mysql-virtual-mailbox-maps.cf 75 | postfix_mysql_file "query = SELECT destination FROM virtual_aliases WHERE source='%s'" mysql-virtual-alias-maps.cf 76 | 77 | if [ $IS_ON_DOCKER == true ]; then 78 | /etc/init.d/postfix start 79 | else 80 | service postfix start 81 | fi 82 | 83 | -------------------------------------------------------------------------------- /roundcube/config: -------------------------------------------------------------------------------- 1 | > /usr/share/nginx/roundcubemail/plugins/password/config.inc.php 45 | sed -i "s/> /etc/postfix/master.cf 24 | 25 | if [ $IS_ON_DOCKER == true ]; then 26 | chown -R postfix:maildrop /var/spool/postfix/maildrop/ 27 | chmod -R 0770 /var/spool/postfix/maildrop/ 28 | postfix reload 29 | else 30 | service postfix restart 31 | fi 32 | service spamassassin restart 33 | 34 | #Move spam message to spam folder 35 | apt-get install dovecot-sieve dovecot-managesieved 36 | 37 | echo " 38 | protocol lmtp { 39 | postmaster_address = admin@$HOSTNAME 40 | mail_plugins = \$mail_plugins sieve 41 | } 42 | " >> /etc/dovecot/conf.d/20-lmtp.conf 43 | 44 | 45 | echo " 46 | plugin { 47 | sieve = ~/.dovecot.sieve 48 | sieve_global_path = /var/lib/dovecot/sieve/default.sieve 49 | sieve_dir = ~/sieve 50 | sieve_global_dir = /var/lib/dovecot/sieve/ 51 | } 52 | " > /etc/dovecot/conf.d/90-sieve.conf 53 | 54 | 55 | mkdir /var/lib/dovecot/sieve/ 56 | echo " 57 | require \"fileinto\"; 58 | if header :contains \"X-Spam-Flag\" \"YES\" { 59 | fileinto \"Junk\"; 60 | } 61 | " > /var/lib/dovecot/sieve/default.sieve 62 | chown -R vmail:vmail /var/lib/dovecot 63 | sievec /var/lib/dovecot/sieve/default.sieve 64 | 65 | if [ $IS_ON_DOCKER == true ]; then 66 | /usr/sbin/dovecot 67 | /etc/init.d/postfix restart 68 | else 69 | service dovecot restart 70 | fi -------------------------------------------------------------------------------- /tests.sh: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | # Spamassassin 4 | # Check your local.cf syntax 5 | # spamassassin --lint 6 | # tail -f /var/log/spamassassin/spamd.log 7 | # Message with content XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X must always be spam. 8 | 9 | # Postfix 10 | # postmap -q admin@$HOSTNAME mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf must return 1 11 | # postmap -q alias@$HOSTNAME mysql:/etc/postfix/mysql-virtual-alias-maps.cf must return admin@$HOSTNAME 12 | # postmap -q $HOSTNAME mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf must return 1 13 | 14 | # Debugging 15 | # openssl passwd -1 123456 WORKING CUURECTLY 16 | # openssl passwd -1 123456 = $1$pfhfftkU$3/0sv66/HiM0Dn6l3qRiq/ 17 | --------------------------------------------------------------------------------