PHP最初是被稱作Personal Home Page,后來隨著PHP成為一種非常流行的腳本語言,名稱也隨之改變了,叫做Professional HyperText PreProcessor。以PHP4.2為例支持它的WEB服務(wù)器有:Apache, Microsoft Internet information Sereve, Microsoft Personal web Server,AOLserver,Netscape Enterprise 等等。 PHP是一種功能強(qiáng)大的語言和解釋器,無論是作為模塊方式包含到web服務(wù)器里安裝的還是作為單獨(dú)的CGI程序程序安裝的,都能訪問文件、執(zhí)行命令或者在服務(wù)器上打開鏈接。而這些特性都使得PHP運(yùn)行時(shí)帶來安全問題。雖然PHP是特意設(shè)計(jì)成一種比用Perl或C語言所編寫的CGI程序要安全的語言,但正確使用編譯時(shí)和運(yùn)行中的一些配置選項(xiàng)以及恰當(dāng)?shù)膽?yīng)用編碼將會(huì)保證其運(yùn)行的安全性。 一、安全從開始編譯PHP開始。 在編譯PHP之前,首先確保操作系統(tǒng)的版本是最新的,必要的補(bǔ)丁程序必須安裝過。另外使用編譯的PHP也應(yīng)當(dāng)是最新的版本,關(guān)于PHP的安全漏洞也常有發(fā)現(xiàn),請(qǐng)使用最新版本,如果已經(jīng)安裝過PHP請(qǐng)升級(jí)為最新版本:4.2.3。 相關(guān)鏈接:http://security.e-matters.de/advisories/012002.html 安裝編譯PHP過程中要注意的3個(gè)問題: 1、只容許CGI文件從特定的目錄下執(zhí)行:首先把處理CGI腳本的默認(rèn)句柄刪除,然后在要執(zhí)行CGI腳本的目錄在http.conf 文件中加入ScriptAlias指令。 #Addhadler cgi-script .cgi ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/" <Directory "/usr/local/apache/cgi-bin‘> AllowOverride None Options None Order allow,deny Allow from all </Directory> <Directory "/home/*/public_html/cgi-bin"> AllowOverride None Options ExecCGI Order allow,deny Allow from all </Directory> SriptAlias的第一個(gè)參數(shù)指明在Web中的可用相對(duì)路徑,第二個(gè)參數(shù)指明腳本放在服務(wù)器的目錄。應(yīng)該對(duì)每個(gè)目錄 別名都用Directory,這樣可使得除系統(tǒng)管理員之外的人不知道Web服務(wù)器上CGI腳本的清單。 Directory允許用戶創(chuàng)建自己的CGI腳本。也可用SriptAliasMatch,但Directory更容易使用。 允許用戶創(chuàng)建自己 CGI腳本可能會(huì)導(dǎo)致安全問題,你可能不希望用戶創(chuàng)建自己的CGI。 Apache默認(rèn)配置是注釋掉cgi—script的處理句柄,但有/cgi-bin目錄使用SriptAlias和Directory指令。 你也可禁止CGI執(zhí)行,但仍允許執(zhí)行PHP腳本。 2.把PHP解析器放在web目錄外 把PHP解析器放在Web目錄樹外是非常重要的做法。這樣可以防止web服務(wù)器對(duì)PHP的解析器的濫用。特別是 不要把PHP解析器放在cgi-bin或允許執(zhí)行CGI程序的目錄下。然而,使用Action解析腳本是不可能的,因?yàn)橛肁ction指令時(shí),PHP解析器大多數(shù)要放在能夠執(zhí)行CGI的目錄下只有當(dāng)PHP腳本作為CGI程序執(zhí)行時(shí),才能把PHP解析器放在Web目錄樹之外。 如果希望PHP腳本作為CGI程序執(zhí)行(這們可以把PHP解析器放在Web目錄樹之外),可以這樣: ( 1)所有的PHP腳本必須位于能執(zhí)行CGI程序的目錄里。 ( 2)腳本必須是可執(zhí)行的(僅在UNIX/Linux機(jī)器里)。 (3)腳本必須在文件頭包括PHP解析器的路徑。 你可用下面命令使PHP腳本為可執(zhí)行: #chmod +x test.php4 這樣使在當(dāng)前目錄下的文件名為test.PhP4的腳本變?yōu)榭蓤?zhí)行。 下面是一個(gè)能作為CGI程序運(yùn)行的PHP腳的小例子。 #!/usr/local/bin/php echo "This is a my small cgi program” 3. 按Apache模塊方式安裝: 當(dāng)將PHP作為Apache模塊使用時(shí),它將繼承Apche的用戶權(quán)限(一般情況下用戶為“nobody”)。這一點(diǎn)對(duì)于安全性和驗(yàn)證有不少影響。例如,使用PHP訪問數(shù)據(jù)庫(kù),除非數(shù)據(jù)庫(kù)支持內(nèi)建的訪問控制,將不得不設(shè)置數(shù)據(jù)庫(kù)對(duì)于用戶“nobody”的可訪問權(quán)限。這將意味著惡意的腳本在沒有訪問用戶名和密碼,也能訪問并修改數(shù)據(jù)庫(kù)。通過Apache驗(yàn)證來保護(hù)數(shù)據(jù)不被暴露,或者也可使用LDAP、.htaccess文件等設(shè)計(jì)自己的訪問控制模型,并在PHP腳本中將此代碼作為其中部分引入。 通常,一旦安全性建立,此處PHP用戶(此情形即Apache用戶)就風(fēng)險(xiǎn)大大降低了,會(huì)發(fā)現(xiàn)PHP護(hù)現(xiàn)在已被封禁了將可能的染毒文件寫入用戶目錄的能力。 此處最常犯的安全性錯(cuò)誤是賦予Apache服務(wù)器根(root)權(quán)限。 將Apache用戶權(quán)限提升到根權(quán)限是極端危險(xiǎn)的??赡軙?huì)危及整個(gè)系統(tǒng),因此要小心使用sudo,chroot安全隱患大的命令等。除非你對(duì)安全有絕對(duì)的掌握,否則不要讓其以ROOT權(quán)限運(yùn)行。 更安全的php 上 二、讓PHP的使用更安全。 1、以安全模式運(yùn)行PHP 以安全模式運(yùn)行PHP是使PHP腳本安全使用的好方法,特別是在允許用戶使用自己開發(fā)的PHP腳本時(shí)。使用安全模式會(huì)使PHP在運(yùn)行函數(shù)時(shí)檢查是否存在安全問題。 include、readfile、fopen、file、unlink、rmdir等等:被包含的文件或者該文件所在目錄的所有者必須是正在運(yùn)行的腳本的所有者; Exec、System、Passthm等等:要執(zhí)行的程序必須位于特定的目錄(默認(rèn)為/usr/local/php/bin)。編譯PHP時(shí)可以用—with-exe-dir選項(xiàng)設(shè)定這個(gè)值。 Mysql—Connect:這個(gè)函數(shù)用可選的用戶名連接MySQL數(shù)據(jù)庫(kù)。在安全模式下,用戶名必須是當(dāng)前被執(zhí)行的腳本的所有者,或運(yùn)行httpd的用戶名(通常是nobody)。 HTTP Authentication:包含HTTP驗(yàn)證代碼腳本所有者的用戶ID(數(shù)字型)會(huì)自動(dòng)加到驗(yàn)證域。這樣可以防止有人通過抓取密碼的程序來欺騙同一個(gè)服務(wù)器上的HTTP驗(yàn)證腳本。 2、使用 用戶識(shí)別和驗(yàn)證 有時(shí)需要唯一地確認(rèn)一個(gè)用戶。用戶通常由請(qǐng)求和響應(yīng)系統(tǒng)確認(rèn)。用戶名/口令組合就是這種系統(tǒng)的一個(gè)很好的例子,比如系統(tǒng)要求給出A1i的口令,響應(yīng)的是Ali的口令。這樣驗(yàn)證是因?yàn)橹挥蠥li才知道這個(gè)口令。 (1)服務(wù)器端用戶驗(yàn)征 這是用于服務(wù)端上對(duì)PHP程序要求最小的驗(yàn)證方法。只要讓Apache來管理對(duì)用戶的驗(yàn)證就行了。 AuthName "Secret page" # The realm AuthType Basic # The password file has been placed outside the web tree AuthUserFile /home/car2002/website.pw <LIMIT GET POST> require valid-user </LIMIT> 你需要把上述文件(文件名為.htaccess)放在需要保護(hù)的地方。用Apache的htpasswd程序,可以建立包含用戶名和口令組合的文件。把這個(gè)文件放在Web目錄樹之外,只讓該文件的擁有者查看和修改這個(gè)文件。當(dāng)然,Web服務(wù)器必須能夠讀取這個(gè)文件。 如果想讀取被保護(hù)的目錄,Web服務(wù)器要求瀏覽器提供用戶名和密碼。瀏覽器彈出對(duì)話框,用戶可以輸入他們的用戶名和密碼。如果用戶名和密碼與口令文件中相符合,就允許用戶讀取被保護(hù)的頁(yè)面;反之,將得到錯(cuò)誤頁(yè)面,告訴用戶沒有通過驗(yàn)證。被保護(hù)的域會(huì)顯示出來以便用戶知道輸入那個(gè)用戶名和密碼。 (2)在PHP中進(jìn)行用戶識(shí)別和驗(yàn)證 和在Apache服務(wù)器端進(jìn)行用戶識(shí)別和驗(yàn)證相比,在PHP進(jìn)行用戶識(shí)別和驗(yàn)證有以下優(yōu)點(diǎn): A、可注銷。 B、可失效。如用戶登錄后40分鐘沒有瀏覽你的網(wǎng)站,你可強(qiáng)制他們重新通過驗(yàn)證。 C、可定制。 D、可基于數(shù)據(jù)庫(kù)。你可以用保存在各種各樣的數(shù)據(jù)庫(kù)里的數(shù)據(jù)來驗(yàn)證用戶,并且記錄訪問者訪問網(wǎng)站的詳細(xì)日志。 E、可用于每個(gè)頁(yè)面。你可在每個(gè)頁(yè)面上決定是否需要驗(yàn)證。 F、你也可以使瀏覽器彈出對(duì)話框。下面的例子顯示了怎樣從,MySQL數(shù)據(jù)庫(kù)中檢索用名和口令:讓用戶填人用戶名和口令。 <? if(!isset($PHP_AUTH_USER)) { Header("WWW-authenticate: basic realm=\"restricted area\""); Header( "HTTP/I.0 401 Unauthorized"); echo "You failed to provide the correct password...\n"; exit; } else { mysql_select_db("users") ; $user_id = strtolower($PHP^AUTH_USER); $result = mysql_query("SELECT password FROM users " . "WHERE username = ‘$username‘") ; $row = mysql_fetch_array($result) ; if ($PHP_AUTH_PW != $row["password"]) { Header( "WWW-authenticate: basic realm=\"restricted area\" Header( "HTTP/I.0 401 Unauthorized"); echo "You failed to provide the correct password...\n" ; exit; } } ?> Only users with a working username/password combination can see this (3) 檢測(cè)IP地址 一般人們普遍認(rèn)為一個(gè)IP地址唯一地確定一個(gè)訪問者。但實(shí)際上并不是這樣的。代理服務(wù)器可用相同的IP地址發(fā)送不同用戶的請(qǐng)求。另外IP地址的盜用也普遍存在。檢測(cè) IP地址有它們的用處,但相當(dāng)有限。例如你是一個(gè)論壇版主,你發(fā)現(xiàn)某個(gè)用戶粘貼一些不健康的、違法的內(nèi)容。你可以找到他的IP地址,把從這個(gè)IP連進(jìn)來的用戶逐出論壇。使用下面一行命令將會(huì)得到某個(gè)特定請(qǐng)求的源IP地址: # ip = $REMOTE_ADDR 4、使用PHP加密技術(shù) 在PHP中,加密技術(shù)主要用來加密信息、產(chǎn)生校驗(yàn)和和摘要。使用加密技術(shù)可大大地增強(qiáng)安全性能。 這里只講述使用加密技術(shù)的一些概念。如果你想進(jìn)一步了解,應(yīng)參考一些好的加密技術(shù)資料。加密技術(shù)的標(biāo)準(zhǔn)是Bmce Schneier的應(yīng)用加密技術(shù),非常值得一讀。他的網(wǎng)站(www.counterpane.com/labs.html )是在互聯(lián)網(wǎng)上查找加密技術(shù)資料的好起點(diǎn)。數(shù)據(jù)加密是一個(gè)非常復(fù)雜的話題,這里只簡(jiǎn)單介紹一下。 PHP中大多數(shù)的加密函數(shù)由mcrypt庫(kù)和mhash庫(kù)提供。你需要在系統(tǒng)中裝上這兩個(gè)庫(kù),在編譯時(shí)加上--ith-mcrypt和--ith-hash選項(xiàng)。PHP從 3.013版本開始支持mcrypt庫(kù)。 5、使用具有SSL技術(shù) SSI是英文Server Side Includes的縮寫。使用具有SSL(安全套接字協(xié)議層)功能的web服務(wù)器,可以不用改變一行代碼而提高網(wǎng)站的安全性能。SSI使用加密方法來保護(hù)web服務(wù)器和瀏覽器之間的信息流。SSL不僅用于加密在互聯(lián)網(wǎng)上傳遞的數(shù)據(jù)流,而且還提供雙方身份驗(yàn)證。這樣,你就可以安全地在線購(gòu)物而不必?fù)?dān)心別人矢隨你的信用卡的信息。這種特性使得SSL適用于那些交換重要信息的地方,像電子商務(wù)和基于Web的郵件。 SSL使用公共密鑰加密技術(shù),服務(wù)器在連接結(jié)束時(shí)給客戶端發(fā)送公用密鑰用來加密信息,而加密的信息只有服務(wù)器用它自己持有的專用密鑰才能解開。客戶端用公用密鑰加密數(shù)據(jù),并且發(fā)送給服務(wù)端自己的密鑰,以唯一確定自己,防止在系統(tǒng)兩端之間有人冒充服務(wù)端或客戶端進(jìn)行欺騙。 加密的HTTP連接用443端口號(hào)代替80端口號(hào),以區(qū)別于普通的不加密的HTTP??蛻舳耸褂眉用蹾TTP連接時(shí)會(huì)自動(dòng)使用443端口而不是80端口。這使得服務(wù)端更容易作出相應(yīng)的響應(yīng)。 在Apache服務(wù)器下,可以通過直接編輯服務(wù)器配置文件或者在需要使用SSI的目錄中創(chuàng)建.htaccess文件來啟動(dòng)SSI。登錄到服務(wù)器,找到配置文件的存放目錄,使用文字編輯器打開文件srm.conf,找到以下幾行: # If you want to use server side includes, or CGI outside # ScriptAliased directories, uncomment the following lines. #AddType text/x-server-parsed-html .shtml #AddType application/x-httpd-CGI .CGI 將以AddType開頭的兩行并且去掉每一行最前面的"#"符號(hào)即可。保存所做的修改,然后再打開文件access.conf。 ?。糄irectory /usr/local/etc/httpd/htdocs> # This may also be "None", "All", or any combination of "Indexes", # "Includes", or "FollowSymLinks" Options Indexes FollowSymLinks ?。?Directory> 將其中的Options Indexes FollowSymLinks改為:Options Indexes FollowSymLinks Includes 即可。 2. PHP安全設(shè)置 PHP本身再老版本有一些問題,比如在 php4.3.10和php5.0.3以前有一些比較嚴(yán)重的bug,所以推薦使用新版。另外,目前鬧的轟轟烈烈的SQL Injection也是在PHP上有很多利用方式,所以要保證安全,PHP代碼編寫是一方面,PHP的配置更是非常關(guān)鍵。 我們php手工編譯安裝的,php的默認(rèn)配置文件在 /usr/local/php/conf/php.ini,我們最主要就是要配置php.ini中的內(nèi)容,讓我們執(zhí)行php能夠更安全。 整個(gè)PHP中的安全設(shè)置主要是為了防止phpshell和SQL Injection的攻擊,一下我們慢慢探討。 (1) 打開php的安全模式 php的安全模式是個(gè)非常重要的內(nèi)嵌的安全機(jī)制,能夠控制一些php中的函數(shù),比如system(),同時(shí)把很多文件操作函數(shù)進(jìn)行了權(quán)限控制,也不允許對(duì)某些關(guān)鍵文件的文件,比如/etc/passwd,但是默認(rèn)的php.ini是沒有打開安全模式的,我們把它打開: safe_mode = on (2) 用戶組安全 當(dāng)safe_mode打開時(shí),safe_mode_gid被關(guān)閉,那么php腳本能夠?qū)ξ募M(jìn)行訪問,而且相同組的用戶也能夠?qū)ξ募M(jìn)行訪問。 建議設(shè)置為: safe_mode_gid = off 如果不進(jìn)行設(shè)置,可能我們無法對(duì)我們服務(wù)器網(wǎng)站目錄下的文件進(jìn)行操作了,比如我們需要對(duì)文件進(jìn)行操作的時(shí)候。 (3) 安全模式下執(zhí)行程序主目錄 如果安全模式打開了,但是卻是要執(zhí)行某些程序的時(shí)候,可以指定要執(zhí)行程序的主目錄: safe_mode_exec_dir = /usr/bin 一般情況下是不需要執(zhí)行什么程序的,所以推薦不要執(zhí)行系統(tǒng)程序目錄,可以指向一個(gè)目錄,然后把需要執(zhí)行的程序拷貝過去,比如: safe_mode_exec_dir = /tmp/cmd 但是,我更推薦不要執(zhí)行任何程序,那么就可以指向我們網(wǎng)頁(yè)目錄: safe_mode_exec_dir = /usr/www (4) 安全模式下包含文件 如果要在安全模式下包含某些公共文件,那么就修改一下選項(xiàng): safe_mode_include_dir = /usr/www/include/ 其實(shí)一般php腳本中包含文件都是在程序自己已經(jīng)寫好了,這個(gè)可以根據(jù)具體需要設(shè)置。 (5) 控制php腳本能訪問的目錄 使用open_basedir選項(xiàng)能夠控制PHP腳本只能訪問指定的目錄,這樣能夠避免PHP腳本訪問/etc/passwd等文件,一定程度上限制了phpshell的危害,我們一般可以設(shè)置為只能訪問網(wǎng)站目錄: open_basedir = /usr/www (6) 關(guān)閉危險(xiǎn)函數(shù) 如果打開了安全模式,那么函數(shù)禁止是可以不需要的,但是我們?yōu)榱税踩€是考慮進(jìn)去。比如,我們覺得不希望執(zhí)行包括system()等在那的能夠執(zhí)行命令的php函數(shù),或者能夠查看php信息的phpinfo()等函數(shù),那么我們就可以禁止它們: disable_functions = system,passthru,exec,shell_exec,popen,phpinfo 如果你要禁止任何文件和目錄的操作,那么可以關(guān)閉很多文件操作 disable_functions = chdir,chroot,dir,getcwd,opendir,readdir,scandir,fopen,unlink,delete,copy,mkdir,rmdir,rename,file,file_get_contents,fputs,fwrite,chgrp,chmod,chown 以上只是列了部分不叫常用的文件處理函數(shù),你也可以把上面執(zhí)行命令函數(shù)和這個(gè)函數(shù)結(jié)合,就能夠抵制大部分的phpshell了。 (7) 關(guān)閉PHP版本信息在http頭中的泄漏 我們?yōu)榱朔乐购诳瞳@取服務(wù)器中php版本的信息,可以關(guān)閉該信息斜路在http頭中: expose_php = Off 比如黑客在 telnet www.irunnet.com 80 的時(shí)候,那么將無法看到PHP的信息。 關(guān)閉注冊(cè)全局變量 打開php的安全模式 php的安全模式是個(gè)非常重要的內(nèi)嵌的安全機(jī)制,能夠控制一些php中的函數(shù),比如system(),同時(shí)把很多文件操作函數(shù)進(jìn)行了權(quán)限控制,也不允許對(duì)某些關(guān)鍵文件的文件,比如/etc/passwd,但是默認(rèn)的php.ini是沒有打開安全模式的,我們把它打開: safe_mode = on (2) 用戶組安全 當(dāng)safe_mode打開時(shí),safe_mode_gid被關(guān)閉,那么php腳本能夠?qū)ξ募M(jìn)行訪問,而且相同組的用戶也能夠?qū)ξ募M(jìn)行訪問。 建議設(shè)置為: safe_mode_gid = off 如果不進(jìn)行設(shè)置,可能我們無法對(duì)我們服務(wù)器網(wǎng)站目錄下的文件進(jìn)行操作了,比如我們需要對(duì)文件進(jìn)行操作的時(shí)候。 (3) 安全模式下執(zhí)行程序主目錄 如果安全模式打開了,但是卻是要執(zhí)行某些程序的時(shí)候,可以指定要執(zhí)行程序的主目錄: safe_mode_exec_dir = /usr/bin 一般情況下是不需要執(zhí)行什么程序的,所以推薦不要執(zhí)行系統(tǒng)程序目錄,可以指向一個(gè)目錄,然后把需要執(zhí)行的程序拷貝過去,比如: safe_mode_exec_dir = /tmp/cmd 但是,我更推薦不要執(zhí)行任何程序,那么就可以指向我們網(wǎng)頁(yè)目錄: safe_mode_exec_dir = /usr/www (4) 安全模式下包含文件 如果要在安全模式下包含某些公共文件,那么就修改一下選項(xiàng): safe_mode_include_dir = /usr/www/include/ 其實(shí)一般php腳本中包含文件都是在程序自己已經(jīng)寫好了,這個(gè)可以根據(jù)具體需要設(shè)置。 (5) 控制php腳本能訪問的目錄 使用open_basedir選項(xiàng)能夠控制PHP腳本只能訪問指定的目錄,這樣能夠避免PHP腳本訪問/etc/passwd等文件,一定程度上限制了phpshell的危害,我們一般可以設(shè)置為只能訪問網(wǎng)站目錄: open_basedir = /usr/www (6) 關(guān)閉危險(xiǎn)函數(shù) 如果打開了安全模式,那么函數(shù)禁止是可以不需要的,但是我們?yōu)榱税踩€是考慮進(jìn)去。比如,我們覺得不希望執(zhí)行包括system()等在那的能夠執(zhí)行命令的php函數(shù),或者能夠查看php信息的phpinfo()等函數(shù),那么我們就可以禁止它們: disable_functions = system,passthru,exec,shell_exec,popen,phpinfo 如果你要禁止任何文件和目錄的操作,那么可以關(guān)閉很多文件操作 disable_functions = chdir,chroot,dir,getcwd,opendir,readdir,scandir,fopen,unlink,delete,copy,mkdir,rmdir,rename,file,file_get_contents,fputs,fwrite,chgrp,chmod,chown 以上只是列了部分不叫常用的文件處理函數(shù),你也可以把上面執(zhí)行命令函數(shù)和這個(gè)函數(shù)結(jié)合,就能夠抵制大部分的phpshell了。 (7) 關(guān)閉PHP版本信息在http頭中的泄漏 我們?yōu)榱朔乐购诳瞳@取服務(wù)器中php版本的信息,可以關(guān)閉該信息斜路在http頭中: expose_php = Off 比如黑客在 telnet www.irunnet.com 80 的時(shí)候,那么將無法看到PHP的信息。 關(guān)閉注冊(cè)全局變量 在PHP中提交的變量,包括使用POST或者GET提交的變量,都將自動(dòng)注冊(cè)為全局變量,能夠直接訪問,這是對(duì)服務(wù)器非常不安全的,所以我們不能讓它注冊(cè)為全局變量,就把注冊(cè)全局變量選項(xiàng)關(guān)閉: register_globals = Off 當(dāng)然,如果這樣設(shè)置了,那么獲取對(duì)應(yīng)變量的時(shí)候就要采用合理方式,比如獲取GET提交的變量var,那么就要用$_GET[‘var‘]來進(jìn)行獲取,這個(gè)php程序員要注意。 (9) 打開magic_quotes_gpc來防止SQL注入 SQL注入是非常危險(xiǎn)的問題,小則網(wǎng)站后臺(tái)被入侵,重則整個(gè)服務(wù)器淪陷,所以一定要小心。php.ini中有一個(gè)設(shè)置: magic_quotes_gpc = Off 這個(gè)默認(rèn)是關(guān)閉的,如果它打開后將自動(dòng)把用戶提交對(duì)sql的查詢進(jìn)行轉(zhuǎn)換,比如把 ‘ 轉(zhuǎn)為 \‘等,這對(duì)防止sql注射有重大作用。所以我們推薦設(shè)置為: magic_quotes_gpc = On (10) 錯(cuò)誤信息控制 一般php在沒有連接到數(shù)據(jù)庫(kù)或者其他情況下會(huì)有提示錯(cuò)誤,一般錯(cuò)誤信息中會(huì)包含php腳本當(dāng)前的路徑信息或者查詢的SQL語句等信息,這類信息提供給黑客后,是不安全的,所以一般服務(wù)器建議禁止錯(cuò)誤提示: display_errors = Off 如果你卻是是要顯示錯(cuò)誤信息,一定要設(shè)置顯示錯(cuò)誤的級(jí)別,比如只顯示警告以上的信息: error_reporting = E_WARNING & E_ERROR 當(dāng)然,我還是建議關(guān)閉錯(cuò)誤提示。 (11) 錯(cuò)誤日志 建議在關(guān)閉display_errors后能夠把錯(cuò)誤信息記錄下來,便于查找服務(wù)器運(yùn)行的原因: log_errors = On 同時(shí)也要設(shè)置錯(cuò)誤日志存放的目錄,建議根apache的日志存在一起: error_log = /usr/local/apache2/logs/php_error.log 注意:給文件必須允許apache用戶的和組具有寫的權(quán)限。 3. Mysql的安全設(shè)置 我們把Mysql安裝在 /usr/local/mysql目錄下,我們必須建立一個(gè)用戶名為mysql,組為mysql的用戶來運(yùn)行我們的mysql,同時(shí)我們把它的配置文件拷貝到 /etc目錄下: # cp suport-files/my-medium.cnf /etc/my.cnf chown root:sys /etc/my.cnf chmod 644 /etc/my.cnf 使用用戶mysql來啟動(dòng)我們的mysql: # /usr/local/mysql/bin/mysqld_safe -user=mysql & (1) 修改root用戶的的口令 缺省安裝的mysql是沒有密碼的,所以我們要修改,以防萬一。下面采用三種方式來修改root的口令。 * 用mysqladmin命令來改root用戶口令 # mysqladmin -uroot password test 這樣,MySQL數(shù)據(jù)庫(kù)root用戶的口令就被改成test了。(test只是舉例,我們實(shí)際使用的口令一定不能使用這種易猜的弱口令) * 用set password修改口令: mysql> set password for root@localhost=password(‘test‘); 這時(shí)root用戶的口令就被改成test了。 * 直接修改user表的root用戶口令 mysql> use mysql; mysql> update user set password=password(‘test‘) where user=‘root‘; mysql> flush privileges; 這樣,MySQL數(shù)據(jù)庫(kù)root用戶的口令也被改成test了。其中最后一句命令flush privileges的意思是強(qiáng)制刷新內(nèi)存授權(quán)表,否則用的還是緩沖中的口令,這時(shí)非法用戶還可以用root用戶及空口令登陸,直到重啟MySQL服務(wù)器。 (2) 刪除默認(rèn)的數(shù)據(jù)庫(kù)和用戶 我們的數(shù)據(jù)庫(kù)是在本地,并且也只需要本地的php腳本對(duì)mysql進(jìn)行讀取,所以很多用戶不需要。mysql初始化后會(huì)自動(dòng)生成空用戶和test庫(kù),這會(huì)對(duì)數(shù)據(jù)庫(kù)構(gòu)成威脅,我們?nèi)縿h除。 我們使用mysql客戶端程序連接到本地的mysql服務(wù)器后出現(xiàn)如下提示: mysql> drop database test; mysql> use mysql; mysql> delete from db; mysql> delete from user where not(host="localhost" and user="root"); mysql> flush privileges; (3) 改變默認(rèn)mysql管理員的名稱 這個(gè)工作是可以選擇的,根據(jù)個(gè)人習(xí)慣,因?yàn)槟J(rèn)的mysql的管理員名稱是root,所以如果能夠修改的話,能夠防止一些腳本小子對(duì)系統(tǒng)的窮舉。我們可以直接修改數(shù)據(jù)庫(kù),把root用戶改為"admin" mysql> use mysql; mysql> update user set user="admin" where user="root"; mysql> flush privileges; (4) 提高本地安全性 提高本地安全性,主要是防止mysql對(duì)本地文件的存取,比如黑客通過mysql把/etc/passwd獲取了,會(huì)對(duì)系統(tǒng)構(gòu)成威脅。mysql對(duì)本地文件的存取是通過SQL語句來實(shí)現(xiàn),主要是通過Load DATA LOCAL INFILE來實(shí)現(xiàn),我們能夠通過禁用該功能來防止黑客通過SQL注射等獲取系統(tǒng)核心文件。 禁用該功能必須在 my.cnf 的[mysqld]部分加上一個(gè)參數(shù): set-variable=local-infile=0 (5) 禁止遠(yuǎn)程連接mysql 因?yàn)槲覀兊膍ysql只需要本地的php腳本進(jìn)行連接,所以我們無需開socket進(jìn)行監(jiān)聽,那么我們完全可以關(guān)閉監(jiān)聽的功能。 有兩個(gè)方法實(shí)現(xiàn): * 配置my.cnf文件,在[mysqld]部分添加 skip-networking 參數(shù) * mysqld服務(wù)器中參數(shù)中添加 --skip-networking 啟動(dòng)參數(shù)來使mysql不監(jiān)聽任何TCP/IP連接,增加安全性。如果要進(jìn)行mysql的管理的話,可以在服務(wù)器本地安裝一個(gè)phpMyadmin來進(jìn)行管理。 (6) 控制數(shù)據(jù)庫(kù)訪問權(quán)限 對(duì)于使用php腳本來進(jìn)行交互,最好建立一個(gè)用戶只針對(duì)某個(gè)庫(kù)有 update、select、delete、insert、drop table、create table等權(quán)限,這樣就很好避免了數(shù)據(jù)庫(kù)用戶名和密碼被黑客查看后最小損失。 比如下面我們創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)為db1,同時(shí)建立一個(gè)用戶test1能夠訪問該數(shù)據(jù)庫(kù)。 mysql> create database db1; mysql> grant select,insert,update,delete,create,drop privileges on db1.* to test1@localhost identified by ‘a(chǎn)dmindb‘; 以上SQL是創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)db1,同時(shí)增加了一個(gè)test1用戶,口令是admindb,但是它只能從本地連接mysql,對(duì)db1庫(kù)有select,insert,update,delete,create,drop操作權(quán)限。 (7) 限制一般用戶瀏覽其他用戶數(shù)據(jù)庫(kù) 如果有多個(gè)數(shù)據(jù)庫(kù),每個(gè)數(shù)據(jù)庫(kù)有一個(gè)用戶,那么必須限制用戶瀏覽其他數(shù)據(jù)庫(kù)內(nèi)容,可以在啟動(dòng)MySQL服務(wù)器時(shí)加--skip-show-database 啟動(dòng)參數(shù)就能夠達(dá)到目的。 ( 忘記mysql密碼的解決辦法 如果不慎忘記了MySQL的root密碼,我們可以在啟動(dòng)MySQL服務(wù)器時(shí)加上參數(shù)--skip-grant-tables來跳過授權(quán)表的驗(yàn)證 (./safe_mysqld --skip-grant-tables &),這樣我們就可以直接登陸MySQL服務(wù)器,然后再修改root用戶的口令,重啟MySQL就可以用新口令登陸了。 (9) 數(shù)據(jù)庫(kù)文件的安全 我們默認(rèn)的mysql是安裝在/usr/local/mysql目錄下的,那么對(duì)應(yīng)的數(shù)據(jù)庫(kù)文件就是在/usr/local/mysql/var目錄下,那么我們要保證該目錄不能讓未經(jīng)授權(quán)的用戶訪問后把數(shù)據(jù)庫(kù)打包拷貝走了,所以要限制對(duì)該目錄的訪問。 我們修改該目錄的所屬用戶和組是mysql,同時(shí)改變?cè)L問權(quán)限: # chown -R mysql.mysql /usr/local/mysql/var # chmod -R go-rwx /usr/local/mysql/var (10) 刪除歷史記錄 執(zhí)行以上的命令會(huì)被shell記錄在歷史文件里,比如bash會(huì)寫入用戶目錄的.bash_history文件,如果這些文件不慎被讀,那么數(shù)據(jù)庫(kù)的密碼就會(huì)泄漏。用戶登陸數(shù)據(jù)庫(kù)后執(zhí)行的SQL命令也會(huì)被MySQL記錄在用戶目錄的.mysql_history文件里。如果數(shù)據(jù)庫(kù)用戶用SQL語句修改了數(shù)據(jù)庫(kù)密碼,也會(huì)因.mysql_history文件而泄漏。所以我們?cè)趕hell登陸及備份的時(shí)候不要在-p后直接加密碼,而是在提示后再輸入數(shù)據(jù)庫(kù)密碼。 另外這兩個(gè)文件我們也應(yīng)該不讓它記錄我們的操作,以防萬一。 # rm .bash_history .mysql_history # ln -s /dev/null .bash_history # ln -s /dev/null .mysql_history (11) 其他 另外還可以考慮使用chroot等方式來控制mysql的運(yùn)行目錄,更好的控制權(quán)限,具體可以參考相關(guān)文章。 4. vsFTPd安全設(shè)置 vsFTPd是一款非常著名的ftp daemon程序,目前包括Redhat.com在內(nèi)很多大公司都在使用,它是一款非常安全的程序,因?yàn)樗拿志徒校篤ery Secure FTP Daemon (非常安全的FTP服務(wù)器)。 vsftpd設(shè)置選項(xiàng)比較多,涉及方方面面,我們下面主要是針對(duì)安全方面進(jìn)行設(shè)置。 目前我們的需求就是使用系統(tǒng)帳戶同時(shí)也作為是我們的FTP帳戶來進(jìn)行我們文件的管理,目前假設(shè)我只需要一個(gè)帳戶來更新我的網(wǎng)站,并且我不希望該帳戶能夠登陸我們的系統(tǒng),比如我們的網(wǎng)站的目錄是在/usr/www下面,那么我們新建一個(gè)用戶ftp,它的主目錄是/usr/www,并且它的shell是/usr/sbin/nologin,就是沒有shell,防止該用戶通過ssh等登陸到系統(tǒng)。 下面在進(jìn)行系統(tǒng)詳盡的設(shè)置,主要就是針對(duì)vsftpd的配置文件vsftpd.conf文件的配置。 (1) 禁止匿名用戶訪問, 我們不需要什么匿名用戶,直接禁止掉: anonymous_enable=NO (2) 允許本地用戶登陸,因?yàn)槲覀冃枰褂胒tp用戶來對(duì)我們網(wǎng)站進(jìn)行管理: local_enable=YES (3) 只允許系統(tǒng)中的ftp用戶或者某些指定的用戶訪問ftp,因?yàn)橄到y(tǒng)中帳戶眾多,不可能讓誰都訪問。 打開用戶文件列表功能: userlist_enable=YES 只允許用戶文件列表中的用戶訪問ftp: userlist_deny=NO 用戶名文件列表路徑: userlist_file=/etc/vsftpd.user_list 然后在/etc下建立文件 vsftpd.user_list 文件,一行一個(gè),把用戶ftp加進(jìn)去,同時(shí)也可以加上你允許訪問的系統(tǒng)帳戶名。 (4) 禁止某些用戶登陸ftp: pam_service_name=vsftpd 指出VSFTPD進(jìn)行PAM認(rèn)證時(shí)所使用的PAM配置文件名,默認(rèn)值是vsftpd,默認(rèn)PAM配置文件是/etc/pam.d/vsftpd。 /etc/vsftpd.ftpusers VSFTPD禁止列在此文件中的用戶登錄FTP服務(wù)器,用戶名是一行一個(gè)。這個(gè)機(jī)制是在/etc/pam.d/vsftpd中默認(rèn)設(shè)置的。 這個(gè)功能和(3)里的功能有點(diǎn)類似,他們倆能結(jié)合使用,那樣就最好了。 (5) 把本地用戶鎖定在自己的主目錄,防止轉(zhuǎn)到其他目錄,比如把/etc/passwd給下載了: chroot_local_users=NO chroot_list_enable=YES chroot_list_file=/etc/vsftpd.chroot_list 然后在/etc下建立vsftpd.chroot_list文件,里面把我們要限制的本地帳戶加進(jìn)去,一行一個(gè),我們加上ftp,防止它登陸到系統(tǒng)。 (6) 隱藏文件真實(shí)的所有用戶和組信息,防止黑客拿下ftp后查看更多系統(tǒng)用戶信息: hide_ids=YES (7) 取消ls -R命令,節(jié)省資源,因?yàn)槭褂迷撁?,在文件列表很多的時(shí)候?qū)⒗速M(fèi)大量系統(tǒng)資源: ls_recurse_enable=NO ( 上傳文件的默認(rèn)權(quán)限,設(shè)置為022: local_umask=022 如果要覆蓋刪除等,還要打開: write_enable=YES (9) ftp的banner信息,為了防止黑客獲取更多服務(wù)器的信息,設(shè)置該項(xiàng): ftpd_banner=banner string 把后面的banner string設(shè)為你需要的banner提示信息,為了安全,建議不要暴露關(guān)于vsFTPd的任何信息。 另外,如果你的信息比較多的話,可以設(shè)置為提示信息是讀取一個(gè)文件中的信息: banner_file=/directory/vsftpd_banner_file (10) 打開日志功能: xferlog_enable=YES 同時(shí)設(shè)置日志的目錄: xferlog_file=/var/log/vsftpd.log 啟用詳細(xì)的日志記錄格式: xferlog_enable=YES (11) 如果打開虛用戶功能等,那么建議關(guān)閉本地用戶登陸: local_enable=NO vsFTPd還有很多安全設(shè)置,畢竟人家的名字就是:Very Secure FTP Daemon,反正它的溢出漏洞什么的是很少的,如果要更安全,建議按照自己的需要設(shè)置vsftpd,設(shè)置的好,它絕對(duì)是最安全的。 |
聯(lián)系客服