Home | 簡體中文 | 繁體中文 | 雜文 | 知乎專欄 | Github | OSChina 博客 | 雲社區 | 雲棲社區 | Facebook | Linkedin | 視頻教程 | 打賞(Donations) | About
知乎專欄多維度架構 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者”

第 26 章 Server

目錄

26.1. Linux 系統安全與優化配置
26.1.1. Openssh 安全配置
26.1.1.1. 禁止root用戶登錄
26.1.1.2. 限制SSH驗證重試次數
26.1.1.3. 禁止證書登陸
26.1.1.4. 使用證書替代密碼認證
26.1.1.5. 圖形窗口客戶端記憶密碼的問題
26.1.1.6. 關閉 GSSAPI
26.1.1.7. 禁止SSH連接埠映射
26.1.1.8. IP地址限制
26.1.1.9. 禁止SSH密碼窮舉
26.1.2. Shell 安全
26.1.2.1. .history 檔案
26.1.2.2. sudo 安全問題
26.1.2.3. 臨時檔案安全
26.1.2.4. 執行權限
26.1.3. 防火牆
26.1.3.1. 策略
26.1.3.2. 防止成為跳板機
26.1.3.3. 連接埠安全
26.1.3.4. 封鎖特定字元串
26.1.4. Linux 系統資源調配
26.1.4.1. /etc/security/limits.conf
26.1.4.2. 關閉寫磁碟I/O功能
26.1.5. PAM 插件認證加固配置
26.1.5.1. pam_tally2.so
26.1.5.2. pam_listfile.so
26.1.5.3. pam_access.so
26.1.5.4. pam_wheel.so
26.2. Tomcat 安全配置與性能優化
26.2.1. JVM
26.2.1.1. 使用 Server JRE 替代JDK。
26.2.1.2. JAVA_OPTS
26.2.1.3. java.security 優化
26.2.2. Tomcat 優化
26.2.2.1. maxThreads 連接數限制
26.2.2.2. 虛擬主機
26.2.2.3. 壓縮傳輸
26.2.3. Tomcat 安全配置
26.2.3.1. 禁用8005連接埠
26.2.3.2. 安裝後初始化配置
26.2.3.2.1. 隱藏版本信息
26.2.3.2.2. 應用程序安全
26.2.3.2.3. JSESSIONID
26.2.3.3. 啟動用戶與連接埠
26.2.4. 如何部署應用程序
26.2.5. 延伸閲讀
26.3. PHP 安全與性能優化
26.3.1. Apache mod_php / php-fpm
26.3.1.1. 用戶權限
26.3.1.1.1. Apache
26.3.1.1.2. Nginx / lighttpd + fastcgi
26.3.1.2. web server 版本信息
26.3.1.3. php_flag / php_admin_flag
26.3.1.4. 防止URL注入
26.3.2. php.ini
26.3.2.1. Magic quotes
26.3.2.2. 危險PHP函數
26.3.2.2.1. chdir()函數安全演示
26.3.2.3. 隱藏PHP版本信息
26.3.2.4. session名字可以泄露你的伺服器採用php技術
26.3.2.5. 隱藏PHP出錯信息
26.3.2.6. open_basedir 防止操作web環境意外檔案目錄
26.3.3. 開發於安全
26.3.3.1. 徹底解決目錄于檔案的安全
26.3.3.2. 目錄訪問控制
26.3.3.3. Session / Cookie安全
26.3.3.4. 注入安全
26.3.3.4.1. 禁止輸出調試信息
26.3.3.4.2. 預防SQL注入攻擊
26.3.3.4.3. SHELL 命令注入
26.3.4. 執行效率
26.3.4.1. timeout
26.3.4.1.1. mysql
26.3.4.2. 瀏覽器上傳檔案尺寸控制
26.3.5. 伺服器版本信息
26.4. 環境安裝模板化
26.4.1. 雲主機初始化
26.4.2. CentOS 7 初始化
26.4.3. Nginx
26.4.4. Tomcat
26.4.5. Node.js
26.4.6. MongoDB
26.5. 時間同步
26.6. 郵件系統
26.6.1. Mailing List
26.7. TPC
26.8. IOPS (Input/Output Operations Per Second, pronounced i-ops)
26.9. rPerf
26.10. 磁碟規劃
26.10.1. 物理隔離
26.10.2. 硬件邏輯卷隔離
26.11. Distributed File System(簇檔案系統)
26.11.1. FC 光纖存儲
26.11.2. 聚合檔案系統
26.11.3. 全局檔案系統
26.11.4. 負載均衡檔案系統
26.11.5. 網絡塊設備
26.11.6. Storage 存儲
26.11.6.1. 存儲種類
26.11.6.1.1. Direct Attached Storage
26.11.6.1.2. Network-attached storage
26.11.6.1.3. Storage area network
26.11.6.2. RAID
26.11.6.2.1. 緩存伺服器
26.11.6.2.2. Web 伺服器
26.11.6.2.3. 資料庫
26.11.6.2.4. 數據備份
26.11.6.3. File System 檔案系統
26.11.6.3.1. Distributed File System(DFS)
26.11.6.4. 數據訪問協議
26.11.6.5. 數據管理
26.11.6.5.1. Share 共享
26.11.6.5.2. Mirror 遠程鏡像同步
26.11.6.5.3. 壓縮與重複數據消除
26.11.6.5.4. Backup 備份與恢復
26.11.6.5.5. 故障報告
26.11.7. 磁碟快照
26.12. iDRAC / iLO / IMM

26.1. Linux 系統安全與優化配置

26.1.1. Openssh 安全配置

這節主要講與SSH有關的安全配置

26.1.1.1. 禁止root用戶登錄

只允許普通用戶登陸,然後通過su命令切換到root用過。後面還會將怎樣限制su命令

			
PermitRootLogin no
			
			

26.1.1.2. 限制SSH驗證重試次數

超過3次socket連接會斷開,效果不明顯,有一點點用。

			
MaxAuthTries 3
			
			

26.1.1.3. 禁止證書登陸

證書登陸非常安全,但是很有可能正常用戶在你不知道情況下,給你安裝了一個證書,他隨時都可能進入你的系統

任何一個有權限的用戶都能很方便的植入一個證書到 .ssh/authorized_keys 檔案中

			
PubkeyAuthentication no
AuthorizedKeysFile /dev/null
			
			

26.1.1.4. 使用證書替代密碼認證

是不是自相矛盾? 這個跟上面講的正好相反,這裡只允許使用key檔案登陸。

			
PasswordAuthentication no
			
			

這種方式比起密碼要安全的多,唯一要注意的地方就是證書被拷貝 ,建議你給證書加上 passphrase。

證書的 passphrase 是可以通過openssl工具將其剝離的,SSH證書我沒有試過,但是原理都差不多。

26.1.1.5. 圖形窗口客戶端記憶密碼的問題

當你使用XShell, Xftp, WinSCP, SecureCRT, SecureFX ......等等軟件登錄時,該軟件都提供記住密碼的功能,使你下次再登陸的時候無須輸入密碼就可以進入系統。這樣做的確非常方便,

但是你是否想過你的電腦一旦丟失或者被其他人進入,那有多麼危險。我之前每天背着筆記型電腦上班,上面安裝着XShell並且密碼全部記憶在裡面。這使我意識到一點電腦丟失,有多麼可怕。

禁止SSH客戶端記住密碼,你不要要求別人那麼做。你也無法控制,最終我找到了一種解決方案。

			
ChallengeResponseAuthentication yes
			
			

每次登陸都回提示你輸入密碼。密碼保存也無效。

26.1.1.6. 關閉 GSSAPI

			
GSSAPIAuthentication no
#GSSAPIAuthentication yes
#GSSAPICleanupCredentials yes
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
			
			

26.1.1.7. 禁止SSH連接埠映射

禁止使用SSH映射Socks5翻牆等等

			
AllowTcpForwarding no
			
			

26.1.1.8. IP地址限制

只允許通過192.168.2.1,192.168.2.2 訪問本機

			
# vim /etc/hosts.allow
sshd:192.168.2.1,192.168.2.2
			
			

禁止所有人訪問本機

			
# vim /etc/hosts.deny
sshd:ALL
			
			

上面使白名單策略,你也可以採用黑名單策略。

26.1.1.9. 禁止SSH密碼窮舉

駭客常常使用駭客字典窮舉你的SSH密碼,使用下面腳本可以封殺頻繁連結的IP地址

			
#!/bin/bash
########################################
# Homepage: http://netkiller.github.io
# Author: neo <netkiller@msn.com>
########################################
PIPE=/var/tmp/pipe
pidfile=/var/tmp/$0.pid
BLACKLIST=/var/tmp/black.lst
WHITELIST=/var/tmp/white.lst

LOGFILE=/var/log/secure
DAY=5
########################################

if [ -z "$( egrep "CentOS|7." /etc/centos-release)" ]; then
	echo 'Only for CentOS 7.x'
	exit
fi

if [ -f $BLACKLIST ]; then
	find $BLACKLIST -type f -mtime +${DAY} -delete
fi

if [ ! -f ${BLACKLIST} ]; then
    touch ${BLACKLIST}
fi

if [ ! -f ${WHITELIST} ]; then
    touch ${WHITELIST}
fi

for ipaddr in $(grep rhost ${LOGFILE} | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | sort | uniq -c | sort -r -n | head -n 10| awk '{print $2}')
do

    if [ $(grep -c $ipaddr ${WHITELIST}) -gt 0 ]; then
		continue
    fi

    if [ $(grep -c $ipaddr ${BLACKLIST}) -eq 0 ] ; then
		echo $ipaddr >> ${BLACKLIST}
        iptables -I INPUT -p tcp --dport 22 -s $ipaddr -j DROP
        #iptables -I INPUT -s $ipaddr -j DROP
    fi
done			
			
			

26.1.2. Shell 安全

26.1.2.1. .history 檔案

SA的操作記錄問題

通過~/.bash_history檔案記錄系統管理員的操作記錄,定製.bash_history格式

			
HISTSIZE=1000
HISTFILESIZE=2000
HISTTIMEFORMAT="%Y-%m-%d-%H:%M:%S "
export HISTTIMEFORMAT
			
			

看看實際效果

			
$ history | head
    1  2012-02-27-09:10:45 do-release-upgrade
    2  2012-02-27-09:10:45 vim /etc/network/interfaces
    3  2012-02-27-09:10:45 vi /etc/network/interfaces
    4  2012-02-27-09:10:45 ping www.163.com
			
			

26.1.2.2. sudo 安全問題

/etc/sudoers

			
Cmnd_Alias WEBMASTER = /srv/nginx/sbin/nginx, /srv/php/sbin/php-fpm, !/srv/mysql/bin/*
www localhost = NETWORKING, SERVICES, DELEGATING, PROCESSES, WEBMASTER

Cmnd_Alias Database = /usr/bin/mysqldump, /srv/mysql/bin/mysql, /u01/oracle/10.x.x/bin/sqlplus
mysql localhost = NETWORKING, SERVICES, DELEGATING, PROCESSES, WEBMASTER, Database
			
			

使用www用戶測試登錄,無誤後修改SSH配置檔案,禁止root登錄。

			
vim /etc/ssh/sshd_config
PermitRootLogin no
			
			

然後在測試從www sudo 執行命令, 可能成功啟動nginx 與 php-fpm

26.1.2.3. 臨時檔案安全

臨時檔案不應該有執行權限

/tmp

			
/dev/sda3 /tmp ext4 nosuid,noexec,nodev,rw 0 0
			
			

同時使用符號連接將/var/tmp 指向 /tmp

/dev/shm

			
none /dev/shm tmpfs defaults,nosuid,noexec,rw 0 0
			
			

26.1.2.4. 執行權限

以資料庫為例,從安全形度考慮我們需要如下更改

			
chown mysql:mysql /usr/bin/mysql*
chmod 700 /usr/bin/mysql*
			
			

mysql用戶是DBA專用用戶, 其他用戶將不能執行mysql等命令。

26.1.3. 防火牆

開啟防火牆

		
lokkit --enabled
		
		

26.1.3.1. 策略

預設INPUT,FORWARD,OUTPUT 三個都是ACCEPT

			
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
			
			

從安全的角度出發,INPUT,FORWARD,OUTPUT 三個都是DROP最安全,但配置的時候會給你帶來非常多的不可預料的麻煩。

			
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT DROP
			
			

折中的方案,也是打多少硬件防火牆廠商改採用的方案,他們都是採用INPUT預設禁用所有,OUTPUT預設允許所有,你只要關注INPUT規則即可。

			
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
			
			

26.1.3.2. 防止成為跳板機

跳板機就是用戶首先登陸任意一台伺服器後,由該伺服器在登陸另外一台伺服器。

封鎖22等連接埠,避免相互跳轉

			
iptables -A OUTPUT -p tcp -m multiport --dports 22,21,873 -j REJECT
/etc/init.d/iptables save
iptables -L -n
			
			

web 伺服器禁止使用ssh,作為跳板機

用戶將不能使用ssh命令登陸到其他電腦

26.1.3.3. 連接埠安全

有一種情況,例如你的伺服器被植入了木馬,木馬將開啟一個Socket連接埠給遠程駭客接入進來,通常會啟動一個類似telnet伺服器,怎樣防止未經允許的程序監聽一個連接埠呢?

			
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT  
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT 
-A INPUT -m state --state INVALID,NEW -j DROP
			
			

用法

  1. systemctl stop iptables

  2. 啟動 httpd / nginx

  3. systemctl start iptables

注意必須按照上面的步驟,如果你試圖如下嘗試將失敗

  1. systemctl start iptables

  2. 啟動 httpd / nginx

80連接埠將無法對外提供服務,因為當 -A INPUT -m state --state INVALID,NEW -j DROP 運行以後,任何試圖監聽連接埠的程序將被拒絶。

26.1.3.4. 封鎖特定字元串

下面的例子是拒絶爬蟲

			
# iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string "Spider" -j DROP
# iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string "Baidu" -j DROP
# iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string "Robat" -j DROP
			
			

26.1.4. Linux 系統資源調配

26.1.4.1. /etc/security/limits.conf

很多資料上是這麼寫的

			
* soft nofile 65535
* hard nofile 65535
 			
			

這樣做是偷懶,會帶來很多問題,如果你的伺服器被攻擊,由於你的設置,系統將耗光你的資源,直到沒有任何響應為止,你可能鍵盤輸入都成問題,你不得不重啟伺服器,但你會發現重啟只能維持短暫幾分鐘,又會陷入無響應狀態。

			
nobody soft nofile 4096
nobody hard nofile 8192
			
			

為什麼會設置為nobody用戶呢?因為root用戶啟動系統後web 伺服器會使用nobody用戶創建子進程,socket連接實際上是nobody用戶在處理。root 僅僅是守護父進程。

			
mysql soft nofile 2048
mysql hard nofile 2048
			
			

針對 mysql 做限制

[提示]提示

關於 nofile 即打開檔案數,這個跟socket有非常緊密的關係,在linux系統中任何設備都被看做是一個檔案(字元設備),你連接一個滑鼠,鍵盤,攝像頭,硬碟等等都被看作打開一個設備檔案,所以預設1024是遠遠不夠的。

26.1.4.2. 關閉寫磁碟I/O功能

對於某些檔案沒必要記錄檔案的訪問時間,由其是在高並發的IO密集操作的環境下,通過兩個參數可以實現noatime,nodiratime減少不必要的系統IO資源。

編輯/etc/fstab 添加 noatime,nodiratime 參數

			
/dev/sdb1    /www          ext4    noatime,nodiratime        0 0
			
			

26.1.5. PAM 插件認證加固配置

配置檔案

		
ls  /etc/pam.d/
chfn         crond                login    passwd            remote    runuser-l          smtp          ssh-keycat  sudo-i       system-auth-ac
chsh         fingerprint-auth     newrole  password-auth     run_init  smartcard-auth     smtp.postfix  su          su-l
config-util  fingerprint-auth-ac  other    password-auth-ac  runuser   smartcard-auth-ac  sshd          sudo        system-auth
		
		

認證插件

		
ls /lib64/security/
		
		

26.1.5.1. pam_tally2.so

此模組的功能是,登陸錯誤輸入密碼3次,5分鐘後自動解禁,在未解禁期間輸入正確密碼也無法登陸。

在配置檔案 /etc/pam.d/sshd 頂端加入

			
auth required pam_tally2.so deny=3 onerr=fail unlock_time=300
			
			

查看失敗次數

			
# pam_tally2
Login           Failures Latest failure     From
root               14    07/12/13 15:44:37  192.168.6.2
neo                 8    07/12/13 15:45:36  192.168.6.2
			
			

重置計數器

			
# pam_tally2 -r -u root
Login           Failures Latest failure     From
root               14    07/12/13 15:44:37  192.168.6.2

# pam_tally2 -r -u neo
Login           Failures Latest failure     From
neo                 8    07/12/13 15:45:36  192.168.6.2
			
			

pam_tally2 計數器日誌保存在 /var/log/tallylog 注意,這是二進制格式的檔案

例 26.1. /etc/pam.d/sshd - pam_tally2.so

				
# cat  /etc/pam.d/sshd
#%PAM-1.0
auth required pam_tally2.so deny=3 onerr=fail unlock_time=300

auth	   required	pam_sepermit.so
auth       include      password-auth
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    optional     pam_keyinit.so force revoke
session    include      password-auth
				
				

以上配置root用戶不受限制, 如果需要限制root用戶,參考下面

auth required pam_tally2.so deny=3 unlock_time=5 even_deny_root root_unlock_time=1800
			

26.1.5.2. pam_listfile.so

用戶登陸限制

將下面一行添加到 /etc/pam.d/sshd 中,這裡採用白名單方式,你也可以採用黑名單方式

auth       required     pam_listfile.so item=user sense=allow file=/etc/ssh/whitelist onerr=fail
			

將允許登陸的用戶添加到 /etc/ssh/whitelist,除此之外的用戶將不能通過ssh登陸到你的系統

# cat /etc/ssh/whitelist
neo
www
			

例 26.2. /etc/pam.d/sshd - pam_listfile.so

# cat /etc/pam.d/sshd
#%PAM-1.0
auth       required     pam_listfile.so item=user sense=allow file=/etc/ssh/whitelist onerr=fail
auth       required     pam_tally2.so deny=3 onerr=fail unlock_time=300

auth	   required	pam_sepermit.so
auth       include      password-auth
account    required     pam_nologin.so
account    include      password-auth
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    optional     pam_keyinit.so force revoke
session    include      password-auth
				

sense=allow 白名單方式, sense=deny 黑名單方式

auth       required     pam_listfile.so item=user sense=deny file=/etc/ssh/blacklist onerr=fail
			

更多細節請查看手冊 $ man pam_listfile

26.1.5.3. pam_access.so

編輯 /etc/pam.d/sshd 檔案,加入下面一行

account required pam_access.so
			

保存後重啟sshd進程

編輯 /etc/security/access.conf 檔案

			
cat >>  /etc/security/access.conf << EOF

- : root : ALL EXCEPT 192.168.6.1
EOF
			
			

只能通過 192.168.6.1 登陸, 添加多個IP地址

- : root : ALL EXCEPT 192.168.6.1 192.168.6.2
			

測試是否生效

26.1.5.4. pam_wheel.so

限制普通用戶通過su命令提升權限至root. 只有屬於wheel組的用戶允許通過su切換到root用戶

編輯 /etc/pam.d/su 檔案,去掉下面的註釋

auth		required	pam_wheel.so use_uid
			

修改用戶組別,添加到wheel組

# usermod -G wheel www

# id www
uid=501(www) gid=501(www) groups=501(www),10(wheel)
			

沒有加入到wheel組的用戶使用su時會提示密碼不正確。

$ su - root
Password:
su: incorrect password