postfix + postfixadmin + dovecot + rspamd + roundcubemail

PostfixAdmin

1. 安裝 / 設定 PostfixAdmin

依據 https://github.com/postfixadmin/postfixadmin/blob/master/INSTALL.TXT 安裝

2. 最後完成的設定檔

##### 檔案內容如下 #####
$CONF['configured'] = true;
$CONF['setup_password'] = '$xx$xx$/1234567890.xxxxx.xxxxx';
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = '127.0.0.1';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'thisispostfixadminpassword';
$CONF['database_name'] = 'postfix';

$CONF['default_aliases'] = array (
    'abuse' => 'abuse@example.com',
    'hostmaster' => 'hostmaster@example.com',
    'postmaster' => 'postmaster@example.com',
    'webmaster' => 'webmaster@example.com'
);

$CONF['fetchmail'] = 'NO';
$CONF['show_footer_text'] = 'NO';

$CONF['aliases'] = '100';
$CONF['mailboxes'] = '100';

$CONF['quota'] = 'YES';
$CONF['used_quotas'] = 'NO';
$CONF['maxquota'] = '2048';
$CONF['domain_quota_default'] = '4096';

Postfix

1. 安裝 Postfix

因為 postfix 只有 3.4+ 才支援 tls_server_sni_maps, 所以須要將系統原先的 postfix 移除,然後安裝 GhettoForge repository, 啟用 gf-plus 有 postfix 3.4 的 RPM

yum --nogpg install https://mirror.ghettoforge.org/distributions/gf/gf-release-latest.gf.el7.noarch.rpm
yum-config-manager --enable gf-plus
yum remove postfix; yum install postfix3 postfix3-mysql

2. 新增 vmail user for postfix/dovecot

groupadd -g 150 vmail
useradd vmail -u 150 -g 150 -m -s /sbin/nologin

3. 設定 postfix

LMTP 和 LDA 擇一

##### 有改動到的項目 #####
# interfaces / mynetworks
inet_interfaces = all
# Enable IPv4 Only
inet_protocols = ipv4
mynetworks = 127.0.0.0/8,
    192.168.9.0/24,
    192.168.19.0/24,
    1.2.3.4
##### 加在 最下方 #####
# 虛擬網域 / postfixadmin
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
virtual_alias_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf
virtual_mailbox_limit_maps = mysql:/etc/postfix/sql/mysql_virtual_mailbox_limit_maps.cf
virtual_uid_maps = static:150
virtual_gid_maps = static:150
proxy_read_maps = $local_recipient_maps,
    $mydestination,
    $virtual_alias_maps,
    $virtual_alias_domains,
    $virtual_mailbox_maps,
    $virtual_mailbox_domains,
    $relay_recipient_maps,
    $relay_domains,
    $canonical_maps,
    $sender_canonical_maps,
    $recipient_canonical_maps,
    $relocated_maps,
    $transport_maps,
    $mynetworks,
    $virtual_mailbox_limit_maps

# Dovecot
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions =  permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination

# TRANSPORT MAP
##### lda start #####
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
##### lda end   #####

##### lmtp start #####
virtual_transport = lmtp:unix:private/dovecot-lmtp
##### lmtp end   #####
##### lda start #####
##### 加在 最下方 #####
dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/dovecot-lda -f ${sender} -d ${recipient}
##### lda end   #####
##### 檔案內容如下 #####
user = postfix
password = thisispostfixadminpassword
hosts = 127.0.0.1
dbname = postfix
#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'
##### 檔案內容如下 #####
user = postfix
password = thisispostfixadminpassword
hosts = 127.0.0.1
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
##### 檔案內容如下 #####
user = postfix
password = thisispostfixadminpassword
hosts = 127.0.0.1
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
#query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = '1'
##### 檔案內容如下 #####
user = postfix
password = thisispostfixadminpassword
hosts = 127.0.0.1
dbname = postfix
query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1'

Dovecot

1. 安裝 Dovecot

因為 epel 只有 2.2 版, 要裝 2.3 的話須要透過 dovecot 的 repo
所以要先建立 dovecot 2.3 的 repo file

##### 檔案內容如下 #####
[dovecot-2.3-latest]
name=Dovecot 2.3 CentOS $releasever - $basearch
baseurl=https://repo.dovecot.org/ce-2.3-latest/centos/$releasever/RPMS/$basearch
gpgkey=https://repo.dovecot.org/DOVECOT-REPO-GPG
gpgcheck=1
enabled=1
yum clean all
yum install dovecot dovecot-mysql

2. 設定 Dovecot

##### 有改動到的項目 #####
disable_plaintext_auth = no
auth_mechanisms = plain login
#!include auth-system.conf.ext
!include auth-sql.conf.ext
##### 有改動到的項目 #####
mail_location = maildir:%h
# 因為我的 vmail 的 uid, gid 設 150, 所以 這邊也要跟著調整, 不然會有權限的問題
first_valid_uid = 150
##### 有改動到的項目 #####
...
...
##### lmtp start #####
service lmtp {
...
...
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
...
...
}
##### ltmp end #####
....
....
service auth {
....
....
  unix_listener auth-userdb {
      mode = 0600
      user = vmail
      group = vmail
  }

  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
....
....
}

service auth-worker {
....
....
  unix_listener dict {
      mode = 0600
      user = vmail
      group = vmail
  }
....
....
}
##### 有改動到的項目 #####
ssl = no
##### 有改動到的項目 #####
...
...
##### lda start #####
protocols = imap pop3
##### lda end   #####

##### ltmp start #####
protocols = imap pop3 lmtp
##### lmtp end   #####

listen = *, ::

##### 新增的項目 #####
service stats {
    unix_listener stats-reader {
        user = vmail
        group = vmail
        mode = 0660
    }

    unix_listener stats-writer {
        user = vmail
        group = vmail
        mode = 0660
    }
}
...
...
##### 檔案內容如下 #####
# This file is commonly accessed via passdb {} or userdb {} section in
# conf.d/auth-sql.conf.ext

driver = mysql
connect = host=127.0.0.1 dbname=postfix user=postfix password=thisispostfixadminpassword
#default_pass_scheme = PLAIN MD5 CRAM-MD5
default_pass_scheme = MD5
#user_query = SELECT concat('/nfs_mbox/', maildir) AS home, concat('maildir:/nfs_mbox/', maildir) AS mail , 150 AS uid, 150 AS gid FROM mailbox INNER JOIN domain ON mailbox.domain = domain.domain WHERE username = '%u' AND mailbox.active = '1' AND domain.active = '1'
user_query = SELECT CONCAT('/var/vmail/', maildir) AS home, 150 AS uid, 150 AS gid, CONCAT('*:bytes=', quota) as quota_rule FROM mailbox WHERE username = '%u' AND active='1'
#password_query = SELECT username AS user, password, concat('/nfs_mbox/', maildir) AS userdb_home, concat( 'maildir:/nfs_mbox/', maildir ) AS userdb_mail,  150 AS userdb_uid, 150 AS userdb_gid FROM mailbox INNER JOIN domain ON mailbox.domain = domain.domain WHERE username = '%u' AND mailbox.active = '1' AND domain.active = '1'
password_query = SELECT username AS user, password, CONCAT('/var/vmail/', maildir) AS userdb_home, 150 AS userdb_uid, 150 AS userdb_gid, CONCAT('*:bytes=', quota) as userdb_quota_rule FROM mailbox WHERE username = '%u' AND active='1'
iterate_query = SELECT username AS user FROM mailbox
##### 有改動到的項目 #####
...
...
namespace inbox {
  mailbox Drafts {
    auto = subscribe
    special_use = \Drafts
  }
  mailbox Junk {
    auto = subscribe
    special_use = \Junk
  }
  mailbox "Junk Email" {
    special_use = \Junk
  }
  mailbox Trash {
    auto = subscribe
    special_use = \Trash
  }
  mailbox Sent {
    auto = subscribe
    special_use = \Sent
  }
...
...
}

Roundcubemail

1. 安裝 Roundcubemail

依據 https://github.com/roundcube/roundcubemail/blob/master/INSTALL 安裝

##### Web GUI 上 有改動到的項目 installer/index.php?_step=2 #####
smtp_host => localhost:25
language => zh_TW
htmleditor => always

啟用 password plugin

##### 有改動到的項目 #####
$config['plugins'] = ['password'];
cp <Roundcubemail_DIR>/plugins/password/config.inc.php.dist <Roundcubemail_DIR>/plugins/password/config.inc.php
##### 有改動到的項目 #####
$config['password_minimum_score'] = 5;
$config['password_db_dsn'] = 'mysql://postfix:thisispostfixadminpassword@127.0.0.1/postfix';
$config['password_query'] = "UPDATE mailbox SET password=ENCRYPT(%p,concat(_utf8'\$1\$',right(md5(rand()),8),_utf8'\$')) WHERE username=%u LIMIT 1";

加密 支援 (optional)

基本上 上述做完就有一個簡易的 mail server 能跑了

這邊主要是 記錄怎麼樣 實現 加密功能
目前就我的理解主要有兩種 加密的方法
1. SSL/TLS
2. STARTTLS
這兩個的差別可以看這邊

1. 憑證

準備好相關的憑證,免費的可以使用 zerossl、Let’s Encrypt …..
我自已是使用 acme.sh 去自動產生所須要的憑證
簡單的寫了一個 bash,使用 acme.sh 的 DNS API 去 cloudflare 做認證完後,自動去產生各 DOMAIN 須要的憑證。

#!/bin/bash

## Install
# wget -O -  https://get.acme.sh | sh

## Function
run_root_acme () {

    ## Get Parameters
    CF_Key=$1
    CF_Email=$2
    L_DOMAIN=$3
    L_DIR=$4

    ## Export ENV
    export CF_Key="${CF_Key}"
    export CF_Email="${CF_Email}"

    len=${#L_DIR[@]}
    for ((i=0; i < len; i++)); do
        echo "====================================== ${L_DOMAIN[$i]} =========================================="
        [ ! -d "${L_DIR[$i]}" ] && echo "Directory ${L_DIR[$i]} DOES NOT exists. Create it." && /bin/mkdir -p ${L_DIR[$i]}

        /root/.acme.sh/acme.sh --issue -d "*.${L_DOMAIN[$i]}" -d "${L_DOMAIN[$i]}" --dns dns_cf \
            --server letsencrypt \
            --cert-file ${L_DIR[$i]}/cert.pem \
            --key-file ${L_DIR[$i]}/key.pem \
            --fullchain-file ${L_DIR[$i]}/fullchain.pem \
            --ca-file ${L_DIR[$i]}/ca.pem
        if [ -f ${L_DIR[$i]}/fullchain.pem ] && [ -f ${L_DIR[$i]}/key.pem ]
        then
            /bin/cat ${L_DIR[$i]}/fullchain.pem ${L_DIR[$i]}/key.pem > ${L_DIR[$i]}/haproxy.pem
        else
            echo "${L_DIR[$i]}/fullchain.pem or ${L_DIR[$i]}/key.pem DOES NOT exists."
        fi
    done
}

## Function
run_sub_acme () {

    ## Get Parameters
    CF_Key=$1
    CF_Email=$2
    L_DOMAIN=$3
    L_DIR=$4

    ## Export ENV
    export CF_Key="${CF_Key}"
    export CF_Email="${CF_Email}"

    len=${#L_DIR[@]}
    for ((i=0; i < len; i++)); do
        echo "====================================== ${L_DOMAIN[$i]} =========================================="
        [ ! -d "${L_DIR[$i]}" ] && echo "Directory ${L_DIR[$i]} DOES NOT exists. Create it." && /bin/mkdir -p ${L_DIR[$i]}

        /root/.acme.sh/acme.sh --issue -d "*.${L_DOMAIN[$i]}" --dns dns_cf \
            --server letsencrypt \
            --cert-file ${L_DIR[$i]}/cert.pem \
            --key-file ${L_DIR[$i]}/key.pem \
            --fullchain-file ${L_DIR[$i]}/fullchain.pem \
            --ca-file ${L_DIR[$i]}/ca.pem
        if [ -f ${L_DIR[$i]}/fullchain.pem ] && [ -f ${L_DIR[$i]}/key.pem ]
        then
            /bin/cat ${L_DIR[$i]}/fullchain.pem ${L_DIR[$i]}/key.pem > ${L_DIR[$i]}/haproxy.pem
        else
            echo "${L_DIR[$i]}/fullchain.pem or ${L_DIR[$i]}/key.pem DOES NOT exists."
        fi
    done
}

#################### yourcloudflareaccount@example.com ####################
CF_Key="YOUR Cloudflare API KEY"
CF_Email="yourcloudflareaccount@example.com"
L_DOMAIN=(
"example.com"
"example.com.tw"
)
L_DIR=(
"/ssl/example.com/wildcard"
"/ssl/example.com.tw/wildcard"
)

run_root_acme "${CF_Key}" "${CF_Email}" "${L_DOMAIN}" "${L_DIR}"

2. 設定 Postfix

##### 加在 最下方 #####
# TLS
smtpd_use_tls=yes
smtpd_tls_CAfile = /etc/ssl/certs/ca-bundle.crt
smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt
smtpd_tls_security_level = may
smtp_tls_security_level = may
# smtpd_tls_CAfile = /etc/pki/tls/root.crt
smtpd_tls_loglevel = 1
smtp_tls_loglevel = 1
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_tls_cache
smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_tls_cache
tls_random_source = dev:/dev/urandom
tls_random_exchange_name = /var/lib/postfix/prng_exch

# 25 不使用 tls
smtpd_tls_auth_only = no

smtpd_tls_chain_files =
    /ssl/example.com/wildcard/key.pem,
    /ssl/example.com/wildcard/fullchain.pem

# provide the map to be used when SNI support is enabled
tls_server_sni_maps = hash:/etc/postfix/vmail_ssl.map
# 有修改的話, 要執行
# postmap -F hash:/etc/postfix/vmail_ssl.map
# 可以用以下指令測試 是不是有走 starttls
# openssl s_client -connect localhost:25 -servername mail.example.com -starttls smtp
##### 有改動到的項目 #####
...
...
# STARTTLS(587)
submission inet n       -       n       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
# 認證是否強制使用 tls
  -o smtpd_tls_auth_only=yes
...
...
##### 加在 最下方 #####
# SSL/TLS(465)
smtps inet n - y - - smtpd
    -o syslog_name=postfix/smtps
    -o smtpd_tls_wrappermode=yes
    -o smtpd_sasl_auth_enable=yes
...
...
##### 檔案內容如下 #####
# Compile with postmap -F hash:/etc/postfix/vmail_ssl.map when updating
# One host per line
mail.example.com /ssl/example.com/wildcard/key.pem /ssl/example.com/wildcard/fullchain.pem
mail.example.com.tw /ssl/example.com.tw/wildcard/key.pem /ssl/example.com.tw/wildcard/fullchain.pem
# add more domains with keys and certs as needed

3. Dovecot

##### 有改動到的項目 #####
...
...
ssl = yes
ssl_cert = </etc/pki/dovecot/certs/dovecot.pem
ssl_key = </etc/pki/dovecot/private/dovecot.pem

local_name mail.example.com {
    ssl_cert = </ssl/example.com/wildcard/fullchain.pem
    ssl_key = </ssl/example.com/wildcard/key.pem
}
local_name mail.example.com.tw {
    ssl_cert = </ssl/example.com.tw/wildcard/fullchain.pem
    ssl_key = </ssl/example.com.tw/wildcard/key.pem
}
...
...

4. Roundcubemail

##### 有改動到的項目 #####
...
...
// IMAP 未加密
//$config['imap_host'] = 'localhost:143';
// IMAP SSL/TLS
$config['imap_host'] = 'ssl://%n:993';

// SMTP 未加宓
//$config['smtp_host'] = 'localhost:25';
// SMTP Starttls
//$config['smtp_host'] = 'tls://%n:587';
// SMTP SSL/TLS
$config['smtp_host'] = 'ssl://%n:465';
...
...

Rspamd

1. 設定 Postfix

##### 加在 最下方 #####
## Rspamd
#milter_protocol = 6 # postfix 3 不用設, 預設就是 6 了
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen} # 有加這行, rspamd 才有辦法取得 authenticated user
milter_default_action = accept
smtpd_milters = inet:127.0.0.1:11332
non_smtpd_milters = $smtpd_milters

2. 設定 Dovecot

##### 須要 sieve #####
yum install dovecot-pigeonhole
##### 有改動到的項目 #####
...
...
protocol lmtp {
...
...
  mail_plugins = $mail_plugins sieve
...
...
}
...
##### lmtp start #####
##### lmtp end   #####
##### 有改動到的項目 #####
...
...
protocol imap {
...
...
  mail_plugins = $mail_plugins imap_sieve
}
...
...
##### 有改動到的項目 #####
...
...
plugin {
...
...
  sieve_plugins = sieve_imapsieve sieve_extprograms
  sieve_before = /etc/dovecot/sieve/spam-to-folder.sieve

  imapsieve_mailbox1_name = "Junk"
  imapsieve_mailbox1_causes = COPY
  imapsieve_mailbox1_before = file:/etc/dovecot/sieve/report-spam.sieve

  imapsieve_mailbox2_name = *
  imapsieve_mailbox2_from = "Junk"
  imapsieve_mailbox2_causes = COPY
  imapsieve_mailbox2_before = file:/etc/dovecot/sieve/report-ham.sieve

  sieve_pipe_bin_dir = /usr/bin # 因為 要用 rspamc, 而 rspamc 的位置在 /usr/bin/rspamc
  sieve_global_extensions = +vnd.dovecot.pipe
}
mkdir /etc/dovecot/sieve
touch /etc/dovecot/sieve/spam-to-folder.sieve
touch /etc/dovecot/sieve/report-spam.sieve
touch /etc/dovecot/sieve/report-ham.sieve
##### 檔案內容如下 #####
require ["fileinto","mailbox"];

if header :contains "X-Spam" "Yes" {
  fileinto :create "Junk";
}
if header :contains "X-DSPAM-Result" "Spam" {
  fileinto :create "Junk";
}
if header :contains "X-HiNet-Brightmail" "Spam" {
  fileinto :create "Junk";
}
if header :contains "subject" ["SPAM-TEST", "sex"] {
  fileinto :create "Junk";
}
##### 檔案內容如下 #####
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
pipe :copy "rspamc" ["learn_spam"];
##### 檔案內容如下 #####
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
pipe :copy "rspamc" ["learn_ham"];
sievec /etc/dovecot/sieve/spam-to-folder.sieve
sievec /etc/dovecot/sieve/report-spam.sieve
sievec /etc/dovecot/sieve/report-ham.sieve
chown -R vmail: /etc/dovecot/sieve

3. 安裝 及 設定 redis

yum install redis
##### 有改動到的項目 #####
# 預設
# 用途如果只是快取不需要持久化則維持預設
# save ""
# 如果需要持久化避免資料因為Redis Server關閉而資料消失
# 3600秒有一次變動則快照
# save 3600 1
# 300秒內有100次變動則快照
# save 300 100
# 60秒內有10000次變動則快照
# save 60 10000

save 3600 1 300 100 60 10000
maxmemory 512MB
maxmemory-policy volatile-lru

4. 安裝 及 設定 Rspamd

安裝 rspamd

curl https://rspamd.com/rpm-stable/centos-7/rspamd.repo > /etc/yum.repos.d/rspamd.repo # For Centos-7
rpm --import https://rspamd.com/rpm-stable/gpg.key
yum update
yum install rspamd
rspamadm configwizard
# 都照預設的, 只有 redis db 我改成 9
##### 檔案內容如下 #####
reject = 150;
add_header = 6;
greylist = 4;

5. 設定 Roundcubemail Plugin

透過 markasjunk plugin 將 mark spam 的信, 搬到 spam folder
上面也設定了 dovecot 會去看被搬進 spam 資料夾的信, 會自動呼叫 rspamc 做學習

##### 有改動到的項目 #####
...
...
$config['plugins'] = ['password', 'markasjunk'];
cp <Roundcubemail_DIR>/plugins/markasjunk/config.inc.php.dist <Roundcubemail_DIR>/plugins/markasjunk/config.inc.php

DKIM

我們透過 RSPAMD 的 dkim_module 來幫我們處理 dkim

mkdir -p /var/lib/rspamd/dkim
rspamadm dkim_keygen -s 'dkim' -b 2048 -d example.com -k /var/lib/rspamd/dkim/example.com.dkim.key > /var/lib/rspamd/dkim/example.com.dkim.key.pub
rspamadm dkim_keygen -s 'dkim' -b 2048 -d example.com.tw -k /var/lib/rspamd/dkim/example.com.tw.dkim.key > /var/lib/rspamd/dkim/example.com.tw.dkim.key.pub
chown -R _rspamd: /var/lib/rspamd/dkim

要確定 /var/lib/rspamd/dkim 和 /var/lib/rspamd/dkim/* 的權限為 _rspamd
否則 dkim 不會生效

##### 檔案內容如下 #####
domain {
    example.com {
        path = "/var/lib/rspamd/dkim/example.com.dkim.key";
        selector = "dkim";
    }
    example.com.tw {
        path = "/var/lib/rspamd/dkim/example.com.tw.dkim.key";
        selector = "dkim";
    }
}

設定 DNS record

cat /var/lib/rspamd/dkim/example.com.dkim.key.pub

會輸出像下面的內容

dkim._domainkey IN TXT ( "v=DKIM1; k=rsa; "
  "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxfvW0mJGHMQ7CW3oe4jvSzVmDNSyjhoHn2iuue+E7aK9C4IDqJPKxqV8srRpdU2O8LdhiT6gnj3SxHPHRMxcoL4cwggn7SUmSreBD0uBfDcqD2bfQKpB5OMBzNRqpmoMijJYtiNGOkELBHhtsIYjBljhhiGAD8Iq/fA92oVyjJfsCUC0cZF0aJoBNWPaZVAqflVWR8SEm8tV3krN0"
  "AooknHI6UNMIE5PiaSVTWHZipRKgIcSCfJ7moPIopQvZqV27zC2ehoQ3eoYnrvZpm74vzIrGM+qd02EhwN6lCz2AHP5rla6brWh7zQ4uq2T2ImeWQGL3BNDVhc2TdiTp1d9oQIDAQAB"
) ;

取出 括號內容的內容整理成一行 去掉 “

v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxfvW0mJGHMQ7CW3oe4jvSzVmDNSyjhoHn2iuue+E7aK9C4IDqJPKxqV8srRpdU2O8LdhiT6gnj3SxHPHRMxcoL4cwggn7SUmSreBD0uBfDcqD2bfQKpB5OMBzNRqpmoMijJYtiNGOkELBHhtsIYjBljhhiGAD8Iq/fA92oVyjJfsCUC0cZF0aJoBNWPaZVAqflVWR8SEm8tV3krN0AooknHI6UNMIE5PiaSVTWHZipRKgIcSCfJ7moPIopQvZqV27zC2ehoQ3eoYnrvZpm74vzIrGM+qd02EhwN6lCz2AHP5rla6brWh7zQ4uq2T2ImeWQGL3BNDVhc2TdiTp1d9oQIDAQAB

在你的 DNS 加上一筆 名稱為 dkim._domainkey 的 TXT Record
值(value) 就是上述 v=DKIM1……. 的內容
參考下圖

可以透過 dig 檢查是否設定正確

dig dkim._domainkey.example.com TXT +short

DMARC

在你的 DNS 加上一筆 名稱為 _dmarc 的 TXT Record
值(value) 為 v=DMARC1; p=none; adkim=r; aspf=r;

NFS

##### 有改動到的項目 #####
# Single Dovecot server setup or Dovecot director cluster setup:
mmap_disable = yes
mail_fsync = always
mail_nfs_storage = no
mail_nfs_index = no

# Multi-Server server setup that tries to flush NFS cache (increases NFS operations, and isn't fully reliable), try not to use this
#mmap_disable = yes
#mail_fsync = always
# These settings slow things down and don't fully work, use director proxy instead:
#mail_nfs_storage = yes
#mail_nfs_index = yes

Ratelimit

##### 檔案內容如下 #####
# 若是沒有在 local.d/redis.conf 設定 redis, 則須要在這邊設定, 不然 ratelimit 不會生效
#servers="127.0.0.1"; # redis server
rates {
# Selector based ratelimit
    user = {
        selector = 'user.lower';
        # You can define more than one bucket, however, you need to use array syntax only
        bucket = [
            {
                burst = 120; # 只要寄件量超過 120 就要等 30 分鐘到了, 再開放的 60 封信的量
                rate = "60 / 30min"; # 每 30 分鐘 開放 60 信的 quota
            }
        ]
    }
}

Quota

mkdir /etc/dovecot/bin
vim /etc/dovecot/bin/quota-warning.sh
##### 檔案內容如下 #####
#!/bin/sh
PERCENT=$1
USER=$2
cat << EOF | /usr/libexec/dovecot/dovecot-lda -d $USER -o "plugin/quota=dict:User quota::noenforcing:proxy::sqlquota"
From: postmaster@luckyball.com.tw
Subject: Quota warning

Your mailbox is now $PERCENT% full.
EOF
##### 有改動到的項目 #####
mail_plugins = quota
##### 有改動到的項目 #####
...
...
service dict {
...
...
  unix_listener dict {
    mode = 0600
    user = vmail
    group = vmail
  }
}
...
...
##### 有改動到的項目 #####
protocol imap {
....
....
  mail_plugins = $mail_plugins imap_sieve imap_quota
....
....
}
##### 加在 最下方 #####
...
plugin {
  quota = dict:User quota::proxy::sqlquota
  quota_rule = *:storage=1GB
  quota_rule2 = Trash:storage=+100M
  quota_grace = 10%%
  quota_exceeded_message = Quota exceeded, please contact your system administrator.
  quota_warning = storage=100%% quota-warning 100 %u
  quota_warning2 = storage=95%% quota-warning 95 %u
  quota_warning3 = storage=90%% quota-warning 90 %u
  quota_warning4 = storage=85%% quota-warning 85 %u
}

service quota-warning {
  executable = script /etc/dovecot/bin/quota-warning.sh
  user = vmail

  unix_listener quota-warning {
    group = vmail
    mode = 0660
    user = vmail
  }
}

dict {
  sqlquota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
}
##### 檔案內容如下 #####
connect = host=127.0.0.1 dbname=postfix user=postfix password=thisispostfixadminpassword
map {
  pattern = priv/quota/storage
  table = quota2
  username_field = username
  value_field = bytes
}
map {
  pattern = priv/quota/messages
  table = quota2
  username_field = username
  value_field = messages
}

Ref.
https://doc.dovecot.org/installation_guide/dovecot_community_repositories/centos_packages/
https://www.postfix.org/postconf.5.html
https://doc.dovecot.org/settings/core/
https://blog.csdn.net/xianglingchuan/article/details/88144763
https://www.myfreax.com/install-and-configure-postfix-and-dovecot/
https://www.myfreax.com/install-and-integrate-rspamd/
https://serverfault.com/questions/928926/postfix-multi-domains-and-multi-certs-on-one-ip
https://www.mimecast.com/blog/ssl-vs-tls-vs-starttls-encryption/
https://rspamd.com/downloads.html
https://www.rspamd.com/doc/modules/dkim_signing.html
https://rspamd.com/doc/modules/ratelimit.html
https://doc.dovecot.org/configuration_manual/nfs/
https://doc.dovecot.org/configuration_manual/quota/
https://wiki.dovecot.org/HowTo/Fail2Ban
https://www.dovecot.org/list/dovecot/2016-July/105077.html
https://wiki.dovecot.org/Tools/Doveadm/Mailbox
https://www.benhup.com/freebsd/clamav-antivirus-for-rspamd-anti-spam-install#test-real-virus

發佈留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料