Tomcat安全加固

一、 基线目标

  通过在系统生命周期不同阶段对目标系统展开各类安全检查,找出不符合基线定义的安全配置项并选择和实施安全措施来控制安全风险,并通过对历史数据的分析获得系统安全状态和变化趋势。

二、 Tomcat经典漏洞

  后台wargetshell、后台爆破、CVE-2016-8735 Tomcat反序列化漏洞、CVE-2017-12615 tomcat任意上传漏洞、CVE-2018-1305 Tomcat安全绕过漏洞、CVE-2020-1938 Ajp协议文件读取漏洞,等。

三、 Tomcat安全配置规范

1、版本安全

  升级到最新稳定版,出于稳定性考虑,不建议进行跨版本升级。

  当前测试环境:Tomcat 8.5

2、 删除默认应用及示例程序

1) Tomcat 的目录结构
bin-----#存放Tomcat的脚本文件,例如启动、关闭
conf----#Tomcat的配置文件,例如server.xml和web.xml
lib-----#存放Tomcat运行需要的库文件(JAR包)
logs----#存放Tomcat执行时的LOG文件
temp----#存放Tomcat运行时所产生的临时文件
webapps-#Web发布目录,默认情况下把Web应用文件放于此目录
work----#存放jsp编译后产生的class文件
2) 里面一些重要的文件,需要了解其作用
server.xml:配置tomcat启动的端口号、host主机、Context等
web.xml文件:部署描述文件,这个web.xml中描述了一些默认的servlet,部署每个webapp时,都会调用这个文件,配置该web应用的默认servlet 
tomcat-users.xml:tomcat的用户密码与权限。
3) 删除不使用的目录和文件

  如果业务不需要使用 Tomcat 管理后台业务代码,删除webapps目录的所有目录和文件,防止有人利用Tomcat后台弱口令进行漏洞利用。

  删除 webapps 目录下的 docsexamplesmanagerROOThost-manager 文件夹。

  创建webapps/www,编辑conf/server.xml 更改默认的ROOT目录为www<Host>标签之间添加:

 <Context path="" docBase="www" debug="0" reloadable="true" />

3、 端口保护

8005端口管理

  关闭tomcat进程所用,当执行shutdown.sh关闭tomcat时就是连接8005端口执行“SHUTDOWN”命令。由此,我们直接telnet 8005端口执行“SHUTDOWN”也可以成功关闭tomcat。

  防止恶意关闭服务,默认仅允许本地访问。

  conf/server.xml配置文件,shutdown的值为复杂的字符串,或者将端口改为 -1,可禁用端口,但修改后使用shutdown.sh时会报错,可用kill -9 pid。

<Serverport=”8005″ shutdown="复杂的字符串">

AJP端口管理

  AJP是为 Tomcat HTTP 服务器之间通信而定制的协议,能提供较高的通信速度和效率。如果tomcat前端放的是apache的时候,会使用到AJP这个连接器。前端如果是由nginx做的反向代理的话可以不使用此连接器,因此需要注销掉该连接器,避免被远程连接,如Tomcat Ajp 漏洞(CVE-2020-1938)。

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />   #可注释掉此行

  可以修改默认的8080端口为80,或其它端口。

  注意,非root用户不能监听小于1024的端口号,有时重启服务但配置不生效,可杀掉进程,再用startup.sh启动!

4、 隐藏tomcat版本信息

  解压bin目录下的catalina.jar文件,进入org/apache/catalina/util 目录编辑配置文件ServerInfo.properties

cd /usr/local/tomcat8/lib/ && unzip catalina.jar
vi /usr/local/tomcat8/lib/org/apache/catalina/util/ServerInfo.properties
# 修改info和number参数,将修改后的信息压缩回jar包,并重启tomcat
jar uvf catalina.jar org/apache/catalina/util/ServerInfo.properties

修改infonumber

5、 使用非root权限启动服务

  Tomcat以非root权限启动,应用部署目录权限和tomcat服务启动用户分离,比如tomcattomcat用户启动,而部署应用的目录设置为nobody用户750

ps -ef | grep tomcat|grep -v "grep"

创建用户组 及用户tomcat,并禁止该用户登录

groupadd tomcat
useradd -g tomcat -s /usr/sbin/nologin tomcat

更改所有者为刚才创建的用户

chown tomcat.tomcat /usr/local/tomcat8 -R 

对组内用户开放tomcat下所有文件的可读权限,以免启动时报错。如,不能读取sever.xml文件

chmod g+r -R /usr/local/tomcat8
chmod g+x -R /usr/local/tomcat8/bin
chmod g+x -R /usr/local/tomcat8/conf

对组内用户开放tomcatwebappslogsworktemp目录的可写权限

chmod g+w -R /usr/local/tomcat8/webapps
chmod g+w -R /usr/local/tomcat8/logs
chmod g+w -R /usr/local/tomcat8/work
chmod g+w -R /usr/local/tomcat8/temp

新建用户dev,同时指定属组为tomcat组,并设置密码,切换dev用来启动tomcat

useradd -g tomcat dev
passwd dev
$ /usr/local/tomcat8/bin/startup.sh
$ /usr/local/tomcat8/bin/shutdown.sh   #如不成功,重复上面命令添加权限

使用用户dev登陆系统,启动tomcat,成功。

6、 关闭war自动部署

  默认 Tomcat 是开启了对war包的热部署的。为了防止被植入木马等恶意程序,因此我们要关闭自动部署。server.xml中修改unpackWARs=”false” autoDeploy=”false”

7、自定义错误页面 防止信息泄露

  conf/web.xml底部添加以下内容,可配置全局错误页。如果是某个项的,就打开webapp下对应项目的WEB-INF/web.xml,注意标签完整性,否则会报错。

vim /usr/local/tomcat8/conf/web.xml
#在</web-app>标签内 添加以下内容,然后创建webapps/www/error.html
     <error-page>
         <error-code>400</error-code>
         <location>/error.html</location>
     </error-page>

     <error-page>
         <error-code>404</error-code>
         <location>/error.html</location>
     </error-page>

     <error-page>
         <error-code>500</error-code>
         <location>/error.html</location>
     </error-page>

8、 多虚拟主机

  强烈建议不要使用 Tomcat 的虚拟主机,推荐每个站点使用一个实例。即,可以启动多个 Tomcat,而不是启动一个 Tomcat 里面包含多个虚拟主机。

  因为 Tomcat是多线程,共享内存,任何一个虚拟主机中的应用崩溃,都会影响到所有应用程序。虽然采用多实例的方式会产生过多的开销,但至少保障了应用程序的隔离和安全。

9、 限定访问的IP来源

  编辑conf/server.xml文件,增加:

<Valve className="org.apache.catalina.valves.RemoteAddrValve"  allow="192.168.1.10" deny=""/>  
</Host>

   例如,只允许192.168.1.*网段访问:allow=”192.168.1.*” 只允许192.168.1.10192.168.1.30访问:allow=”192.168.1.10,192.168.1.30″  

10、慢速dos攻击防范

  慢速dos攻击漏洞是让服务器等待,当服务器在保持连接等待时,恶意消耗服务器资源。

  修改server.xml文件,connectiontimeout默认是20000ms,此处修改为5000ms,可有效缓解该问题,(该参数是指当建立链接后,如果既收不到客户端的fin也没有数据,此连接等待20s后会被超时释放)。