使用自行管理的 SSL 憑證

自行管理的 SSL 憑證是您自行取得、佈建及更新的憑證。您可以使用這項資源,確保用戶端與負載平衡器之間的通訊安全無虞。

自行管理的憑證可以是下列憑證類型的任意組合:

  • 網域驗證 (DV)
  • 機構驗證 (OV)
  • 延伸驗證 (EV)

下列負載平衡器支援自行管理的憑證:

  • 區域認證
    • 區域性外部應用程式負載平衡器
    • 區域性內部應用程式負載平衡器

本頁說明如何取得有效的 Compute Engine 憑證,然後上傳憑證來建立 Cloud de ConfianceSSL 憑證資源。

如要使用 Certificate Manager 建立 Google 代管的憑證,請參閱「部署總覽」。

事前準備

權限

如要執行本指南中的工作,您必須能在專案中建立及修改 SSL 憑證。如要這麼做,必須符合下列任一條件:

  • 您是專案擁有者或編輯者 (roles/ownerroles/editor)。
  • 您在專案中同時具備 Compute 安全管理員角色 (compute.securityAdmin) 和 Compute 網路管理員角色 (compute.networkAdmin)。
  • 您擁有專案的自訂角色,其中包含 compute.sslCertificates.* 權限,以及 compute.targetHttpsProxies.*compute.targetSslProxies.* 其中一項或兩項權限,視您使用的負載平衡器類型而定。

步驟 1:建立私密金鑰和憑證

如果您已有來自憑證授權單位 (CA) 的私密金鑰和憑證,請略過這一節並前往建立 SSL 憑證資源

選取或建立私密金鑰

Cloud de Confiance SSL 憑證包含私密金鑰和憑證本身,兩者皆為 PEM 格式。私密金鑰必須符合下列條件:

  • 必須採用 PEM 格式
  • 無法使用通關密語保護。 Cloud de Confiance 會以自己的加密格式儲存私密金鑰。
  • 加密演算法必須為 RSA 或 ECDSA。如要瞭解可使用的金鑰類型,請參閱「支援的金鑰類型」。

如要建立新的私密金鑰,請使用下列其中一個 OpenSSL 指令。

  • 建立 RSA-2048 私密金鑰:

    openssl genrsa -out PRIVATE_KEY_FILE 2048
    
  • 建立 ECDSA P-256 私密金鑰:

    openssl ecparam -name prime256v1 -genkey -noout -out PRIVATE_KEY_FILE
    

PRIVATE_KEY_FILE 替換為新私密金鑰檔案的路徑和檔案名稱。

建立憑證簽署要求 (CSR)

具備私密金鑰後,您可以使用 OpenSSL,產生採用 PEM 格式的憑證簽署要求 (CSR)。CSR 必須符合下列條件:

  • 必須採用 PEM 格式。
  • 必須具備通用名稱 (CN) 或主體別名 (SAN) 屬性。實際上,即使憑證用於單一網域,也應同時包含 CNSAN 屬性,因為現行 macOS 和 iOS 版本等新型用戶端不會只使用 CN 屬性。

如要建立 CSR,請按照下列步驟操作:

  1. 建立 OpenSSL 設定檔。在以下範例中,主體別名是在 [sans_list] 中定義。

    cat <<'EOF' >CONFIG_FILE
    [req]
    default_bits              = 2048
    req_extensions            = extension_requirements
    distinguished_name        = dn_requirements
    prompt                    = no
    
    [extension_requirements]
    basicConstraints          = CA:FALSE
    keyUsage                  = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName            = @sans_list
    
    [dn_requirements]
    countryName               = Country Name (2 letter code)
    stateOrProvinceName       = State or Province Name (full name)
    localityName              = Locality Name (eg, city)
    0.organizationName        = Organization Name (eg, company)
    organizationalUnitName    = Organizational Unit Name (eg, section)
    commonName                = Common Name (e.g. server FQDN or YOUR name)
    emailAddress              = Email Address
    
    [sans_list]
    DNS.1                     = SUBJECT_ALTERNATIVE_NAME_1
    DNS.2                     = SUBJECT_ALTERNATIVE_NAME_2
    
    EOF
    
  2. 執行下列 OpenSSL 指令,建立憑證簽署要求 (CSR) 檔案。這項指令是互動式指令,系統會提示您輸入屬性,主體別名除外,因為您已在上一個步驟的 CONFIG_FILE 中定義 [sans_list]

    openssl req -new -key PRIVATE_KEY_FILE \
        -out CSR_FILE \
        -config CONFIG_FILE
    

在這兩個步驟中,請替換下列項目:

  • CONFIG_FILE:OpenSSL 設定檔的路徑 (包括檔案名稱)。完成這項程序後,您可以刪除該檔案。
  • SUBJECT_ALTERNATIVE_NAME_1SUBJECT_ALTERNATIVE_NAME_2:憑證的主體替代名稱

    如果憑證只適用於一個主機名稱,您應該只定義一個與通用名稱相符的主體別名。如果需要兩個以上的替代主體名稱,請將這些名稱新增至設定檔,並遞增 DNS 後方的數字 (DNS.3DNS.4 等)。

  • PRIVATE_KEY_FILE:私密金鑰檔案的路徑

  • CSR_FILE:CSR 的路徑,包括檔案名稱

簽署 CSR

憑證授權單位 (CA) 簽署 CSR 時,會使用自己的私密金鑰建立憑證。請使用下列其中一種方法簽署 CSR:

使用公開信任的 CA

如果要求公開信任的 CA 簽署 CSR,則信任該公開 CA 的所有用戶端都會信任產生的憑證。公開 CA 只需要您的 CSR,即可產生已簽署的憑證。

使用自己的內部 CA

您可以使用自行管理的 CA 簽署 CSR。如果用戶端也已設為信任您擁有的 CA,使用該 CA 簽署 CSR 時會建立內部信任的憑證。

使用自行簽署的憑證

如果使用同一個私密金鑰建立及簽署 CSR,就會建立自行簽署的憑證。建議只將自行簽署的憑證用來測試。

Cloud de Confiance 不支援自行簽署伺服器憑證的用戶端驗證。因此,您必須將用戶端設定為略過憑證驗證。舉例來說,您可以建立網路瀏覽器用戶端,顯示訊息詢問您是否要信任自行簽署的憑證。

如果您是自行管理 CA,或想建立自行簽署的憑證以用於測試,可以使用下列 OpenSSL 指令:

openssl x509 -req \
    -signkey PRIVATE_KEY_FILE \
    -in CSR_FILE \
    -out CERTIFICATE_FILE \
    -extfile CONFIG_FILE \
    -extensions extension_requirements \
    -days TERM

更改下列內容:

  • PRIVATE_KEY_FILE:CA 私密金鑰的路徑;如要建立自行簽署的憑證以用於測試,這個私密金鑰與用於建立 CSR 的金鑰相同
  • CSR_FILE:CSR 的路徑
  • CERTIFICATE_FILE:要建立的憑證檔案路徑
  • TERM:從現在起,驗證憑證的用戶端應將憑證視為有效的時間 (以天為單位)

通用名稱中的萬用字元

您自行管理的 SSL 憑證可以在一般名稱中使用萬用字元。舉例來說,一般名稱為 *.example.com. 的憑證符合主機名稱 www.example.comfoo.example.com,但不符合 a.b.example.comexample.com。負載平衡器選取憑證時,一律會為主機名稱優先選取沒有萬用字元的相符憑證,而不是有萬用字元的憑證。

系統不支援含有萬用字元片段的憑證,例如 f*.example.com

步驟 2:建立自行管理的 SSL 憑證資源

您必須先具備私密金鑰和憑證,才能建立 Cloud de Confiance SSL 憑證資源。如果您尚未建立或取得這兩者,請參閱建立私密金鑰和憑證

憑證建立完成後,就無法將範圍從全域變更為區域,反之亦然。

控制台

您無法在 Cloud de Confiance 控制台中建立區域性 SSL 憑證。 請改用 gcloud 或 REST API。

gcloud

如要建立區域 SSL 憑證,請使用 gcloud compute ssl-certificates create 指令搭配 --region 旗標:

gcloud compute ssl-certificates create CERTIFICATE_NAME \
    --certificate=CERTIFICATE_FILE \
    --private-key=PRIVATE_KEY_FILE \
    --region=REGION

更改下列內容:

  • CERTIFICATE_NAME:要建立的憑證資源名稱
  • CERTIFICATE_FILE:PEM 格式憑證檔案的路徑

    您可以選擇將 CA 憑證鏈結納入與憑證相同的檔案中。 Cloud de Confiance 不會為您驗證憑證鏈結,驗證責任由您承擔。

  • PRIVATE_KEY_FILE:PEM 格式私密金鑰的路徑;私密金鑰不得受通關密語保護

  • REGION:如適用,地區 SSL 憑證的區域

    如果這個憑證資源適用於內部應用程式負載平衡器或區域性外部應用程式負載平衡器,則區域必須與負載平衡器的區域相同。

Java

如要使用 API 方法,請先讀取憑證和私密金鑰檔案,然後建立 SSL 憑證。這是因為 API 要求必須包含檔案內容。

以下範例說明如何使用 Java 執行這項操作。

如要使用區域性 SSL 憑證,請使用 regionSslCertificates.insert API 方法:


import com.google.cloud.compute.v1.InsertRegionSslCertificateRequest;
import com.google.cloud.compute.v1.RegionSslCertificatesClient;
import com.google.cloud.compute.v1.SslCertificate;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateRegionalCertificate {
  public static void main(String[] args)
          throws IOException, InterruptedException, ExecutionException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Google Cloud project you want to use.
    String project = "your-project-id";
    // The certificate you want to create in your project.
    String certificate = "your-certificate";
    // The private key you used to sign the certificate with.
    String privateKey = "your-private-key";
    // Name for the certificate once it's created in your project.
    String certificateName = "your-certificate-name";
    // Name of the region you want to use.
    String region = "your-region";

    createRegionCertificate(project, certificate, region, privateKey, certificateName);
  }

  // Create a regional SSL self-signed certificate within your Google Cloud project.
  public static SslCertificate createRegionCertificate(String project, String certificate,
                                                       String region, String privateKey,
                                                       String certificateName)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (RegionSslCertificatesClient client = RegionSslCertificatesClient.create()) {
      SslCertificate certificateResource = SslCertificate.newBuilder()
              .setCertificate(certificate)
              .setPrivateKey(privateKey)
              .setName(certificateName)
              .build();

      InsertRegionSslCertificateRequest request = InsertRegionSslCertificateRequest.newBuilder()
              .setProject(project)
              .setRegion(region)
              .setSslCertificateResource(certificateResource)
              .build();

      client.insertCallable().futureCall(request).get(60, TimeUnit.SECONDS);

      // Wait for server update
      TimeUnit.SECONDS.sleep(1);

      SslCertificate sslCert = client.get(project, region, certificateName);

      System.out.printf("Regional cert '%s' has been created successfully", sslCert.getName());

      return sslCert;
    }
  }
}

如需其他程式碼範例,請參閱 API 參考資料頁面

Python

如要使用 API 方法,請先讀取憑證和私密金鑰檔案,然後建立 SSL 憑證。這是因為 API 要求必須包含檔案內容。

以下範例說明如何使用 Python 執行這項操作。

如要使用區域性 SSL 憑證,請使用 regionSslCertificates.insert API 方法:

from pathlib import Path
from pprint import pprint
from typing import Union

from googleapiclient import discovery


def create_regional_certificate(
    project_id: str,
    region: str,
    certificate_file: Union[str, Path],
    private_key_file: Union[str, Path],
    certificate_name: str,
    description: str = "Certificate created from a code sample.",
) -> dict:
    """
    Create a regional SSL self-signed certificate within your Google Cloud project.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        region: name of the region you want to use.
        certificate_file: path to the file with the certificate you want to create in your project.
        private_key_file: path to the private key you used to sign the certificate with.
        certificate_name: name for the certificate once it's created in your project.
        description: description of the certificate.

        Returns:
        Dictionary with information about the new regional SSL self-signed certificate.
    """
    service = discovery.build("compute", "v1")

    # Read the cert into memory
    with open(certificate_file) as f:
        _temp_cert = f.read()

    # Read the private_key into memory
    with open(private_key_file) as f:
        _temp_key = f.read()

    # Now that the certificate and private key are in memory, you can create the
    # certificate resource
    ssl_certificate_body = {
        "name": certificate_name,
        "description": description,
        "certificate": _temp_cert,
        "privateKey": _temp_key,
    }
    request = service.regionSslCertificates().insert(
        project=project_id, region=region, body=ssl_certificate_body
    )
    response = request.execute()
    pprint(response)

    return response

如需其他程式碼範例,請參閱 API 參考資料頁面

步驟 3:將 SSL 憑證與目標 Proxy 建立關聯

您必須將至少一個 SSL 憑證與每個目標 HTTPS 或 SSL Proxy 建立關聯。您最多可以為目標 Proxy 設定每個目標 HTTPS 或目標 SSL Proxy 的 SSL 憑證數量上限。您可以在同一個目標 Proxy 上參照多個自行管理的憑證。

控制台

使用 Cloud de Confiance 控制台編輯現有負載平衡器時,系統會自動將 SSL 憑證與適當的目標 Proxy 建立關聯。

gcloud

如要將區域 SSL 憑證與目標 HTTPS Proxy 建立關聯,請使用 gcloud compute target-https-proxies update 指令,並搭配 --region--ssl-certificates-region 旗標:

gcloud compute target-https-proxies update TARGET_PROXY_NAME \
    --region=REGION \
    --ssl-certificates=SSL_CERTIFICATE_LIST \
    --ssl-certificates-region=REGION

更改下列內容:

  • TARGET_PROXY_NAME:負載平衡器目標 Proxy 的名稱
  • REGION (如適用):區域性目標 Proxy 和區域性 SSL 憑證的區域;這些區域必須相符
  • SSL_CERTIFICATE_LIST:以半形逗號分隔的 Cloud de Confiance SSL 憑證名稱清單

    請確認參照憑證清單包含所有舊的有效 SSL 憑證和新的 SSL 憑證。gcloud compute target-ssl-proxies update 指令會以新值覆寫 --ssl-certificates 的原始值。

API

如要將地區 SSL 憑證與目標 HTTPS Proxy 建立關聯,請向 targetHttpsProxies.insert 方法發出 POST 要求,並將 PROJECT_ID 替換為您的專案 ID。

POST https://compute.s3nsapis.fr/compute/v1/projects/PROJECT_ID/global/targetHttpsProxy

{
"name": "l7-xlb-proxy",
"urlMap": "projects/PROJECT_ID/global/urlMaps/l7-ilb-map",
"region": "us-west1"
"sslCertificates": /projectsPROJECT_IDregions/us-west1/sslCertificates/SSL_CERT_NAME
}

步驟 4:更新 DNS A 和 AAAA 記錄,指向負載平衡器的 IP 位址

在您的註冊商網站、DNS 主機或網際網路服務供應商 (ISP) (視管理 DNS 記錄的位置而定),新增或更新網域和任何子網域的 DNS A 記錄 (適用於 IPv4) 和 DNS AAAA 記錄 (適用於 IPv6),使其指向與負載平衡器轉送規則相關聯的 IP 位址。

如果您使用 Cloud DNSCloud Domains,請設定網域更新名稱伺服器

如果單一憑證使用多個網域,您必須為所有網域和子網域新增或更新 DNS 記錄,讓這些記錄都指向負載平衡器的 IP 位址。

DNS 傳播完成後,您就可以執行 dig 指令來驗證設定。舉例來說,假設您的網域是 www.example.com。執行下列 dig 指令:

dig www.example.com
; <<>> DiG 9.10.6 <<>> www.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31748
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.example.com.           IN  A

;; ANSWER SECTION:
www.example.com.        1742    IN  CNAME   www.example.com.edgekey.net.
www.example.com.edgekey.net. 21330 IN   CNAME   www.example.com.edgekey.net.globalredir.akadns.net.
www.example.com.edgekey.net.globalredir.akadns.net. 3356 IN CNAME   e6858.dsce9.akamaiedge.net.
e6858.dsce9.akamaiedge.net. 19  IN  A   203.0.113.5

;; Query time: 43 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Wed Jun 03 16:54:44 PDT 2020
;; MSG SIZE  rcvd: 193

在本範例中,203.0.113.5 是負載平衡器的 IP 位址。

步驟 5:使用 OpenSSL 測試

負載平衡器最多可能需要 30 分鐘,才會開始使用自行管理的 SSL 憑證。

如要測試,請執行下列 OpenSSL 指令,並將 DOMAIN 替換為您的 DNS 名稱,IP_ADDRESS 則替換為負載平衡器的 IP 位址。

echo | openssl s_client -showcerts -servername DOMAIN -connect IP_ADDRESS:443 -verify 99 -verify_return_error

這項指令會輸出負載平衡器向用戶端出示的憑證。輸出內容應包含憑證鏈結和 Verify return code: 0 (ok),以及其他詳細資訊。

使用自行管理的 SSL 憑證

下列各節說明如何列出、查看、刪除及取代 SSL 憑證資源。

列出 SSL 憑證

控制台

您無法在 Cloud de Confiance 控制台中維護區域性 SSL 憑證。 請改用 gcloud 或 REST API。

gcloud

如要列出區域性 SSL 憑證,請使用 gcloud compute ssl-certificates list 指令搭配 region 篩選器:

gcloud compute ssl-certificates list \
   --filter="region:(REGION ...)"

更改下列內容:

  • REGION: Cloud de Confiance 區域;以空格分隔的清單形式列出多個區域

說明 SSL 憑證

控制台

您無法在 Cloud de Confiance 控制台中維護區域性 SSL 憑證。 請改用 gcloud 或 REST API。

gcloud

如要說明區域性 SSL 憑證,請使用 gcloud compute ssl-certificates describe 指令搭配 --region 旗標:

gcloud compute ssl-certificates describe CERTIFICATE_NAME \
   --region=REGION

更改下列內容:

  • CERTIFICATE_NAME:SSL 憑證的名稱
  • REGION: Cloud de Confiance 區域

刪除 SSL 憑證

如要刪除 SSL 憑證,必須先更新每個參照該憑證的目標 Proxy。針對每個目標 Proxy,執行適當的 gcloud update 指令,更新目標 Proxy 的 SSL_CERTIFICATE_LIST,使其不再包含您需要刪除的 SSL 憑證。每個目標 SSL Proxy 或目標 HTTPS Proxy 都必須參照至少一個 SSL 憑證。

更新目標 Proxy 後,您就可以刪除 SSL 憑證。

控制台

您無法在 Cloud de Confiance 控制台中維護區域性 SSL 憑證。 請改用 gcloud 或 REST API。

gcloud

如要刪除地區 SSL 憑證,請使用 gcloud compute ssl-certificates delete 指令搭配 --region 指令:

gcloud compute ssl-certificates delete CERTIFICATE_NAME \
    --region=REGION

更改下列內容:

  • CERTIFICATE_NAME:SSL 憑證的名稱
  • REGION: Cloud de Confiance 區域

在 SSL 憑證到期前更換或續訂

如要更換、續約或輪替 SSL 憑證,請按照下列步驟操作:

  1. 針對目前的憑證執行 gcloud compute ssl-certificates describe 指令,檢查憑證是否即將到期。

  2. 建立新的 SSL 憑證資源。新 SSL 憑證的名稱在專案中不得重複。

  3. 更新目標 Proxy,卸離舊的 SSL 憑證並新增憑證。請務必加入要保留的任何其他現有 SSL 憑證。

    為避免停機,請執行單一 gcloud 指令並加上 --ssl-certificates 旗標。例如:

    區域性外部應用程式負載平衡器和區域性內部應用程式負載平衡器:

    使用 gcloud compute target-https-proxies update 指令時加上 --region 旗標。

    gcloud compute target-https-proxies update TARGET_PROXY_NAME \
       --region=REGION \
       --ssl-certificates=new-ssl-cert,other-certificates \
       --ssl-certificates-region=REGION
    
  4. 執行下列 OpenSSL 指令,確認負載平衡器是否提供替代憑證:

    echo | openssl s_client -showcerts -connect IP_ADDRESS:443 -verify 99 -verify_return_error
    
  5. 等待 15 分鐘,確保替換作業已傳播至所有 Google Front Ends (GFE)。

  6. (選用) 刪除舊的 SSL 憑證

後續步驟