【问题标题】:reverse proxy setup using subdirs using haproxy使用 haproxy 使用子目录的反向代理设置
【发布时间】:2018-03-08 14:48:45
【问题描述】:

我无法使用在 ubuntu 16 上运行的 haproxy 1.6.3 来设置反向代理。 这是我想要实现的目标:

  • 在我的主机上,我有一个在 https://bar.com 下运行的带有 apache 的 web 应用程序,它使用 mod_rewrite 进行路由
  • 各种内部服务器(机器 1..n)通过 vpn 链接到主机,都只在 vpn 适配器的端口 8081 上公开一个支持 websocket 的 http 接口
  • 我希望内部机器可以通过主机的子目录访问,例如。对于机器 1,我想通过 https://bar.com/machine1 访问其网页 - 内部流量为 http,从主机到访问者的流量由主机的 ssl 证书保护
  • 与 /machine1 不匹配的所有其他流量不应受到影响,应像以前一样由主机 apache 提供服务
  • 机器 1..n 的转发 Web 界面上的路径不是问题,因为它们能够通过以下配置中的标头指令(Orig-Path 和 X-Script-Path)动态修改其路径李>
  • 主机上的 apache2 被配置为仅使用 Listen 127.0.0.1 侦听 localhost,并且到主站点的所有流量都由 haproxy 通过默认后端处理

以下是相关配置:

  • 主站点的apache.htaccess(不包括相关子目录)

    # Exclude machine1 subdirectory from rewrite
    RewriteRule ^(machine1)($|/) - [L]
    RewriteCond %{REQUEST_URI} !^/index\.php
    RewriteCond %{SCRIPT_FILENAME} !-f
    RewriteCond %{SCRIPT_FILENAME} !-d
    RewriteRule .* index.php [L]
    
  • 代理设置

    frontend http-in
        bind <external-ip>:80
        mode tcp
        option tcplog
        acl machine1 path_beg /machine1
        use_backend machine1-backend if machine1
        default_backend default-backend-http
    
    frontend https-in
        bind <external-ip>:80
        mode tcp
        option tcplog
        default_backend default-backend-https
    
    backend machine1-backend
        reqrep ^([^\ :]*)\ /machine1/(.*)  \1\ /\2
        http-request set-header Orig-Path /machine1/
        http-request set-header X-Script-Path /machine1/
        http-request set-header Host bar.com
        option http-server-close  
        server m1 10.0.0.4:8081
    
    backend default-backend-https
        server main 127.0.0.1:443
        mode tcp
    
    backend default-backend-http
        server main 127.0.0.1
        mode tcp
    

我目前遇到的问题/疑问:

  • 访问未加密的变体 (http://bar.com/machine1)有时 服务于 machine1 的正确页面,但大多数时候,我从主机 apache 得到 404 - 我认为这可能可以通过选项 http-server-close 解决,但不是 - 有人可以指出我在这里缺少什么吗?我在极少数有效响应的情况下验证了路径已使用 /machine1 正确扩展 - 例如用于 css 的 /machine1/css/main.css 包括 - 但即使在从 machine1 成功初始拉取之后 - 所有后续对脚本、图像和 css 的提取都会再次返回 404

  • 我无法弄清楚如何正确设置 ssl 以使用 haproxy 处理 https->http 流量转换的 /machine1 请求,因此 ssl 部分目前不包括路由 - 如何我是否需要扩展配置以使其适用于https://bar.com/machine1? (假设 bar.com 的有效证书存在于 /etc/keys/web.pem 下)

额外问题:

  • 是否有机会使此配置动态化?例如从数据库中提取相关信息(服务器 ip,子目录名称)/在此处使用某种逻辑,因为机器 1...n 链接将在运行时更改(新机器连接,其他机器断开连接,可能的机器数量为很大)
  • 是否有在使用 /machine1 之前验证用户的选项?主 Web 应用程序进行用户管理,所以我最好在允许访问 /machine1 之前检查用户是否经过身份验证 - 可以这样做吗?

【问题讨论】:

    标签: config reverse-proxy haproxy


    【解决方案1】:

    在这里回答我自己的问题: 经过一番研究,问题是这个用例的配置中的错误模式tcp,通过将前后端模式切换到http很容易解决。 来自docs

    • mode tcp:

    在这种模式下,HAProxy 不会解密流量。它只是打开一个 客户端和服务器之间的 TCP 隧道并让它们在一起 协商和处理 TLS 流量。

    使用此模式时,HAProxy 不会评估数据包中的 HTTP 标头。在这种情况下,显然没有选项来区分 http 特定标头(如 uri)上的后端,这就是初始配置不起作用的原因。

    • mode http:

    在这种模式下,HAProxy 在客户端解密流量并 在服务器端重新加密。它可以访问的内容 请求和响应并执行高级处理 交通。

    在这种情况下,所有 http 标头字段都可供 haproxy 用于后端选择。

    这当然对 ssl 有影响 - 此设置有多种变体,我选择使用 SSL/TLS 卸载并让 HAProxy 解密客户端的流量并清楚地连接到内部服务器。

    这使得运行 haproxy 的机器成为 sslendpoint,并且需要在此处设置 ssl 证书而不是在网络服务器上。此外,通过这种设置,运行 webapp 的网络服务器可以完全隔离,仅在内部为 haproxy 机器提供页面。这也回答了问题 2。

    最后,关于奖金问题:

    • 我已经通过 shell 脚本实现“动态”配置,当新机器连接到数据库中的信息时,这些脚本会即时修改 haproxy 配置,从而通过service haproxy reload (ubuntu) 实现更改 - 这似乎效果很好。
    • 对于用户身份验证,我设置了后端计算机现在查询主 Web 应用程序以获取授权,如果授权被拒绝,则重定向到主 Web 应用程序。为了验证,使用了一个 cookie(或没有它)。我目前正在测试此设置,但现在看来可以使用。

    最后,我得到的(工作)配置(请注意,我也在 haproxy 上添加了 http 到 https 重定向):

    frontend http-in
        bind <external-ip>:80
        bind <external-ip>:443 ssl crt /path/to/cert/cert.pem
        acl machine1 path_beg /machine1
        reqadd X-Forwarded-Proto:\ https
        mode http
        option httplog
        use_backend machine1-backend if machine1
        default_backend default-backend
    
    backend default-backend
        redirect scheme https if !{ ssl_fc }
        server main 127.0.0.1:80
        mode http
    
    backend machine1-backend
        http-request set-header Orig-Path /machine1/
        http-request set-header X-Script-Path /machine1/
        http-request set-header Host bar.com
        reqirep ^([^\ :]*)\ /machine1/(.*)  \1\ /\2
        server m1 10.0.0.4:8081
    

    【讨论】:

      猜你喜欢
      • 2021-06-30
      • 2018-09-01
      • 2020-01-02
      • 2016-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多