在CentOS或RHEL上如何為LAMP服務(wù)器保駕護航
譯文LAMP是一套軟件架構(gòu),包括這幾大部分:Linux(作為基礎(chǔ)層的操作系統(tǒng)),Apache(“位于操作系統(tǒng)之上”的網(wǎng)站服務(wù)器),MySQL(或MariaDB,作為關(guān)系數(shù)據(jù)庫管理系統(tǒng)),最后是PHP(這種服務(wù)器端腳本語言用來處理和顯示存儲在數(shù)據(jù)庫中的信息)。
我們在本文中假設(shè)這套架構(gòu)的每個部分都已經(jīng)搭建并運行起來,因而專門著重介紹為一臺或多臺LAMP服務(wù)器保駕護航。不過必須要強調(diào)的是,服務(wù)器端安全是個龐大繁雜的課題,因而別指望僅僅用一篇文章就能充分而全面地加以論述。
我們在本文中將探討為LAMP軟件架構(gòu)的每個部分保駕護航所要做的基本事項。
確保Linux安全
你可能想通過ssh來管理自己的CentOS服務(wù)器,那就應(yīng)該考慮下面這些小貼士:通過編輯/etc/ssh/sshd_config配置文件,確保安全地遠程訪問服務(wù)器。
1)只要有可能,盡量使用基于密鑰的驗證遠程登錄到服務(wù)器,而不是使用基本的驗證機制(用戶名和密碼)。我們假設(shè)你已經(jīng)在客戶機上建立了密鑰對和用戶名,并拷貝到服務(wù)器上。
PasswordAuthentication no
RSAAuthentication yes
PubkeyAuthentication yes
2)更改sshd將偵聽的端口。建議使用高于1024的端口:
Port XXXX
3)只允許協(xié)議版本2:
Protocol 2
4)配置驗證超時,不允許root登錄,并且限制哪些用戶可以通過ssh登錄:
LoginGraceTime 2m
PermitRootLogin no
AllowUsers gacanepa
5)只允許特定的主機(及/或特定的網(wǎng)絡(luò))通過ssh登錄:
在/etc/hosts.deny文件中:
sshd: ALL
在/etc/hosts.allow文件中:
sshd: XXX.YYY.ZZZ. AAA.BBB.CCC.DDD
其中XXX.YYY.ZZZ.代表IPv4網(wǎng)絡(luò)地址的頭3個8位位組,而AAA.BBB.CCC.DDD是個IPv4地址。有了這種設(shè)置后,只有來自網(wǎng)絡(luò)XXX.YYY.ZZZ.0/24的主機和主機AAA.BBB.CCC.DDD才可以通過ssh進行連接。其他的所有主機還沒有進入到登錄提示符就被斷開,會收到類似這樣的錯誤信息:
(別忘了重啟sshd后臺程序讓這些變更內(nèi)容生效:service sshd restart)。
我們必須要強調(diào)的是,說到阻止訪問你服務(wù)器的入站連接,這種方法快捷又簡單,不過有點原始。想獲得進一步的定制性、擴展性和靈活性,應(yīng)該考慮使用普通iptables及/或fail2ban。
確保Apache安全
1)確保運行Apache網(wǎng)站服務(wù)器的系統(tǒng)用戶無法訪問外殼:
# grep -i apache /etc/passwd
要是用戶apache有默認外殼(比如/bin/sh),我們必須將它更改成/bin/false或/sbin/nologin:
# usermod -s /sbin/nologin apache
下列建議(2到5)針對/etc/httpd/conf/httpd.conf文件:
2)禁止目錄列表:如果目錄里面沒有index.html,這將防止瀏覽器顯示該目錄的內(nèi)容。
刪除Options指令中的單詞Indexes:
# Options指令既復(fù)雜又重要。請參閱
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# 了解更多信息。
# Options Indexes FollowSymLinks
應(yīng)顯示為:
Options None
此外,你需要確保目錄和虛擬主機的設(shè)置并沒有覆蓋這個全局配置。
請注意上述這個例子,如果我們檢查設(shè)置、查找/var/www/icons目錄,就會看到“Indexes MultiViews FollowSymLinks”應(yīng)該被更改成了“None”。
更改前:
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
更改后:
Options None
AllowOverride None
Order allow,deny
Allow from all
3)隱藏Apache版本,并隱藏出錯頁面(比如Not Found和Forbidden頁面)中的模塊/操作系統(tǒng)信息。
ServerTokens Prod # 這意味著http響應(yīng)頭只返回“Apache”,而不返回版本號
ServerSignature Off # 操作系統(tǒng)信息隱藏起來
4)通過注釋掉聲明不需要模塊的對應(yīng)行,禁用那些模塊:
小提示:如果目錄列表中沒有index.html文件,禁用autoindex_module是隱藏目錄列表的另一個方法。
5)限制HTTP請求大小(請求主體和請求頭),并設(shè)置連接超時:
想了解更多指令以及設(shè)置指令方面的說明,請參閱Apache文檔(http://httpd.apache.org/docs/)。
確保MySQL服務(wù)器安全
我們首先運行mysql-server軟件包隨帶的mysql_secure_installation腳本。
1)如果我們在安裝過程中沒有為MySQL服務(wù)器設(shè)置root密碼,現(xiàn)在可以設(shè)置root密碼了,另外要記?。哼@在生產(chǎn)環(huán)境中必不可少。
繼續(xù)這個過程:
2)刪除匿名用戶:
3)只允許root從本地主機來連接:
4)刪除名為test的默認數(shù)據(jù)庫:
5)讓變更內(nèi)容生效:
6)下一步,我們將編輯/etc/my.cnf文件中的一些變量:
[mysqld]
bind-address=127.0.0.1 # MySQL將只接受來自本地主機的連接
local-infile=0 # Disable direct filesystem access log=/var/log/mysqld.log # 啟用日志文件以留意惡意活動
別忘了使用‘service mysqld restart’,重啟MySQL服務(wù)器。
現(xiàn)在,說到日常數(shù)據(jù)庫管理,你會發(fā)現(xiàn)下列建議很有用:
•要是由于某個原因我們需要遠程管理數(shù)據(jù)庫,我們可以首先通過ssh連接到服務(wù)器,本地執(zhí)行必要的查詢和管理任務(wù),以實現(xiàn)遠程管理。
•我們之后可能需要啟用直接訪問文件系統(tǒng)的功能,比如說為了需要將文件批量導(dǎo)入到數(shù)據(jù)庫中。
•保存日志不像上面兩點來得重要,但許多日志對于為數(shù)據(jù)庫排查故障及/或留意不熟悉的活動大有幫助。
•千萬不要以明文格式存儲敏感信息,比如密碼、信用卡號、銀行PIN等等??梢钥紤]使用散列函數(shù)來加密這些信息。
•確保針對特定應(yīng)用程序的數(shù)據(jù)庫只能由該應(yīng)用程序為此創(chuàng)建的相應(yīng)用戶訪問:
想調(diào)整MySQL用戶的訪問權(quán)限,請使用這些指令。#p#
首先,檢索來自用戶表的用戶列表:
gacanepa@centos:~$ mysql -u root -p
Enter password: [Your root password here]
mysql> SELECT User,Host FROM mysql.user;
確保每個用戶只能訪問它所需要的數(shù)據(jù)庫,并確保每個用戶只有最基本的權(quán)限。在下面這個示例中,我們將檢查用戶db_usuario的權(quán)限:
mysql> SHOW GRANTS FOR 'db_usuario'@'localhost';
你隨后可以根據(jù)需要撤銷權(quán)限和訪問權(quán)。
確保PHP安全
由于本文旨在為LAMP架構(gòu)的幾個部分保駕護航,我們在編程方面不會深入介紹。我們假設(shè)我們的Web應(yīng)用程序很安全,因為開發(fā)人員已不怕麻煩地確保沒有留下為跨站腳本攻擊(XSS)或SQL注入攻擊等常見攻擊可趁之機的任何安全漏洞。
1) 禁用不必要的模塊:
我們可以使用下面這個命令:php -m,顯示當(dāng)前編譯模塊列表:
然后禁用不需要的那些模塊,為此只要刪除或更名/etc/php.d目錄中的相應(yīng)文件。
比如說,由于自PHP v5.5.0起mysql擴展部分已被廢棄(將來會被刪除),我們需要禁用它:
# php -m | grep mysql
# mv /etc/php.d/mysql.ini /etc/php.d/mysql.ini.disabled
2) 隱藏PHP版本信息:
# echo "expose_php=off" >> /etc/php.d/security.ini [or modify the security.ini file if it already exists]
3)將open_basedir設(shè)置成幾個特定的目錄(在php.ini中),目的是為了限制對底層文件系統(tǒng)的訪問:
4)禁用遠程代碼/命令執(zhí)行以及容易被利用的函數(shù),比如exec()、system()、passthru()和eval()等函數(shù)(在php.ini)中:
allow_url_fopen = Off
allow_url_include = Off
disable_functions = "exec, system, passthru, eval"
結(jié)束語
1)將軟件包更新到最新版本(比較下列命令的輸出和‘yum info [package]’的輸出):
下列命令返回Apache、MySQL和PHP的當(dāng)前版本:
# httpd -v
# mysql -V (capital V)
# php -v
然后,‘yum update [package]’可用于更新軟件包,以便擁有最新的安全補丁。
2) 確保配置文件只能被root帳戶寫入:
# ls -l /etc/httpd/conf/httpd.conf
# ls -l /etc/my.cnf
# ls -l /etc/php.ini /etc/php.d/security.ini
3)最后,如果你有機會的話,在不同的物理機或虛擬機中(通過防火墻來保護這些機器之間的聯(lián)系),運行這些服務(wù)(網(wǎng)站服務(wù)器、數(shù)據(jù)庫服務(wù)器和應(yīng)用服務(wù)器),那樣萬一某一項服務(wù)受到了危及,攻擊者也無法立即訪問其他服務(wù)。如果真出現(xiàn)攻擊者能立即訪問其他服務(wù)這種情況,就得改動本文中討論的一些配置。請注意:有多種方案可以用來增強LAMP服務(wù)器的安全性,本文介紹的僅僅是其中之一。