搭建廉價Cluster Mail Service - FrontEnd篇

Frontend 事實上有一大堆物體喺裡面,主要係負責客戶端服務(IMAP/POP3/SIEVE/SUBMISSION)同MX(Mail Exchange)。注意有米嘅網友們,唔好咁孤寒!要將SMTP服務同content filtering分開唔同嘅機做。

FrontEnd 工作內容,比較豐富,但貧窮嘅你同我,可以放嗮喺一部機度運行Frontend只係一個統稱,代表與外界連接嘅部份。圖中的紅色框框可以放喺唔同server上面run,仲可以多台機load balance。當中建議做content filtering嘅server做HA(唔load balance啦)或乾脆同時放埋入SMTP部機度。 你會見到個design只有一個連接,係統一嘅連接去backend。方法係採用Dovecot Director,Proxy嗮的service去backend處理。

至於咩係Submission?咪就係TCP/587咯,一般嚟講呢個PORT同SMTP一樣,不同之處係提供Authentication,所以將佢同唔需要身份驗證嘅MTA服務分開可以減少SMTP Gateway被hack嘅麻煩。注意一點,以前流行POP before SMTP已經無必要,呢個嘢嘅出現係因為古代嘅Outlook好白癡,方便唔到人去setup個email。依家就唔同,隨時可以auto configure嗮個email,都係用一致嘅password嚟Login個Submission Port去發送email。根本唔再需要呢個複雜嘅logic去控制。

SMTP係與MX對應。注意唔好懶醒目,用唔同嘅MX preference嚟映射到唔同嘅server,點解唔講啦。正常啲嘅做法係用最小嘅preference(即priority最高)load balance嗮去大部份嘅SMTP server。再用一個或兩個低啲嘅preference映射到一啲後備嘅server度。最高檔嘅做法係唔用自己嘅server同IP,到外面租機做SMTP server(當然要帶埋content filtering去啦),當個IP比人block,即刻申請多個換過去先慢慢trouble shoot。

好啦,下面將configure啦,一個個嚟:

Postfix

處理收發電郵嘅核心,喺今日你已經無選擇(唔通用QMAIL咩,已經停產超過10年),posftix已經壟斷咗Unix嘅market。如果今日你仲去用QMAIL底嘅solution,你真係要小心啲諗諗,唔係個solution有問題,係你個腦有問題。

呢個年代用POSTFIX基本上只係做以下幾件事:

1. MTA,即係SMTP Gateway,決定如何傳送電郵,如係喺本地派送定係傳到對方MTA,定係RELAY比另一個SMTP Gateway

2. 檢查SPAM

3. 檢查VIRUS

如果唔考慮電郵Account嘅個人SPAM設定,可以好簡單(要都唔煩,自己諗諗,我嘅setup已經幫你喺LDAP度搵埋正確嘅userid,必須優先考慮通過database做又兼容spamassassin嘅solution)。注意我地唔會用Postfix嚟做本地分發(deliver)email,而係用LMTP比埋Dovecot做統一處理,呢個係整個infrastructure嘅要點之一。因為要集中用Dovecot Proxy嚟將相同Account嘅email分配到一個指定嘅Backend Server嚟處理。個Backend Server都係一部Dovecot Server,個/home就係由NAS提供,同一個Account都永遠比死一個Backend Server嚟讀寫佢自己個home directory,咁就唔會因為用咗cache而corrupt個file system。

講翻Postfix main.cf 嘅 configure,有下幾個部份:

TLS 加密

SMTP同Submission都要設定。呢個年代,我地會流行用STARTTLS(做IMAP、LDAP等連接都會用都),特點係唔洗咁多個port,加密同唔加密都係用同一個port去做。當發現服務端支援呢個方式就會進行加密傳輸。

smtpd_tls_cert_file = /etc/ssl/certs/ssl-mail.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-mail.key
smtpd_use_tls = yes
smtpd_tls_received_header = yes
smtpd_tls_mandatory_protocols = SSLv3, TLSv1
smtpd_tls_mandatory_ciphers = medium
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
tls_random_source = dev:/dev/urandom

注意所有Postfix、Dovecot都係用同一張cert同key,全場嘅機都要係一樣!唔買張堅Cert都無咩大問題,不過有米嘅最好申請張堅Cert。

 

設定 Network

mynetworks_style = host     # 乾脆狠啲,只接受本機,再用下面呢句嚟指定咩IP可以無須認證轉發
mynetworks = 127.0.0.0/8 192.168.101.0/24 10.3.3.21 10.2.2.21
inet_interfaces = all       # 呢句唔係default,一定要改,一般都all架啦
inet_protocols = ipv4       # 如果唔用IPv6,最好off咗佢,因為有幾個相關directive係有影響嘅,default係開嘅。all就係有埋IPv6

呢幾句都好標準架啦,夠靚仔架啦。當中注意儘量唔好成個subnet比喺mynetworks度,一般client如outlock、thunderbird都用埋AUTH LOGIN SMTP嚟sent email算啦。理論上純做Submission嘅Postfix最好只有127.0.0.0/8。注意我無起IPv6,如果你有,加埋 [::1]/128唔該。而SMTP嘅Postfix就記得加埋所有Submission嘅IP(設計得好啲嘅係用一個subnet,通過一個VLAN幫Submission send信)。

呢度提一提,成個Postfix main.cf嘅改動,就係呢度要行service postfix restart,其它directive同相關表嘅改動係唔洗restart,唔好咁笨。

 

申報本地電郵domain

以下directive統統影響你個電郵接收,收唔收一個email deliver到你個mailbox,全部由下面設定決定,好緊要!有時候你會收埋啲唔想要嘅嘢,都系因為呢度出事。

recipient_canonical_maps = regexp:/etc/postfix/canonical   # 呢個嘢識得用會好好用,可以代換個目的email先再處理
mydestination = $myhostname  # 可以寫好多個domain,當發現目的電郵domain係同呢度其中一個一樣,咁Postfix就會食咗個mail去deliver 
virtual_alias_domains = /etc/postfix/domains  # 最好用嗮呢個嚟列出本機要處理嘅email domain,一行一個
virtual_alias_maps = hash:/etc/postfix/virtual   # 呢個係email同本地user(loginname)嘅對應表
alias_maps = hash:/etc/aliases    # 標準嘢,sendmail年代咸豐年嘅嘢,唔講啦
alias_database = hash:/etc/aliases    

其中 virtual_alias_domains 可以直接寫domain喺 = 後面,或用過file放。改咗/etc/postfix/domains就要postfix reload。當email目的地吻合就會deliver (睇DELIVER),唔中又唔喺mydestination就會繼續轉發(睇 RELAY)。而virtual_alias_maps 就最重要,放嗮啲email入去,一行一個,格式好簡單,前面係email,後面係本地user name,可以用逗號分隔寫好多個本地user或外部email,會同時分發同轉發嗮。update完記得打postmap /etc/postfix/virtual。注意我呢度用text file舉例,遲啲會改嗮用LDAP lookup。virtual_alias_maps係可以喺LDAP搵倒個關係嘅。

我強烈建議唔好用mydestination,用嗮virtual嚟處理,皆因mydestination代表個電郵名(@前面)等於O/S user login名,兩個naming標準極度唔同,不如唔好用。有好多時候個user login都可能係用代碼,如 u453423 咁樣,費事煩。至於呢個代碼如何映射到一個email address,用戶係唔係要記多個代碼都由LDAP同小弟嘅技巧嚟解決,用戶永遠只有兩樣嘢要記,就係email同password。

canonical 係用嚟做代換嘅,例如你有幾個domain alias,但系mailbox都係同一個,可以用呢個方法嚟代換,注意用嘅係regex!

/^(.*)@smtp.aconcept.info/        $1@aconcept.info
/^(.*)@advancedconcept.com.hk/    $1@aconcept.info

 

純SMTP可以無本地domain

講嗮申報自身domain嘅方法啦,依家講講Submission同SMTP嘅postfix setting上有咩分別,可以一樣嘅,但係知道你地有啲玩花式嘅係唔滿意架啦。事實上如果SMTP係分離嘅可以簡化:

mydestination = $myhostname  # 你千奇唔好將自己嘅hostname改到同domain一樣呀!如果唔係神仙都幫唔倒你 
virtual_alias_domains =  # 唔用!
virtual_alias_maps = # 都唔用!!咁即係點呀?
relay_domains = /etc/postfix/relaydomains  # 同上面講個virtual_alias_domains內容一樣
transport_maps = hash:/etc/postfix/transport  # 就係用內聯網轉發,將屬於自己domain嘅轉比Submission部Postfix就收工

講講個transport嘅寫法,update完記得行一次postmap /etc/postfix/transport,乖啦!見到有hash:嘅表就行啦:

aaa.com.hk smtp:[10.3.3.20]
bbb.com.hk smtp:[10.3.3.20]
xxx.com smtp:[10.3.3.20]
yyy smtp:[10.3.3.20]

其中 10.3.3.20 係你部Submission嘅IP,注意可以寫FQDN嘅,通過DNS resolve都得,又可以用load balance嘅IP。

呢度出現咗relay_domains啦,要講講唔好將同一個domain同時放喺virtual_alias_domains同relay_domains,係無意義嘅!唔係話你錯,係無意義同會出warning,自己諗諗點解。最後在三溫馨提示,改完記得postfix reload

呢個做法有好大好處。就係SMTP根本唔需要接觸LDAP等內部信息。只要兩個表就夠,因為SMTP係公開嘅,係人都可以TCP/25接入,你無得block嘅,block咗等於唔做生意。

 

RELAY

relay嘅應用有啲講究架。喺一個比較複雜嘅infrastructure裡面,要活用transport map。

relayhost = [smtp1.att.net]  # 如果你係扮演大型網絡電郵供應商,就comment咗佢,唔係會比人笑。對於私人公司,儘量用ISP比你嘅SMTP Gateway
transport_maps = hash:/etc/postfix/transport  # 內聯網轉發,通過唔同嘅domain,決定轉發到下一個MTA

呢兩個directive可以活用。一般大型電郵服務供應商都需要自己直接發送,咪洗旨意IDC、ISP幫你轉發,佢采 你都傻。但系私人公司,就最好通過ISP轉發,原因係當你個Mail Server出事(SPAM咗)嘅時候,全世界都會睇唔起你,唔接受你嘅轉發,甚至唔Send email比你。如果通過ISP轉發,ISP會先Block咗你,然後再打電話比你。咁你就簡單,救翻部機唔SPAM人地時寫份悔過書比ISP就可以開 翻。比人SPAM咗個IP係好煩嘅,所以要識得借廁所。

而transport map嘅用法就自己查查,記得update完打postmap /etc/postfix/transport!佢一般係幫你做內部轉發。例如你個Postfix只係用嚟做SPAM同ANTIVIRUS,DNS個MX 直接指落呢個PUBLIC IP,咁就可以list嗮你公司要處理嘅domain(有限數),指定呢啲domain嘅email就通過內網轉發到真正處理電郵嘅Mail Server。你喺街邊買翻嚟部Barracuda、IronPort全部個湯底都係咁整出嚟嘅。而目的電郵地址無喺呢個map出現嘅email,如果有 relayhost會盲目掟過去。

好!返嚟講翻Submission同SMTP嘅正確SET法。

SMTP而言,relayhost可以對住ISP或係空(講咗點解啦)。transport_maps要睇你係唔係分開server做同做唔做本地電郵account configure(分開run一般唔做)。假如係得一部Postfix做嗮,呢個表理論上係空嘅,假如唔係,上面講咗!

Submission嘅relayhost多一個選擇,就係指向SMTP,統一通過SMTP send,避免咗用port 25做出入,就等於避免咗比人list做spam。transport可以講一定係空架啦。

總結RELAY嘅精神係儘量只比一個公共IP做MX同send out email,出事即換。

 

CONTENT FILTERING

講到好高級咁,其實configure得一句。如果你有個獨立嘅Postfix或啲貴嘢(街邊買嗰啲如ironport呀barracuda呀咁),就唔好重複做啦,好嘥米飯嘅(有米又例外播!)。

content_filter = smtp-amavis:[amavisserver]:10028

我地用amavis service嚟隔spam同virus,至於點設定遲啲講(搵 amavis)。呢個directive就好簡單,個service喺邊部機都run通過[ ]中間個IP同後面個port決定。正路嚟講,好多時候考要考慮到redundant、HA等問題,係可以同時安裝埋喺部postfix度。退一步你又可以唔考慮redundant,死咗算數!因為大不了唔filter,Postfix會識得bypass嘅。

注意一點係個port,假如你用一部機(load balance IP都算一部架!)做amavis,要服侍多部Postfix,係需要用唔同嘅port嘅(都叫咗放埋一齊唔洗煩!),你用唔同嘅port先啦,之後先講點set個amavis。

 

DELIVER

我啲選用LMTP protocol嚟做deliver,用法都係好簡便(喺dovecot set餐死就另一回事:>)。

mailbox_transport = lmtp:inet:[127.0.0.1]:24
virtual_transport = lmtp:inet:[127.0.0.1]:24

一般情況都係同一部機,唔 係就寫翻個IP,注意LMTP係100%唔可能比第三者用,一定要用一個內部網絡搞掂佢(只有postfix, dovecot director同backend dovecot server)。注意呢個IP係director嘅IP,唔系部Backend Server!咩係director下面會講。

注意Submission嘅Postfix先需要有deliver,喺純SMTP嘅Postfix上面可以通過transport relay比嗮Submission嘅Postfix做,上面講咗做法同理由。所以純SMTP嘅setting唔好打呢兩句!

 

認證與安檢

點先可以比個email喺你部 Server經過,呢個係好哲學嘅問題。先聲明下面可能有多可能有少,不過差唔得幾遠架啦。先講點理解認證,佢只係提供一種手法比一個陌生IP可以令 permit_sasl_authenticated 成立個手段。成立後仲需要進一步個安檢嚟控制嘅,下面慢慢講:


# Submission 先有需要加呢三句,SMTP唔可以有!
# smtpd_sasl_auth_enable = yes        # 呢幾句說明我部SMTP提供認證檢查,要知點解自己上網查啦,重有sasl要set架,下面講
# smtpd_sasl_authenticated_header = yes
# broken_sasl_auth_clients = yes

smtpd_recipient_restrictions =      # 呢個係針對目的電郵地址嘅檢查,即 RCPT TO: 個value
  reject_non_fqdn_recipient,        # domain 名必須係fqdn,即係DNS查得出,否則即刻reject
  permit_mynetworks,                # client IP喺mynetworks上就放行
  check_sender_access hash:/etc/postfix/sender_access,   # 即系檢查FROM個email domain中唔中,中就比佢send
  reject_unauth_destination         # 呢句無咗一定報錯,信試試
smtpd_sender_restrictions =         # 檢查FROM: 個value
  reject_unknown_sender_domain,     # DNS無效唔做,呢句已經避免咗大量random gen嘅惡意junk mail
  check_sender_access hash:/etc/postfix/sender_access  # 上面講過啦
smtpd_client_restrictions =         # 呢個限制其實可以唔用,如果單純用port 587嚟做用戶認證
  check_client_access hash:/etc/postfix/access, # 你可以用一個table去DISCARD(一般唔用REJECT架啦)某個domain、IP、email
  permit_mynetworks,                # client IP喺mynetworks上就放行,default都應該係咁
  permit_sasl_authenticated,        # 就係呢一個value處理已認證嘅connection
  reject_unauth_destination         # 上面講咗啦
smtpd_peername_lookup = no          # 不要求client ip能夠喺DNS度有反向lookup,可以節省CPU time

注意純SMTP server只要無咗頭三級就足以令LOGIN AUTH失效,其它configure可以寫到一樣都OK。而比較正規嘅做法係喺master.cf裡面configure Submission(port 587),呢度只係影響port 25,可以唔寫嘅。實際認證電郵account映射喺sasl嘅setup裡面,唔好心急,一陣講。

 

功能性設定

唔好睇小呢啲setting,可以救你一命。尤其是有關rate嘅設定,例如bounce back嘅email好多時候都係製造ddos嘅根源,係咁依比2 hours嘅lifetime,兩個鐘後就放棄,唔再嘥時間去retry,皆因九成九對方係不存在。

message_size_limit = 150000000               # 單位默認係byte,記得set!set幾大你收發嘅email就可以幾大
default_destination_concurrency_limit = 2    # 最多只可以同時連接到2個相同嘅MTA發送
default_destination_rate_delay = 3s          # 對同一個MTA,隔3秒先send下一個email
smtpd_client_message_rate_limit = 15         # 呢個係針對每分鐘可以send幾多個email到同一個MTA
queue_run_delay = 45m                        # 衰咗嘅email隔大半個鐘先再試
maximal_queue_lifetime = 3d                  # 對於任何轉發,如果反覆測試3日都有error,就放棄
bounce_queue_lifetime = 2h                   # 對於bounced back嘅email,如果反覆測試2個鐘都有error,就放棄

 

擴展 master.cf

以上統統係 main.cf嘅configure,而master.cf係掌管socket service,有幾個位置要做做手腳,注意改咗master.cf就要restart postfix啦。

提供tcp port 587連接

哪!唔好用網上啲IPTABLES redirect 方法,會比人笑嘅,啟動tcp port 587係用以下方法,default唔開姐。

submission inet n       -       -       -       -       smtpd
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_sasl_authenticated_header=yes
  -o broken_sasl_auth_clients=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject   

哪哪哪!呢度有自己嘅directive做587嘅認證,係可以同port 25唔同嘅!嗰三句yes,見唔見到?

處理queue時用

我都唔知係乜,你最好話我知。

pickup    fifo  n       -       -       60      1       pickup
         -o content_filter=
         -o receive_override_options=no_header_body_checks

接收amavis返回結果。如果係本機做amavis就係用127.0.0.1,如果amavis喺另一部腦度,就要用一個本機IP。注意個port 10025,唔一定係呢個,當部amavis有幾個老婆嘅時候,就要注意啦,點set睇埋amavis就知架啦。

10.1.1.110:10025 inet    n       -       -       -       -       smtpd
        -o content_filter=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o smtpd_restriction_classes=
        -o smtpd_delay_reject=no
        -o smtpd_client_restrictions=permit_mynetworks,reject
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o smtpd_data_restrictions=reject_unauth_pipelining
        -o smtpd_end_of_data_restrictions=
        -o mynetworks=127.0.0.0/8,10.1.1.0/24                # 最重要嘅部分,要包括amavis server個IP
        -o smtpd_error_sleep_time=0
        -o smtpd_soft_error_limit=1001
        -o smtpd_hard_error_limit=1000
        -o smtpd_client_connection_count_limit=0
        -o smtpd_client_connection_rate_limit=0
        -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

 

SASL設定

好!講嗮Postfix喺Submission同SMTP嘅configure啦,一啲都唔複雜。其實Submission嘅Postfix如何認證,你都未見到啲configure做喺邊樹。答案係用SASL服務。先講下安裝:

apt-get install sasl2-bin libsasl2-modules-ldap 

安裝無咩特別,configure就辛苦啲。第一個file係/etc/default/saslauthd。有以下幾個directive,自己領略下:

START=yes            # 唔洗問啦掛
MECHANISMS="ldap"    # 注意default係pam,即係用o/s user做authentication
THREADS=3            # 視乎你個server有幾多生意,不過理論上10個至15個算啦,人多等佢地排下隊
OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd"   # 呢句就係精粹啦!控制個socket點create,記得同check個permission,postfix user要讀寫到

未完,仲有個LDAP係喺呢度做configure;/etc/saslauthd.conf。簡單到痹,只係無咩人知道係呢個file。

ldap_servers: ldap://ldapserver
ldap_search_base: ou=People,dc=abc,dc=com
ldap_filter: (&(objectClass=person)(|(mail=%u)(uid=%u)))

唔洗點解釋啦,最後個filter方法大家學學啦,有啲白癡打兩三嘅file做同一件事:用email同username都compatible。其實一句搞掂。

最後一個file /etc/postfix/sasl/smtpd.conf,漏咗呢個file保證check死你,postfix唔知咩年代開始搵呢條path做sasl嘅setting,以前係睇大圍嘅。smtpd個名係有意思,係Postfix sasl嘅default protocol名,唔好改啦,照用啦!裡面一句都OK。

pwcheck_method: saslauthd

 

小結

咁樣個Postfix喺SMTP同Submission嘅功能都靚仔嗮。記住,實際上兩個角色假如分體也可以用相同嘅configure,只係security程度低啲姐,唔死得人嘅。等有空再寫埋amavis啦,瞓啦!