AJP 连接器配置为 secretRequired="true" 但在升级到 2.2.5 后 secret 属性为 null 或 ""

The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "" after upgrade to 2.2.5

原因:java.lang.IllegalArgumentException:AJP 连接器配置有 secretRequired="true",但 secret 属性为 null 或“”。此组合无效。在 org.apache.coyote.ajp.AbstractAjpProtocol.start(AbstractAjpProtocol.java:264) 在 org.apache.catalina.connector.Connector.startInternal(Connector.java:1035) ... 省略了 22 个公共帧

将springboot 从2.1.9 升级到2.2.5 后出现上述错误。通过将 tomcat 版本升级到与最新的 springboot 2.2.5 捆绑在一起的 9.0.31,升级是克服 Ghostcat 漏洞所必需的。

这是一个解决方案,虽然可能不是最好的,但我的重点不是这个,只是为了解决错误,我在 Spring Boot 2.2.5.RELEASE 版本上启用了 AJP . 添加:

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

My full class for AJP configuration:

package com.ssldemo.config;

import org.apache.catalina.connector.Connector;
import org.apache.coyote.ajp.AbstractAjpProtocol;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TomcatConfiguration {

    @Value("${tomcat.ajp.port}")
    int ajpPort;

    @Value("${tomcat.ajp.remoteauthentication}")
    String remoteAuthentication;

    @Value("${tomcat.ajp.enabled}")
    boolean tomcatAjpEnabled;

    @Bean
    public TomcatServletWebServerFactory servletContainer() {

        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        if (tomcatAjpEnabled) {
            Connector ajpConnector = new Connector("AJP/1.3");
            ajpConnector.setPort(ajpPort);
            ajpConnector.setSecure(false);
            ajpConnector.setAllowTrace(false);
            ajpConnector.setScheme("http");
            ((AbstractAjpProtocol) ajpConnector.getProtocolHandler()).setSecretRequired(false);
            tomcat.addAdditionalTomcatConnectors(ajpConnector);
        }

        return tomcat;
    }

}

application.properties

server.port=8082
tomcat.ajp.port=9090
tomcat.ajp.remoteauthentication=false
tomcat.ajp.enabled=true

导航至 tomcat 中的 server.xml

AJP替换为:

<Connector protocol="AJP/1.3" address="::1" port="8009"
           redirectPort="8443" secretRequired="false" />

但请确保您了解其中的安全隐患(参见 Krzysztof Skrzynecki 的回答)。

使用 secretRequired="false" 重新引入 Ghostcat 漏洞已解释过的内容,例如here:

This is a configuration issue with AJP protocol in Tomcat/Undertow. AJP is a highly trusted protocol and should never be exposed to untrusted clients. It is insecure (clear text transmission) and assumes that your network is safe. The preventive measures should be taken by using the configuration that will not allow AJP to be exposed.

In order of preference, one of the following mitigations should be applied:

  • ...
  • Protect the AJP connection with a secret, as well as carefully reviewing network binding and firewall configuration to ensure incoming connections are only allowed from trusted hosts.
  • ...

下面是安全配置的样子:

@Configuration
public class TomcatConfig {


  @Bean
  public TomcatServletWebServerFactory servletContainer() {
      TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
      Connector ajpConnector = new Connector("org.apache.coyote.ajp.AjpNioProtocol");
      AjpNioProtocol protocol= (AjpNioProtocol)ajpConnector.getProtocolHandler();
      protocol.setSecret("myapjsecret");
      ajpConnector.setPort(9090);
      ajpConnector.setSecure(true);
      tomcat.addAdditionalTomcatConnectors(ajpConnector);
      return tomcat;
  }
}

旧文件 conf/server.xml

<Connector protocol="AJP/1.3" address="::1" port="8089" redirectPort="8443">

新建,文件conf/server.xml

<Connector protocol="AJP/1.3" address="::1" port="8089" redirectPort="8443" secretRequired="false">

应该是:

redirectPort="8443" />

secretRequired="false" />