淺談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動彈不得的時候,依然順利地達成上傳檔案的任務。

利用VPN及Host Access Control來避免scan password攻擊

VPS客戶和獨立主機客戶最頭痛的問題之一,莫過於admin的帳號/密碼外流了。舉個例子,如果ssh port設成22,那主機必定不停地回報被大量地敲門–因為網路上總是不停地有大量的攻擊者試圖透過暴力法來猜測ssh的密碼。同樣的原理,由於cpanel登入的port是2083或是2087,這兩個port也是會不停地被攻擊者試探。

有沒有什麼比較簡單的方法可以解決這個被攻擊者試探的問題呢?畢竟,並不是每一種服務的port都可以輕易地修改的。

單純又暴力的解法,就是設定白名單(white list),限定只有從某些特定IP address來的連線,才會被接受。這個功能要透過cpanel的Home >> Security Center >> Host Access Control 來設定。下圖的範例是設定一台主機的sshd服務,只容許由140.112.18.71這個IP address來登入,即設定sshd 的白名單。

Cpanel Host Access Control

然而,這樣子的設定,有一個難題,以台灣的用戶,很多人是沒有固定IP的,此外,一旦用筆電在外頭上網時,就是使用動態IP了。這種時候,如果搭配 VPN使用,就可以輕易地在任何時間/地點取得固定的同一IP Address。如此一來,只要把Host Access Control中容許的IP address設定成為VPN的IP address即可。

如何在centOS上,透過yum安裝基本的web server

有的客戶因為要跑相對比較吃硬碟I/O數的遊戲,喜歡不裝cpanel。但是不裝cpanel的話,剛拿到的centOS是連完整的web server環境都沒有的。本文就是來講解,如何在一台乾淨的centOS上,透過yum安裝基本的web server

(*) 安裝web server
1 for php
yum install php

2 for ioncube loader ( ioncube loader是一個跟加密的php source code有關的模組,不灌這個的話,如果要執行的插件是有加密的php source code,就跑不動了。)
wget -q -O – http://www.atomicorp.com/installers/atomic |sh
yum install php-ioncube-loader

3 for mysql
yum install mysql mysql-server php-mysql
chkconfig –levels 235 mysqld on
/etc/init.d/mysqld start
修改mysql的 password
/usr/bin/mysqladmin -u root password ‘你要設定給mysql root的密碼

4 for httpd
yum install httpd
service httpd restart

如何透過shell script來做domain name的篩選

如果從cpanel WHM抓出所有主機的域名(domain name)時,往往會發現,子域名(sub domain) 和頂層域名(top level domain) 是混雜的。

這時候,可以用基本的sed來做篩選。做法如下:
在一個文字檔 list 裡放所有的域名,例如:

aa.bb.com
cc.net
1123.org
1aa.bbcd.com

下指令:
cat list | sed -e “/[^\.]*\.[^\.]*\.[^\.]*/d” | sort

即可抓出所有想要的top level domain。( 這個指令的功能就是把所有的sub domain刪去而已。)

如何設定mysql的自動備分

cpanel有一個功能是mysql備分,這個功能有一個不足的地方是,沒有辦法設定成自動化的。然而,只要透過ftp上傳一個shell script,再加上crontab的設定,還是可以完成類似的事。

下方是shell script的內容,將這個shell script用文字編輯器,編輯好之後,存檔成為backup.sh。並且在透過ftp上傳到使用者的家目錄下之後,加上可執行的權限。

#!/bin/sh
receiver=此處填要用來收backup的email
mysql_username=此處填mysql的使用者名稱
mysql_dbname=此處填mysql的資料庫名稱
mysql_userpwd=此處填mysql的密碼
file=./mysqldb_`date ‘+%m-%d-%Y’`.sql.gz
name=mysqldb_`date ‘+%m-%d-%Y’`.sql.gz
mysqldump -u $mysql_username -p$mysql_userpwd -h localhost –routines  –single-transaction  –skip-add-locks –skip-lock-tables –default-character-set=utf8 $mysql_dbname | gzip > $file
uuencode $file $name  | mail -s “Database backup” $receiver
rm $file

 

接著就要來設定cron job,cron job可以透過cpanel的GUI來設定。下方的例子,就是每天的0時0分要執行一次這個backup.sh。

0 0 * * * /home/使用者名稱/backup.sh>/dev/null 2>&1

Fastcgi and Custom php.ini

如果主機的php是用fastcgi的方式來配置時,會發生一個現象,無法用.htaccess來修改php.ini裡的參數。這時候,就必須做一些特定的修改,才能辦到。

何時會需要修改php.ini的參數呢?一個很常見的例子,就是register_globals 。在php 4之前,這個常常是On的。但是為了安全性,php 5開始,及很多新的php套裝程式,都必須是Off才能安裝。

1) 將客製化的php.ini ( custom php.ini )移到 public_html/cgi-bin/這個資料夾下

2) 在 cgi-bin 這個資料下, 生成 php.fcgi 這個檔案,並寫入下方的內容
#!/bin/sh
export PHP_FCGI_CHILDREN=1
export PHP_FCGI_MAX_REQUESTS=10
exec /usr/local/cpanel/cgi-sys/php5

3) chmod +x php.fcgi

4) 上傳 .htaccess 到 public_html資料夾,並加入下方的內容
AddHandler php5-fastcgi .php
Action php5-fastcgi /cgi-bin/php.fcgi

5) 在php.conf中,加入path
在 /usr/local/apache/conf/php.conf 這個檔案中,加入下方的內容
Action php5-fastcgi /cgi-bin/php.fcgi
AddType application/x-httpd-php .php

6)萃取apache的conf檔,並且重新啟動之
/usr/local/cpanel/bin/apache_conf_distiller –update
/scripts/rebuildhttpdconf
/etc/init.d/httpd restart

後記:
經過我們實際上的實驗,(4)這個步驟修改.htaccess檔在某些情況下,必須省略。例如,要修改的網站,本身的空間裡有附加(attach) 子網域(subdomain) 的時候。

灌Memcached於Fedora 17/16, CentOS(RHEL) 6.3/5.8

在部分舊版的fedora或是CentOS上,直接用yum是沒有辦法裝memcached的。所以這種時候,必須要引入額外的repositories

(1)安裝Remi repository (Fedora 12~17, RHEL 6不需要)

## Remi Dependency on CentOS and Red Hat (RHEL)
rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm

rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-5.rpm

(2) 安裝memcached的軟体包(package)
如果是fedora 17/16/15/14/13/12或CentOS 6.3/6.2/6.1/6

yum install memcached

如果是 CentOS 5.8

yum --enablerepo=remi install memcached

(3) 設置memcached

vim /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="512"
OPTIONS=""

(4) 啟動memcached

# Set Memcached to start automatically on boot
chkconfig memcached on
# Start Memcached
/etc/init.d/memcached start
## OR ##
service memcached start

(5) 檢查memcached是否正常的運作。

echo stats | nc localhost 11211
STAT pid 7599
STAT uptime 10
STAT time 1265288542
STAT version 1.4.4
STAT pointer_size 32
STAT rusage_user 0.003999
STAT rusage_system 0.052991
STAT curr_connections 10
STAT total_connections 11
STAT connection_structures 11
STAT cmd_get 0
STAT cmd_set 0
STAT cmd_flush 0
STAT get_hits 0
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 6
STAT bytes_written 0
STAT limit_maxbytes 536870912
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT bytes 0
STAT curr_items 0
STAT total_items 0
STAT evictions 0
END

# Try to get some value
echo get some_value | nc localhost 11211
END

# Not found, but check the stats again
echo stats | nc localhost 11211
STAT pid 7599
STAT uptime 10
STAT time 1265288542
STAT version 1.4.4
[...]
STAT cmd_get 1
STAT cmd_set 0
STAT cmd_flush 0
STAT get_hits 0
STAT get_misses 1
STAT delete_misses 0
[...]
STAT evictions 0
END

(6) 打開firewall

加下方的 INPUT 規則:

-A INPUT -m state --state NEW -m tcp -p tcp --dport 11211 -j ACCEPT

重新啟動 Firewall:

service iptables restart
## OR ##
/etc/init.d/iptables restart

 

在cpanel/WHM的centos主機上灌php的memcached擴展

如果運氣好的話,用下方的指令就可以搞定了。
yum install php php-pecl-memcache

直接用yum install安裝,有時候會因為repo的問題而裝不起來。所以用tarball來裝,反而快。

Step 1 – 下載memcache
mkdir repo
cd repo
wget  http://pecl.php.net/get/memcache-3.0.6.tgz
tar -xvfz memcache-3.0.6.tgz

Step 2 – 編繹 & 安裝
cd memcache-3.0.6
phpize

這時候,應該會看到類似的訊息:
Configuring for:
PHP Api Version: 20041225
Zend Module Api No: 20060613
Zend Extension Api No: 220060519
./configure
make
make install

Step 3 – 修改php.ini
在php中,啟用memcache
echo "extension=memcache.so" >> /usr/local/lib/php.ini
service httpd restart