優化主要參考了這裡
在我們跑Web服務器的時候,大家可能都會一致認為使用Linux+Mysql+apache+php整個開源的系統是比較好的選擇,但是我個人認為這是不合理的,首先要根據你的應用來覺得你使用什麼服務。假如你需要跑Oracle等大型應用的話,而且Oracle在Linux下是支持的比較好的,那麼使用Linux是個好的選擇,因為在freebsd下安裝Oracle是個非常麻煩的事情。那麼如果是跑普通的網站應用的話,我覺得使用freebsd+Mysql+apache+php是個好的選擇,因為對於一個網站來講,穩定安全是第一位的,否則你的網站什麼時候被人修改了都不知道怎麼回事,或者被黑客入侵,把數據修改或者刪除,那就糟糕了,畢竟現在什麼紅客、黑客的一堆,不能不防。當然,不是說Linux不安全,但是在Linux下集成了很多不安全的程序,導致了它的不安全,但如果設置的好,Linux一樣可以很安全。在中國網絡應急響應中心(http://www.cert.org.cn)這幾個月的數據來看,每個月被入侵成功最高的是Linux系統,占百分之六十多,然後過來是Windows系統,占百分之三十多,而freebsd的入侵比例是百分之幾。
任何系統都可以很安全,也可以很不安全,關鍵是管理員怎麼做的,世界上沒有最安全的系統,只有更安全的系統。下面的文章就是
在freebsd平台上構建一個比較安全的Web服務器,希望對網管和網絡安全愛好者能有一些啟發,權當拋磚引玉,希望能夠有更好闡述的文章。
一、系統和服務程序的安裝
1. 系統安裝
為了保證系統的安全,我們系統准備采用最新的freebsd版本,首先是安全,系統兼容性也比較好,這個主要是個人習慣和需求,為了簡單起見,這裡我們選用了最新的FreeBSd5.3版本進行安裝。整個安裝過程我就不講了,如果不清楚的朋友可以參考FreeBSD中文手冊(http://www.freebsd.org.cn),整個過程不是很復雜,雖然沒有Windows/Linux的系統安全簡單,但是比起有些Unix的安裝來講是人性許多的。安裝中必須把基本包和內核源代碼都裝上,為了以後編譯內核方便,如果另外,如果喜歡使用ports安裝軟件的話,還要把ports裝上,但是盡量一些沒有必要的程序不要裝。如果要安裝Webmin等,還要把perl等包裝上。系統文件拷貝完以後,會要求配置一些設置,比如把IP地址、名字服務器等設好,不要打開IPv6,不需要DHCP等服務,不要系統默認的FTP服務,配置 /etc/inetd.conf 時把SSH服務打開,方便我們進行遠程管理,如果不想使用inetd這個超級服務來管理的話,可以關閉它,在/etc/rc.conf中添加inetd_enable="NO",然後設置sshd_enable="YES"一樣可以打開SSH服務,後面我們會詳細談到SSH的設置。
系統裝完後,在 /etc/inetd.conf 中把除了ssh之外的服務全部關閉,特別是telnet和rlogin等服務,一定要慎重,否則很可能每幾天系統就被入侵了。安裝完系統後,建議對系統進行升級,比如使用 make world 或 cvsup 把系統內核和ports進行升級。這個步驟和Windows裝完後打補丁差不多。
2. 服務程序安裝
系統裝完以後,就開始安裝我們的應用軟件,我們的方針還是最新的軟件是最安全的,比如能夠防止一些老版本中的溢出等等。我們基本就是要讓我們的系統有數據庫,同時能夠處理Web服務,同時能夠遠程對網站進行文件管理的FTP服務。我們基本選擇的程序都是比較通常的程序。另外,為了有個可視化的管理工具,我們同時也可以安裝一個基於浏覽器的管理工具Webmin,方便沒有ssh客戶端等等的時候進行管理。
首先我們選用的Web服務是apache httpd 2.0.53,這是目前的最新版本,當然你也可以考慮1.3的版本,主要是看個人習慣。我們網站是php程序編寫,所以要安裝php,版本是4.3.11,也是最新的版本,如果你的網站程序需要PHP5的支持,那麼可以下載php5.0.4。數據庫還是最快速的Mysql,選擇的版本是最新的 4.0.23,如果你需要外鍵、事務、子查詢、存儲過程等的支持,那麼你可以考慮4.1和5.0的版本。最後我們的FTP選擇最安全的vsFTPd,因為它是最安全快速的,我在局域網中測試它的最高創數速率能夠達到10MB/S,proFTPd只有8MB/S,vsFTPd針對小型FTP服務器支持非常好,畢竟我用戶不多,幾個更新網站而已,當然,如果你喜歡簡單方便,也可以考慮使用FreeBSD自帶的FTPd,功能和易用性也是不錯的。如果你用戶比較多,並且功能要求比較高,建議使用proFTPd、pure-FTPd、wu-FTPd等,但有些FTPd不是非常安全,選擇時候一定要慎重考慮。
服務器程序列表:
apache 2.0.53 下載地址:http://httpd.apache.org
PHP 4.3.11 下載地址:http://www.php.net
Mysql 4.0.23 下載地址:http://dev.mysql.com
vsFTPd 2.0.2 下載地址:http://vsftpd.beasts.org
反正最少的服務+最少的端口+安全的設置 = 最大的安全,盡量能夠不需要使用的服務就不要安裝,比如telnetd、rlogind等,那麼相反會對服務器安全構成威脅。
安裝以上程序你可以采用手工編譯安裝,也可以采用FreeBSD的ports 來進行安裝,這看個人愛好,我個人比較喜歡使用手工安裝,如果不明白具體安裝的朋友可以參考我的Blog上關於安裝Apache+PHP+Mysql的方法。
二、系統安全設置
1. 用戶控制
盡量少的用戶,我們的FTP帳戶是和系統帳戶綁定在一起的,所以我們添加用戶的時候先建立一個目錄,然後把新建的用戶主目錄指向到該目錄下。假設我需要一個用戶能夠管理我的網站,而我網站的目錄是在 /usr/www 目錄下,那麼我們新建立的用戶 www_user 的主目錄就指向 /usr/www 目錄,同時它的shell是沒有的:/usr/sbin/nologin ,主要是為了防止它通過ssh登陸到系統。同時FTP的密碼也要設置的非常復雜,防止黑客通過暴力破解獲得FTP權限。另外還要說道我們的root用戶的密碼,我想最少應該不要少於10位的數字+字母+字符的密碼(我的密碼是18位),否則是非常不安全的,如果密碼簡單,那麼黑客通過短時間的暴力破解SSH中的root帳戶,不用幾天,系統就可能被攻破了,同時也建議最少一個月更改一次root用戶的密碼。(強烈建議一般帳戶不要有登陸系統的權限,就是把shell設為/usr/sbin/nologin)
一般如果要使用root權限建議建立一個屬於wheel組的小用戶,然後登陸後通過su命令提升為root用戶進行管理,如果黑客通過破解了我們普通用戶的權限後登陸系統,也不能直接通過root權限進行管理,這是一種安全防范的簡單方法。
2. 文件訪問控制
有時候被黑客入侵後拿到了小權限用戶,比如傳了一個WebShell到系統中,那麼對方很可能會把 /etc/passwd 等內容直接讀取出來,同時查看/etc/master.passwd中對加密後的root用戶的密碼hash進行破解,最後拿到密碼進行登陸系統。那麼我們就要控制部分文件只有root能夠訪問,其他用戶無權訪問。比如uname,gcc等,如果黑客拿到小權限用戶後就會查看系統版本,然後找到該版本系統對應的溢出程序,使用gcc來進行編譯,如果我們能夠限制黑客訪問uname和gcc等程序,能在一定程度上減緩黑客入侵的腳步。
使用chmod來改變某個文件的權限信息,比如我要 /etc/passwd 和 /etc/master.passwd 文件只能允許root訪問:
使用八進制數字來設置
# chmod 700 /etc/passwd
# chmod 700 /etc/master.passwd
使用字符標記來進行設置
# chmod u+w+r+x,go-w-r-x /etc/passwd
# chmod u+w+r+x,go-w-r-x /etc/master.passwd
系統中有多個重要文件需要設置控制訪問權限,一定要控制好,否則將會構成重要威脅。
3. 系統服務和端口控制
端口開的越多就越給黑客多一個入侵的機會,服務越多,危險越大,因為你不知道那些服務是不是有潛在的漏洞或者又發現了新的漏洞,所以盡量少的服務,比如sendmail默認是打開的,那麼些建議你把sendmail關閉,關閉防范是在 /etc/rc.conf中加上:
sendmail_enable = "NONE",如果設為"NO"那麼只能夠關閉掉pop3服務,不能關閉smtp的服務,所以要設置為"NONE"。
系統中最好除了我們能夠看到的Apache、Mysql、vsFTPd、SSH之外不要打開其他任何端口和服務。基本的方式是使用netstat -a 查看打開的端口,然後從對應的端口來找相關的服務,比如我們這裡應該只允許開的端口有 21, 22, 80, 3306等,如果有其他端口,那麼一定要仔細檢查,很可能是黑客的後門或者是會對系統安全構成威脅的服務。同時有些服務不需要監聽網絡連接的話,只是需要本地的連接,比如Mysql,那麼就可以關閉Socket監聽,這個將在Mysql安全設置中講解,另外,可以通過防火牆來控制部分端口訪問和連接狀況,比如Mysql的3306端口只允許192.168.0.1訪問,那麼我們就在ipfw裡添加規則:
ipfw add 10001 allow tcp from 192.168.0.1 to 10.10.10.1 80 in
這樣就能夠防止黑客來訪問服務器上的Mysql服務。具體防火牆的設置將在下面“防火牆設置”中詳細講解。
4. 日志管理和控制 (未完)
5. 文件指紋檢測
文件指紋就是我們文件的基本信息,比如文件權限、文件所屬用戶/組、文件最後修改日期、文件大小等等,這些都是重要信息,一般黑客入侵後都可能修改文件,那麼文件指紋就不一樣了。另外,文件的md5校驗值也屬於文件的指紋的一種。
為了防止黑客篡改系統中的部分核心文件,比如 /etc/passwd, /etc/shadow, /etc/inetd.conf 等等,那麼我們就可以考慮把部分重要文件進行備份,同時做一份目前有的文件的一個指紋保留,比如把 /etc,/bin, /usr/bin 目錄下的文件進行指紋保留:
# ls -l /etc > /var/back/etc.txt
# ls -l /bin > /var/back/bin.txt
# ls -l /bin > /var/back/usrbin.txt
當然,還有就是給每個重要的文件加上md5校驗值,如果覺得不對勁的時候就進行匹配,保證文件的安全。
你可以給你覺得需要做指紋備份的目錄進行備份,一般這是為了以後被黑客入侵後的系統檢測和系統恢復。比如可以通過文件被修改的時間來確定是不是被入侵,比如可以對比看 /etc/inetc.conf文件和備份的文件有什麼不同來確定是不是安裝了服務型後門等。
6. 系統指紋洩漏和防范 (未完)
一般黑客為了入侵某個系統,一定會先進行掃描等工作,掃描包括目標系統的端口開放情況和服務器使用服務程序和操作系統情況。比如很簡單的手工檢測Web服務的指紋:
# telnet target.com 80
那麼就很可能返回Apache和PHP的版本信息,那麼同時也可能使用掃描工具對Mysql、vsFTPd、SSH等服務的端口進行掃描,獲取這些服務的指紋。多暴露一份系統信息,那麼系統就多一份危險。那麼解決辦法就是把服務器上服務程序的Banner全部修改掉,從而能夠迷惑黑客。
下面簡單的說一些修改那些服務Banner的方法。
* Apache
修改httpd.conf文件,設置以下選項:
ServerSignature Off
ServerTokens Prod
上面的適用apache1***, apache 2.0這些都是默認 , 不過還是有server=Apache字樣, 若要完全去掉需重新編譯。
徹底地去掉banner, 修改httpd.h:
Include/httpd.h
Define SERVER_BASEVENDOR "Apache Group"
Define SERVER_PRODUCTVENDOR "Apache"
Define SERVER_BASEVERSION "1.3.27"
後從新編譯Apache就能夠完全去掉了。
* PHP
在php.ini中設置 expose_php = Off ,那麼將無法在 http頭信息中看到php的版本信息。
* Mysql
* vsFTPd
vsFTPd基本上是無法獲取到一些關於vsFTPd的banner信息的,不過因為vsFTPd默認的banner信息是"Welcome to FTP Server!"對於高手來說,還是能夠猜測到一點,所以我們要徹底改掉。修改vsFTPd的配置文件 vsftpd.conf 中的下面選項:
Ftpd_banner=xxxxx
把後面的xxxxx改為你想要的banner信息。
* SSH
好象FreeBSD下默認安裝的SSH被telnet target.com 22 的時候會顯示SSH和FreeBSD的信息,簡直是個大禍害,什麼都告訴別人了,但是目前為止我還不知道怎麼修改,知道的高手請指點。
7. 系統內核安全
FreeBSD有個比較強的功能,就是能夠定義系統內核的安全等級,主要是為了防止內核後門專門定制的,能通過不同的等級限制對內核的訪問和對防火牆等的修改。我們首先要開啟系統的安全等級,然後設定安全等級,我們打開 /etc/rc.conf:
# ee /etc/rc.conf
加入下面的內容:
kern_securelevel_enable="YES"
kern_securelevel="-1"
第一句是打開安全等級,第二句是定義等級。它一共五個等級,下面說說不同之處。
* kern_securelevel -1:這是系統默認級別,沒有提供任何內核的保護錯誤;
* kern_securelevel 0:基本上作用不多,當你的系統剛啟動就是0級別的,當進入多用戶模式的時候就自動變成1級了。
* kern_securelevel 1:在這個級別上,有如下幾個限制:
a. 不能通過kldload或者kldunload加載或者卸載可加載內核模塊;
b. 應用程序不能通過/dev/mem或者/dev/kmem直接寫內存;
c. 不能直接往已經裝在(mounted)的磁盤寫東西,也就是不能格式化磁盤,但是可以通過標准的內核接口執行寫操作;
d. 不能啟動X-windows,同時不能使用chflags來修改文件屬性;
* kern_securelevel 2:在 1 級別的基礎上還不能寫沒裝載的磁盤,而且不能在1秒之內制造多次警告,這個是防止DoS控制台的;
* kern_securelevel 3:在 2 級別的級別上不允許修改IPFW防火牆的規則。
如果你已經裝了防火牆,並且把規則設好了,不輕易改動,那麼建議使用3級別,如果你沒有裝防火牆,而且還准備裝防火牆的話,不建議使用。我們這裡推薦使用 2 級別,能夠避免比較多對內核攻擊。
8. 系統安全優化
一般優化系統主要是重新編譯內核,去掉一些不要的驅動等等,你可以參考我在我Blog上寫的關於編譯內核的文章。我們這裡對網絡和內核一些選項進行優化和安全設置。編輯 /etc/sysctl.conf 文件,在裡面加入如下內容:(有注釋)
#最大的待發送TCP數據緩沖區空間
net.inet.tcp.sendspace=65536
#最大的接受TCP緩沖區空間
net.inet.tcp.recvspace=65536
#最大的接受UDP緩沖區大小
net.inet.udp.sendspace=65535
#最大的發送UDP數據緩沖區大小
net.inet.udp.maxdgram=65535
#本地套接字連接的數據發送空間
net.local.stream.sendspace=65535
#加快網絡性能的協議
net.inet.tcp.rfc1323=1
net.inet.tcp.rfc1644=1
net.inet.tcp.rfc3042=1
net.inet.tcp.rfc3390=1
#最大的套接字緩沖區
kern.ipc.maxsockbuf=2097152
#系統中允許的最多文件數量
kern.maxfiles=65536
#每個進程能夠同時打開的最大文件數量
kern.maxfilesperproc=32768
#當一台計算機發起TCP連接請求時,系統會回應ACK應答數據包。該選項設置是否延遲ACK應答數據包,把它和包含數據的數據包一起發送,在高速網絡和低負載的情況下會略微提高性能,但在網絡連接較差的時候,對方計算機得不到應答會持續發起連接請求,反而會降低性能。
net.inet.tcp.delayed_ack=0
#屏蔽ICMP重定向功能
net.inet.icmp.drop_redirect=1
net.inet.icmp.log_redirect=1
net.inet.ip.redirect=0
net.inet6.ip6.redirect=0
#防止ICMP廣播風暴
net.inet.icmp.bmcastecho=0
net.inet.icmp.maskrepl=0
#限制系統發送ICMP速率
net.inet.icmp.icmplim=100
#安全參數,編譯內核的時候加了options TCP_Drop_SYNFIN才可以用
net.inet.icmp.icmplim_output=0
net.inet.tcp.drop_synfin=1
#設置為1會幫助系統清除沒有正常斷開的TCP連接,這增加了一些網絡帶寬的使用,但是一些死掉的連接最終能被識別並清除。死的TCP連接是被撥號用戶存取的系統的一個特別的問題,因為用戶經常斷開modem而不正確的關閉活動的連接
net.inet.tcp.always_keepalive=1
#若看到net.inet.ip.intr_queue_drops這個在增加,就要調大net.inet.ip.intr_queue_maxlen,為0最好
net.inet.ip.intr_queue_maxlen=1000
#防止DOS攻擊,默認為30000
net.inet.tcp.msl=7500
#接收到一個已經關閉的端口發來的所有包,直接drop,如果設置為1則是只針對TCP包
net.inet.tcp.blackhole=2
#接收到一個已經關閉的端口發來的所有UDP包直接drop
net.inet.udp.blackhole=1
#為網絡數據連接時提供緩沖
net.inet.tcp.inflight.enable=1
#如果打開的話每個目標地址一次轉發成功以後它的數據都將被記錄進路由表和arp數據表,節約路由的計算時間,但會需要大量的內核內存空間來保存路由表
net.inet.ip.fastforwarding=0
#kernel編譯打開options POLLING功能,高負載情況下使用低負載不推薦SMP不能和polling一起用
#kern.polling.enable=1
#並發連接數,默認為128,推薦在1024-4096之間,數字越大占用內存也越大
kern.ipc.somaxconn=32768
#禁止用戶查看其他用戶的進程
security.bsd.see_other_uids=0
#設置kernel安全級別
kern.securelevel=0
#記錄下任何TCP連接
net.inet.tcp.log_in_vain=1
#記錄下任何UDP連接
net.inet.udp.log_in_vain=1
#防止不正確的udp包的攻擊
net.inet.udp.checksum=1
#防止DOS攻擊
net.inet.tcp.syncookies=1
#僅為線程提供物理內存支持,需要256兆以上內存
kern.ipc.shm_use_phys=1
# 線程可使用的最大共享內存
kern.ipc.shmmax=67108864
# 最大線程數量
kern.ipc.shmall=32768
# 程序崩潰時不記錄
kern.coredump=0
# lo本地數據流接收和發送空間
net.local.stream.recvspace=65536
net.local.dgram.maxdgram=16384
net.local.dgram.recvspace=65536
# 數據包數據段大小,ADSL為1452。
net.inet.tcp.mssdflt=1460
# 為網絡數據連接時提供緩沖
net.inet.tcp.inflight_enable=1
# 數據包數據段最小值,ADSL為1452
net.inet.tcp.minmss=1460
# 本地數據最大數量
net.inet.raw.maxdgram=65536
# 本地數據流接收空間
net.inet.raw.recvspace=65536
#ipfw防火牆動態規則數量,默認為4096,增大該值可以防止某些病毒發送大量TCP連接,導致不能建立正常連接
net.inet.ip.fw.dyn_max=65535
#設置ipf防火牆TCP連接空閒保留時間,默認8640000(120小時)
net.inet.ipf.fr_tcpidletimeout=864000
系統安全,主要看設置密碼文件只有root可以查看修改,設置內核安全級別為不允許修改防止內核後門。