Mengamankan Gateway


Halaman ini menjelaskan cara mengamankan Gateway menggunakan berbagai fitur keamanan:

  • Kebijakan SSL untuk memastikan Gateway menggunakan protokol dan algoritma aman yang diperlukan

  • Sertifikat untuk mengamankan traffic Client-to-Gateway dan Gateway-to-Backend dengan TLS

  • Kebijakan keamanan Google Cloud Armor untuk melindungi Layanan dari serangan DDoS

  • Identity-Aware Proxy (IAP) untuk memberikan lapisan autentikasi dan otorisasi sebelum mengizinkan akses ke Layanan

Untuk mempelajari keamanan Gateway lebih lanjut, lihat keamanan Gateway.

Sebelum memulai

Sebelum memulai, pastikan Anda telah menjalankan tugas berikut:

  • Aktifkan Google Kubernetes Engine API.
  • Aktifkan Google Kubernetes Engine API
  • Jika ingin menggunakan Google Cloud CLI untuk tugas ini, instal lalu initialize gcloud CLI. Jika sebelumnya Anda telah menginstal gcloud CLI, dapatkan versi terbaru dengan menjalankan gcloud components update.

Persyaratan GKE Gateway Controller

  • Untuk Standard, GKE versi 1.24 atau yang lebih baru.
  • Untuk Autopilot, GKE versi 1.26 atau yang lebih baru.
  • Google Cloud CLI versi 407.0.0 atau yang lebih baru.
  • Gateway API hanya didukung di cluster native VPC.
  • Jika menggunakan GatewayClass internal, Anda harus mengaktifkan subnet khusus proxy.
  • Cluster Anda harus mengaktifkan add-on HttpLoadBalancing.
  • Jika menggunakan Istio, Anda harus mengupgrade Istio ke salah satu versi berikut:
    • 1.15.2 atau yang lebih baru
    • 1.14.5 atau yang lebih baru
    • 1.13.9 atau yang lebih baru.
  • Jika menggunakan VPC Bersama, maka di project host, Anda perlu menetapkan peran Compute Network User ke akun Layanan GKE untuk project layanan tersebut.

Batas dan pembatasan

Selain batasan dan batasan pengontrol Gateway GKE, batasan berikut berlaku khusus untuk keamanan Gateway:

  • Anda tidak dapat menggunakan anotasi networking.gke.io/certmap dengan tls.certificateRefs di resource Gateway yang sama. Jika Anda mereferensikan CertificateMap di Gateway, GKE akan memperlakukan ini sebagai error.
  • Certificate Manager mendukung sertifikat baik yang dikelola sendiri maupun dikelola Google, tetapi tidak kompatibel dengan Gateway regional.
  • Gateway Controller tidak mendukung resource ManagedCertificate.

  • Gateway Controller tidak mendukung anotasi networking.gke.io/managed-certificates.

  • Kolom appProtocol dalam konfigurasi Service hanya menerima huruf kapital untuk nilai protokol (HTTP, HTTPS, atau HTTP2). Penggunaan huruf kecil mengakibatkan penggunaan HTTP sebagai protokol dengan backend.

Mengamankan Gateway menggunakan Secret Kubernetes

Dalam contoh ini, Anda akan mengonfigurasi Gateway menggunakan Secret Kubernetes.

Menyimpan sertifikat di Secret Kubernetes

Anda dapat menggunakan sertifikat yang diterbitkan dan divalidasi oleh certificate authority (CA) atau membuat sertifikat yang ditandatangani sendiri. Langkah-langkah berikut menggunakan sertifikat yang ditandatangani sendiri.

  1. Buat kunci pribadi:

    openssl genrsa -out PRIVATE_KEY_FILE 2048
    

    Ganti PRIVATE_KEY_FILE dengan nama file kunci pribadi Anda, misalnya private-key.pem. Untuk informasi selengkapnya, lihat Memilih atau membuat kunci pribadi.

  2. Buat file konfigurasi Open SSL:

    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]
    0.organizationName        = example
    commonName                = store.example.com
    
    [sans_list]
    DNS.1                     = store.example.com
    EOF
    

    Ganti CONFIG_FILE dengan nama untuk file konfigurasi baru, misalnya config-file.cnf.

  3. Buat file permintaan penandatanganan sertifikat (CSR):

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

    Ganti CSR_FILE dengan nama file CSR baru, misalnya cert.pem. Untuk informasi selengkapnya, lihat Membuat CSR.

  4. Tanda tangani CSR:

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

    Ganti CERTIFICATE_FILE dengan jalur dan nama file yang dihasilkan perintah ini, misalnya cert-file.pem. Untuk informasi selengkapnya, lihat Menandatangani CSR.

  5. Buat Secret TLS Kubernetes menggunakan kunci dan file sertifikat yang sudah Anda buat:

    kubectl create secret tls store-example-com \
        --cert=CERTIFICATE_FILE \
        --key=PRIVATE_KEY_FILE
    

    GKE menyimpan sertifikat dan kunci ini sebagai resource Kubernetes yang dapat dilampirkan ke Gateway.

Membuat Gateway dan HTTPRoute

  1. Simpan manifes berikut sebagai external-gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: external-http
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
        tls:
          mode: Terminate
          certificateRefs:
          - name: store-example-com
    

    Manifes ini menjelaskan Gateway dengan properti berikut:

    • gatewayClassName: gke-l7-global-external-managed: men-deploy Load Balancer Aplikasi eksternal global.
    • protocol: HTTPS dan port: 443: diperlukan untuk mengaktifkan TLS.
    • tls: mereferensikan Secret Kubernetes yang dibuat pada langkah sebelumnya.
  2. Terapkan manifes ke cluster:

    kubectl apply -f external-gateway.yaml
    
  3. Simpan manifes berikut sebagai store-external-route.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store-external
      labels:
        gateway: external-http
    spec:
      parentRefs:
      - name: external-http
      hostnames:
      - "store.example.com"
      rules:
      - backendRefs:
        - name: store-v1
          port: 8080
    

    Manifes ini menjelaskan HTTPRoute yang cocok dengan traffic ke store.example.com dan mengirimkannya ke Service store-v1.

  4. Terapkan manifes ke cluster:

    kubectl apply -f store-external-route.yaml
    

Memverifikasi Gateway

Pastikan Gateway berfungsi dengan mengirim permintaan melalui internet.

  1. Dapatkan alamat IP Gateway:

    kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
    

    Outputnya mirip dengan hal berikut ini:

    203.0.113.12
    

    Output ini adalah alamat IP publik, yang berarti semua klien dengan akses internet dapat terhubung ke sana.

  2. Akses domain Gateway menggunakan curl:

    curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
    

    Ganti kode berikut:

    • GATEWAY_IP_ADDRESS: alamat IP load balancer Gateway.
    • CERTIFICATE_FILE: file sertifikat yang Anda buat. Anda harus menyimpan file ini di komputer yang digunakan untuk terhubung ke Gateway. Sertifikat ini diperlukan untuk mengautentikasi Gateway karena Gateway menggunakan sertifikat yang ditandatangani sendiri.

    Opsi --resolve me-resolve nama domain ke alamat IP Gateway, yang diperlukan karena DNS tidak dikonfigurasi untuk domain ini.

    Outputnya mirip dengan hal berikut ini:

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=store.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: store.example.com (matched)
    *  issuer: O=example; CN=store.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gw",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "store-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08"
      # Several lines of output omitted here.
    }
    

    Output ini mencakup TLS handshake yang berhasil, diikuti dengan respons dari aplikasi. Koneksi TLS dihentikan di Gateway dan aplikasi merespons klien dengan aman.

Mengamankan Gateway menggunakan Certificate Manager

Dalam contoh ini, Anda akan mengonfigurasi Gateway menggunakan Certificate Manager.

Membuat CertificateMap

  1. Buat CertificateMap:

    gcloud certificate-manager maps create store-example-com-map
    
  2. Muat sertifikat dan kunci yang dikelola sendiri ke Certificate:

    gcloud certificate-manager certificates create store-example-com-cert \
        --certificate-file="cert.pem" \
        --private-key-file="PRIVATE_KEY_FILE"
    
  3. Buat CertificateMapEntry yang menetapkan sertifikat ke CertificateMap:

    gcloud certificate-manager maps entries create store-example-com-map-entry \
        --map=store-example-com-map \
        --hostname=store.example.com \
        --certificates=store-example-com-cert
    

Membuat Gateway dan HTTPRoute

  1. Simpan manifes berikut sebagai cert-map-gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: external-http
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
    

    Manifes ini menjelaskan Gateway dengan properti berikut:

    • gatewayClassName: gke-l7-global-external-managed: men-deploy Load Balancer Aplikasi eksternal global.
    • protocol: HTTPS dan port: 443: diperlukan untuk mengaktifkan TLS.

    Tidak ada bagian TLS karena TLS dikonfigurasi dengan Certificate Manager menggunakan anotasi networking.gke.io/certmap.

  2. Terapkan manifes ke cluster:

    kubectl apply -f cert-map-gateway.yaml
    

    Mungkin perlu waktu beberapa menit bagi GKE untuk men-deploy Gateway.

  3. Simpan manifes berikut sebagai cert-map-http-route.yaml:

    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: HTTPRoute
    metadata:
      name: foo
      namespace: default
    spec:
      parentRefs:
      - name: external-http
      hostnames:
      - foo.example.com
      rules:
      - matches:
        - path:
            value: /
        backendRefs:
        - name: foo-v1
          port: 8080
    
  4. Terapkan manifes ke cluster:

    kubectl apply -f cert-map-http-route.yaml
    

Memverifikasi Gateway

  1. Dapatkan alamat IP Gateway:

    kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
    

    Outputnya mirip dengan hal berikut ini:

    203.0.113.12
    

    Output ini adalah alamat IP publik, yang berarti semua klien dengan akses internet dapat terhubung ke sana.

  2. Perbarui data A atau AAAA untuk mengarahkan domain Anda ke alamat IP Gateway.

    Langkah ini hanya diperlukan jika Anda mengonfigurasi sertifikat SSL yang dikelola Google. Jika mengonfigurasi sertifikat yang dikelola sendiri, Anda dapat melewati langkah ini.

    Setelah data DNS diperbarui, diperlukan waktu hingga 10 menit agar load balancer mulai menggunakan sertifikat yang dikelola Google.

  3. Akses domain Gateway menggunakan curl:

    curl https://store.example.com -v
    

    Outputnya mirip dengan hal berikut ini:

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=store.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: store.example.com (matched)
    *  issuer: O=example; CN=store.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gw",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "store-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

    Output ini mencakup TLS handshake yang berhasil dan respons dari aplikasi. TLS dihentikan di Gateway dengan benar dan aplikasi merespons klien dengan aman.

Mengamankan traffic load balancer ke aplikasi menggunakan TLS

Anda dapat mengenkripsi traffic dari load balancer ke Pod backend menggunakan kolom ports[].appProtocol. Kolom yang didukung untuk appProtocol adalah: HTTP, HTTPS, dan HTTP2.

Manifes berikut menjelaskan Service yang menentukan load balancer harus menggunakan traffic HTTPS untuk berkomunikasi dengan Pod backend:

apiVersion: v1
kind: Service
metadata:
  name: store-v2
spec:
  selector:
    app: store
    version: v2
  ports:
  - port: 8080
    targetPort: 8080
    appProtocol: HTTPS

Load balancer tidak memverifikasi sertifikat yang digunakan oleh Pod backend. Anda bertanggung jawab untuk memastikan sertifikat yang digunakan di Pod backend valid.

Mengamankan traffic klien ke load balancer menggunakan kebijakan SSL

Jika aplikasi Anda diekspos melalui gateway eksternal yang menggunakan HTTPS, penting untuk menggunakan protokol terbaru atau menentukan versi SSL atau TLS minimum. Anda dapat mengamankan traffic klien ke load balancer menggunakan kebijakan SSL.

Untuk mengetahui lebih lanjut kebijakan SSL yang dapat dilampirkan ke Gateway dan cara membuatnya, lihat Mengonfigurasi Kebijakan SSL untuk mengamankan traffic klien ke load balancer.

Melindungi backend menggunakan Google Cloud Armor

Kebijakan keamanan Google Cloud Armor membantu melindungi aplikasi yang mengaktifkan load balancing dari serangan berbasis web. Setelah mengonfigurasi kebijakan keamanan Google Cloud Armor, Anda dapat mereferensikannya dalam GCPBackendPolicy yang diterapkan ke Service Kubernetes.

Untuk mengonfigurasi kebijakan Google Cloud Armor dengan Gateway, lihat Mengonfigurasi kebijakan keamanan Google Cloud Armor untuk mengamankan Service backend.

Mengautentikasi permintaan ke backend menggunakan Identity-Aware Proxy

Identity-Aware Proxy membantu Anda melindungi backend dari traffic yang tidak diinginkan dengan mengautentikasi klien yang mengirim permintaan ke aplikasi Anda dan memberlakukan otorisasi traffic berbasis peran. Setelah mengaktifkan Identity-Aware Proxy untuk GKE, Anda dapat mereferensikan kredensial OAuth di GCPBackendPolicy yang diterapkan ke Service Kubernetes Anda.

Untuk mengonfigurasi Identity-Aware Proxy dengan Gateway, lihat Mengonfigurasi Identity-Aware Proxy.

Langkah selanjutnya