1. 程式人生 > 其它 >Tomcat 安全配置與效能優化

Tomcat 安全配置與效能優化

Tomcat 安全配置與效能優化

摘要

我的系列文件

Netkiller Architect 手札

Netkiller Developer 手札

Netkiller PHP 手札

Netkiller Python 手札

Netkiller Testing 手札

Netkiller Cryptography 手札

Netkiller Linux 手札

Netkiller Debian 手札

Netkiller CentOS 手札

Netkiller FreeBSD 手札

Netkiller Shell 手札

Netkiller Security 手札

Netkiller Web 手札

Netkiller Monitoring 手札

Netkiller Storage 手札

Netkiller Mail 手札

Netkiller Docbook 手札

Netkiller Project 手札

Netkiller Database 手札

Netkiller PostgreSQL 手札

Netkiller MySQL 手札

Netkiller NoSQL 手札

Netkiller LDAP 手札

Netkiller Network 手札

Netkiller Cisco IOS 手札

Netkiller H3C 手札

Netkiller Multimedia 手札

Netkiller Perl 手札

Netkiller Amateur Radio 手札

Netkiller DevOps 手札

您可以使用iBook閱讀當前文件


目錄

  • 1. JVM
    • 1.1. 使用 Server JRE 替代JDK。
    • 1.2. JAVA_OPTS
  • 2. Tomcat 優化
    • 2.1. maxThreads 連線數限制
    • 2.2. 虛擬主機
    • 2.3. 壓錯傳輸
  • 3. Tomcat 安全配置
    • 3.1.1. 隱藏版本資訊
    • 3.1.2. 應用程式安全
    • 3.1.3. JSESSIONID
    • 3.1. 安裝後初始化配置
    • 3.2. 啟動使用者與埠
  • 4. 如何部署應用程式

1. JVM

1.1. 使用 Server JRE 替代JDK。

伺服器上不要安裝JDK,請使用 Server JRE. 伺服器上根本不需要編譯器,程式碼應該在Release伺服器上完成編譯打包工作。

理由:一旦伺服器被控制,可以防止在其伺服器上編譯其他惡意程式碼並植入到你的程式中。

1.2. JAVA_OPTS

export JAVA_OPTS="-server -Xms512m -Xmx4096m  -XX:PermSize=64M -XX:MaxPermSize=512m"			

-Xms 指定初始化時化的棧記憶體

-Xmx 指定最大棧記憶體

2. Tomcat 優化

2.1. maxThreads 連線數限制

maxThreads 是 Tomcat 所能接受最大連線數。一般設定不要超過8000以上,如果你的網站訪問量非常大可能使用執行多個Tomcat例項的方法。

即,在一個伺服器上啟動多個tomcat然後做負載均衡處理。

			<Connector port="8080" address="localhost"
	maxThreads="2048" maxHttpHeaderSize="8192"
	emptySessionPath="true" protocol="HTTP/1.1"
	enableLookups="false" redirectPort="8181" acceptCount="100"
	connectionTimeout="20000" disableUploadTimeout="true" />			

提示

很多做過php運維的朋友在這裡會犯一個大錯誤,php優化伺服器通常怎做法是安裝cpu以及記憶體的情況配置連線數,連線數過萬都很正常,但java不同jvm配置要非常小心,稍有差錯就會崩潰。

maxThreads 配置要結合 JVM -Xmx 引數調整,也就是要考慮記憶體開銷。

maxThreads  		客戶請求最大執行緒數
minSpareThreads    	初始化時建立的 socket 執行緒數
maxSpareThreads   	聯結器的最大空閒 socket 執行緒數			

2.2. 虛擬主機

不要使用Tomcat的虛擬主機,每個站點一個例項。即,啟動多個tomcat.

這也是PHP運維在這裡常犯的錯誤,PHP的做法是一個Web下面放置多個虛擬主機,而不是每個主機啟動一個web伺服器。Tomcat 是多執行緒,共享記憶體,任何一個虛擬主機中的應用出現崩潰,會影響到所有應用程式。採用多個例項方式雖然開銷比較大,但保證了應用程式隔離與安全。

2.3. 壓錯傳輸

通常所說的gzip壓縮,Tomcat通過在server.xml配置設定壓縮的選項。

			<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
               compression="on"
               compressionMinSize1="2048"
               noCompressionUserAgents="gozilla, traviata"
               compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,,application/octet-stream"/>			

提示

壓縮會增加Tomcat負擔,最好採用Nginx + Tomcat 或者 Apache + Tomcat 方式,壓縮交由Nginx/Apache 去做。

compression 			開啟壓縮功能   
compressionMinSize   	啟用壓縮的輸出內容大小,這裡面預設為2KB
compressableMimeType 	壓縮型別			

3. Tomcat 安全配置

3.1. 安裝後初始化配置

當Tomcat完成安裝後你首先要做的事情如下:

首次安裝完成後立即刪除webapps下面的所有程式碼

rm -rf /srv/apache-tomcat/webapps/*			

註釋或刪除 tomcat-users.xml 所有使用者許可權,看上去如下:

			# cat conf/tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
</tomcat-users>			

3.1.1. 隱藏版本資訊

隱藏Tomcat版本資訊

				vim $CATALINA_HOME/conf/server.xml

    <Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
				maxThreads="8192"
				minSpareThreads="64"
				maxSpareThreads="128"
				acceptCount="128"
				enableLookups="false"
                server="Neo App Srv 1.0"/>

# curl -I http://localhost:8080/
HTTP/1.1 400 Bad Request
Transfer-Encoding: chunked
Date: Thu, 20 Oct 2011 09:51:55 GMT
Connection: close
Server: Neo App Srv 1.0				

伺服器資訊已經被改為 Server: Neo App Srv 1.0

3.1.2. 應用程式安全

關閉war自動部署 unpackWARs="false" autoDeploy="false"。防止被植入木馬等惡意程式

關閉 reloadable="false" 也用於防止被植入木馬

3.1.3. JSESSIONID

修改 Cookie 變數 JSESSIONID, 這個cookie 是用於維持Session關係。建議你改為PHPSESSID。

3.2. 啟動使用者與埠

不要使用root使用者啟動tomcat,Java程式與C程式不同。nginx,httpd 使用root使用者啟動守護80埠,子程序/執行緒會通過setuid(),setgid()兩個函式切換到普通使用者。即父程序所有者是root使用者,子程序與多執行緒所有者是一個非root使用者,這個使用者沒有shell,無法通過ssh與控制檯登陸系統,Java 的JVM 是與系統無關的,是建立在OS之上的,你使用什麼使用者啟動Tomcat,那麼Tomcat 就會繼承該所有者的許可權。

這造成了一個問題,Linux系統小於1024的埠只有root可以使用,這也是為什麼Tomcat預設埠是8080。如果你想使用80埠只能使用root啟動Tomcat。這有帶來了很多安全問題。

解決方案是建立一個不同使用者,如:

groupadd -g 80 daemon
adduser -o --home /daemon --shell /sbin/nologin --uid 80 --gid 80 -c "Web Server" daemon			

注意 /sbin/nologin , 意味著該使用者不能登入,同時我也沒有給它指定密碼,這個使用者只能用於啟動tomcat

chown daemon:daemon -R /srv/*
su - daemon -c "/srv/apache-tomcat/bin/startup.sh"			

接下來解決80埠問題, 思路就是80去呼叫8080,或者對映埠。

下面是影射方案,80 跳轉 8080

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

取消跳轉
iptables -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

檢視規則
iptables -t nat -L			

另一個就是從80請求去呼叫8080的方案

這個方案可以在 Tomcat 前段增加反向代理,例如:Nginx,Apache,Squid,Varnish或者F5, Array這類裝置等等

4. 如何部署應用程式

應用程式部署與tomcat啟動,不能使用同一個使用者。

我的tomcat 安裝在 /srv目錄下,Tomcat啟動使用者為daemon; 應用程式放在/www目錄下www所有者是www使用者。這樣的目的是一旦tomcat被植入web shell程式,它將不能建立或編輯/www目錄下面的任何內容。

adduser --home /www -c "Web Application" www		

我的Tomcat安裝在/srv目錄下,但應用程式放在/www目錄下,一般是這樣的結構。

/www/example.com/www.example.com		

每次升級將壓錯包解壓到 /www/example.com/目錄下,www.example.com 是符號連線,連線到剛剛解壓的目錄。

這個可以實現通過符號連線在多個版本之間快速切換。