Tomcat derrière Apache en utilisant ajp pour L'application de démarrage à ressort
J'ai essayé de configurer le serveur web Apache avec une application de démarrage qui utilise Tomcat intégré. Avant la botte de printemps, j'avais l'habitude de créer un ajp.fichier conf comme:
<VirtualHost *:80>
ServerName localhost
<Proxy *>
AddDefaultCharset Off
Order deny,allow
Allow from all
</Proxy>
ProxyPass /app ajp://localhost:8009/app
ProxyPassReverse /app ajp://localhost:8009/app
</VirtualHost>
et inclure dans le httpd.fichier conf
Include /opt/lampp/apache2/conf/ajp.conf
et dans le serveur du Tomcat.fichier xml, Je l'ai utilisé pour le configurer pour écouter le port 8009
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" connectionTimeout="5000"
Cette configuration fonctionne. Mais maintenant, avec Spring Boot, j'essaie de réaliser quelque chose de similaire avec un tomcat intégré. J'ai lu Documentation De La Botte De Printemps ici et ajouté les possédants sur ma demande.fichier yml:
server:
port: 8080
tomcat:
remote_ip_header: x-forwarded-for
protocol_header: x-forwarded-proto
mon ajp.fichier conf ressemble à ceci:
<VirtualHost *:80>
ServerName localhost
<Proxy *>
AddDefaultCharset Off
Order deny,allow
Allow from all
</Proxy>
ProxyPass /app ajp://localhost:8009/
ProxyPassReverse /app ajp://localhost:8009/
</VirtualHost>
j'ai la classe de configuration
@Configuration
public class TomcatConfiguration {
private final Logger log = LoggerFactory.getLogger(TomcatConfiguration.class);
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
tomcat.addAdditionalTomcatConnectors(createConnector());
tomcat.addContextValves(createRemoteIpValves());
return tomcat;
}
private RemoteIpValve createRemoteIpValves(){
RemoteIpValve remoteIpValve = new RemoteIpValve();
remoteIpValve.setRemoteIpHeader("x-forwarded-for");
remoteIpValve.setProtocolHeader("x-forwarded-protocol");
return remoteIpValve;
}
private Connector createConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
connector.setScheme("ajp");
connector.setProtocol("AJP/1.3");
connector.setRedirectPort(8443);
//connector.setSecure(true);
connector.setPort(8009);
return connector;
}
sur mes journaux d'erreurs apache je vois:
AH01080: ajp_msg_check_header() got bad signature 4854
[proxy_ajp:error] [pid 24073] AH01031: ajp_ilink_receive() received bad header
[proxy_ajp:error] ajp_read_header: ajp_ilink_receive failed
[proxy_ajp:error] (120007)APR does not understand this error code: [client xx.xx.xx.xx:60916] AH00878: read response failed from (null) (*)
Pas sûr de ce qui se passe ici. J'ai cherché beaucoup en ligne, mais je n'ai pas pu trouver une bonne documentation sur la façon de servir tomcat derrière apache avec des applications de démarrage de printemps. Finalement, j'aimerais charger plusieurs instances tomcat.
3 réponses
déduit des commentaires ci-dessus:
@Configuration
public class TomcatAjpConfig {
@Bean
@SuppressWarnings("static-method")
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
tomcat.addAdditionalTomcatConnectors(createConnector());
tomcat.addContextValves(createRemoteIpValves());
return tomcat;
}
private static RemoteIpValve createRemoteIpValves() {
RemoteIpValve remoteIpValve = new RemoteIpValve();
remoteIpValve.setRemoteIpHeader("x-forwarded-for");
remoteIpValve.setProtocolHeader("x-forwarded-proto");
return remoteIpValve;
}
private static Connector createConnector() {
Connector connector = new Connector("AJP/1.3");
connector.setPort(8009);
return connector;
}
}
avait un problème similaire mais avec le Proxy HTTP. Après un peu de débogage de la botte de printemps 1.3 j'ai trouvé la solution suivante. Il devrait en être de même pour le mandataire de L'AJP.
1. vous devez configurer les en-têtes sur votre proxy Apache:
<VirtualHost *:443>
ServerName www.myapp.org
ProxyPass / http://127.0.0.1:8080/
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443
ProxyPreserveHost On
... (SSL directives omitted for readability)
</VirtualHost>
2. vous devez dire à votre application de démarrage à ressort d'utiliser ces en-têtes. Donc, mettez la ligne suivante dans votre demande.Propriétés (ou tout autre endroit où les bottes à ressort comprennent les propriétés):
server.use-forward-headers=true
si vous faites ces deux choses correctement, chaque redirection envoyée par votre application sera http://127.0.0.1:8080/[chemin] mais https://www.myapp.com/[chemin]
mise à jour 1. La documentation sur ce sujet est ici. Vous devriez le lire au moins être conscient de la propriété server.tomcat.internal-proxies
qui définit la plage d'adresses IP pour les serveurs proxy qui on peut faire confiance.
Configurable à travers des propriétés ou un fichier yml.
@Configuration
@ConfigurationProperties(prefix = "tomcat")
public class TomcatConfiguration {
private int ajpPort = 8009;
private boolean ajpAllowTrace = false;
private boolean ajpSecure = false;
private String ajpScheme = "http";
private boolean ajpEnabled;
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
if (isAjpEnabled()) {
Connector ajpConnector = new Connector("AJP/1.3");
ajpConnector.setProtocol("AJP/1.3");
ajpConnector.setPort(getAjpPort());
ajpConnector.setSecure(isAjpSecure());
ajpConnector.setAllowTrace(isAjpAllowTrace());
ajpConnector.setScheme(getAjpScheme());
tomcat.addAdditionalTomcatConnectors(ajpConnector);
}
return tomcat;
}
// ... Get/Set
}
application.yml
tomcat:
ajpEnabled: true
ajpPort: 9009
...