如何使用GCP负载平衡器将HTTP重定向到HTTPS

时间:2018-12-06 09:25:30

标签: linux apache google-cloud-platform load-balancing

我要在GCP中设置2个节点(Apache httpd),域为lblb.tonegroup.net的负载均衡器。

当前我的负载均衡器工作正常,流量正在2个节点之间切换,但是如何配置将http://lblb.tonegroup.net重定向到https://lblb.tonegroup.net

是否可以在负载均衡器级别配置它,或者我需要在apache级别配置它?我已安装Google托管SSL证书供参考。

6 个答案:

答案 0 :(得分:5)

现在,通过负载平衡器的流量管理,可以将从http重定向到https

下面是如何在其文档中进行设置的示例: https://cloud.google.com/load-balancing/docs/https/setting-up-traffic-management#console

基本上,您将创建每个“转发规则”中的两个,即targetproxy和urlmap。

2个URLMaps

  • 在第一个URL映射中,您只需设置重定向。下面是定义重定向规则,无需在此处定义后端服务
    • httpsRedirect: true
    • redirectResponseCode: FOUND
  • 在第二张地图中,您将不得不在其中定义后端服务

2条转发规则

  • 第一个转发规则是服务http请求,因此基本上是端口80
  • 第二条转发规则是处理http请求,因此端口443

2个目标代理

  • 第一个目标代理是targetHttpProxy,它将第一个转发规则转发到该地址并映射到第一个URLMap
  • 第二个目标代理是targetHttpsProxy,第二条转发规则将转发到该地址并映射到第二个URLMap

================================================ ========================

下面是一个 Cloud Deployment Manager 示例,其中托管证书和存储桶为后端

storagebuckets-template.jinja

resources:
- name: {{ properties["bucketExample"] }}
  type: storage.v1.bucket
  properties:
    storageClass: REGIONAL
    location: asia-east2
    cors:
    - origin: ["*"]
      method: [GET]
      responseHeader: [Content-Type]
      maxAgeSeconds: 3600
    defaultObjectAcl:
    - bucket: {{ properties["bucketExample"] }}
      entity: allUsers
      role: READER
    website:
     mainPageSuffix: index.html

backendbuckets-template.jinja

resources:
- name: {{ properties["bucketExample"] }}-backend
  type: compute.beta.backendBucket
  properties:
    bucketName: $(ref.{{ properties["bucketExample"] }}.name)
    enableCdn: true

ipaddresses-template.jinja

resources:
- name: lb-ipaddress
  type: compute.v1.globalAddress

sslcertificates-template.jinja

resources:
- name: example
  type: compute.v1.sslCertificate
  properties:
    type: MANAGED
    managed:
      domains:
      - example1.com
      - example2.com
      - example3.com

loadbalancer-template.jinja

resources:
- name: centralized-lb-http
  type: compute.v1.urlMap
  properties:
    defaultUrlRedirect:
      httpsRedirect: true
      redirectResponseCode: FOUND
- name: centralized-lb-https
  type: compute.v1.urlMap
  properties:
    defaultService: {{ properties["bucketExample"] }}
    pathMatchers:
    - name: example
      defaultService: {{ properties["bucketExample"] }}
      pathRules:
      - service: {{ properties["bucketExample"] }}
        paths:
        - /*
    hostRules:
    - hosts:
      - example1.com
      pathMatcher: example
    - hosts:
      - example2.com
      pathMatcher: example
    - hosts:
      - example3.com
      pathMatcher: example

httpproxies-template.jinja

resources:
- name: lb-http-proxy
  type: compute.v1.targetHttpProxy
  properties:
    urlMap: $(ref.centralized-lb-http.selfLink)
- name: lb-https-proxy
  type: compute.v1.targetHttpsProxy
  properties:
    urlMap: $(ref.centralized-lb-https.selfLink)
    sslCertificates: [$(ref.example.selfLink)]
- name: lb-http-forwardingrule
  type: compute.v1.globalForwardingRule
  properties:
    target: $(ref.lb-http-proxy.selfLink)
    IPAddress: $(ref.lb-ipaddress.address)
    IPProtocol: TCP
    portRange: 80-80
- name: lb-https-forwardingrule
  type: compute.v1.globalForwardingRule
  properties:
    target: $(ref.lb-https-proxy.selfLink)
    IPAddress: $(ref.lb-ipaddress.address)
    IPProtocol: TCP
    portRange: 443-443

templates-bundle.yaml

 imports:
 - path: backendbuckets-template.jinja
 - path: httpproxies-template.jinja
 - path: ipaddresses-template.jinja
 - path: loadbalancer-template.jinja
 - path: storagebuckets-template.jinja
 - path: sslcertificates-template.jinja

resources:
 - name: storagebuckets
   type: storagebuckets-template.jinja
   properties:
     bucketExample: example-sb
 - name: backendbuckets
   type: backendbuckets-template.jinja
   properties:
     bucketExample: example-sb
 - name: loadbalancer
   type: loadbalancer-template.jinja
   properties:
     bucketExample: $(ref.example-sb-backend.selfLink)
 - name: ipaddresses
   type: ipaddresses-template.jinja
 - name: httpproxies
   type: httpproxies-template.jinja
 - name: sslcertificates
   type: sslcertificates-template.jinja

$ gcloud deployment-manager deployments create infrastructure --config=templates-bundle.yaml > output 命令输出

 NAME                                   TYPE                             STATE      ERRORS  INTENT
 centralized-lb-http                    compute.v1.urlMap                COMPLETED  []
 centralized-lb-https                   compute.v1.urlMap                COMPLETED  []
 example                                compute.v1.sslCertificate        COMPLETED  []
 example-sb                             storage.v1.bucket                COMPLETED  []
 example-sb-backend                     compute.beta.backendBucket       COMPLETED  []
 lb-http-forwardingrule                 compute.v1.globalForwardingRule  COMPLETED  []
 lb-http-proxy                          compute.v1.targetHttpProxy       COMPLETED  []
 lb-https-forwardingrule                compute.v1.globalForwardingRule  COMPLETED  []
 lb-https-proxy                         compute.v1.targetHttpsProxy      COMPLETED  []
 lb-ipaddress                           compute.v1.globalAddress         COMPLETED  []

答案 1 :(得分:1)

不可能直接在GCP负载均衡器上执行此操作。

一种可能性是对您的后端服务进行重定向。 GCP加载程序平衡器在请求标头中添加x-forwarded-proto属性,该属性等于http或https。您可以基于此属性添加条件以进行重定向。

答案 2 :(得分:0)

我相信Alexandre提供的先前答案是正确的;当前,使用HTTP(S)负载平衡器时,不可能将所有HTTP流量重定向到HTTPS。我发现已经为此功能提交了功能请求;您可以使用此link进行访问并添加评论。

您还提到您正在使用Google托管的SSL证书,但我发现的唯一解决方法是在服务器级别重定向它。在这种情况下,您将必须使用self-managed SSL certificate.

要将HTTP URL重定向到HTTPS,请在Apache服务器中执行以下操作:

<VirtualHost *:80>
    ServerName www.example.com
    Redirect "/" "https://www.example.com/"
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.com
    # ... SSL configuration goes here
</VirtualHost>

您将必须配置Apache服务器配置文件。有关更多详细信息,请参见apache.org documentation on Simple Redirection

答案 3 :(得分:0)

也许为时已晚,但是我遇到了同样的问题,下面是我的解决方案:

  1. 在GCP负载均衡器(HTTP和HTTPS)上配置两个前端。
  2. 设置端口80(http协议)以与后端服务和最终VM进行通信。
  3. 在后端服务上,添加Google变量:{tls_version}作为X-SSL-Protocol的自定义标头。
  4. 在最终服务器上,根据X-SSL-Protocol值执行重定向:
  5. 如果为空(没有https),请重定向(301),否则什么也不做。

您可以在Web服务器上或从中间负载平衡器VM实例检查标头值。我的HAProxy案例:

frontend fe_http
        bind *:80
        mode http
        #check if value is empty
        acl is_http res.hdr(X-SSL-Protocol) -m len 0
        #perform redirection only if no value found in custom header
        redirect scheme https code 301 if is_http
        #when redirect is performed, subsequent instructions are not reached
        default_backend bk_http1

答案 4 :(得分:0)

如果您使用Terraform(强烈建议用于GCP配置),这是一个示例配置。这段代码创建了两个IP地址(v4和v6),您也可以在https转发规则中使用它们。

// HTTP -> HTTPS redirector
resource "google_compute_url_map" "http-to-https" {
  name = "my-http-to-https"

  default_url_redirect {
    https_redirect         = true
    strip_query            = false
    redirect_response_code = "PERMANENT_REDIRECT"
  }
}

resource "google_compute_target_http_proxy" "proxy" {
  name    = "my-http-proxy"
  url_map = google_compute_url_map.http-to-https.self_link
}

resource "google_compute_global_forwarding_rule" "http-v4" {
  name       = "my-fwrule-http-v4"
  target     = google_compute_target_http_proxy.proxy.self_link
  ip_address = google_compute_global_address.IPv4.address
  port_range = "80"
}

resource "google_compute_global_forwarding_rule" "http-v6" {
  name       = "my-fwrule-http-v6"
  target     = google_compute_target_http_proxy.proxy.self_link
  ip_address = google_compute_global_address.IPv6.address
  port_range = "80"
}

resource "google_compute_global_address" "IPv4" {
  name = "my-ip-v4-address"
}

resource "google_compute_global_address" "IPv6" {
  name       = "my-ip-v6-address"
  ip_version = "IPV6"
}

答案 5 :(得分:0)

概括地说,要将 HTTP 流量重定向到 HTTPS,您必须执行以下操作:

  1. 创建 HTTPS LB1(此处称为 web-map-https)。
  2. 使用 LB1 中使用的相同 IP 地址和 URL 映射中配置的重定向创建 HTTP LB2(无后端)(此处称为 web-map-http)。

请检查: https://cloud.google.com/load-balancing/docs/https/setting-up-http-https-redirect