-
什么是AJP协议?
tomcat的AJP协议及漏洞解决
HTTP协议:连接器监听8080端口,负责建立HTTP连接。在通过浏览器访问Tomcat服务器的Web应用时,使用的就是这个连接器。
AJP协议:连接器监听8009端口,负责和其他的HTTP服务器建立连接。在把Tomcat与其他HTTP服务器集成时,就需要用到这个连接器。所以它的定位就是 “ Tomcat 与 HTTP 服务器之间通信的协议”
AJP 是一种二进制 TCP 传输协议,通过在网络传输二进制包(packet)来完成 Tomcat 与 http 服务器的请求与响应,显然这种方式比纯文本(如 text、xml等)传输的 http 协议效率要高的多。
2.AJP存在的漏洞
2020 年 1 月 6 日,国家信息安全漏洞共享平台(CNVD)收录了由北京长亭科技有限公司发现并报送的 Apache Tomcat 文件包含漏洞。Tomcat AJP 协议由于存在实现缺陷导致相关参数可控,攻击者利用该漏洞可通过构造特定参数,读取服务器 webapp 下的任意文件。若服务器端同时存在文件上传功能,攻击者可进一步实现远程代码的执行。
漏洞影响版本:
7.*分支7.0.100之前版本,建议更新到7.0.100版本;
8.*分支8.5.51之前版本,建议更新到8.5.51版本;
9.*分支9.0.31之前版本,建议更新到9.0.31版本。
3.springboot中与tomcat相关的依赖
基于 SpringBoot 开发 web 应用时,一定要引入 spring-boot-starter-web 组件,spring-boot-starter-web 的职责是负责 web 应用的启动 、初始化、运行和停止。而 spring-boot-starter-web 组件之所以能够跑起来,少不了 http 协议的支持,典型代表就是 tomcat 服务器。
spring-boot-starter-web 组件的相关 maven 依赖中是包含spring-boot-starter-tomcat 组件的,而spring-boot-starter-tomcat 的 maven 依赖又引入了 tomcat-embed-core 、tomcat-embed-el 、tomcat-annotations-api 等嵌入式组件。
4.springboot解决AJP漏洞方法
springboot中是默认不启用AJP的,如果需要开启还需要手动配置。
这一点可以从下图验证(如果已经开启AJP的话启动的日志信息中会包含以下信息)
public class AJPConfig {
private static final String PROTOCOL = "AJP/1.3";
"${tomcat.ajp.port:8009}") (
private int ajpPort;
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
Connector ajpConnector = new Connector();
ajpConnector.setProtocol(PROTOCOL);
ajpConnector.setPort(ajpPort);
tomcat.addAdditionalTomcatConnectors(ajpConnector);
return tomcat;
}
}
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainer() {
return server -> {
if (server instanceof TomcatServletWebServerFactory) {
((TomcatServletWebServerFactory) server).addAdditionalTomcatConnectors(redirectConnector());
}
};
}
private Connector redirectConnector() {
Connector connector = new Connector("AJP/1.3");
connector.setScheme("http");
connector.setPort(ajpPort);
connector.setSecure(false);
connector.setAllowTrace(false);
return connector;
}
如果使用的是外置tomcat
(1)编辑 <CATALINA_BASE>/conf/server.xml,找到如下行(<CATALINA_BASE> 为 Tomcat 的工作目录):
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
(2)将此行注释掉(也可删掉该行):
<!--<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />-->
(3)保存后需重新启动,规则方可生效。
如果springboot(使用默认内置tomcat)并没有手动开启AJP,那么你可以不升级tomcat内置版本。当然你想升级也可以。
如果使用的是springboot的内置tomcat,且手动开启了AJP协议,则需要升级内置tomcat版本。下面贴出一种我亲测可行的方法:
正常情况下每个springboot的版本都会带有一个内置的默认的tomcat,如果需要升级的话,我们可以直接去更改maven库中的该springboot的pom文件中tomcat的版本号即可,以Spring Boot :: (v1.5.22.RELEASE)为例
我们进入repository/org/springframework/boot/spring-boot-dependencies/1.5.12.RELEASE/目录中
编辑修改spring-boot-dependencies-1.5.12.RELEASE.pom文件的
<tomcat.version>8.5.43</tomcat.version>
改为
<tomcat.version>8.5.51</tomcat.version>
每天分享Java知识点
喜欢的话给小编点个赞呗~
关注加❤不丢失~
求帮忙求鼓励么么哒!