組み込みTomcatを使用するSpringBootアプリを使用してApacheWebサーバーを構成しようとしています。 Spring Bootの前は、次のようなajp.confファイルを作成していました。
<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>
そして、次のようにhttpd.confファイルに含めます
Include /opt/lampp/Apache2/conf/ajp.conf
また、Tomcatのserver.xmlファイルでは、ポート8009をリッスンするように構成していました。
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" connectionTimeout="5000"
この設定は機能します。しかし、今Spring Bootを使用して、組み込みTomcatで同様のことを達成しようとしています。 Spring Boot Documentation をここで読み、application.ymlファイルに次のプロパティを追加しました。
server:
port: 8080
Tomcat:
remote_ip_header: x-forwarded-for
protocol_header: x-forwarded-proto
私のajp.confファイルは次のようになります。
<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>
SpringBootのTomcat構成クラスを次のように使用しています
@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;
}
Apacheエラーログに次のように表示されます。
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) (*)
ここで何が起こっているのかわからない。私はオンラインでたくさん検索しましたが、SpringBootアプリでApacheの背後にあるTomcatを提供する方法に関する適切なドキュメントを見つけることができませんでした。最終的には、複数のTomcatインスタンスも負荷分散したいと思います。
上記のコメントから推測:
@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;
}
}
同様の問題がありましたが、HTTPプロキシに問題がありました。 Spring Boot 1.3をデバッグした後、次の解決策を見つけました。 AJPプロキシについても同様である必要があります。
1。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。これらのヘッダーを使用するようにSpringBootアプリに指示する必要があります。したがって、application.properties(またはSpring Bootsがプロパティを理解するその他の場所)に次の行を配置します。
server.use-forward-headers=true
これら2つのことを正しく行うと、アプリケーションが送信するすべてのリダイレクトはnotに移動します http://127.0.0.1:8080/ [パス] ただし自動的に https://www.myapp.com/ [path]
更新1。このトピックに関するドキュメントは ここ です。少なくともプロパティを知っておくためにそれを読む必要がありますserver.Tomcat.internal-proxies
これは信頼できるプロキシサーバーのIPアドレスの範囲を定義します。
構成可能なthroughtプロパティまたは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
...