iT邦幫忙

0

系統毀損後,PHP郵件發不出去之疑

php

◆ 狀況敘述

原本程式建在fedora 14之上,使用PHPMailer 以sendmail 方式發信,可以正常
發出。系統毀損之後,重新安裝在Scientific 6.0之上,同樣程式卻不再能發信,
改成用smtp直接發信,卻也一樣不能發出。我找過許多中英文參考資料,但一直找不
出真正原因在哪裡?不得已,只好來向高手們求救!

◆ 系統環境
▶ OS 版本:Scientific 6.0 x86_64 (測試過i686版本的反應也一樣不能寄信)
▶ Apache 版本:httpd-2.2.15-9.sl6.2.x86_64
▶ OpenSSL 版本:openssl-1.0.0-10.el6.x86_64
▶ PHP 版本:php-5.3.2-6.el6_0.1.x86_64
▶ firewall 已開25,tcp 465,udp 465
▶ SELinux 已停用
▶ 修改 php.ini [mail function]
只設定 sendmail_path = /usr/sbin/sendmail -t -i
▶ 修改 /etc/pki/tls/openssl.cnf 二個參數
(1) countryName_default = TW
(2) stateOrProvinceName_default = Taipei
◆ 測試過程
▶ 錯誤訊息
Warning: fsockopen(): unable to connect to smtp.googlemail.com:465
(Permission denied)
in /var/www/html/PHPMailer/class.smtp.php on line 109

errorno => 13
errstr => Permission denied

▶ telnet 成功
在Linux 上安裝VM OS (windows 2003)做telnet 測試 mail server 可以
成功 => telnet smtp.googlemail.com 465

▶ Thunderbird 可以正常收發信

◆ Source Code
include_once("class.phpmailer.php");

$mail = new PHPMailer();

$mail->IsSMTP();

$mail->SMTPAuth = true;
$mail->SMTPSecure = "ssl";
$mail->Host = "smtp.googlemail.com";
$mail->Port = 465;

$mail->CharSet = "utf-8";

$mail->Encoding = "base64";

$mail->Username = "XXX@gmail.com";
$mail->Password = "XXX";

$mail->From = "XXX@gmail.com";
$mail->FromName = "系統測試";
$mail->Subject = "寄信測試標題";
$mail->Body = "這是一封測試信件!";
$mail->IsHTML(true);

$mail->AddAddress("xxx@gmail.com", "xxx收信人");

if(!$mail->Send()) echo "Mail error: ".$mail->ErrorInfo;
else echo "Mail sent";

◆ 疑問
查看/etc/httpd/modules 之下只有libphp5.so 而沒有類似 mod_openssl.so
的程式,這是正常的嗎?

◆ 結論

依照上述的描述,我個人的猜測應該是少設定某些參數,或少安裝某些套件,但不知
倒底是什麼? 乃至是意料外的問題!

在此先向回覆的大大們致謝!

看更多先前的討論...收起先前的討論...
wiseguy iT邦超人 1 級 ‧ 2011-09-09 09:59:52 檢舉
▶ firewall 已開25,tcp 465,udp 465


用 iptables -L 確認一下 465 port 是開 INPUT 的還是 OUTPUT 的。
你要寄信出去,是要開 465 port OUTPUT。如果是開成 INPUT,try 到死也連不出去啊。
studentie iT邦新手 5 級 ‧ 2011-09-09 19:04:52 檢舉
Chain INPUT (policy ACCEPT)

target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ftp
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:imaps
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:smtp
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:pop3s
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:http
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:mysql
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:urd
ACCEPT udp -- anywhere anywhere state NEW udp dpt:igmpv3lite
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
studentie iT邦新手 5 級 ‧ 2011-09-09 19:09:37 檢舉
Chain FORWARD (policy ACCEPT)

target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited


Chain OUTPUT (policy ACCEPT)

target prot opt source destination


從上述的資料看來,的確沒有「OutPut」的設定。我想請教,應該如何設定?

我在firewall的設定方式,是使用下列路徑的程式 (我安裝英文版的OS):
System => Administration => Firewall

這項工具,並沒有Input, Output 的選項,怎麼辦呢?


再次對回覆者致謝!
studentie iT邦新手 5 級 ‧ 2011-09-09 19:13:57 檢舉
以下這兩個就是 TCP 465, UDP 465。它們在Scientific Linux 6.0 中,已有預設的服務
名稱「urd」及「igmpv3lite」,不知它們是否有影響?

studentie提到:

ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:urd
ACCEPT udp -- anywhere anywhere state NEW udp dpt:igmpv3lite
studentie iT邦新手 5 級 ‧ 2011-09-09 19:31:57 檢舉
突然想到的疑問:

「Thunderbird 可以正常收發信」,這是否代表 tcp/udp 465 port 早就已開了? 或是說,開不開無所謂?


Thunderbird 可以收發信,為何我用PHP 就發不出信呢? 真是奇怪呀~~~
studentie iT邦新手 5 級 ‧ 2011-09-09 19:38:01 檢舉
想請大家給我您們可以用PHP發郵件的,與郵件相關之Linux環境設定值。

我個人猜想一定某個地方沒設定,或沒安裝套件,所以有必要參考能正常作業者的資料。

再說,萬一「wiseguy」大大所建議的「465 port output 已設定完畢」仍不能寄出信時,我還可以再參考您們給我的資料再去測試。

先謝了!
wiseguy iT邦超人 1 級 ‧ 2011-09-10 00:16:17 檢舉
規則名只是個用來識別的代表名稱,即使用在別的用途也沒有任何影響的。
嗯~ 你的 output 沒有任何規則,代表是可以出得去的沒錯。
wiseguy iT邦超人 1 級 ‧ 2011-09-10 00:22:09 檢舉
請你檢查一下你的 php 有沒有安裝 openssl 支援。在 shell 下此指令:

php -r 'phpinfo();' | fgrep 'OpenSSL support'
arsee iT邦新手 4 級 ‧ 2011-09-10 17:35:08 檢舉
補充說明﹕SSL Key 在 /etc/pki/tls 之下設定
arsee iT邦新手 4 級 ‧ 2011-09-10 18:24:18 檢舉
也有可能是SELinux 及 PHPMailer 版本臭蟲的因素。
studentie iT邦新手 5 級 ‧ 2011-09-11 14:40:52 檢舉
目前總算可以發信,在這裡總結一下。

原始使用PHPMailer v1.71,目前已恢復到改用 v5.1版使用smtp方式,可以符合需求,這代表我要去改一些程式才行。

整個問題與「SELinux 遮蔽」及「PHPMailer 程式臭蟲」有關係。建議有類似問題的朋友,把PHPMailer昇級到 v5.1版以上。

至於sendmail,則無論是哪一版本,或SELinux是否有失能,全都不能使用,這是美中不足之處,也令人感到莫名其妙,過去在fedora 14是可以正發信的。大概還有什麼地方沒設定到吧?

宥於字數限制,所有的測試結果會貼到下一帖。
studentie iT邦新手 5 級 ‧ 2011-09-11 14:43:45 檢舉
全部測試結果:

◆ PHPMailer v5.1

.SELinux permissive
port 25: smtp 正常可發信
port 465: smtp 正常可發信
port 25: sendmail 發信失敗 (傳送成功,實際沒傳出)
port 465: sendmail 發信失敗 (傳送成功,實際沒傳出)

.SELinux enforcing
port 25: smtp 不能發信
port 465: smtp 不能發信
port 25: sendmail 不能發信
port 465: sendmail 不能發信

.SELinux disabled
port 25: smtp 正常可發信
port 465: smtp 正常可發信
port 25: sendmail 發信失敗 (傳送成功,實際沒傳出)
port 465: sendmail 發信失敗 (傳送成功,實際沒傳出)




◆ PHPMailer v1.71

.SELinux disabled
port 25: smtp 正常可發信
port 465: smtp 不能發信
port 25: sendmail 發信失敗 (傳送成功,實際沒傳出)
port 465: sendmail 發信失敗 (傳送成功,實際沒傳出)

.SELinux enforcing
port 25: smtp 不能發信
port 465: smtp 不能發信
port 25: sendmail 不能發信
port 465: sendmail 不能發信
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
6
wiseguy
iT邦超人 1 級 ‧ 2011-09-10 22:28:56
最佳解答

php 是用 apache runner 身份在執行
telnet 是用 root 身份在執行
既然 root 行而 apache 不行
可以確定是被 SELinux 擋掉了

請修改 /etc/selinux/config 檔案裡面的
SELINUX=enforcing
變成
SELINUX=disabled
再重開機就行了
不想重開機要立刻生效,就執行
setenforce 0

6
mwu4
iT邦新手 2 級 ‧ 2011-09-10 00:03:56

看錯誤訊息有顯示「Permission denied」,可試著查看是檔案權限、使用者權限、還是其他權限問題所造成的。如果將sendmail的log level加大,或許亦可提供更多進一步的除錯參考訊息。謝謝。

arsee iT邦新手 4 級 ‧ 2011-09-10 18:29:19 檢舉

它是以下這個錯誤訊息,猜測還真可能是存取權限的問題。

Warning: fsockopen(): unable to connect to smtp.googlemail.com:465
(Permission denied)
in /var/www/html/PHPMailer/class.smtp.php on line 109

6
regis276
iT邦新手 5 級 ‧ 2011-09-10 00:43:22

如果是用本機當smtp host卻發不出信
應該是預設smtp server都會擋relay的問題
sendmail跟postfix都會擋這個避免變成垃圾信主機
所以檢查一下smtp server的relay設定
把對localhost連線的權限打開就好
可不要全部打開,不然就很可能會變垃圾信主機了

arsee iT邦新手 4 級 ‧ 2011-09-10 18:26:38 檢舉

有可能

arsee iT邦新手 4 級 ‧ 2011-09-10 18:45:30 檢舉

看來PHPMailer 的問題不少,學了個經驗!

6
lukeshei
iT邦新手 3 級 ‧ 2011-09-10 08:36:41

使用root 去執行程式後 , 使用 ps 去觀察是是否 chgowner 到另一個 uid , port <1024 需要 root 執行,所以,你的程序如果需要改變owner , 必須在 sendmail 執行後

我要發表回答

立即登入回答