前段时间,做了一个新项目。在项目打包时,将jdk和tomcat打包到版本包里了,还贴心的附上了在linux环境安装以及配置教程,结果被怼了。
一则是说不需要安装jdk,只需要安装jre,即可让项目跑起来。jdk是java开发工具,jre是java运行环境,jdk是包含jre的。安装过jdk的都知道,在安装jdk的过程中,还会单独让装一个jre的,其实这个地方的jre不用安装,因为jdk里面是包含jre的,在配置环境变量的时候,也通常不会去配置到单独安装的jre的,而是直接指到jdk下的jre。
一则是说这个tomcat不安全,需要给tomcat安全加固和优化。这不就涉及到知识盲点了吗?
在server.xml中一般配置有三个端口,一个是shutdown的端口,监听停止tomcat的命令,一个是http的监听端口,再一个是AJP的监听端口。
shutdown的默认配置如下:
<Server port="8005" shutdown="SHUTDOWN">
那么当其他用户能telnet到这个ip的端口,就可以使用SHUTDOWN来停止tomcat服务。
启动tomcat如下:
在windown10中默认telnet服务是不开启的,想要尝试的同学需要先开启telnet服务。
在cmd中telnet命令如下,点击确定,在Telnet新窗口输入SHUTDOWN,即可看到tomcat服务已关闭。
那么就需要修改默认的端口以及关闭tomcat的命令。例子如下:
<Server port="18000" shutdown="STOP123">
在webapps下有tomcat预先放置的项目。如下图:
这些项目使得我访问http://127.0.0.1:8080就可以访问tomcat的管理等页面。
删除掉之后,再次访问这个路径,就会显示报错。
当用不上ajp端口时,需要将如下代码注释掉。
<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
修改conf/server.xml配置,开启access日志,在logs目录下会生成localhost_access_log.txt,记录每次请求。
如下图:
修改conf/web.xml的listings为false
其实上述的大多数配置,在tomcat9中已经配置,所以为了安全,请使用高版本tomcat.
安装使用tomcat时,不要使用root用户。同时bin目录下的sh脚本权限要限制在最小范围。
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目录下即可。
还需要修改conf/web.xml,使得必须使用https端口才能访问,配置如下:
<login-config>
·
<auth-method>CLIENT-CERTauth-method>
<realm-name>Client Cert Users-only Arearealm-name>
login-config>
<security-constraint>
<web-resource-collection >
<web-resource-name >SSLweb-resource-name>
<url-pattern>/*url-pattern>
web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIALtransport-guarantee>
user-data-constraint>
security-constraint>
增加了上面这个配置后,假如关闭了https的connector,只保留http的connector,也无法通过http访问服务,因为这个地方强制必须使用https来访问。
下列http的不安全的请求方式配置在web.xml中,禁止使用,只允许GET和POST方式
<security-constraint>
<web-resource-collection>
<url-pattern>/*url-pattern>
<http-method>PUThttp-method>
<http-method>DELETEhttp-method>
<http-method>HEADhttp-method>
<http-method>OPTIONShttp-method>
<http-method>TRACEhttp-method>
web-resource-collection>
<auth-constraint>
auth-constraint>
security-constraint>
上面证书的密钥是以明文的方式存储的,还需要将密钥以加密的方式配置在server.xml文件中。
先建立一个maven项目,来重写org.apache.coyote.http11.Http11NioProtocol(上述Connector配置的http协议类)中设置证书秘钥的方法。
<!-- 这两个依赖是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>
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);
}
}
<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” 配置的是加密后的证书秘钥.
在公司的红线要求中有一条,sessionId的长度必须是48位以上。那么需要在context.xml中配置如下:
<Manager>
<SessionIdGenerator sessionIdLength = "24"/>
</Manager>