最新文章:

首页 运维技术

Apache-Tomcat安全优化和性能优化

发布时间:2017年10月27日 评论数:抢沙发 阅读数:644

    一、Tomcat 安全优化

    1、Telnet 管理端口保护

          使用telnet连接进来可以输入SHUTDOWN可以直接关闭tomcat,极不安全,必须关闭。可以修改默认的管理端口8005改为其他端口,修改SHUTDOWN指令为其他字符串。

    #  vim /data/project/apache-tomcat1/conf/server.xml
    <Server port="8011" shutdown="IN0IT">

    Apache-Tomcat安全优化和性能优化 环境部署 第1张

    2. AJP 连接端口保护

           Tomcat 服务器通过Connector连接器组件与客户程序建立连接,Connector组件负责接收客户的请求,以及把Tomcat服务器的响应结果发送给客 户。默认情况下,Tomcat在server.xml中配置了两种连接器,一种使用ajp,要和apache结合使用,一种使用http。当使用http 时,可以限制ajp端口访问,在于防止线下测试流量被mod_jk转发至线上tomcat服务器。可以通过iptables规则限制ajp端口的访问,或 者直接将改行注释。

    #  vim /data/project/apache-tomcat1/conf/server.xml
    <Connector port="8081" protocol="AJP/1.3"
    connectionTimeout="20000" redirectPort="8443" />

    Apache-Tomcat安全优化和性能优化 环境部署 第2张

    3.禁用管理端

            对于tomcat的web管理端属于高危安全隐患,一旦被攻破,黑客通过上传web shell方式取得服务器的控制权,那是非常可怕的。我们需要删除tomcat安装目录下conf/tomcat-user.xml或者删除webapps下默认的目录和文件。

    # mv webapps/* /tmp  #在此我们选择将默认目录拷贝到/tmp下

    4.降权启动tomcat

            tomcat 启动用户权限必须为非root,避免一旦tomcat服务被入侵,获取root权限,普通用户只能使用大于1024端口,如果要想使用80端口,可以使用 iptables规则进行转发,或者使用代理。一般情况下,tomcat前方有一个反向代理服务器nginx或者apache等。

    参考:https://tomcat.apache.org/tomcat-8.0-doc/setup.html

    [root@Tomcat bin]# cd /data/project/apache-tomcat1/bin/
    [root@Tomcat bin]# tar xf commons-daemon-native.tar.gz 
    [root@Tomcat bin]# cd commons-daemon-1.0.15-native-src/unix/
    [root@Tomcat unix]# ./configure --with-java=/usr/local/jdk1.8.0_60/
    [root@Tomcat unix]# make
    [root@Tomcat unix]# cp jsvc /data/project/apache-tomcat1/bin/
    [root@Tomcat unix]# cd  /data/project/apache-tomcat1/bin/

    编辑daemon.sh,首行加入以下内容,表示启动tomcat用户为nginx

     TOMCAT_USER=nginx

    Apache-Tomcat安全优化和性能优化 环境部署 第3张

    启动关闭tomcat

    [root@Tomcat bin]# ./daemon.sh start
    [root@Tomcat bin]# ./daemon.sh stop
    [root@Tomcat bin]# ./daemon.sh version
    jsvc (Apache Commons Daemon) 1.0.15-dev
    Copyright (c) 1999-2011 Apache Software Foundation.
    java version "1.8.0_60"
    Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
    Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
    commons daemon version "1.0.15-dev"
    commons daemon process (id: 7561, parent: 7560)
    Server version: Apache Tomcat/8.0.27
    Server built:   Sep 28 2015 08:17:25 UTC
    Server number:  8.0.27.0
    OS Name:        Linux
    OS Version:     3.10.0-229.el7.x86_64
    Architecture:   amd64
    JVM Version:    1.8.0_60-b27
    JVM Vendor:     Oracle Corporation
    [root@Tomcat bin]# ./daemon.sh run

    查看启动状态:

    Apache-Tomcat安全优化和性能优化 环境部署 第4张

    5. 文件列表访问控制

            web.xml文件中的default部分listings的配置必须为false,false为不列出目录文件,true为允许列出,默认为false。

    # vim /data/project/apache-tomcat1/conf/web.xml
    <init-param>
                <param-name>listings</param-name>
                <param-value>false</param-value>
            </init-param>

    Apache-Tomcat安全优化和性能优化 环境部署 第5张

    6.隐藏版本信息

            对一些常见错误重定向,避免出错暴露服务器和版本信息。在conf/web.xml重定向403,404及500等错误到指定页面。

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

    7. 脚本权限回收

            去除其他用户对bin目录下可执行权限,防止其他用户起停tomcat

    #  chmod 744 /data/project/apache-tomcat1/bin/*

    8. 访问日志格式规范

        开启Referer和User-Agetn是为了一旦出现安全问题能够更好的根据日志进行排查

    # vim /data/project/apache-tomcat1/conf/server.xml
    <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" />

    Apache-Tomcat安全优化和性能优化 环境部署 第6张

    9. 设置信任IP白名单

    # vim /data/project/apache-tomcat1/conf/server.xml
    <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="192.168.1.*"/>

    Apache-Tomcat安全优化和性能优化 环境部署 第7张

    10.屏蔽DNS查询

    # vim /data/project/apache-tomcat1/conf/server.xml
        <Connector port="8081" protocol="AJP/1.3"
                   connectionTimeout="20000"
                   enableLookups="false"        #  enableLookups="false" 代表屏蔽
                   acceptCount="800"
                   redirectPort="8443" />

    Apache-Tomcat安全优化和性能优化 环境部署 第8张

    二、Tomcat 性能优化

    1、jvm调优

            Tomcat最吃内存,只要内存足够,这只猫就跑的很快。如果系统资源有限,那就需要进行调优,提高资源使用率。

    a.优化catalina.sh

        在catalina.sh配置文件中添加以下代码:

    JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m"

    -server :一定要作为第一个参数,在多个CPU时性能最佳

    -Xms:初始堆内存Heap大小,使用的最小内存,cpu性能高时此值应设的大一些

    -Xmx:初始堆内存heap最大值,使用的最大内存

           上面两个值是分配JVM的最小和最大内存,取决于硬件物理内存的大小,建议均设为物理内存的一半。

    -XX:PermSize:设定内存的永久保存区域

    -XX:MaxPermSize:设定最大内存的永久保存区域

    -XX:MaxNewSize:

    -Xss 15120 这使得JBoss每增加一个线程(thread)就会立即消耗15M内存,而最佳值应该是128K,默认值好像是512k.

    +XX:AggressiveHeap 会使得 Xms没有意义。这个参数让jvm忽略Xmx参数,疯狂地吃完一个G物理内存,再吃尽一个G的swap。

    -Xss:每个线程的Stack大小

    -verbose:gc 现实垃圾收集信息

    -Xloggc:gc.log 指定垃圾收集日志文件

    -Xmn:young generation的heap大小,一般设置为Xmx的3、4分之一

    -XX:+UseParNewGC :缩短minor收集的时间

    -XX:+UseConcMarkSweepGC :缩短major收集的时间

    配置完成后重启tomcat,通过以下命令查看是否配置生效:

    查看tomcat进程号

    [root@Tomcat conf]#  ps -ef|grep java

    Apache-Tomcat安全优化和性能优化 环境部署 第9张

    查看是否生效:

    Apache-Tomcat安全优化和性能优化 环境部署 第10张

    我们可以看到MaxHeapSize 等参数已经生效。

    2. 优化server.xml

            Tomcat的主配置文件,该文件中包含很多主要元素,比如Service、Connector、Host等,这些元素都会创建软件"对象"、排序及进程管道中设置的这些元素嵌套方,使我们可以执行过滤、分组等工作。

            如果要对该文件做优化,我们需要先了解该文件的结构!

    server.xml的结构图:

    Apache-Tomcat安全优化和性能优化 环境部署 第11张

    该文件描述了如何启动Tomcat Server

    <Server>
      <Listener />
      <GlobaNamingResources>
      </GlobaNamingResources
      <Service>
        <Connector />
        <Engine>
          <Logger />
          <Realm />
             <host>
               <Logger />
               <Context />
             </host>
        </Engine>
      </Service>
    </Server>

    针对该文件,我们需要优化的点有如下:

    1、 maxThreads 连接数限制

            maxThreads 是 Tomcat 所能接受最大连接数。一般设置不要超过8000以上,如果你的网站访问量非常大可能使用运行多个Tomcat实例的方法, 即,在一个服务器上启动多个tomcat然后做负载均衡处理。

    这里还需要注意的一点是,tomcat 和 php 不同。php可以按照cpu和内存的情况去配置连接数,上万很正常。而 java 还需要注意 jvm 的参数配置。如果不注意就会因为jvm参数过小而崩溃。

    2、多虚拟主机

            强烈建议不要使用 Tomcat 的虚拟主机,推荐每个站点使用一个实例。即,可以启动多个 Tomcat,而不是启动一个 Tomcat 里面包含多个虚拟主机。因为 Tomcat是多线程,共享内存,任何一个虚拟主机中的应用崩溃,都会影响到所有应用程序。虽然采用多实例的方式会产生过多的开销,但至少保障了应用程序的隔离和安全。

    3、压缩传输

            tomcat作为一个应用服务器,也是支持 gzip 压缩功能的。我们可以在 server.xml 配置文件中的 Connector 节点中配置如下参数,来实现对指定资源类型进行压缩。

    compression="on"             # 打开压缩功能 
    compressionMinSize="50"      # 启用压缩的输出内容大小,默认为2KB 
    noCompressionUserAgents="gozilla, traviata"      # 对于以下的浏览器,不启用压缩 
    compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" # 哪些资源类型需要压缩

    提示:

            Tomcat 的压缩是在客户端请求服务器对应资源后,从服务器端将资源文件压缩,再输出到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程 HTML、CSS、Javascript和Text,它可以节省40% 左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP、JSP、ASP、Servlet,SHTML等输出的网页也能进行压缩,压缩效率也很高。但是, 压缩会增加 Tomcat 的负担,因此最好采用Nginx + Tomcat 或者 Apache + Tomcat 方式,将压缩的任务交由 Nginx/Apache 去做。

            一旦启用了这个压缩功能后,我们怎么来测试压缩是否有效呢?首先Tomcat是根据浏览器请求头中的accept-encoding来判断浏览器是否支持 压缩功能,如果这个值包含有gzip,就表明浏览器支持gzip压缩内容的浏览,所以我们可以用httpclient来写一个这样的简单测试程序

    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.methods.GetMethod;
     
    public class HttpTester {
     
    public static void main(String[] args) throws Exception{
    HttpClient http = new HttpClient();
    GetMethod get = new GetMethod("http://www.dlog.cn/js/prototype.js");
    try{
    get.addRequestHeader("accept-encoding", "gzip,deflate");
    get.addRequestHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Alexa Toolbar; Maxthon 2.0)");
    int er = http.executeMethod(get);
    if(er==200){
    System.out.println(get.getResponseContentLength());
    String html = get.getResponseBodyAsString();
    System.out.println(html);
    System.out.println(html.getBytes().length);
    }
    }finally{
    get.releaseConnection();
    }
    }
     
    }

    执行这个测试程序,看看它所输出的是什么内容,如果输出的是一些乱码,以及打印内容的长度远小于实际的长度,那么恭喜你,你的配置生效了,你会发现你网站的浏览速度比以前快多了。

    3.关闭war自动部署

    默认 Tomcat 是开启了对war包的热部署的。为了防止被植入木马等恶意程序,因此我们要关闭自动部署。

          <Host name="localhost"   appBase="/data/www/www"
                unpackWARs="false" autoDeploy="true">

    Apache-Tomcat安全优化和性能优化 环境部署 第12张

    4. 并发优化

    调整连接器connectior的并发处理能力

    # vim /data/project/apache-tomcat1/conf/server.xml

    参数说明:

    maxThreads         #客户请求最大线程数

    minSpareThreads    #Tomcat初始化时创建的 socket 线程数

    maxSpareThreads    #Tomcat连接器的最大空闲 socket 线程数

    minProcessors:    #最小空闲连接线程数,用于提高系统处理性能,默认值为 10

    maxProcessors:    #最大连接线程数,即:并发处理的最大请求数,默认值为 75

    acceptCount:    #允许的最大连接数,应大于等于 maxProcessors ,默认值为 100

    enableLookups:    #是否反查域名,取值为: true 或 false 。为了提高处理能力,应设置为 false

    redirectPort       #在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort 端口

    acceptAccount      #监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads  )

    connectionTimeout  #网络连接超时,单位:毫秒。设置为 0 表示永不超时,这样设置有隐患的。通常可设置为30000 毫秒。

    URIEncoding        ##URL统一编码

    其中和最大连接数相关的参数为maxProcessors 和 acceptCount 。如果要加大并发连接数,应同时加大这两个参数。

    web server允许的最大连接数还受制于操作系统的内核参数设置,通常 Windows 是 2000 个左右, Linux 是1000 个左右。

    示例:

     <Connector port="8081" protocol="AJP/1.3"
                connectionTimeout="20000"
                maxHttpHeaderSize="8192"  
                maxThreads="1000"  
                minSpareThreads="100"  
                maxSpareThreads="1000"  
                minProcessors="100"  
                maxProcessors="1000"  
                enableLookups="false"  
                URIEncoding="utf-8"  
                acceptCount="1000"  
                redirectPort="8443"  
                disableUploadTimeout="true"/>

    Apache-Tomcat安全优化和性能优化 环境部署 第13张

    4.tomcat缓存优化

    # vim /data/project/apache-tomcat1/conf/server.xml

    参数说明:

    maxThreads:tomcat起动的最大线程数,即同时处理的任务个数,默认值为200

    acceptCount:当tomcat起动的线程数达到最大时,接受排队的请求个数,默认值为100

    示例:

    <Connector port="8081" protocol="AJP/1.3"
               connectionTimeout="20000"
               maxThreads="800"
               acceptCount="1000"/>

    Apache-Tomcat安全优化和性能优化 环境部署 第14张

    这两个值如何起作用,请看下面三种情况

    情况1:接受一个请求,此时tomcat起动的线程数没有到达maxThreads,tomcat会起动一个线程来处理此请求。

    情况2:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,tomcat会把此请求放入等待队列,等待空闲线程。

    情况3:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,等待队列中的请求个数也达到了acceptCount,此时tomcat会直接拒绝此次请求,返回connection refused

    maxThreads如何配置

            一般的服务器操作都包括量方面:1计算(主要消耗cpu),2等待(io、数据库等)

            第一种极端情况,如果我们的操作是纯粹的计算,那么系统响应时间的主要限制就是cpu的运算能力,此时maxThreads应该尽量设的小,降低同一时间内争抢cpu的线程个数,可以提高计算效率,提高系统的整体处理能力。

            第二种极端情况,如果我们的操作纯粹是IO或者数据库,那么响应时间的主要限制就变为等待外部资源,此时maxThreads应该尽量设的大,这样才能提高同时处理请求的个数,从而提高系统整体的处理能力。此情况下因为tomcat同时处理的请求量会比较大,所以需要关注一下tomcat的虚拟机内存设置和linux的open file限制。

            我在测试时遇到一个问题,maxThreads我设置的比较大比如3000,当服务的线程数大到一定程度时,一般是2000出头,单次请求的响应时间就会急剧的增加,百思不得其解这是为什么,四处寻求答案无果,最后我总结的原因可能是cpu在线程切换时消耗的时间随着线程数量的增加越来越大,

            cpu把大多数时间都用来在这2000多个线程直接切换上了,当然cpu就没有时间来处理我们的程序了。

            以前一直简单的认为多线程=高效率。。其实多线程本身并不能提高cpu效率,线程过多反而会降低cpu效率。

            当cpu核心数<线程数时,cpu就需要在多个线程直接来回切换,以保证每个线程都会获得cpu时间,即通常我们说的并发执行。

            所以maxThreads的配置绝对不是越大越好。

            现实应用中,我们的操作都会包含以上两种类型(计算、等待),所以maxThreads的配置并没有一个最优值,一定要根据具体情况来配置。

            最好的做法是:在不断测试的基础上,不断调整、优化,才能得到最合理的配置。

            acceptCount的配置,我一般是设置的跟maxThreads一样大,这个值应该是主要根据应用的访问峰值与平均值来权衡配置的。如果设的较小,可以保证接受的请求较快相应,但是超出的请求可能就直接被拒绝如果设的较大,可能就会出现大量的请求超时的情况,因为我们系统的处理能力是一定的。

    提示:

            很多做过php运维的朋友在这里会犯一个大错误,php优化服务器通常怎做法是安装cpu以及内存的情况配置连接数,连接数过万都很正常,但java不同jvm配置要非常小心,稍有差错就会崩溃。

    maxThreads 配置要结合 JVM -Xmx 参数调整,也就是要考虑内存开销。

    5.优化网络

    # sysctl settings are defined through files in
    # /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
    #
    # Vendors settings live in /usr/lib/sysctl.d/.
    # To override a whole file, create a new file with the same in
    # /etc/sysctl.d/ and put new settings there. To override
    # only specific settings, add a file with a lexically later
    # name in /etc/sysctl.d/ and put new settings there.
    #
    # For more information, see sysctl.conf(5) and sysctl.d(5).
    ###############################################################
    net.core.netdev_max_backlog = 32768 
    net.core.somaxconn = 32768 
    net.core.wmem_default = 8388608 
    net.core.rmem_default = 8388608
    net.core.rmem_max = 16777216
    net.core.wmem_max = 16777216 
    net.ipv4.ip_local_port_range = 1024 65000 
    net.ipv4.route.gc_timeout = 100 
    net.ipv4.tcp_fin_timeout = 30 
    net.ipv4.tcp_keepalive_time = 1200 
    net.ipv4.tcp_timestamps = 0 
    net.ipv4.tcp_synack_retries = 2 
    net.ipv4.tcp_syn_retries = 2 
    net.ipv4.tcp_tw_recycle = 1 
    net.ipv4.tcp_tw_reuse = 1 
    net.ipv4.tcp_mem = 94500000 915000000 927000000 
    net.ipv4.tcp_max_orphans = 3276800 
    net.ipv4.tcp_max_syn_backlog = 65536
    ######################################################################
    net.core.netdev_max_backlog = 32768   #每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目  
    net.core.somaxconn = 32768                  #定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为1024
    net.core.wmem_default = 8388608        #该文件指定了发送套接字缓冲区大小的缺省值(以字节为单位)。 
    net.core.rmem_default = 8388608         #该文件指定了接收套接字缓冲区大小的默认值(以字节为单位)。
    net.core.rmem_max = 16777216    #指定了接收套接字缓冲区(接收窗口)大小的最大值(以字节为单位)最大的TCP数据接收缓冲
    net.core.wmem_max = 16777216 #指定了发送套接字缓冲区(接收窗口)大小的最大值(以字节为单位)最大的TCP数据发送缓冲
    net.ipv4.ip_local_port_range = 1024 65000 #指定端口范围的一个配置,默认是32768 61000
    net.ipv4.route.gc_timeout = 100      #路由缓存刷新频率,当一个路由失败后多长时间跳到另一个路由,默认是300。 
    net.ipv4.tcp_fin_timeout = 30          #表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。 
    net.ipv4.tcp_keepalive_time = 1200 #表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
    net.ipv4.tcp_timestamps = 0           #以一种比重发超时更精确的方法(请参阅 RFC 1323)来启用对 RTT 的计算;为了实现更好的性能应该启用这个选项,时间戳在(请参考RFC 1323)TCP的包头增加12个字节 
    net.ipv4.tcp_synack_retries = 2       # syn-ack握手状态重试次数,默认5,遭受syn-flood攻击时改为1或2 
    net.ipv4.tcp_syn_retries = 2            #外向syn握手重试次数,默认4
    net.ipv4.tcp_tw_recycle = 1            # 默认0,tw快速回收
    net.ipv4.tcp_tw_reuse = 1               #表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
    net.ipv4.tcp_mem = 94500000 915000000 927000000 
    #确定 TCP 栈应该如何反映内存使用;每个值的单位都是内存页(通常是 4KB)。
    第一个值是内存使用的下限。
    第二个值是内存压力模式开始对缓冲区使用应用压力的上限。
    第三个值是内存上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。
    对于较大的 BDP 可以增大这些值(但是要记住,其单位是内存页,而不是字节)
    net.ipv4.tcp_max_orphans = 3276800 
    #系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。
    如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。
    这个限制仅仅是为了防止简单的DoS攻击,你绝对不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)

    net.ipv4.tcp_max_syn_backlog = 65536#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。


二维码加载中...
本文作者:Mr.linus      文章标题: Apache-Tomcat安全优化和性能优化
本文地址:http://www.90qj.com/451  百度暂未收录本文
版权声明:若无注明,本文皆为“挨踢 Blog”原创,转载请保留文章出处。
挤眼 亲亲 咆哮 开心 想想 可怜 糗大了 委屈 哈哈 小声点 右哼哼 左哼哼 疑问 坏笑 赚钱啦 悲伤 耍酷 勾引 厉害 握手 耶 嘻嘻 害羞 鼓掌 馋嘴 抓狂 抱抱 围观 威武 给力
提交评论

清空信息
关闭评论