HAProxy将HTTP重定向到HTTPS(SSL)

102
我正在使用HAProxy进行负载均衡,仅想支持https访问我的站点。因此,我希望将所有端口80的请求重定向到端口443。
如何操作?
编辑:我们希望重定向到相同的https URL,保留查询参数。因此,http://foo.com/bar 将 重定向到 https://foo.com/bar
17个回答

151

我发现这是最大的帮助

使用HAProxy 1.5或更高版本,只需在前端配置中添加以下行:

redirect scheme https code 301 if !{ ssl_fc }

22
此外,参考下面User2966600的回答,加上301重定向后,可使用以下代码将特定域名重定向到https:redirect scheme https code 301 if { hdr(Host) -i www.mydomain.com } !{ ssl_fc } - Quentin Skousen
1
那个有效。虽然没有“代码301”就无法工作。感谢更新。 - deej
7
给出的答案等价的语法如下: http-request redirect scheme https code 301 if !{ ssl_fc }ALOHA HAProxy 7.0中的http重定向文档甚至提到“两个指令的语法是相同的,也就是说,重定向现在被视为旧版,配置应该转移到http-request redirect形式”。我推断(不完全确定),这个解释同样适用于新版本的开源版本HAProxy。 - rodolfojcj
1
重要的是要注意,这必须在单独的前端块中完成。许多在线示例代码都在同一块中绑定了两个内容,在双向绑定块中执行重定向将防止haproxy启动。 - Sami Fouad
这个(好的)答案被埋在五个得分为零的答案下面 - 发生了什么事? - UpTheCreek
显示剩余4条评论

69

我没有足够的声望来评论之前的回答,所以我发表了一个新的答案来补充Jay Taylor的答案。基本上他的答案将会重定向,虽然是一个隐性的重定向,意味着它将发出302(临时重定向),但既然问题表明整个网站将作为https提供,则适当的重定向应该是301(永久重定向)。

redirect scheme https code 301 if !{ ssl_fc }

这似乎是一个微小的变化,但它对网站的影响可能是巨大的。通过永久重定向,我们告诉浏览器从一开始就不再寻找http版本(避免未来的重定向),这对于https网站来说是一个节省时间的好方法。它还有助于SEO,但不会分散你链接的权重。


42

重定向所有流量:

如果没有{ ssl_fc },则重定向方案为https

重定向单个URL(在多个前端/后端的情况下)

如果{ hdr(Host) -i www.mydomain.com } !{ ssl_fc },则重定向方案为https


1
谢谢,"仅限于特定主机"的条件正是我在寻找的! - Quentin Skousen
请您展示第二个选项的一个实际例子好吗? - RicHincapie

21

将所有http重定向到https的最佳保证方法是:

frontend http-in
   bind *:80
   mode http
   redirect scheme https code 301

这是使用“301代码”的稍微高级一些的方法,但最好让客户端知道它是永久的。“mode http”部分在默认配置中不是必需的,但也无妨。如果你在默认部分(就像我一样)有mode tcp,那么它是必要的。


你可能想使用 http-request redirect scheme https code 301,因为前缀 http-request 允许使用 log-format 来影响记录日志的方式:https://docs.haproxy.org/2.4/configuration.html#4.2-http-request%20redirect - Mikko Rantalainen

15
根据http://parsnips.net/haproxy-http-to-https-redirect/的说法,将haproxy.cfg配置为包含以下内容应该很容易。
#---------------------------------------------------------------------
# Redirect to secured
#---------------------------------------------------------------------
frontend unsecured *:80
    redirect location https://foo.bar.com

#---------------------------------------------------------------------
# frontend secured
#---------------------------------------------------------------------
frontend  secured *:443
   mode  tcp
   default_backend      app

#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
    mode  tcp
    balance roundrobin
    server  app1 127.0.0.1:5001 check
    server  app2 127.0.0.1:5002 check
    server  app3 127.0.0.1:5003 check
    server  app4 127.0.0.1:5004 check

7
这样会将所有内容重定向到https://foo.bar.com。但理想情况下,我们希望http://foo.bar.com/baz重定向到https://foo.bar.com/baz。我们还需要查询参数。 - Jon Chu
@JonChu提出了一个有效的用例,这只是部分解决方案。 - Jay Taylor
3
尝试使用重定向前缀 https://foo.bar.com 而不是使用重定向位置(redirect location),这应该有助于解决 Jon Chu 提到的使用案例问题。 - xangxiong

12

基于user2966600的解决方案做了轻微的改动...

为了重定向一个单独的URL之外的所有URL(如果有多个前端/后端):

redirect scheme https if !{ hdr(Host) -i www.mydomain.com } !{ ssl_fc }

4
像Jay Taylor所说,HAProxy 1.5-dev有一个名为redirect scheme的配置指令,可以实现你需要的功能。
然而,如果你无法使用1.5版本,并且愿意从源代码编译HAProxy,我将redirect scheme功能移植到了1.4版本中。你可以在这里获取补丁:http://marc.info/?l=haproxy&m=138456233430692&w=2

3

重定向语句已经过时

请使用http-request redirect

acl http      ssl_fc,not
http-request redirect scheme https if http

2
frontend unsecured *:80
    mode http
    redirect location https://foo.bar.com

1
可以这样做 -
  frontend http-in
   bind *:80
   mode http
   redirect scheme https code 301

任何访问http的流量都将重定向到https。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接