5. 關于延遲郵件的再投遞控制
可以通過以下的幾個參數實現對延遲郵件的再投遞控制:
queue_run_delay:設置隊列管理進行掃描deferred郵件隊列的頻率,缺省值為1000秒。
maximal_queue_lifetime:設置postfix在放棄投遞而返回不可投遞信息前,被延遲郵件再deferred郵件隊列中的生存時間。
minimal_backoff_time:當一封郵件投遞失敗后,郵件隊列將在一段時間內忽視該郵件的存在,也就是我們前面講的時間郵票。該參數就是用來設置最小的時間郵票。缺省值為1000秒。
maximal_backoff_time:設置最大的時間郵票。
6. 對拒絕服務攻擊的處理
postfix對每一個SMTP會話都設置一個錯誤計數器,當該客戶端的請求未
被接受或違反那UCE規則時,該計數器就增1。隨著計數器的增加,postfix將采取不同的措施來防止惡意用戶的拒絕服務攻擊。
smtpd_error_sleep_time:當該錯誤計數器的值還很小時,postfix將暫停
smtpd_error_sleep_time指定的時間,然后向客戶端報告一個錯誤。該參數的缺省值為5秒。
smtpd_soft_error_limit:當錯誤計數器的值超過該參數指定的值時,postfix在響應該客戶端請求前將沉睡一段時間。缺省值為10。
smtpd_hard_error_limit:當錯誤計數器的值超過該參數指定的值時,postfix
中斷同該客戶端的連接。缺省值為100。
4.5 postfix對使用資源的控制
通過特定的postfix配置參數,我們可以實現postfix運行時對所消耗的資源的靈活控制??梢酝ㄟ^以下幾個方面來控制postfix消耗的資源:
1. 限制內存中的對象的大小
要控制對內存資源的消耗,必須控制內存中對象的大小??梢杂靡韵碌膮祦磉M行對象大小的控制:
line_length_limit:控制讀入數據時每一行的大小,如果太長則強行將其分割成更短的行,太長的行在投遞時再重組。缺省值為2048 bytes。
header_size_limit:限制信頭長度。缺省值為102400bytes。
message_size_limit:限制postfix隊列文件的大小。缺省值為10240000 bytes。
queue_minfree:郵件隊列中可用的空間大小。缺省為無限制。建議該值最好時message_size_limit的數倍以便于處理大郵件。
bounce_size_limit:限制某一郵件不可投遞時,返回給發件人不可投遞報告的大小,缺省值為50000 bytes。
2. 限制內存中對象的數目
qmgr_message_recipient_limit:設置內存中收件人地址的最大數目。缺省值為10000。
qmgr_message_active_limit:設置active郵件隊列中郵件數目的最大值。缺省值為1000。
duplicate_filter_limit:設置需要local和cleanup后臺程序記住的收件人地址的最大數目。缺省值為1000。
3.限制等待一個外部命令完成的時間
command_time_limit:設置local程序等待一個外部命令完成的時間。缺省值為1000秒。
4. 限制文件鎖定的操作時間
deliver_lock_attempts:設置鎖定一個文件的最大嘗試次數。缺省值為5次。
deliver_lock_delay:設置如果鎖定一個文件失敗后再次嘗試的等待時間,缺省值為1秒。
5. 控制錯誤恢復
在某些情況下(如高負載),postfix的某個進程可能會死掉,這時master進
程會試圖重新啟動該進程,我們可以通過下面的參數來控制這種行為:
fork_attempts:試圖重啟動一個進程的最大嘗試次數。缺省值為5次。
fork_delay:每兩次嘗試之間的等待時間,缺省值為1秒。
transport_retry_time:隊列管理進程每兩次嘗試連接一個不正常的投遞代理進程之間的等待時間。缺省為60秒。
4.6 postfix中的地址操作
1. 將地址改寫為標準格式
在cleanup進程進行表查詢之前,它首選請求trivial-rewrite進程將新
郵件地址改寫成標準的格式。改寫的目的是為了減少查詢表中的條目,從而提供查詢的效率。trivial-rewrite進程可以實現以下的地址改寫:
* 將包含源路由信息的地址如@hosta,@hostb:user@site寫成,因為postfix不支持包含源路由信息的地址格式。
* 將形如user%domain的地址改寫成的形式。該特性可通過allow_percent_hack參數進行控制,其缺省值為yes。
* 將只包含user的地址改寫成。該特性可通過append_at_myorigin參數進行控制,其缺省值為yes。最好不要改動其缺省值,因為大多數的postfix進程更擅長處理地址形如的郵件。
* 將形如的地址改寫成。該特性可通過append_dot_mydomain參數進行控制,其缺省值為yes。
* 將形如.的地址改寫成 ,也即除去了最后的點號。
2. 規范地址映射
在cleanup進程將一封新郵件存入incoming郵件隊列之前,cleanup進程
將根據查詢規范表來進行地址改寫,從而使之更具可讀性。主要是替換形如Firstname.Lastname 風格的地址以及清除無效的域。缺省postfix是不進行規范地址改寫的,你可以通過指定canonical_maps參數的值來使其生效。如:
canonical_maps = hash:/etc/postfix/canonical
也可以分別為收件人和發件人地址分別指定不同的改寫規范,這時參數sender_canonical_maps和recipient_canonical_maps的優先級比canonical_maps高。如:
sender_canonical_maps = hash:/etc/postfix/sender_canonical
recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
3. 地址欺騙
就是將形如的地址改寫成或,
好像是從其他的郵件服務器發出的一樣。缺省該功能是被禁止的,可以用參數masquerade_domains使其生效,如:
masquerade_domains = $mydomain
也可以通過masquerade_exceptions參數對特定的用戶不進行地址欺騙,如:
masquerade_exceptions = root
注意:地址欺騙只對發件人地址有作用。
4. 虛擬地址映射
在運用了規范地址映射和地址欺騙之后,cleanup將使用虛擬表映射將郵件
重定向到所有的收件人。注意,該操作僅僅作用于信頭上的收件人地址。這樣,我們就可以將發送到虛擬域的郵件投遞到真實用戶的郵箱。系統的別名數據庫同樣可以起到相同的作用。缺省該功能是被禁止的,可以用參數virtual_maps使其生效,如:
virtual_maps = hash:/etc/postfix/virtual
5. Relocated數據庫查詢
Relocated表格提供如何將郵件發送給在系統中沒有帳號的用戶。缺省該功能是被禁止的,可以用參數relocated_maps使其生效,如:
relocated_maps = hash:/etc/postfix/relocated
6. 別名數據庫查詢
當郵件在本地投遞時,local投遞代理進程會在別名數據庫(linux下為
/etc/aliases)中查詢收件人的別名。該操作不會作用于郵件信頭中的地址??梢杂胊lias_maps指定使用的別名數據庫。缺省地,該功能是有效的,如:
alias_maps = hash:/etc/aliases
可以通過alias_database參數控制別名數據庫的路徑,如:
alias_database = hash:/etc/aliases
五、 postfix的配置實例
5.1為撥號用戶配置postfix
假設有一個小公司使用撥號上網,公司通過ISP的SMTP服務器(假設其域名為mail.isp.com,ip地址為201.110.1.100)發送郵件;公司內部的員工通過公司的SMTP服務器(運行postfix)收發郵件,下面我們一起來配置公司內部的SMTP服務器。
1. 因為沒有自己的固定ip和域名,所以必須指定ISP的SMTP服務器作
為郵件網關(智能主機)??梢杂萌缦碌膮抵付ǎ?
relayhost = [201.110.1.100]
注意:relayhost的值可以是domain、host、host:port、[address]或[address:port]。
2. 當接收到新郵件時,postfix就會嘗試投遞該郵件。如果將該公司內部的
SMTP服務器設置為按需撥號,也就是一有程序請求外聯就撥號,則會增加上網的費用。這時我們可以通過postfix的defer_transports參數推遲投遞新郵件直到postfix提出明確的要求,如指定:
defer_transports = smtp
這時如果我們在ppp的腳本(如/etc/ppp/ip-up.local)加上如下命令,則postfix只在撥號成功后投遞新郵件:
/usr/sbin/sendmail
3. 因為我們是將郵件轉發到郵件網關(201.110.1.100)而不是自己進行投
遞,所以我們沒有必要使用DNS,因此我們通過如下的參數取消DNS查詢:
disable_dns_lookups = yes
4. 為了保證我們能收到回信,我們必須進行域偽裝。
masquerade_domains = isp.com
下面就是我們的配置文件mail.cf:
#指定郵件網關
relayhost = [201.110.1.100]
# 在撥號成功后才投遞郵件
defer_transports = smtp
#取消DNS查詢
disable_dns_lookups = yes
#一般常規配置
queue_directory = /var/spool/postfix
program_directory = /usr/libexec/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
mail_owner = postfix
default_privs = nobody
mail_spool_directory = /var/spool/mail
mailbox_command = /usr/bin/procmail
local_destination_concurrency_limit = 2
default_destination_concurrency_limit = 10
debug_peer_level = 2
debugger_command=PATH=/usr/bin:/usr/X11R6/bin,xxgdb$
daemon_directory/$ process_name $process_id & sleep 5
# 假設本地網絡為192.168.1.1/24
mynetworks = 192.168.1.1/24
# host specific information
myhostname = yourhost.isp.com
mydomain = local.isp.com
myorigin = $mydomain
where do we receive mail and who do we accept/receive mail for?
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, $mydomain
default_transport = smtp
masquerade_domains = isp.com
需要注意的是:這里的$mydomain、$myorigin、$mydestination不能為isp.com, 因為你如果設定為isp.com,內部SMTP服務器就會認為你的郵件是轉發給它的,故而在本地嘗試投遞郵件,結果只會返回“unknown user”的錯誤。其次,該配置只實現了將郵件通過SMTP發送到ISP的SMTP服務器的手段,缺乏從ISP的郵件服務器取信的方法,這一點就只能通過如outlook或foxmail等的mail客戶端軟件來實現了。
5.2為中小型企業用戶配置postfix
假設有一家數千名員工的公司,該公司通過租用專線上網?,F在公司決定
通過postfix來建立自己的郵件系統。在這里我們假設該公司的域為some.com, 郵件服務器的域名mail.some.com,地址為202.200.180.2,DNS服務器的域名為dns.some.com,地址為202.200.180.1。
1. 配置DNS服務器,設置MX記錄指向mail.some.com。相關的配置文件
為/var/named/some.com(假設其zone文件就叫some.com, 有關DNS配置的內容請參看本書的相關章節)的內容如下:
@ IN SOA dns.some.com. root.dns.some.com (
2000011307 ; serial
28800 ; refresh, seconds
14400 ; retry, seconds
3600000 ; expire, seconds
86400 ; minimum, seconds
)
@ IN NS dns.some.com.
@ IN A 202.200.180.1
@ IN MX 10 mail.some.com.
localhost IN A 127.0.0.1
dns IN A 202.200.180.1
mail IN A 202.200.180.2
host1 IN A 202.200.180.3
host2 IN A 202.200.180.4
2. 配置postfix,其配置文件及相關的解釋如下:
#設置一般的路徑信息
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
mail_spool_directory = /var/spool/mail
#設置郵件及郵件隊列的所有者為postfix
mail_owner = postfix
#設置郵件服務器的主機名
myhostname = mail.some.com
#設置mydomain、myorigin和mydomain參數
mydomain = some.com
myorigin =$mydomain
mydestination = $mydomain
#設置postfix服務監聽的端口
inet_interfaces = all
#設置本地收件人的用戶名查詢手段,缺省是查詢/etc/passwd文件
#和別名數據庫
local_recipient_maps = $alias_maps unix:passwd.byname
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
#設置最終的本地投遞代理程序,在這里我們使用流行的procmail
mailbox_command = /usr/bin/procmail
#設置該值為$mydomain以便客戶端的連接
relay_domains = $mydomain
mynetworks = 202.200.180.0/24
#設置向用戶顯示的主機名和版本信息
smtpd_banner = $myhostname ESMTP $mail_name
#對于并發進程的限制,保持系統缺省值就可以滿足要求了。
local_destination_concurrency_limit = 2
default_destination_concurrency_limit = 10
#如果你不知道你在做什么,最好不要改變下面的設置
debug_peer_level = 2
debugger_command =
PATH=/usr/bin:/usr/X11R6/bin
xxgdb $daemon_directory/$process_name $process_id & sleep 5
3. 在RedHat中我們通常使用imap作為pop3服務器,可以通過rpm -q imap
命令查看系統有沒有安裝imap。如果沒有安裝則插入linux光盤,用rpm -ivh imap-4.5-4.rpm 進行安裝。
4. 缺省地,pop3服務器是由inet 啟動的,所以必須去掉/etc/inetd.conf文
件中有關pop3的一行注釋。如下所示:
pop-3 stream tcp nowait root /usr/sbin/ipop3d ipop3d
5. 重新啟動inet服務器,啟動postfix:
#/etc/rc.d/init.d/inet restart
#postfix start
5.3在防火墻內部配置postfix
假設一公司通過租用專線上網,公司內部使用192.168.0.0的私有ip, 然后通過防火墻(雙宿主主機)的ip欺騙上網,公司的郵件服務器(mail.some.com)也在內部網中,也使用私有ip。我們假設在防火墻上進行了端口轉發,可以將Internet對防火墻25端口的請求包轉發到內部的郵件服務器上,并且運行DNS服務的防火墻的MX記錄指向防火墻本身。
在這個例子中,我想著重說明的是有關映射文件的用法。main.cf配置文件和相關的解釋如下所示:
#表明自己的身份
myhostname = mail.some.com
mydomain = some.com
mydestination = $mydomain, $myhostname, localhost.$mydomain
myorigin = $mydomain
#讓postfix監聽所有接口
inet_interfaces = all
#通過mynetworks參數接受內部網用戶的SMTP連接請求
mynetworks = 192.168.0.0/8
#向postfix管理員報告的信息量
notify_classes = resource, software, bounce, policy
#如果客戶端的ip地址符合$maps_rbl_domains參數中列出的則拒絕之
maps_rbl_domains = rbl.maps.vix.com, dul.maps.vix.com
#對可以連接的客戶端進行嚴格的限制
smtpd_client_restrictions =
#客戶端ip符合$mynetworks定義的范圍則接受連接
permit_mynetworks,
#根據access的查詢結果判斷客戶端連接的合法性
check_client_access hash:/etc/postfix/access,
#拒絕ip符合$maps_rbl_domains定義范圍的連接
reject_maps_rbl,
#如果客戶端在DNS中沒有記錄則拒絕連接,要慎用
reject_unknown_hostname
#通過發件人的地址進行限制
smtpd_sender_restrictions =
permit_mynetworks,
check_sender_access hash:/etc/postfix/access
#設置數據庫,別忘了執行"postmap virtual"進行格式轉換
virtual_maps = hash:/etc/postfix/virtual
#對無系統帳號的郵件進行轉發設置,如離開公司的員工
relocated_maps = hash:/etc/postfix/relocated
#設置別名數據庫
alias_maps = hash:/etc/postfix/aliases
# 我們使用smtp投遞代理
default_transport = smtp
# 一些常規設置
mail_owner = postfix
default_privs = nobody
#設置路徑信息
queue_directory = /var/spool/postfix
program_directory = /usr/libexec/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
mail_spool_directory = /var/spool/mail
mailbox_command = /usr/bin/procmail
#并發連接設置
local_destination_concurrency_limit = 2
default_destination_concurrency_limit = 10
然后,我們執行以下命令:
#進入postfix配置目錄
cd /etc/postfix
#用newaliases初始化別名數據庫
newaliases
#用postmap分別建立virtual、access和relocated查詢數據庫
postmap virtual
postmap access
postmap relocated
#啟動postfix
/etc/rc.d/init.d/postfix start
現在我們來看看virtual、access和reloacted幾個查詢文件的格式,下面是這幾個文件的示例和注釋:
#virtual文件示例
#假設在這個例子中我們有個虛擬域為other.com
other.com
#access 文件示例
#如果符合前面的條件則進行后面操作,可以有三種操作:
#1. [45]XX $messag:拒絕接受并且向客戶端顯示預定義的信息
#2. REJECT:拒絕接受,不顯示信息
#3. OK允許連接
550 Go away
friend.com OK
202.192 REJECT
#relocated 文件示例
#該文件主要是將發給無系統帳號的郵件進行轉發
六、 postfix中的命令行工具及其它
下面我們來看一看postfix的命令行工具,通過這些工具的使用可能會使你
對postfix的管理更簡單。
6.1 sendmail兼容的命令行工具
1. mailq 對郵件隊列文件進行列表。表中的每一個條目包含有以下信息:
隊列文件ID、郵件的大小、到達的時間、發件人、收件人和投遞延遲的原因(如果投遞有延遲的話)。該命令主要是與showq后臺程序通信來獲取隊列文件的相關信息。該命令無參數。
2. newaliases 該工具進行別名數據庫的初始化。如果沒有指定數據庫的類
型,則使用系統默認的數據庫類型(在linux下為hash)。該命令可以不帶參數執行。
6.2 postfix自帶的命令行工具
1. postcat 打印郵件隊列文件的內容。后面界要顯示的隊列文件名,可以
帶一個-v的參數進行冗余顯示。
2. postconf 打印配置參數設置后的值或postfix的其他信息。
-d 打印配置參數的缺省值。
-m 列出所有支持的查詢表類型。
不帶參數則打印配置參數設置后的值。
3. postmap 建立postfix查詢數據庫。在linux下可以直接跟上原始文件
而不帶任何參數來建立該數據庫。
6.3 postfix的日志
postfix的日志文件位于/etc/log/maillog, 文件中包含有postfix的啟動信息、出錯信息以及同其他SMTP服務器的會話等等。如下所示:
Sep 10 05:54:17 mail postfix/smtpd[5072]: disconnect from unknown[204.140.244.150]
Sep 10 06:06:00 mail postfix/qmgr[467]: 50D403DF8: from=<>, size=6591 (queue active)
Sep 10 06:11:06 mail postfix/smtp[5085]: connect to bjmx2.163.net[202.108.255.241]: read timeout (port 25)
Sep 10 06:16:07 mail postfix/smtp[5085]: connect to bjmx3.163.net[202.108.255.242]: read timeout (port 25)
Sep 10 06:21:08 mail postfix/smtp[5085]: connect to bjmx1.163.net[202.108.255.240]: read timeout (port 25)
6.4 在postfix中使用MySQL數據庫
Scott Cotton 和 Joshua Marcus寫了一段可以在postfix中添加mysql映射類型的代碼,從而我們可以將postfix查詢的別名數據庫等數據存儲在mysql數據庫中,讓postfix進行mysql查詢來得到結果。這樣做將有助于提供postfix的運行效率, 有其對需要不斷對映射數據的站點特別有用。
1.為postfix添加識別mysql數據庫映射的功能
a. 由于這段代碼使用了mysql客戶端庫,所以我們必須安裝mysql的開包。
可以到等linux相關站點下載mysql開發包,也可以從某些linux的資源光盤中取得mysql的開發包,如MySQL-client-3.22.30-1.i386.rpm。
b. 安裝該開發包:
rpm -ivh MySQL-client-3.22.30-1.i386.rpm
c. 下載postfix的源代碼包,根據本章“3.1源代碼包的安裝”的提示進行
安裝,但是注意在執行make命令之前先執行以下命令:
make -f Makefile.init makefiles @#CCARGS=-DHAS_MYSQL -I /usr/include/mysql@#
@#AUXLIBS=/usr/lib/mysql/libmysqlclient.a -lm@#
5. 配置postfix使用mysql數據庫映射
我們以alias_maps進行說明。在main.cf中指定:
alias_maps = mysql:/etc/postfix/mysql-aliases.cf
6. 編輯mysql-aliases.cf
#首先指定登錄到mysql服務器的用戶名和密碼
user = your_user_name
password = your_password
#連接的數據庫名稱
dbname = your_database_name
#查詢的表名
table = mytable
#添加表的字段名稱
#forward_addr為轉發地址
#alias為別名數據
select_field=forward_addr
where_field=alias
#添加附加的查詢條件
additional_conditions=and status=@#paid@#
#指定要連接的MySQL服務器
hosts=your.mysql.server
這樣,當發生一個查詢的時候,postfix是以這樣的SQL語句進行查詢的:
select forward_addr from mytable where alias=@#$lookup@# and status=@#paid@#
以上只是一個例子。在實際的運用中您可以指定多個mysql數據庫,使用多個數據表格。