Apache无法连接到新的tomcat 9 ajp



在将Spring boot的版本从2.1.4升级到2.3.2后,我的apache2无法再连接(通过ajp(到我的Spring boot嵌入式tomcat。

它显示以下错误:

[proxy:error] [pid xxxx ] (111)Connection refused: AH00957: AJP: attempt to connect to 10.0.75.1:8500 (10.0.75.1) failed
[proxy_ajp:error] [pid xxxx ] [client xxx ] AH00896: failed to make connection to backend: 10.0.75.1, referer: http://myapp.develop/home/

我的开发环境是这样设置的:

  • Angular应用程序(运行在4200上的节点服务器(

  • 一个弹簧引导后端(在tomcat上8500端口上设置的ajp连接器(

  • 一个前端apache2服务器(位于docker容器上(,用于将请求重定向到两个应用程序:

    <VirtualHost *:80>
    ServerName myapp.develop
    ProxyPass "/home" "http://10.0.75.1:4200/home"
    ProxyPassReverse "/home" "http://10.0.75.1:4200/home"
    ProxyPass "/backend" "ajp://10.0.75.1:8500/backend"
    ProxyPassReverse "/backend" "ajp://10.0.75.1:8500/backend"
    

我通过/etc/hosts上的域名访问我的web应用程序:myapp.develope

这是我的春靴tomcat的配置

Connector connector = new Connector("AJP/1.3");
connector.setScheme("http");
connector.setPort(8500);
connector.setSecure(false);
connector.setAllowTrace(false);
((AbstractAjpProtocol) connector.getProtocolHandler()).setSecretRequired(false);

在app.properties:中

tomcat.ajp.port=8500
tomcat.ajp.remoteauthentication=false
tomcat.ajp.enabled=true

这是tomcat日志:

o.s.b.w.e.t.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http) 8500 (http)
o.a.c.h.Http11NioProtocol    : Initializing ProtocolHandler ["http-nio-8080"]
o.a.c.a.AjpNioProtocol       : Initializing ProtocolHandler ["ajp-nio-127.0.0.1-8500"]
o.a.c.c.StandardService      : Starting service [Tomcat]
o.a.c.c.StandardEngine       : Starting Servlet engine: [Apache Tomcat/9.0.37]

我怀疑这种变化:

  • 在8.5.51以后的版本中,AJP连接器的默认侦听地址被更改为环回地址,而不是所有地址

是造成我这个问题的原因,但我不知道如何解决它。

我在升级tomcat版本时遇到了类似的问题。将下面提到的属性添加到ajp连接器帮助了我的案例。

connector.setProperty("address","0.0.0.0");
connector.setProperty("allowedRequestAttributesPattern",".*");
((AbstractAjpProtocol)connector.getProtocolHandler()).setSecretRequired(false);

详细说明:

对于您的疑问:

在8.5.51以后的版本中,AJP连接器的默认侦听地址为更改为环回地址,而不是所有地址。

在此更新之前,tomcat AJP连接器愿意接受来自任何IP地址的请求,因此不需要显式指定";地址";所有物但在这次更新之后,默认行为是AJP连接器愿意接受仅作为localhost(环回(发出的请求。使用下面列出的";地址";属性以将侦听范围扩展到不仅环回地址

connector.setProperty("address","0.0.0.0"); // OR connector.setProperty("address","::");

使用以下属性可以启用所有类型的请求属性(除非您有标头信息,否则请启用特定的请求属性(。具有无法识别的请求属性的请求将被403响应拒绝:

connector.setProperty("allowedRequestAttributesPattern",".*"); 

使用";secretRequired";属性来定义是否需要与HTTP服务器交换机密,以便允许通过ajp进行请求。如果是,则设置"是";秘密";属性。否则,请求将以403失败。

((AbstractAjpProtocol)connector.getProtocolHandler()).setSecretRequired(false);

参考:Apache Tomcat 8配置参考

AJP协议的使用需要额外的安全考虑因为它允许更直接地操作Tomcat的内部数据结构而不是HTTP连接器。应特别注意支付给地址机密secretRequired使用的值allowedRequestAttributesPattern属性。

我从未见过在这样的代码中设置连接器,它是在server.xml 中声明的

但是,您的代码是

Connector connector = new Connector("AJP/1.3");
connector.setScheme("http");
connector.setPort(8500);
connector.setSecure(false);
connector.setAllowTrace(false);
((AbstractAjpProtocol) connector.getProtocolHandler()).setSecretRequired(false);

然后你声明你知道这个突破性的改变

在8.5.51以后的版本中,AJP连接器的默认侦听地址被更改为环回地址,而不是所有地址。

两者结合:您从未在代码中设置侦听地址,因此您可能使用默认地址。当你试图转发到一个非环回地址时,没有办法通过这种方式到达服务器。

这个答案的一位匿名编辑器建议使用connector.setAttribute("address", "0.0.0.0");,但就我个人而言,我更喜欢将其保存在server.xml中:连接器通常不会在运行时进行配置和更改,让管理员编辑文本文件在日常操作中会方便得多。

最新更新