主機負載太高造成死當的解法

#!/bin/sh
# Bash script that checks apache:
# – If server load is higher than 20, kill web server
#
# Script to be ran as cronjob (every 5 minutes)
# */2 * * * * /path/to/httpd_check >> /path/to/httpd_check.log

echo “httpd checker running at " `date`
check=`uptime | sed ‘s/\./ /g’ | awk ‘{print $10}’`
if [ $check -gt 20 ]
then
echo “Server load too high ($check), kill all the following program: httpd, php, mysqld"
killall httpd
killall php
killall mysqld
else
echo “Server load OK ($check)"
fi

echo “—————-“

如何設定cpanel單一帳戶的遠端自動備份?

cpanel有提供可以從外部呼叫的API,如果活用這些API,就可以做到:定時將帳戶的內容備分到遠端的ftp主機中。

實作方法:

(1) 準備好用來作遠端備分的ftp,並且在ftp的登入目錄裡,加上 /backup/AAA這個目錄,建議AAA的部分,取有意義一點的名稱,最好和網站的名稱相關。

(2)  在cpbackup.php 這個檔案之中,要先做對應的修改,總共需要改九行

// Credentials for cPanel account ( 這邊填原始,要被備分的cpanel account相關資訊 )
$source_server_ip = “"; // Server IP or domain name eg: 212.122.3.77 or cpanel.domain.tld
$cpanel_account = “"; // cPanel username
$cpanel_password = “"; // cPanel password
// Credentials for FTP remote site ( 這邊填遠端的ftp資訊 )
$ftphost = “"; // FTP host IP or domain name
$ftpacct = “"; // FTP account
$ftppass = “"; // FTP password
$email_notify = “"; // Email address for backup notification
//
// Delete any other backup before create new backup
$conn_id = ftp_connect($ftphost);
$login_result = ftp_login($conn_id, $ftpacct, $ftppass);
$logs_dir = “/backup/AAA“;
ftp_chdir($conn_id, $logs_dir);
$files = ftp_nlist($conn_id, “.");
foreach ($files as $file){
    ftp_delete($conn_id, $file);
}
ftp_close($conn_id);
$api_args = array(
                           ‘passiveftp’,
                           $ftphost,
                           $ftpacct,
                           $ftppass,
                           $email_notify,
                            21,
                            /backup/AAA
                         );

(3) 用ftp 上傳檔案
在account的public_html  下,放上這兩個檔案,( 檔案在此可以下載,選cpbackup script )
xmlapi.php
cpbackup.php

在這邊要特別注意一點:
backup這個功能,因為相對消耗資源,放在public_html下,是說可以透過browser來啟動,很方便。但是,如果是很容易被攻擊的網址。就最好不要放在這麼明顯的地方。

(4) 此處,有兩種方法可以執行這個php來做檔案的備分:
(a)  在browser上, http://你的域名/cpbackup.php
(b)  用該account的id/pw ( 不要用root的 )   ssh 登入這個account, 然後下指令     php -q /home/你的帳戶名稱/public_html/cpbackup.php 

理論上,出現的message應該是長成這樣子:

Warning: ftp_delete(): Could not delete .: Invalid argument in /home/blog66rr/public_html/cpbackup.php on line 28
Warning: ftp_delete(): Could not delete ..: Invalid argument in /home/blog66rr/public_html/cpbackup.php on line 28
{“apiversion":"1″,"type":"event","module":"Fileman","func":"fullbackup","source":"module","data":{“result":""},"evenls -l /home/blog66rr/public_html/cpbakcup.php

這樣子,資料應該就會備分到你的ftp了。

另外,週期性執行不一定需要。如果說只做一次的話,就不用這麼麻煩。用這個方式,因為是透過ftp的關系,比較不會受到browser 斷線的問題。ftp比較適合處理這種大型的backup檔。

(5) 用該account的id/pw ( 不要用root的 )   ssh 登入這個account
下指令:
crontab -e

這樣子是設定每天備分:
0 0 * * *   php -q /home/你的帳戶名稱/public_html/cpbackup.php
這是每週備分
@weekly    php -q /home/你的帳戶名稱/public_html/cpbackup.php
這是每月備分
@monthly  php -q /home/你的帳戶名稱/public_html/cpbackup.php

(6) 最後還有一個但書。在用來backup的ftp這邊,會有一個問題:檔案愈積愈多。所以在用來backup的ftp主機這邊。最好也設置工作排程 ( cronjob )

find /path/to/files* -mtime +5 -exec rm {} \;

這個指令的意思是:到 /path/to/files* 這邊,找出超過5天沒有使用的檔案,將它刪除。

 

(備註:unethost.com虛擬主機,已有每日自動異地備份)

主機商選購指南

本篇文章是一篇帶有強烈置入性行銷的文章。請大家多多包涵。

作為一個主機商,由於客戶中有許多常常三天兩頭有被DDoS, 被放木馬之類的問題,本公司在累積了無數的經驗(?客訴)之後, 對於安全性的議題有著異常的執著與重視。要提高安全性,確保php程式碼沒有漏洞的部分,是客戶端在管的。但是,要確保php的版本沒有漏洞的部分,則是主機商的事。

升級php, 升級mysql, 升級apache, 更換ip,這一類的事,由於會影響到客戶的程式,對於主機商而言算是苦差事。但是,不升級也不行。不升級的話,漏洞就會一直存在。是否應該升級?何時最好一定要升級,其實這個問題,也是有客觀的參考。

以美國的五大主機商為例子,hostgatorwebhostingpad都已經升級PHP 5.3了。( 這些資訊,我是直接用官網去查的 )

而台灣地區,搜尋「虛擬主機」這個關鍵字,google出來第一頁的主機商之中,大間的5、6家裡,幾乎都還是使用PHP 5.2.17版。(台灣的同胞怎麼這麼不重視資訊安全啊? 這不是已經應該要升級很久了嗎? )只有一家有升級PHP 5.3。這一家,呃,當然不是敝公司,因為unethost.com的google rank在很多頁之後。但是,本公司升級PHP 5.3是老早以前的事。官網的主機已經升級到 PHP 5.3.22版了。

最後要在這邊順便講解一下,如何看php的版本。如果是用chrome來當browser 的話,先按Ctrl + shift + i,選Network,按F5,之後,點選一個php網頁。看到最下方,應該會有一串字串 X-Powered-By:,例如:

X-Powered-By: PHP/5.3.22

這就是了!

用Madmimi來發電子報

之前就有聽人介紹Madmimi的EDM服務,最近公司也來用一下吧。想收到電子報的請按這邊註冊。

本來以為一切會順利無比,想不到,到了電子報要發出去的前一刻,才收到Madmimi官方的關切信函。一開始的信函內容是這樣子的:

Hi Laurence,

Macdara here 🙂 I see you’re ready to send your promotion off, sweet!

I just need a little info before I can get you verified. Let me know how your contacts signed up and agreed to hear from you when you get the chance. This way we can be sure to get you overall awesome sending!

Cheers,

Macdara

非常客氣地問我,我發電子報的連絡人是從哪裡來的? 於是我回信,這是從官網的whmcs系統中匯出的。想不到,Madmimi的官方還是不讓我過關,又來了一封信問得更詳細了:

Hi Laurence,
Thanks for getting back to us! I’m happy to get you sending shortly. Will you let me know how you gathered the contacts you didn’t collect from http://unethost.com/whmcs? It’s important that all the contacts you’re sending to gave you their permission to send to them.

Also, did the registration or opt-in process on the Unethost.com site specify these contacts were agreeing to hear from you via email?

I’m not trying to give you a hard time – we ask these questions of all our users to make sure you’ll inbox successfully 🙂

Best,

Kate

像這樣子這麼嚴格的問法,實在讓人心生放棄的念頭。在上頭的信函裡,Madmimi問我,「這些註冊的email,他們有沒有同意我寫信給他們?」 還問我,「在註冊的過程中,有沒有問人家,我可以寄信給你嗎?」

像我這麼含蓄內向的人,我怎麼好意思沒事亂發email給人家呢!所以我最後回信給對方的理由,我就寫得理直氣壯,大意是說『雖然我沒有問過可否發信的事,但是全部都是我的客戶』,  順便附上我從官網匯出的連絡名單原始檔。

I create two list: One name is whmcs, the other is firend. Just as the name
goes, one contact list is from whmcs system, and the other contact consists of my firends. As for the friend contact, I am sure that I have asked them. The registration process on Unethost.com does not ask this kind of email question. This is limited
by software system.

However, I am sure that my clients they permit my sending email to them.
WHMCS is a helpdesk system. If my client has problems, he will submit tickets
to my help desk system. At the meanwhile of submitting ticket, he will receive
his ticket from email too. Therefore, he can then just send and receive
tickets by email. If you take a look of my website, all the articles in
knowledge base, and files in download area, we do not require client login.
Given that anyone can get most of the free resources from our website, why
they choose to login? I believe the answer is obvious, because they are my
clients.

I provide objective information for you to justify my saying. The attachment
is the original file that I exported from WHMCS system.

最後,Madmimi官方回給我的信,還是讓我滿感動的 –> 他們終於相信我不是在亂發垃圾信了!

I really appreciate the detail. Thanks for taking the time to explain it so
well 🙂

It’s all I needed to hear, so I’ve verified your account and have sent your
email on its way now.

淺談hash dos攻擊

身為一個主機商,處理過的攻擊中,最容易得手的攻擊,往往是DoS攻擊。DoS又名denial of service ,這種攻擊的概念不強調去更改網站的內容或是偷取資料,只是讓網站倒站。相對於SQL injection, XSS這一類的攻擊,需要依賴寫程式的不小心。DoS單純又暴力,但是從攻擊者的觀點來說,非常的有效。

以php這種語言為例子,在寫程式的時候,可以利用$_POST[“name"]從用戶端的Post request中存取name這個變數。像這樣子的機制,就是php語言實作的hash tables(哈希表)所提供的。然而hash tables固有的特性之一,就是會有衝突的時候,即Hash Collision。攻擊者可以利用Hash Collision會消耗大量的CPU運算這個特性,發動hash DoS攻擊。

這個攻擊的發動方式是這樣子:攻擊者給予php網頁一個Post request,並且在這個單一的request之中,提交大量的參數,而且這些參數透過php的hash規則都恰好會發生hash collision。這樣子的攻擊方式,在2003年在許多語言(Perl, CRuby)中被發現。

目前,許多語言在其更新的版本中,已經有針對這一點去改善了。以php為例子,從 php的5.3.9版本開始,有一個指令 max_input_var,它可以去限制GET,POST,Cookie這些變數的長度,最長只能到1000。有了這個特性,要hash dos就不太容易了。

對於不幸使用舊版php的人,也可以考慮使用ModSecurity的規則來攔阻這種攻擊。例如下方的rule,就是類似max_input_vars的效果。

SecRule &ARGS|&REQUEST_COOKIES_NAMES|&REQUEST_COOKIES "@gt 1000" "phase:2, \t:none,log,block,severity:2,msg:'Hash DoS Detected'"

php handler — suphp, mod_php, cgi, fastcgi

在虛擬主機的控制台中,效能和安全性都關系重大的一件事,就是php handler的選擇。可以說是每一種handler都各有其特色。

(1) CGI是最古老的handler,因為最古老,也沒有什麼過人的長處。不快也不太安全。
(2) suphp是最慢的handler,但是它在安全性上其長處。如果使用者的檔案或是資料夾的權限設定太過寬鬆,suphp都會丟出error。可以說是超級嚴謹,一絲不苟。
(3) mod_php是最快的handler,因為它直接嵌入apache中,做為apache的module來執行。也因此,mod_php在執行網頁時,使用的是nobody這個user,而並非是php檔案的擁有者。所以mod_php並不太安全。
(4) fastcgi可以說是有各家之所長,速度上不輸給mod_php,又像suphp一樣,可以用php檔案擁有者的身分來執行。唯一的缺點就是fastcgi的設定也比較複雜。

下方是一個圖表,用來說明這四種php handler的特色。

php handler 比較表

Unethost.com 採用的php handler是fastcgi。因為用了fastcgi的關系,客戶們並不需要將自己的程式中,被php寫入資料的資料夾設定成權限777。客戶們在public_html下的網站檔案,也不會被改成擁有者為nobody。

本來以為用了fastcgi這個php handler既有速度又有安全性。然而,真正的考驗是在當我們讓fastcgi上線之後一個月,機器開始瘋狂地當機。經過一番折騰後,才發現,原來php fastcgi內部有輕微的bug。這個bug會造成orphan process,也就是一些php的process,他們的PPID都會變成1。當這樣子的程序愈來愈多時,就會使用大量的記憶体,最後吃光主機的swap,導致當機。 一旦找出問題的根源後,要處理也就不難了。在我們加入了會自動去砍掉php orphan process的cron jobs,php fastcgi就平平順順地運作,再也沒有出過惱人的問題了。

 

延伸閱讀: 如何透過排程,解決fastcgi崩潰問題?

 

(本篇教學由unethost.com客服撰寫)

延伸閱讀:如何備份Cpanel後台安裝的套裝程式?

安裝上述的軟體,我們提供虛擬主機試用,七天滿意保證,
功能完整使用不受限制,歡迎點我申請。

webftp

虛擬主機因為是多人共用一台實體主機,當主機遭受DDoS攻擊,或是剛好執行一些備分的工作時,機器的負載總是難免會偶爾有上昇的時候。當機器的負載上昇時,除了網頁伺服器的反映速度會變慢一些之外,有時候比較嚴重的問題是,ftp會不停地斷線。

在一次偶然的情形下,我用filezilla會不停地斷線時,用webftp卻可以順利地上傳檔案!

這樣的一件事,讓我不由得開始重新檢視webftp和ftp不同之處。unethost.com的webftp是安裝在美國的主機上的。當使用者使用webftp時,其實檔案的傳輸是先從客戶端,走http的傳輸協定到webftp所在的機器,再透過ftp傳輸協定到真實的目標機器上。所以是兩階段式的。前面這一段往往是最容易逾時(timeout),最容易有掉封包(packet loss)的。原因是前面的這一段是從台灣連線到美國,所以延遲(delay)會比較長。考慮到前面這一段的傳輸有這種特性之後,就不難理解,為何webftp在這種條件下可以有較佳的表現了。http這個傳輸協定由於有較多的超文件標記(meta tag)本身對於這種延遲長、容易掉封包的連線,本來就有較佳的表現。而webftp很巧妙地剛好可以利用http這個傳輸協定來處理前一段的連線,所以就可以在filezilla動彈不得的時候,依然順利地達成上傳檔案的任務。