Apache non riesce a connettersi al nuovo Tomcat 9 ajp
Il mio apache2 non può più connettersi (tramite ajp) al tomcat incorporato del mio avvio di primavera dopo aver aggiornato la versione di avvio di primavera da 2.1.4 a 2.3.2.
Mostra il seguente errore:
[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/
Ho il mio ambiente di sviluppo impostato in questo modo:
un'app Angular (node server in esecuzione su 4200)
un backend di avvio a molla (connettore ajp impostato su Tomcat sulla porta 8500)
un server apache2 frontale (su un contenitore docker) impostato per reindirizzare le richieste a entrambe le app:
<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"
e accedo alla mia app Web tramite un nome di dominio sul mio /etc/hosts : myapp.develop
questa è la configurazione del mio Tomcat di avvio primaverile
Connector connector = new Connector("AJP/1.3");
connector.setScheme("http");
connector.setPort(8500);
connector.setSecure(false);
connector.setAllowTrace(false);
((AbstractAjpProtocol) connector.getProtocolHandler()).setSecretRequired(false);
nell'app.properties :
tomcat.ajp.port=8500
tomcat.ajp.remoteauthentication=false
tomcat.ajp.enabled=true
e questo è il log di 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]
Dubito che questo cambiamento:
- A partire dalla versione 8.5.51, l'indirizzo di ascolto predefinito del connettore AJP è stato modificato nell'indirizzo di loopback anziché in tutti gli indirizzi.
è ciò che mi causa questo problema ma non so come risolverlo.
Risposte
Ho riscontrato un problema simile durante l'aggiornamento della versione Tomcat. L'aggiunta delle proprietà menzionate di seguito al connettore ajp ha aiutato il mio caso.
connector.setProperty("address","0.0.0.0");
connector.setProperty("allowedRequestAttributesPattern",".*");
((AbstractAjpProtocol)connector.getProtocolHandler()).setSecretRequired(false);
Spiegazione dettagliata:
Al tuo dubbio:
A partire dalla versione 8.5.51, l'indirizzo di ascolto predefinito del connettore AJP è stato modificato nell'indirizzo di loopback anziché in tutti gli indirizzi.
Prima di questo aggiornamento, il connettore Tomcat AJP era disposto ad accettare richieste da qualsiasi indirizzo IP e quindi non era necessario specificare in modo esplicito la proprietà "indirizzo". Ma dopo questo aggiornamento, il comportamento predefinito è che il connettore AJP è disposto ad accettare le richieste fatte solo come localhost (loopback). Utilizzare la proprietà "indirizzo" elencata di seguito per espandere l'intervallo di ascolto non solo all'indirizzo di loopback
connector.setProperty("address","0.0.0.0"); // OR connector.setProperty("address","::");
Utilizzare la proprietà sottostante per abilitare tutti i tipi di attributi della richiesta (a meno che non si disponga delle informazioni di intestazione, in tal caso abilitare quelle specifiche). Le richieste con attributi di richiesta non riconosciuti verranno rifiutate con una risposta 403:
connector.setProperty("allowedRequestAttributesPattern",".*");
Utilizzare la proprietà "secretRequired" per definire se è necessario scambiare un segreto con il server HTTP in modo da consentire le richieste tramite ajp. In caso affermativo, imposta anche la proprietà "secret". Altrimenti le richieste falliranno con 403.
((AbstractAjpProtocol)connector.getProtocolHandler()).setSecretRequired(false);
Riferimento: riferimento alla configurazione di Apache Tomcat 8
L'uso del protocollo AJP richiede ulteriori considerazioni sulla sicurezza perché consente una maggiore manipolazione diretta delle strutture di dati interne di Tomcat rispetto ai connettori HTTP. Particolare attenzione dovrebbe essere prestata ai valori utilizzati per gli attributi address , secret , secretRequired e enabledRequestAttributesPattern .
Non ho mai visto un connettore impostato in un codice come questo, è stato piuttosto dichiarato in server.xml
Tuttavia, il tuo codice è
Connector connector = new Connector("AJP/1.3");
connector.setScheme("http");
connector.setPort(8500);
connector.setSecure(false);
connector.setAllowTrace(false);
((AbstractAjpProtocol) connector.getProtocolHandler()).setSecretRequired(false);
e in seguito dichiari di essere a conoscenza di questo cambiamento radicale
A partire dalla versione 8.5.51, l'indirizzo di ascolto predefinito del connettore AJP è stato modificato nell'indirizzo di loopback anziché in tutti gli indirizzi.
Combinando entrambi: non hai mai impostato l'indirizzo di ascolto nel tuo codice, quindi potresti utilizzare l'impostazione predefinita. E poiché stai tentando di inoltrare a un indirizzo non di loopback, non ci sarebbe modo di raggiungere il server in questo modo.
Un editor anonimo di questa risposta ha suggerito connector.setAttribute("address", "0.0.0.0");
, ma personalmente, preferirei mantenerlo in server.xml: i connettori in genere non sono configurati e modificati in fase di esecuzione e avere i tuoi amministratori che modificano un file di testo è molto più conveniente di giorno in giorno -day-operazioni.