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 是符号连接,连接到刚刚解压的目录。
这个可以实现通过符号连接在多个版本之间快速切换。
- Python数据科学计算库的安装和numpy简单
- 4G安全:研究人员发现攻击4G无线上网卡和SIM卡的方法
- Python文学化编程 - Jupyter notebook使用和插件拓展
- PoisonCake(毒蛋糕):内置于手机ROM的恶意代码模块
- Spring+SpringMVC+MyBatis整合
- Python之numpy数组学习(五)——广播
- WordPress再悲剧:WPcache-Blogger感染事件影响五万WordPress网站
- 浅谈神经机器翻译
- 窃取Facebook用户信息:利用Android同源策略漏洞的恶意应用被发现
- 关于React Native 安卓首屏白屏优化
- 浅谈spring security 403机制一、无权限访问二、匿名访问三、有权限访问原因机制指定AccessDeniedHandler指定error-page情景原因结论
- Python之numpy数组学习(二)
- Intent 属性详解(上)
- 复仇行动:Notepad++官网被圣战组织黑了
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Java函数式编程之Stream流编程
- 使用docker安装elasticsearch伪分布式集群以及安装ik中文分词插件
- PyQt5 技巧篇-如何让窗体只显示关闭按钮
- Gradle多项目构建与jar包发布
- Gradle初体验
- hexo初始化
- 容器部署Spring Cloud项目
- Python 爬虫篇-爬取网页中的图片,图片爬取实例演示。
- Python 爬虫进阶篇-4行代码实现爬取指定网站中的全部图片,深入剖析
- Python+selenium 自动化-基本环境搭建
- Java多线程与并发笔记
- Python 技术篇-pygame库实现播放音乐,带漂亮小界面!
- Java底层:GC相关
- Python 技术篇-pygame界面添加图片不显示,原因及解决办法
- SpringBoot集成Graylog