#!/usr/bin/env bash ############### #// #// Users and directories #// ############### # Add users to groups adduser dovecot mail >/dev/null adduser ${MYVEMAIL_NGINX_USERGROUP} dovecot >/dev/null adduser postfix opendkim >/dev/null # Virtual mailboxes mkdir /etc/postfix/sql # MariaDB install -m 1777 -d /run/mysqld # DKIM/DMARC mkdir /{run,etc}/{opendkim,opendmarc} >/dev/null 2>&1 install -o opendkim -g postfix -d /var/spool/postfix/opendkim/ install -m 750 -o opendmarc -g postfix -d /var/spool/postfix/opendmarc/ ############### #// #// PHP #// ############### sed -e '/upload_max_filesize =/c upload_max_filesize = 0' \ -e '/post_max_size =/c post_max_size = 0' \ -e '/memory_limit =/c memory_limit = 4096M' \ -i $(find /etc/php*/ -name 'php.ini') ############### #// #// Postfix #// ############### postconf -e 'relay_domains = $mydestination' postconf -e 'smtp_tls_security_level = may' postconf -e 'smtp_tls_loglevel = 1' postconf -e 'smtpd_tls_security_level = may' postconf -e 'smtpd_tls_loglevel = 1' postconf -e 'mailbox_size_limit = 0' postconf -e 'message_size_limit = 0' postconf -e "authorized_submit_users = root,${MYVEMAIL_NGINX_USERGROUP}" postconf -e 'smtpd_tls_session_cache_database = lmdb:${data_directory}/smtpd_scache' postconf -e 'smtp_tls_session_cache_database = lmdb:${data_directory}/smtp_scache' postconf -e 'smtp_tls_note_starttls_offer = yes' postconf -e 'smtpd_tls_received_header = yes' postconf -e 'inet_interfaces = all' postconf -e 'inet_protocols = ipv4' postconf -e 'smtp_address_preference = ipv4' postconf -e 'myorigin = $mydomain' postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost' postconf -e "smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt" postconf -e "smtpd_tls_key_file = /etc/ssl/dovecot/tls.key" postconf -e "smtpd_tls_cert_file = /etc/ssl/dovecot/tls.pem" # Enforce TLSv1.2 or TLSv1.2 postconf -e "smtpd_tls_mandatory_protocols = >=TLSv1.2" postconf -e "smtp_tls_mandatory_protocols = >=TLSv1.2" postconf -e "smtpd_tls_protocols = >=TLSv1.2" postconf -e "smtp_tls_protocols = >=TLSv1.2" # # Logging # postconf -e "maillog_file = /var/log/postfix.log" # Virtual mailboxes postconf -e "mailbox_transport = lmtp:unix:private/dovecot-lmtp" postconf -e "smtputf8_enable = no" postconf -e "virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/virtual_domains_maps.cf" postconf -e "virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/virtual_mailbox_maps.cf, proxy:mysql:/etc/postfix/sql/virtual_alias_domain_mailbox_maps.cf" postconf -e "virtual_alias_maps = proxy:mysql:/etc/postfix/sql/virtual_alias_maps.cf, proxy:mysql:/etc/postfix/sql/virtual_alias_domain_maps.cf, proxy:mysql:/etc/postfix/sql/virtual_alias_domain_catchall_maps.cf" postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp" postconf -e "virtual_mailbox_base = /var/vmail" postconf -e "virtual_uid_maps = static:600" postconf -e "virtual_gid_maps = static:600" postconf -e "virtual_minimum_uid = 600" postconf -e "virtual_mailbox_limit = 0" postconf -e "smtp_header_checks = pcre:/etc/postfix/smtp_header_checks" # SPF and DKIM checks postconf -e "policyd-spf_time_limit = 3600" postconf -e "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, check_client_access pcre:/etc/postfix/whitelisted_domains, check_sender_access lmdb:/etc/postfix/whitelisted_emails, check_client_access pcre:/etc/postfix/blacklisted_domains, check_sender_access lmdb:/etc/postfix/blacklisted_emails, check_policy_service unix:private/policyd-spf" # Milter configuration postconf -e "milter_default_action = accept" postconf -e "milter_protocol = 6" postconf -e "smtpd_milters = local:opendkim/opendkim.sock, local:opendmarc/opendmarc.sock" postconf -e 'non_smtpd_milters = $smtpd_milters' # Blocking spam postconf -e "smtpd_sender_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unknown_sender_domain, reject_unknown_reverse_client_hostname, reject_unknown_client_hostname" postconf -e "smtpd_helo_required = yes" postconf -e "smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, check_helo_access pcre:/etc/postfix/helo_access, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_helo_hostname" # Postscreen spambots postconf -e "postscreen_access_list = permit_mynetworks cidr:/etc/postfix/postscreen_access.cidr cidr:/etc/postfix/postscreen_spf_whitelist.cidr" postconf -e "postscreen_blacklist_action = drop" postconf -e "postscreen_greet_action = enforce" postconf -e "postscreen_dnsbl_threshold = 3" postconf -e "postscreen_dnsbl_action = enforce" postconf -e "postscreen_dnsbl_sites = bl.spameatingmonkey.net*2, bl.spamcop.net, dnsbl.sorbs.net" # zen.spamhaus.org*3, postconf -e "postscreen_dnsbl_whitelist_threshold = -2" postconf -e "header_checks = pcre:/etc/postfix/header_checks" postconf -e "body_checks = pcre:/etc/postfix/body_checks" # master.cf sed -e 's/^smtp .*smtpd$/# &/' \ -e '/#smtp\|#smtpd\|#dnsblog\|#tlsproxy/ s/^#//' -i /etc/postfix/master.cf tee -a /etc/postfix/master.cf >/dev/null <<- master.cf # Enable submission submission inet n - y - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_tls_wrappermode=no -o smtpd_sasl_auth_enable=yes -o smtpd_relay_restrictions=permit_sasl_authenticated,reject -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject -o smtpd_sasl_type=dovecot -o smtpd_sasl_path=private/auth # SPF Policy policyd-spf unix - n n - - spawn user=nobody argv=/usr/bin/perl ${MYVEMAIL_POLICYD} master.cf # Deleting Email Headers For Outgoing Emails echo -e '/^X-Spam-Status:/ IGNORE /^X-Spam-Checker-Version:/ IGNORE /^Received:.*/ IGNORE /^User-Agent:.*/ IGNORE' | tee /etc/postfix/smtp_header_checks >/dev/null # Header checks echo "/free mortgage quote/ DISCARD /repair your credit/ DISCARD /lose weight/ DISCARD /To:.*<>/ DISCARD /From:.*<>/ DISCARD" | tee -a /etc/postfix/header_checks >/dev/null # Body checks echo "/free mortgage quote/ DISCARD /repair your credit/ DISCARD /lose weight/ DISCARD" | tee -a /etc/postfix/body_checks >/dev/null # Touch aliases db newaliases ############### #// #// Dovecot #// ############### rm -r /etc/dovecot/ /etc/ssl/dovecot/ mkdir -p /etc/dovecot/ /etc/ssl/dovecot/ # dovecot.conf cat >/etc/dovecot/dovecot.conf <<- dovecot.conf dovecot_config_version = 2.4.1 dovecot_storage_version = 2.4.1 sql_driver = mysql mysql /run/mysqld/mysqld.sock { user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}} password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}} dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}} } passdb sql { query = SELECT username AS user, \\ password FROM mailbox WHERE username = '%{user}' AND active='1' default_password_scheme = ARGON2I } userdb sql { fields { home = /var/vmail/%{user|domain}/%{user|username} } query = SELECT '~/Maildir' AS mail_path, \\ 600 AS uid, \\ 600 AS gid \\ FROM mailbox WHERE username = '%{user}' AND active='1' iterate_query = SELECT username AS user FROM mailbox } auth_username_format = %{user|lower} auth_mechanisms = plain login auth_default_domain = {{MYVEMAIL_DOMAIN}} auth_debug = yes auth_debug_passwords = yes # mbox_write_locks = fcntl mail_privileged_group = mail mail_home = /var/vmail/%{user|domain}/%{user|username} mail_driver = maildir mail_path = ~/Maildir service lmtp { unix_listener /var/spool/postfix/private/dovecot-lmtp { mode = 0600 user = postfix group = postfix } } service auth { unix_listener /var/spool/postfix/private/auth { mode = 0660 user = postfix group = postfix } } service stats { unix_listener stats-reader { user = ${MYVEMAIL_NGINX_USERGROUP} group = ${MYVEMAIL_NGINX_USERGROUP} mode = 0660 } unix_listener stats-writer { user = ${MYVEMAIL_NGINX_USERGROUP} group = ${MYVEMAIL_NGINX_USERGROUP} mode = 0660 } } ssl = required ssl_min_protocol = TLSv1.2 ssl_server_prefer_ciphers = server namespace inbox { inbox = yes mailbox Archive { auto = subscribe special_use = \Archive } mailbox Drafts { auto = subscribe special_use = \Drafts } mailbox Junk { auto = subscribe special_use = \Junk } mailbox Sent { auto = subscribe special_use = \Sent } mailbox "Sent Messages" { special_use = \Sent } mailbox Trash { auto = subscribe special_use = \Trash } } protocols = imap lmtp !include_try ssl-keys.conf dovecot.conf # 10-ssl.conf install -m 0600 /dev/stdin /etc/dovecot/ssl-keys.conf <<- ssl-keys.conf ssl_server { dh_file = /etc/ssl/dovecot/dh.pem cert_file = /etc/ssl/dovecot/tls.pem key_file = /etc/ssl/dovecot/tls.key } ssl-keys.conf # Virtual mailboxes install -m 0640 /dev/stdin /etc/postfix/sql/virtual_domains_maps.cf <<- eof hosts = localhost dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}} user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}} password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}} query = SELECT domain FROM domain WHERE domain='%s' AND active = '1' #query = SELECT domain FROM domain WHERE domain='%s' #optional query to use when relaying for backup MX #query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1' #expansion_limit = 100 eof install -m 0640 /dev/stdin /etc/postfix/sql/virtual_mailbox_maps.cf <<- eof hosts = localhost dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}} user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}} password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}} query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1' #expansion_limit = 100 eof install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_domain_mailbox_maps.cf <<- eof hosts = localhost dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}} user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}} password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}} query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1' eof install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_maps.cf <<- eof hosts = localhost dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}} user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}} password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}} query = SELECT goto FROM alias WHERE address='%s' AND active = '1' #expansion_limit = 100 eof install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_domain_maps.cf <<- eof hosts = localhost dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}} user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}} password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}} query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1' eof install -m 0640 /dev/stdin /etc/postfix/sql/virtual_alias_domain_catchall_maps.cf <<- eof # handles catch-all settings of target-domain hosts = localhost dbname = {{MYVEMAIL_POSTFIXADMIN_DBNAME}} user = {{MYVEMAIL_POSTFIXADMIN_DBUSER}} password = {{MYVEMAIL_POSTFIXADMIN_DBPASS}} query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1' eof ############### #// #// OpenDKIM #// ############### # sed -i 's\^SOCKET=local:$RUNDIR/opendkim.sock\SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"\' /etc/default/opendkim sed -i "/Canonicalization\|Mode\|SubDomains\|Socket\|SoftwareHeader\|UserID\|UMask/d" ${MYVEMAIL_OPENDKIM_CONF} tee -a ${MYVEMAIL_OPENDKIM_CONF} >/dev/null <<- 'opendkim.conf' Canonicalization relaxed/simple Mode sv SubDomains no Socket local:/var/spool/postfix/opendkim/opendkim.sock SoftwareHeader yes UserID opendkim UMask 007 # Map domains in "from" addresses to keys used to sign messages KeyTable refile:/etc/opendkim/KeyTable SigningTable refile:/etc/opendkim/SigningTable # Hosts to ignore when verifying signatures ExternalIgnoreList /etc/opendkim/trusted.hosts # A set of internal hosts whose mail should be signed InternalHosts /etc/opendkim/trusted.hosts opendkim.conf # trusted.hosts cat >/etc/opendkim/trusted.hosts <<- trusted.hosts 127.0.0.1 localhost trusted.hosts ############### #// #// OpenDMARC #// ############### sed '/TrustedAuthservIDs\|AuthservID\|RejectFailures\|IgnoreAuthenticatedClients\|RequiredHeaders\|SPFSelfValidate\|Socket\|IgnoreHosts\|UMask\|UserID/d' \ -i ${MYVEMAIL_OPENDMARC_CONF} tee -a ${MYVEMAIL_OPENDMARC_CONF} >/dev/null <<- 'opendmarc.conf' TrustedAuthservIDs {{HOSTNAME}} AuthservID OpenDMARC RejectFailures true IgnoreAuthenticatedClients true RequiredHeaders true SPFSelfValidate true Socket local:/var/spool/postfix/opendmarc/opendmarc.sock IgnoreHosts /etc/opendmarc/ignore.hosts UserID opendmarc UMask 0002 opendmarc.conf echo '127.0.0.1' | tee -a /etc/opendmarc/ignore.hosts >/dev/null ############### #// #// Nginx #// ############### # php-fpm sock cat >$(find /etc/php* -type d \( -name "pool.d" -o -name "php-fpm.d" \))/zz-listen.conf <<- php-fpm.sock listen = 127.0.0.1:9000 user = ${MYVEMAIL_NGINX_USERGROUP} group = ${MYVEMAIL_NGINX_USERGROUP} listen.owner = ${MYVEMAIL_NGINX_USERGROUP} listen.group = ${MYVEMAIL_NGINX_USERGROUP} listen.mode = 0660 php-fpm.sock # proxy_params tee /etc/nginx/proxy_params >/dev/null <<'PROXY' proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; PROXY # Roundcube/Postfixadmin virtual proxy tee $(find /etc/nginx -type f -name "default*") >/dev/null <<- 'nginx' upstream php-handler { server 127.0.0.1:9000; } server { listen {{MYVEMAIL_PORT}} default_server; server_name _; index index.php index.html; error_log /var/log/nginx/roundcube_error.log; access_log /var/log/nginx/roundcube_access.log; root /usr/share/webapps/roundcube; # Add trailing slash to URI location /admin { return 302 $scheme://$host/admin/; } # Postfixadmin location ^~ /admin/ { proxy_pass http://127.0.0.1:12000/; include proxy_params; } # Roundcube location ~ \.php$ { client_max_body_size 0; try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php-handler; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } server { listen 12000; root /usr/share/webapps/postfixadmin/public/; index index.php index.html; error_log /var/log/nginx/postfixadmin_error.log; access_log /var/log/nginx/postfixadmin_access.log; location / { try_files $uri $uri/ /index.php; } location ~ ^/(.+\.php)$ { try_files $uri =404; fastcgi_pass php-handler; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include /etc/nginx/fastcgi_params; } } nginx ############### #// #// Postwhite #// ############### cd /usr/local/bin git clone --quiet https://github.com/spf-tools/spf-tools.git git clone --quiet https://github.com/stevejenkins/postwhite.git cp /usr/local/bin/postwhite/postwhite.conf /etc ############### #// #// Syslog #// ############### mkdir -p /var/log/mail/ cat >/etc/syslog.conf <<- syslog mail.info /var/log/mail/maillog mail.* /var/log/mail/maillog.debug syslog