Reputation: 2525
I'm trying to use AJP protocol to communicate with the app created using Spring Boot 2.2.6 with embedded Tomcat and containerised using this official guide. My server uses Apache Server to proxy all requests to different apps and containerised Spring boot app is one of them. Communication works just fine when using http - AJP communication doesn't work though. Moreover, it works just fine when I didn't containerised the app and just launch it using java
command-line tool.
I'm using AJPing script to check AJP access.
And here is AJP connector configuration:
@Configuration
public class TomcatConfiguration implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>
{
@Value( "${tomcat.ajp.secret}" )
String ajpSecret;
@Override
public void customize( TomcatServletWebServerFactory factory )
{
factory.addAdditionalTomcatConnectors( ajpConnector() );
}
private Connector ajpConnector()
{
Connector connector = new Connector( "AJP/1.3" );
AjpNioProtocol protocol = (AjpNioProtocol) connector.getProtocolHandler();
protocol.setSecret( ajpSecret );
connector.setPort( 8009 );
connector.setSecure( true );
return connector;
}
}
Upvotes: 1
Views: 3604
Reputation: 11
Maybe
https://tomcat.apache.org/tomcat-9.0-doc/config/ajp.html
address
For servers with more than one IP address, this attribute specifies which address will be used for listening on the specified port. By default, the connector will listen on the loopback address. Unless the JVM is configured otherwise using system properties, the Java based connectors (NIO, NIO2) will listen on both IPv4 and IPv6 addresses when configured with either 0.0.0.0 or ::. The APR/native connector will only listen on IPv4 addresses if configured with 0.0.0.0 and will listen on IPv6 addresses (and optionally IPv4 addresses depending on the setting of ipv6v6only) if configured with ::.
Upvotes: 1
Reputation: 2525
So I investigated this issue by checking what ports are used in container:
docker ps
docker exec -it ${docker-id-from-previous-command} netstat -lntup
and here is a result I got:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.11:8009 0.0.0.0:* LISTEN 1/java
tcp 0 0 127.0.0.11:37327 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1/java
udp 0 0 127.0.0.11:55038 0.0.0.0:*
So I could see that port 8009 used by AJP was there, but bind-address was different than the one used by port 8080. So setting up port address to "0.0.0.0" resolved my problem, but I can't say I fully understand it - here is the configuration with a fix:
@Configuration
public class TomcatConfiguration implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>
{
@Value( "${tomcat.ajp.secret}" )
String ajpSecret;
@Override
public void customize( TomcatServletWebServerFactory factory )
{
factory.addAdditionalTomcatConnectors( ajpConnector() );
}
private Connector ajpConnector()
{
Connector connector = new Connector( "AJP/1.3" );
AjpNioProtocol protocol = (AjpNioProtocol) connector.getProtocolHandler();
protocol.setSecret( ajpSecret );
connector.setPort( 8009 );
connector.setSecure( true );
try
{
protocol.setAddress( InetAddress.getByName( "0.0.0.0" ) );
}
catch( UnknownHostException e )
{
e.printStackTrace();
}
return connector;
}
}
Upvotes: 4