搭建廉價Cluster Mail Service - AMAVIS篇

諸位睇過前面幾篇文章都知道Postfix有個Content Filtering嘅東西未講。先強調一點,amavis係同Postfix一對(當然可以發生婚外情),同Dovecot無咩關係。重點係可有可無,係呀!呢個係重點嚟架。即係代表唔好諗得太複雜,任何solution都可以接受佢暫時失效,只要你個腦可以容忍到就得架啦。

先講解一下AMAVIS嘅理論,注意佢喺Postfix嘅運作方法都有啲煩,為咗清楚啲,我會重複相關Postfix嘅configure。AMAVIS等價于基本SMTP protocol,你connect咗就講過RFC822流入,就會喺幫你過濾,過濾完會同樣用SMTP protocol轉發去一個指定嘅IP同port。注意一點佢係盲目咁喺一個port流入再流出到另一個SMTP,永遠都係嗰一個!明白咗理論你應該有一個大問題,就係點用?我邊configure邊講啦,唔好心急。

 

安裝

安裝唔難,install嗮呢堆嘢就搞掂:

apt-get install amavisd-new spamassassin clamav-daemon -y
apt-get install libnet-dns-perl libmail-spf-query-perl pyzor razor -y
apt-get install libnet-dns-perl libmail-spf-perl pyzor razor -y
apt-get install arj bzip2 cabextract cpio file gzip lha nomarch pax rar unrar unzip zip zoo -y

第一行係基本嘅package。第二三行都係必要嘅。最後話係optional,但係無咩可能唔裝,有部份可能已經安裝好,一睇就知全部都係啲處理壓縮文件嘅工具。

 

使用權限

有兩個user,amavis clamav 都需要對方嘅group right,咁做就得:

adduser clamav amavis
adduser amavis clamav

 

踢著spamassassin

有兩個variable要set做1。打開 /etc/default/spamassassin ,將ENABLEDCRON set 做1。好似咁:

ENABLED=1
CRON=1

順便教教大家點記spamassassin呢個咁長嘅英文字點串,你只要記住:將罐午餐肉(spam)向住屎眼(ass)+插入(in)兩下, 咁就保證你記得。

 

設定amavis

一般情況,我地會將啲個性化嘅configuration放嗮落 /etc/amavis/conf.d/50-user 度,方便upgrade同管理。先講啲基本嘢:

@local_domains_acl = qw(.);   # 呢句就經典啦,唔好一個個email domain入啦,你唔會記得去加減架!入一點就OK,代表所有
@inet_acl = qw( 127.0.0.1 [::1] 10.3.3.50 10.3.3.51 );  # 用amavis嘅server,要小心唔好漏,上網搵無人教你係呢度出事
$sa_spam_subject_tag = '[SPAM] ';   # 如果係SPAM咗,加個咩label喺SUBJECT 
$sa_tag_level_deflt  = -999;   # 呢個係喺個RFC822 MAIL 內容裡面加入被spamassassin檢查過嘅標記,一個大嘅負數代表係唔係都加
$sa_tag2_level_deflt = 7;   # 假如SPAM計算分數大過呢個值就加[SPAM] label
$sa_kill_level_deflt = 33;   # 假如SPAM到33分以上,就真係好SPAM架啦,將會丟棄
$final_virus_destiny = D_DISCARD;   # 有virus就丟咗佢
$virus_quarantine_to = undef;

$final_banned_destiny = D_BOUNCE;    # bounce back就真係bounce back比個物主
$banned_quarantine_to = undef;

$final_bad_header_destiny = D_PASS;    # 有古怪header,即係amavis睇唔明就唔理啦,時運高當睇唔到,當pass
$bad_header_quarantine_to = undef;

$final_spam_destiny = D_DISCARD;    # 上面sa_kill_level_deflt嘅真正處理方法,default係D_REJECT嘅
$spam_quarantine_to = undef;

其實上面嘅 undef  地方可以填一個email address,咁係做動作之餘同時會send比呢條友以作保存。undef 就代表唔要保存啦。

 

amavis有多個客仔嘅處理手法

假如amavis唔係靜係服侍同一個server(localhost)嘅Postfix,就要有啲本事。我解釋一下,實際amavis係通過一個port流入(用smtp protocol接收),處理完之後再forward比一個MTA(即係SMTP gateway),如default流入嘅port係10024,流出個port係10025(注意呀,呢個port係比forward去嗰個SMTP用!即係個SMTP用嚟listen嘅port,而呢個SMTP當然唔需要做content filtering。你唔係問我點解唔洗filter哇!?你想死循環咩!)。如果你除咗localhost呢個client,仲有其它postfix要用,咁就要啲手段啦:

首先要增加幾個listening port,一個比一個client用!

$inet_socket_port = [10024,10026,10028];
除咗default嘅10024,仲有10026同10028。跟住就係用policy呢家嘢嚟對付,做兩個policy比兩部postfix:
 
$interface_policy{'10026'} = 'gateway1';
$policy_bank{'gateway1} = {
  originating => 1,
  smtpd_discard_ehlo_keywords => ['8BITMIME'],
  forward_method => 'smtp:[10.3.3.50]:10025',
  inet_acl => [qw( 127.0.0.1 [::1] 10.3.3.50 )],
};

$interface_policy{'10028'} = 'gateway2';
$policy_bank{'gateway2'} = {
  originating => 1,
  smtpd_discard_ehlo_keywords => ['8BITMIME'],
  forward_method => 'smtp:[10.3.3.51]:10025',
  inet_acl => [qw( 127.0.0.1 [::1] 10.3.3.51 )],
};
可以見到唔同嘅policy,configuration可以有小小唔同。其實上面inet_acl可以唔寫,用global嘅。最重要係forward_method,就係靠呢句比翻個postfix,千其唔好set錯!為咗配合,例如你部gateway1(10.3.3.50)嘅postfix就要對應做configure:
 
gateway1 嘅 /etc/postfix/main.cf:
content_filter = smtp-amavis:[10.3.3.10]:10026
當中10.3.3.10就代表部amavis server嘅IP,而port 10026就係代表用定義好嘅policy gateway1。
 
gateway1 嘅 /etc/postfix/master.cf:
10.3.3.50: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.3.3.0/24
        -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
用呢個方法加一個10025 port 嚟 listen,注意 mynetworks 中有amavis server嘅IP。用呢個port嚟接收filter後嘅結果,喺呢度接收嘅mail唔會再send去filter架啦。
 

巧妙避免重複filter

其實醒目嘅你都知道,如果一啲完全唔需要filter嘅mail可以直接smtp入呢個port,避免重複filter。尤其是你嘅frontend係分開多部腦做,咁喺做Submission嘅postfix,main.cf嘅relayhost可以用 (Submission 角色): 
relayhost = [10.3.3.61]:10025
其中10.3.3.61係你部SMTP,用佢嚟send出Internet。因為喺Submission嘅postfix已經做咗content filter啦,所以去到SMTP部postfix度就唔洗再filter,避開呢個重複動作嘅方法就係借10025用。而SMTP嘅postfix都有相同嘅生理需要,就係當發現係本地電郵時,會用transport send比Submission個postfix做locol delivery,咁/etc/postfix/transport 嘅定義方式改改就掂,如 (SMTP 角色):
aconcept.info smtp:[10.3.3.51]:10025
如是者Submission同SMTP兩兄弟就唔洗重複filter。能夠咁set,大前提係amavis係compatible SMTP protocol嘅。
 

參考資料:https://help.ubuntu.com/13.04/serverguide/mail-filtering.html