Spring Boot with embedded Tomcat behind Apache proxy

前端 未结 7 1363
暖寄归人
暖寄归人 2020-12-08 09:51

We have a Spring Boot (Spring MVC) app with embedded Tomcat on a dedicated appserver behind an Apache SSL proxy.

The SSL port on the proxy server is 4433, forwarding

相关标签:
7条回答
  • 2020-12-08 10:37

    Try setting the Rewrite rule like: https://proxyserver:4433/appname >>forward>> http://appserver:8080/appname

    And then set your application context to "appname" server.context-path=/appname

    So locally you can run by http://appserver:8080/appname and via Reverse Proxy you access via https://proxyserver:4433/appname

    Since I am using JBOSS, changes in standalone.xm of jboss:

    <http-listener name="default" socket-binding="http" redirect-socket="https" proxy-address-forwarding="true" enable-http2="true"/>
    

    Tomcat would have similar config, to inform Tomcat (proxy-address-forwarding="true") to respect the proxy forwarding address.

    0 讨论(0)
  • 2020-12-08 10:39

    There are several properties that you can configure, related to this. application.yaml example:

    server:
      forward-headers-strategy: native
      tomcat:
        use-relative-redirects: true
        protocol-header: x-forwarded-proto
        remote-ip-header: x-forwarded-for
    

    Setting server.forward-headers-strategy: native is the replacement of the deprecated server.use-forward-headers:true

    0 讨论(0)
  • 2020-12-08 10:41

    A typical solution to this problem is to let the proxy handle any required rewrite. For example, in Apache you can use the rewrite_module and/or headers_module to correct headers. As another example, Nginx handles this and other similar cases automatically for you after configuring upstream servers.

    In response to comments:

    What are the remote_ip_header and protocol_header spring boot configuration values?

    Let's forget Spring Boot for a moment. Tomcat, the embedded servlet container, features a valve known as the RemoteIpValve. This valve is a port of the Apache remotip_module. The primary purpose of this valve is to treat the "useragent which initiated the request as the originating useragent" for "the purposes of authorization and logging". In order for this valve to be used it needs to be configured.

    Please find more information about this valve here.

    Spring Boot conveniently supports configuring this valve via application.properties through the server.tomcat.remote_ip_header and server.tomcat.protocol_header properties.

    0 讨论(0)
  • 2020-12-08 10:42

    I had the same problem the other day. After some debugging of Spring Boot 1.3 I found the following solution.

    1. You have to setup the headers on your Apache proxy:

    <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. You have to tell your Spring Boot app to use these headers. So put the following line in your application.properties (or any other place where Spring Boots understands properties):

    server.use-forward-headers=true
    

    If you do these two things correctly, every redirect your application sends will not go to http://127.0.0.1:8080/[path] but automatically to https://www.myapp.com/[path]

    Update 1. The documentation about this topic is here. You should read it at least to be aware of the property server.tomcat.internal-proxies which defines the range of IP-addresses for proxy servers that can be trusted.

    0 讨论(0)
  • 2020-12-08 10:44

    Your proxy looks fine, and so does the backend app, up to a point, but it doesn't seem to be seeing the RemoteIpValve modified request. The default behaviour of the RemoteIpValve includes a pattern match for the proxy IP address (as a security check) and it only modifies requests that it thinks are from a valid proxy. The pattern defaults in Spring Boot to a well-known set of internal IP addresses like 10.*.*.* and 192.168.*.*, so if your proxy isn't on one of those you need to explicitly configure it, e.g.

    server.tomcat.internal-proxies=172\\.17\\.\\d{1,3}\\.\\d{1,3}|127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}
    

    (using properties file format, which means you have to double escape the backslashes).

    You can see the what is happening in the RemoteIpValve if you set

    logging.level.org.apache.catalina.valves.RemoteIpValve=DEBUG
    

    or set a breakpoint in it.

    0 讨论(0)
  • 2020-12-08 10:48

    Have you tried setting

      server.context-path=/appname
    

    In Spring Boot?

    0 讨论(0)
提交回复
热议问题