My apache2 can no longer connect (by ajp) to my Spring boot’s embedded tomcat after upgrading Spring boot’s version from 2.1.4 to 2.3.2.
It shows the following error :
[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/
I have my dev environment set up this way :
-
an Angular app (node server running on 4200)
-
a spring boot backend (ajp connector set up on tomcat on port 8500)
-
a frontal apache2 server (on a docker container) set up to redirect requests to both apps :
<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"
and I access my web app by a domain name on my /etc/hosts : myapp.develop
this is my spring boot tomcat’s configuration
Connector connector = new Connector("AJP/1.3");
connector.setScheme("http");
connector.setPort(8500);
connector.setSecure(false);
connector.setAllowTrace(false);
((AbstractAjpProtocol) connector.getProtocolHandler()).setSecretRequired(false);
in the app.properties :
tomcat.ajp.port=8500
tomcat.ajp.remoteauthentication=false
tomcat.ajp.enabled=true
and this is tomcat logs :
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]
I’m doubting that this change :
- In 8.5.51 onwards, the default listen address of the AJP Connector was changed to the loopback address rather than all addresses.
is what causing me this problem but I don’t know how to solve it.
2
Answers
I’ve never seen a connector being set up in code like this, it’s rather been declared in server.xml
However, your code is
and later on you state that you know about this breaking change
Combining both: You never set the listening address in your code – so you might be using the default. And as you’re trying to forward to a non-loopback address, there’d be no way to reach the server this way.
An anonymous editor of this answer suggested
connector.setAttribute("address", "0.0.0.0");
, but personally, I’d prefer to keep it in server.xml: Connectors typically aren’t configured and changed at runtime, and having your administrators editing a textfile is so much more convenient in day-to-day-operations.I faced a similar issue upon upgrading the tomcat version. Adding below mentioned properties to the ajp connector helped my case.
Detailed Explanation:
To your doubt:
Prior to this update, the tomcat AJP connector was willing to accept requests from any IP address, and so it wasn’t required to explicitly specify "address" property. But after this update, default behavior is that the AJP connector is willing to accept requests only made as localhost (loopback). Use below listed "address" property to expand the listening range to not only the loopback address
Use below property to enable all types of request attributes (unless you have the header info, in that case enable the specific ones). Requests with unrecognized request attributes will be rejected with a 403 response:
Use "secretRequired" property to define if a secret is required to be exchanged with the HTTP server so as to allow requests via ajp. If yes, then set the "secret" property as well. Otherwise the requests will fail with 403.
Reference: Apache Tomcat 8 Configuration Reference