tomcat安全加固,配置https,keystore生成证书,证书密钥以加密方式配置

    技术2025-01-31  13

    一、前言

    前段时间,做了一个新项目。在项目打包时,将jdk和tomcat打包到版本包里了,还贴心的附上了在linux环境安装以及配置教程,结果被怼了。 一则是说不需要安装jdk,只需要安装jre,即可让项目跑起来。jdk是java开发工具,jre是java运行环境,jdk是包含jre的。安装过jdk的都知道,在安装jdk的过程中,还会单独让装一个jre的,其实这个地方的jre不用安装,因为jdk里面是包含jre的,在配置环境变量的时候,也通常不会去配置到单独安装的jre的,而是直接指到jdk下的jre。 一则是说这个tomcat不安全,需要给tomcat安全加固和优化。这不就涉及到知识盲点了吗?

    二、tomcat安全加固

    1.关闭shutdown端口

    在server.xml中一般配置有三个端口,一个是shutdown的端口,监听停止tomcat的命令,一个是http的监听端口,再一个是AJP的监听端口。 shutdown的默认配置如下:

    <Server port="8005" shutdown="SHUTDOWN">

    那么当其他用户能telnet到这个ip的端口,就可以使用SHUTDOWN来停止tomcat服务。 启动tomcat如下: 在windown10中默认telnel服务是不开启的,想要尝试的同学需要先开启telnet服务。 在cmd中telnet命令如下,点击确定,在Telent新窗口输入SHUTDOWN,即可看到tomcat服务已关闭。 那么就需要修改默认的端口以及关闭tomcat的命令。例子如下:

    <Server port="18000" shutdown="STOP123">

    2.删除ROOT等预置项目

    在webapps下有tomcat预先放置的项目。如下图: 这些项目使得我访问http://127.0.0.1:8080就可以访问tomcat的管理等页面。 删除掉之后,再次访问这个路径,就会显示报错。

    3.关闭AJP端口

    当用不上ajp端口时,需要将如下代码注释掉。

    <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->

    4.注释tomcat用户配置

    这个用户配置在tomcat-users.xml中。如下:

    5.开启tomcat的access日志

    修改conf/server.xml配置,开启access日志,在logs目录下会生成localhost_access_log.txt,记录每次请求。 如下图:

    6.禁止列出目录

    修改conf/web.xml的listings为false 其实上述的大多数配置,在tomcat9中已经配置,所以为了安全,请使用高版本tomcat.

    7.最小权限

    安装使用tomcat时,不要使用root用户。同时bin目录下的sh脚本权限要限制在最小范围。

    8.使用https

    tomcat默认的使用的是http,需要修改为使用https的connector。 在conf/server.xml中配置https如下:

    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" minSpareThreads="5" maxSpareThreads="75" enableLookups="true" disableUploadTimeout="true" acceptCount="100" maxThreads="200" SSLEnabled="true" scheme="https" secure="true" keystoreFile="conf/test.keystore" keystorePass="123456" keyAlias="ykqtest" clientAuth="false" sslProtocol="TLS" />

    keyAlias为生成证书的时的别名。 keystoreFile为证书路径,我这个文件是放在了conf目录下。 keystorePass为证书密码。 与此同时需要注意http的redirectPort端口为https的端口号,这样访问http的端口就会重定向到https。 附上生成证书的命令:

    keytool -genkey -validity 36000 -alias ykqtest -keyalg RSA -keystore d:\test.keystore

    36000这个数字是以天为单位,表示证书有效期为100年。 ykqtest是证书的别名。 生成证书后,将keystore文件复制到tomcat的conf目录下即可。

    9.强制https访问

    还需要修改conf/web.xml,使得必须使用https端口才能访问,配置如下:

    <login-config> ·<!-- Authorization setting for SSL --> <auth-method>CLIENT-CERT</auth-method> <realm-name>Client Cert Users-only Area</realm-name> </login-config> <security-constraint> <!-- Authorization setting for SSL --> <web-resource-collection > <web-resource-name >SSL</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint>

    增加了上面这个配置后,假如关闭了https的connector,只保留http的connector,也无法通过http访问服务,因为这个地方强制必须使用https来访问。

    10.加密证书私钥

    上面证书的密钥是以明文的方式存储的,还需要将密钥以加密的方式配置在server.xml文件中。 先建立一个maven项目,来重写org.apache.coyote.http11.Http11NioProtocol(上述Connector配置的http协议类)中设置证书秘钥的方法。

    1)pom.xml
    <!-- 这两个依赖是Http11NioProtocol类依赖的jar包 --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-juli</artifactId> <version>9.0.36</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>9.0.8</version> </dependency>
    2)重写Http11NioProtocol类
    package com.ykq.util; import java.util.Base64; import java.util.Base64.Decoder; import org.apache.coyote.http11.Http11NioProtocol; /** * @author YKQ * 重写Http11NioProtocol类 */ public class ReSetHttpProtocol extends Http11NioProtocol { /** * 重写设置证书密码的方法 */ public void setKeystorePass(String certificateKeystorePassword) { // 原先的方法 //super.setKeystorePass(certificateKeystorePassword); // 这里简单使用一个base64加解密来存储证书密码,实际环境可以使用AES方式加解密 Decoder decoder = Base64.getDecoder(); String password = new String(decoder.decode(certificateKeystorePassword)); super.setKeystorePass(password); } }
    3)导出jar包,将其放入tomcat的lib目录下

    4)重新配置https
    <Connector port="8443" protocol="com.ykq.util.ReSetHttpProtocol" minSpareThreads="5" maxSpareThreads="75" enableLookups="true" disableUploadTimeout="true" acceptCount="100" maxThreads="200" SSLEnabled="true" scheme="https" secure="true" keystoreFile="conf/test.keystore" keystorePass="MTIzNDU2" keyAlias="ykqtest" clientAuth="false" sslProtocol="TLS" />

    上面的com.ykq.util.ReSetHttpProtocol,就是重写的Http11NioProtocol。 keystorePass=“MTIzNDU2” 配置的是加密后的证书秘钥.

    11.配置sessionId的长度

    在公司的红线要求中有一条,sessionId的长度必须是48位以上。那么需要在context.xml中配置如下:

    <Manager> <SessionIdGenerator sessionIdLength = "24"/> </Manager>

    这个地方配置长度24,生成的sessionId,即可达到48位。如下图:

    Processed: 0.011, SQL: 9