【问题标题】:Does tomcat know that haproxy is a proxy server?tomcat 知道 haproxy 是代理服务器吗?
【发布时间】:2025-12-25 05:55:14
【问题描述】:

我有几个关于 HAProxy (1.5.2) 和 Tomcat (7.0.54) 的问题。我都是新手。

在 Tomcat 中,我有一个应用程序在登录时 (https://my.tomcat.host:8080/access) 会将用户(通过 303 代码)重定向到另一个网页(http://my.tomcat.host:8080/access/sessionId=1234567)。设置 HAProxy 我将前端引擎 (my-frontend-https) 设置为接收 https 请求并将它们发送到后端 (my-backend-https) - 然后将其作为 http 请求发送到 tomcat 服务器。

这就是 haproxy.cfg(对于 my.haproxy.host)的样子:

frontend my-frontend-https
   bind *:8443 ssl crt /my/certs/server.pem
   mode http
   option httplog
   default_backend my-backend-https

backend my-backend-https
  balance roundrobin
  mode http
  option httplog
  option forwardfor
  server my-tomcat-srv my.tomcat.host:8080 check

在发送以下查询时 (https://my.haproxy.host:8443/access),我发现从 tomcat 返回的 Location 标志的格式为:http: //my.haproxy.host:80/access/sessionId=1234567。查看 tomcat 服务器,我发现我必须在 server.xml 中启用 RemoteIPValve 类并将 httpsServerPort 设置为 8443(作为 protocolHeaderHttpsValue - 虽然它是默认设置,但可能不需要执行此操作)。这似乎可行,我将在后端添加更多服务器。

看起来不错,但我有几个问题:

  1. 我注意到,当前端引擎是 http 而不是 https 时,问题似乎不存在。也就是说,位置字段返回了我期望的样子。对差异有任何想法吗?
  2. 如果没有 server.xml 文件中的设置,tomcat 似乎知道我在 Web 浏览器和 tomcat 之间使用了代理。它怎么知道这个?是否有一个指令被传递给 tomcat,告诉它是代理还是比这更简单。
  3. 如果我想在同一个 haproxy.cfg 文件中指向同一个 tomcat 实例的另一个前端/后端引擎(也就是说,上面是跨多个服务器的负载平衡,包括这个,我想要一个入口点就这一个)可以吗? 即 haproxy 将包含以下几行。 前端我的前端-https1 绑定 *:9443 ssl crt /my/certs/server.pem 模式http 选项 httplog default_backend my-backend-https1

    后端我的后端-https1 平衡循环 模式http 选项 httplog 期权转发 服务器 my-tomcat-srv my.tomcat.host:8080 检查

    位置字段是否会返回为http://my.haproxy.host:8443/access/sessionId=1234567,因为这是在 server.xml 中定义的。谢谢

哈罗德。

【问题讨论】:

    标签: tomcat https proxy haproxy


    【解决方案1】:

    这不是 Tomcat 特有的,但除非 haproxy 告诉它,否则您的 Tomcat 后端不会知道 haproxy 是前端。

    您是否在运行 nginx,这是直接来自我的配置:

    proxy_set_header X-Forwarded-Proto https; # Obviously, differentiate based on whether you're serving an HTTP or HTTPS endpoint.
    proxy_set_header Host $host; # Or hardcode a value.
    proxy_set_header X-Real-IP  $remote_addr; # Alternative to X-Forwarded-For.
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    

    虽然我还没有为 haproxy 这样做,但我将 nginx 放在 haproxy 前面,根据a tutorial ,你会想做这样的事情:

    # defaults section
    option forwardfor
    
    # frontend definition
    frontend www-http
       bind haproxy_www_public_IP:80
       reqadd X-Forwarded-Proto:\ http
       default_backend www-backend
    
    frontend www-https
       bind haproxy_www_public_IP:443 ssl crt /etc/ssl/private/example.com.pem
       reqadd X-Forwarded-Proto:\ https
       default_backend www-backend
    
    # backend definition
    backend www-backend
       redirect scheme https if !{ ssl_fc }
       server www-1 www_1_private_IP:80 check
       server www-2 www_2_private_IP:80 check
    

    这是假设 Tomcat 将引用标准字段 X-Forwarded-ProtoX-Forwarded-For

    【讨论】: