参考

基于版本 7.0.50

支持的特性

  • Servlet 3.0 Specification and Javadoc
  • JSP 2.2 and EL 2.2 Specifications, JSP 2.2 Javadoc (note it is labelled as JSP 2.1), EL 2.2 Javadoc
  • WebSocket 1.1 Specification and Javadoc

主要措施

版本安全,使用最新稳定版

服务降级

  • linux

    • 规划用户和用户组

    • 修改 catalina.sh 配置

    1
    2
    3
    4
    5
    # Copy CATALINA_BASE from CATALINA_HOME if not already set  
    [ -z "$CATALINA_BASE" ] && CATALINA_BASE="$CATALINA_HOME"

    # 设置pid。一定要加在CATALINA_BASE定义后面,要不然pid会生成到/下面
    CATALINA_PID="$CATALINA_BASE/tomcat.pid"
    • 未设置JAVA_HOME,JRE_HOME时,catalina.sh 头部添加 JAVA_HOME,JRE_HOME,不添加可能导致服务启动失败

      1
      2
      export JAVA_HOME=/usr/lib/java
      export JRE_HOME=/usr/lib/java/jre
    • 针对使用 systemctl 管理服务,编写 tomcat.service,并放置于
      /lib/systemd/system 目录下

      1
      2
      3
      4
      5
      6
      7
      8
      9
      systemctl daemon-reload //修改tomcat.service文件后使其生效

      systemctl start tomcat
      systemctl start tomcat.service //启动tomcat服务
      systemctl enable tomcat.service //设置开机自启动
      systemctl disable tomcat.service //停止开机自启动
      systemctl status tomcat.service //查看服务当前状态
      systemctl restart tomcat.service //重新启动服务
      systemctl list-units --type=service //查看所有已启动的服务

      tomcat.service:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      [Unit]
      Description=tomcat
      After=syslog.target network.target remote-fs.target nss-lookup.target
      #不同操作系统下,After 后跟的服务名略有不同

      [Service]
      #User=tmct_user
      #Group=tmct_user
      #suse中 用户启动存在问题

      Type=forking

      ExecStart=$TMCT_HOME/bin/startup.sh
      #ExecStop=$TMCT_HOME/bin/shutdown.sh
      ExecReload=/bin/kill -s HUP $MAINPID
      ExecStop=/bin/kill -s QUIT $MAINPID
      PrivateTmp=true

      [Install]
      WantedBy=multi-user.target

      运行效果:

  • windows

    在 windows 下安装 apache,默认情况下,apache 以本地系统权限启动服务,权限过高,存在安全隐患。以普通用户权限启动apache服务的步骤如下:

    • 添加一个普通用户 tmct_user

      1
      2
      net user tmct_user /add #添加用户 tmct_user
      net localgroup users tmct_user /del #该用户不属于任何组
    • 打开服务管理器,在 tomcat 服务的属性页的登录选项卡下,选中“此用户”,然后输入 tmct_user 及其密码,并设置永不过期

    • tomcat 安装目录权限:其他继承父目录权限

      1
      2
      3
      4
      5
      6
      7
      8
      apache-tomcat   //读取和执行、列出文件内容、读取
      ├── bin
      ├── conf
      ├── lib
      ├── logs //读取、写入
      ├── temp
      ├── webapps //读取
      ├── work
  • 重启 tomcat 服务(如果失败,请重启操作系统)

端口保护

  • 默认关闭端口 8005 端口值设置为 -1 表示禁用此端口。

  • 注释 AJP 端口。

  • 更改默认 8080 端口号

1
2
<Server port="-1" shutdown="SHUTDOWN">
<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
  • 更改 tomcat 管理端口 8005 ,此端口有权限关闭 tomcat 服务,但要求端口配置在 8000~8999 之间,并更改 shutdown 执行的命令
  • AJP Connector 利用 AJP13 协议同其他 web 容器进行通信。可以配合 Apache 的 proxy_ajp 模块进行反向代理,暴露成 http 协议给客户端访问,用来做负载均衡或者监控。

网络访问控制

  • 不需要使用 Tomcat 管理后台管理业务代码,建议您使用安全组防火墙功能对管理后台 URL 地址进行拦截,或直接将 Tomcat 部署目录中 webapps 文件夹中的 manager、host-manager 文件夹全部删除,并注释 Tomcat 目录中 conf 文件夹中的 tomcat-users.xml 文件中的所有代码。

  • 需要使用 Tomcat 管理后台进行业务代码的发布和管理,建议为 Tomcat 管理后台配置强口令,并修改默认 admin 用户,且密码长度不低于10位,必须包含大写字母、特殊符号、数字组合。

  • 将 tomcat 应用根目录配置为 tomcat 安装目录以外的目录

隐藏 tomcat 的版本信息,修改 banner

  • 隐藏版本:针对该信息的显示是由一个 jar 包控制的,该 jar 包存放在 $CATALINA_HOME/lib 目录下,名称为 catalina.jar。该 jar 目录有 META-INF 和 org ,
    修改 org/apache/catalina/util/ServerInfo.properties 文件中的 serverinfo 字段来实现来更改我们 tomcat 的版本信息

    1
    2
    server.info= WebServer
    server.number=0.0.0.0
  • 修改 server 属性:tomcat 的 conf/server.xml 找到修改后如下:

    1
    2
    3
    4
    5
    6
    <Connector port="8080" protocol="HTTP/1.1"  
    connectionTimeout="20000"
    redirectPort="8443"
    URIEncoding="UTF-8"
    useBodyEncodingForURI="true"
    server="WebServer/0.0.0.0"/>

关闭热部署

默认Tomcat 是开启了对war包的热部署。为了防止被植入恶意程序,因此我们要关闭自动部署。修改 conf/server.xml,将 unpackWARs 和 autoDeploy 由原先 true 都改为 false :

1
<Host name="localhost"  appBase="" unpackWARs="false" autoDeploy="false">

多实例

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

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

访问日志格式规范

开启 tomcat 默认访问日志中 Referer 和 User-Agent 记录,修改 conf/server.xml,标准配置:

1
2
3
4
5
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="localhost_access_log"
suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b %{Referer}i %{User-Agent}i %D"
resolveHosts="false" />

重定向错误页面

修改访问 Tomcat 错误页面的返回信息,在 webapps/manger 目录中创建相应的401.html、404.htm、500.htm 文件,然后在 conf/web.xml 文件的最后一行之前添加下列代码:

1
2
3
4
5
6
7
8
9
10
11
12
<error-page>
<error-code>401</error-code>
<location>/401.htm</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.htm</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.htm</location>
</error-page>
1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<title>网页访问错误</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="text-align:center">
<h1>网页访问错误,错误代码:404</h1>
</body>
</html>

屏蔽目录文件自动列出

编辑 conf/web.xml 文件,防止直接访问目录时由于找不到默认页面,而列出目录下的文件的情况。在 web.xml 文件中,将 listings 对应指 ture 改成false

本版中已默认配置不列出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>
org.apache.catalina.servlets.DefaultServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>