Mengamankan traffic untuk Ingress GKE

Halaman ini menunjukkan cara mengamankan dan mengoptimalkan traffic untuk Ingress Google Kubernetes Engine (GKE). Anda dapat mengonfigurasi sertifikat SSL antara klien dan load balancer, serta mengamankan traffic antara load balancer dan aplikasi backend Anda. Sebelum melanjutkan, pastikan Anda memahami cara GKE mengamankan Ingress dengan HTTPS.

Halaman ini ditujukan bagi spesialis Jaringan yang mendesain dan membangun arsitektur jaringan untuk organisasi mereka serta menginstal, mengonfigurasi, dan mendukung peralatan jaringan. Untuk mempelajari lebih lanjut peran umum dan contoh tugas yang kami referensikan dalam kontenGoogle Cloud , lihat Peran dan tugas pengguna GKE umum.

Mengamankan dan mengoptimalkan traffic antara klien dan load balancer

Untuk menerima permintaan HTTPS dari klien, load balancer harus memiliki sertifikat untuk membuktikan identitasnya kepada klien. Load balancer juga harus memiliki kunci pribadi untuk menyelesaikan handshake HTTPS. Untuk mempelajari lebih lanjut cara memberikan sertifikat SSL ke load balancer HTTP(S), lihat Mengonfigurasi TLS antara klien dan load balancer.

Menggunakan sertifikat yang dikelola Google

Untuk mengonfigurasi satu atau beberapa sertifikat SSL yang dikelola Google dan mengaitkannya dengan Ingress, Anda harus:

  • Buat satu atau beberapa objek ManagedCertificate dalam namespace yang sama dengan Ingress. Anda dapat menentukan hingga 15 sertifikat untuk load balancer
  • Mengaitkan objek ManagedCertificate ke Ingress dengan menambahkan anotasi networking.gke.io/managed-certificates ke Ingress. Anotasi ini adalah daftar objek ManagedCertificate yang dipisahkan koma.

Batasan

Bagian ini menjelaskan batasan sertifikat yang dikelola Google. Jika Anda memerlukan sertifikat yang dikelola sendiri atau jika sudah memiliki sertifikat SSL yang ingin dikonfigurasi di Ingress, lihat Menyiapkan HTTPS (TLS) antara klien dan load balancer.

  • Sertifikat yang dikelola Google kurang fleksibel jika dibandingkan dengan sertifikat yang Anda dapatkan dan kelola sendiri. Sertifikat yang dikelola Google mendukung hingga 100 domain non-karakter pengganti. Tidak seperti sertifikat yang dikelola sendiri, sertifikat yang dikelola Google tidak mendukung domain karakter pengganti.

  • Jumlah dan jenis sertifikat yang didukung oleh Ingress ditentukan oleh batas sertifikat SSL yang dikelola Google.

  • Memperbarui sertifikat yang dikelola Google tidak didukung. Untuk mengetahui informasi selengkapnya, silakan melihat Memperbarui sertifikat yang dikelola Google secara manual.

  • Jika sertifikat dicabut secara langsung dengan Certificate Authority, Google tidak akan merotasi sertifikat tersebut secara otomatis. Anda harus menghapus ManagedCertificate dan membuat yang baru.

  • GKE Ingress tidak mendukung sertifikat yang dikelola oleh Certificate Manager. Untuk menggunakan sertifikat yang dikelola oleh Certificate Manager, gunakan Gateway API.

Prasyarat

  • Anda harus memiliki nama domain tersebut. Nama domain tidak boleh lebih dari 63 karakter. Anda dapat menggunakan registrar nama domain apa pun untuk mendapatkan nama domain.

  • Jika Anda menggunakan cluster GKE Standard, add-on HttpLoadBalancing harus diaktifkan.

  • Manifes Ingress Anda harus menyertakan anotasi kubernetes.io/ingress.class: "gce". Kolom ingressClassName tidak didukung.

  • Anda harus menerapkan resource Ingress dan ManagedCertificate dalam project dan namespace yang sama.

  • Buat alamat IP eksternal yang dipesan (statis). Memesan alamat IP statis akan memastikan bahwa alamat tersebut tetap menjadi milik Anda, meskipun Anda menghapus Ingress. Jika Anda tidak memesan alamat IP, alamat IP mungkin berubah, sehingga mengharuskan Anda mengonfigurasi ulang data DNS domain. Gunakan Google Cloud CLI atau konsol Google Cloud untuk membuat alamat IP yang dipesan.

    gcloud

    Untuk membuat alamat IP yang dipesan, jalankan perintah berikut:

    gcloud compute addresses create ADDRESS_NAME --global
    

    Ganti ADDRESS_NAME dengan nama alamat IP yang dipesan yang sedang Anda buat.

    Untuk menemukan alamat IP statis yang Anda buat, jalankan perintah berikut:

    gcloud compute addresses describe ADDRESS_NAME --global
    

    Outputnya mirip dengan yang berikut ini:

    address: 203.0.113.32
    ...
    

    Konsol

    Untuk membuat alamat IP yang dipesan, lakukan langkah-langkah berikut:

    1. Buka halaman External IP addresses di konsol Google Cloud .

      Buka External IP addresses

    2. Tentukan nama untuk alamat IP (misalnya, example-ip-address).

    3. Tentukan apakah Anda menginginkan alamat IPv4 atau IPv6.

    4. Pilih opsi Global untuk Type.

    5. Klik Pesan. Alamat IP tersebut akan tercantum di kolom Alamat Eksternal.

    Config Connector

    Catatan: Langkah ini memerlukan Config Connector. Ikuti petunjuk penginstalan untuk menginstal Config Connector di cluster Anda.

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global
    Untuk men-deploy manifes ini, download manifes ke komputer Anda sebagai compute-address.yaml, lalu jalankan:

    kubectl apply -f compute-address.yaml
    

Menyiapkan sertifikat yang dikelola Google

  1. Membuat objek ManagedCertificate. Resource ini menentukan domain untuk sertifikat SSL. Domain karakter pengganti tidak didukung.

    Manifes berikut menjelaskan objek ManagedCertificate. Simpan manifes sebagai managed-cert.yaml.

    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: FIRST_CERT_NAME
    spec:
      domains:
        - FIRST_DOMAIN
    ---
    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: SECOND_CERT_NAME
    spec:
      domains:
        - SECOND_DOMAIN
    

    Ganti kode berikut:

    • FIRST_CERT_NAME: nama objek ManagedCertificate pertama Anda.
    • FIRST_DOMAIN: domain pertama yang Anda miliki.
    • SECOND_CERT_NAME: nama objek ManagedCertificate kedua.
    • SECOND_DOMAIN: domain kedua yang Anda miliki.

    Nama objek ManagedCertificate berbeda dengan nama sertifikat sebenarnya yang dibuat. Anda hanya perlu mengetahui nama objek ManagedCertificate untuk menggunakannya di Ingress Anda.

  2. Terapkan manifes ke cluster Anda:

    kubectl apply -f managed-cert.yaml
    
  3. Ikuti petunjuk untuk membuat Deployment dan Service untuk mengekspos aplikasi Anda ke internet.

  4. Agar objek ManagedCertificate ini menjadi Active, pasang ke Ingress Anda menggunakan anotasi networking.gke.io/managed-certificates, seperti dalam contoh berikut. ManagedCertificate tidak harus Active agar Anda dapat memasangnya ke Ingress.

     apiVersion: networking.k8s.io/v1
     kind: Ingress
     metadata:
       name: my-gmc-ingress
       annotations:
         networking.gke.io/managed-certificates: "FIRST_CERT_NAME,SECOND_CERT_NAME"
     spec:
       rules:
       - host: FIRST_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60001
       - host: SECOND_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60002
     ```
    
    Replace <code><var>FIRST_DOMAIN</var></code> and
    <code><var>SECOND_DOMAIN</var></code> with your domain names.
    
    This manifest describes an Ingress that lists pre-shared certificate
    resources in an annotation.
    
    Note: It might take several hours for Google Cloud to provision the load
    balancer and the managed certificates, and for the load balancer to begin
    using the new certificates. For more information, see
    [Deploy a Google-managed certificate with load balancer authorization](/certificate-manager/docs/deploy-google-managed-lb-auth#wait_until_the_certificate_has_been_activated).
    
  5. Tunggu hingga penyediaan sertifikat yang dikelola Google selesai. Proses ini mungkin memerlukan waktu hingga 60 menit. Anda dapat memeriksa status sertifikat menggunakan perintah berikut:

    kubectl describe managedcertificate managed-cert
    

    Outputnya mirip dengan hal berikut ini:

    Name:         managed-cert
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         ManagedCertificate
    (...)
    Spec:
     Domains:
       FQDN_1
       FQDN_2
    Status:
     CertificateStatus: Active
    (...)
    

    Nilai kolom Status.CertificateStatus menunjukkan bahwa sertifikat telah disediakan. Jika Status.CertificateStatus bukan Active, sertifikat belum disediakan.

  6. Pastikan SSL berfungsi dengan membuka domain Anda menggunakan awalan https://. Browser Anda menunjukkan bahwa koneksi aman dan Anda dapat melihat detail sertifikat.

Bermigrasi ke sertifikat yang dikelola Google dari sertifikat yang dikelola sendiri

Saat Anda memigrasikan Ingress dari penggunaan sertifikat SSL yang dikelola sendiri ke sertifikat SSL yang dikelola Google, jangan sampai ada sertifikat SSL yang dikelola sendiri yang dihapus sebelum sertifikat SSL yang dikelola Google aktif. Setelah sertifikat SSL yang dikelola Google berhasil disediakan, sertifikat tersebut akan otomatis aktif. Setelah sertifikat SSL yang dikelola Google aktif, Anda dapat menghapus sertifikat SSL yang dikelola sendiri.

Gunakan petunjuk ini untuk bermigrasi dari sertifikat SSL yang dikelola sendiri ke sertifikat SSL yang dikelola Google.

  1. Tambahkan sertifikat baru yang dikelola Google ke Ingress, seperti yang dijelaskan di bagian sebelumnya.
  2. Tunggu hingga status resource sertifikat yang dikelola Google adalah Active. Periksa status sertifikat dengan perintah berikut:

    kubectl describe managedcertificate managed-cert
    
  3. Jika statusnya adalah Active, perbarui Ingress untuk menghapus referensi ke sertifikat yang dikelola sendiri.

Menghapus sertifikat yang dikelola Google

Untuk menghapus sertifikat yang dikelola Google dari cluster, Anda harus menghapus objek ManagedCertificate dan menghapus anotasi Ingress yang mereferensikannya.

  1. Hapus objek ManagedCertificate:

    kubectl delete -f managed-cert.yaml
    

    Outputnya mirip dengan yang berikut ini:

    managedcertificate.networking.gke.io "managed-cert" deleted
    
  2. Hapus anotasi dari Ingress:

    kubectl annotate ingress managed-cert-ingress networking.gke.io/managed-certificates-
    

    Perhatikan tanda minus, -, di akhir perintah.

  3. Rilis alamat IP statis yang Anda pesan untuk load balancer.

    Anda dapat menggunakan Google Cloud CLI, konsol Google Cloud , atau Config Connector untuk merilis alamat IP yang dipesan.

    gcloud

    Gunakan perintah berikut untuk merilis alamat IP yang dipesan:

    gcloud compute addresses delete ADDRESS_NAME --global
    

    Ganti ADDRESS_NAME dengan nama alamat IP.

    Konsol

    Untuk merilis alamat IP yang dipesan, lakukan langkah-langkah berikut:

    1. Buka halaman External IP addresses di konsol Google Cloud .

      Buka External IP addresses

    2. Pilih kotak centang di samping alamat IP yang ingin Anda rilis.

    3. Klik Rilis alamat IP.

    Config Connector

    Catatan: Langkah ini memerlukan Config Connector. Ikuti petunjuk penginstalan untuk menginstal Config Connector di cluster Anda.

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global

    Untuk men-deploy manifes ini, download manifes ke komputer Anda sebagai compute-address.yaml, lalu jalankan:

    kubectl delete -f compute-address.yaml
    

Membuat sertifikat dan kunci

Untuk menggunakan sertifikat yang dibagikan sebelumnya atau Secret Kubernetes, Anda memerlukan satu atau beberapa sertifikat terlebih dahulu, dengan kunci pribadi yang sesuai. Setiap sertifikat harus memiliki Nama Umum (CN) yang sama dengan nama domain yang Anda miliki. Jika sudah memiliki dua file sertifikat dengan nilai yang sesuai untuk Nama Umum, Anda dapat langsung melanjutkan ke bagian berikutnya.

  1. Buat kunci pertama Anda:

    openssl genrsa -out test-ingress-1.key 2048
    
  2. Buat permintaan penandatanganan sertifikat pertama Anda:

    openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \
        -subj "/CN=FIRST_DOMAIN"
    

    Ganti FIRST_DOMAIN dengan nama domain yang Anda miliki, seperti example.com.

  3. Buat sertifikat pertama Anda:

    openssl x509 -req -days 365 -in test-ingress-1.csr -signkey test-ingress-1.key \
        -out test-ingress-1.crt
    
  4. Buat kunci kedua:

    openssl genrsa -out test-ingress-2.key 2048
    
  5. Buat permintaan penandatanganan sertifikat kedua Anda:

    openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \
        -subj "/CN=SECOND_DOMAIN"
    

    Ganti SECOND_DOMAIN dengan nama domain lain yang Anda miliki, seperti examplepetstore.com.

  6. Buat sertifikat kedua Anda:

    openssl x509 -req -days 365 -in test-ingress-2.csr -signkey test-ingress-2.key \
        -out test-ingress-2.crt
    

Untuk mengetahui informasi selengkapnya tentang sertifikat dan kunci, lihat Ringkasan sertifikat SSL.

Anda sekarang memiliki dua file sertifikat dan dua file kunci.

Tugas yang tersisa menggunakan placeholder berikut untuk merujuk ke domain, sertifikat, dan kunci Anda:

  • FIRST_CERT_FILE: jalur ke file sertifikat pertama Anda.
  • FIRST_KEY_FILE: jalur ke file kunci yang mengarah dengan sertifikat pertama Anda.
  • FIRST_DOMAIN: nama domain yang Anda miliki.
  • FIRST_SECRET_NAME: nama Secret yang berisi sertifikat dan kunci pertama Anda.
  • SECOND_CERT_FILE: jalur ke file sertifikat kedua Anda.
  • SECOND_KEY_FILE: jalur ke file kunci yang sesuai dengan sertifikat kedua Anda.
  • SECOND_DOMAIN: nama domain kedua yang Anda miliki.
  • SECOND_SECRET_NAME: nama Secret yang berisi sertifikat dan kunci kedua Anda.

Menggunakan sertifikat yang dibagikan sebelumnya

Anda dapat menggunakan sertifikat SSL yang dikelola sendiri yang Anda upload ke Google Cloud project. Sertifikat ini disebut sertifikat yang dibagikan sebelumnya. Anda dapat menentukan satu atau beberapa sertifikat yang dibagikan sebelumnya untuk Ingress.

Untuk menggunakan beberapa sertifikat yang dibagikan sebelumnya, ikuti langkah-langkah berikut:

  1. Untuk setiap pasangan sertifikat dan kunci Anda, buat resource sertifikat SSL yang dapat dilihat secara publik di Google Cloud.

     gcloud compute ssl-certificates create FIRST_CERT_NAME \
         --certificate=FIRST_CERT_FILE \
         --private-key=FIRST_KEY_FILE
     ```
    
    ```sh
     gcloud compute ssl-certificates create SECOND_CERT_NAME \
         --certificate=SECOND_CERT_FILE \
         --private-key=SECOND_KEY_FILE
     ```
    
    Replace the following:
    
    • FIRST_CERT_NAME, SECOND_CERT_NAME: nama sertifikat pertama dan kedua Anda.
    • FIRST_CERT_FILE, SECOND_CERT_FILE: file sertifikat pertama dan kedua Anda.
    • FIRST_KEY_FILE:, SECOND_KEY_FILE file kunci pertama dan kedua Anda.
  2. Dalam manifes Ingress, tambahkan anotasi ingress.gcp.kubernetes.io/pre-shared-cert. Nilai anotasi adalah daftar nama sertifikat Anda yang dipisahkan koma. Selain itu, di bagian spec.rules, sertakan kolom host untuk menentukan domain layanan Anda.

     apiVersion: networking.k8s.io/v1
     kind: Ingress
     metadata:
       name: my-psc-ingress
       annotations:
         ingress.gcp.kubernetes.io/pre-shared-cert: "FIRST_CERT_NAME,SECOND_CERT_NAME"
     spec:
       rules:
       - host: FIRST_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60001
       - host: SECOND_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60002
     ```
    
    Replace <code><var>FIRST_DOMAIN</var></code> and
    <code><var>SECOND_DOMAIN</var></code> with your domain names.
    
    This manifest describes an Ingress that lists pre-shared certificate
    resources in an annotation.
    

Menggunakan Secret Kubernetes

Untuk menyediakan load balancer HTTP(S) dengan sertifikat dan kunci yang Anda buat sendiri, buat satu atau beberapa objek Secret Kubernetes. Setiap Secret menyimpan sertifikat dan kunci. Anda menambahkan Secret ke kolom tls dari manifes Ingress Anda. Load balancer menggunakan Server Name Indication (SNI) untuk menentukan sertifikat yang akan ditampilkan kepada klien, berdasarkan nama domain di handshake TLS.

Untuk menggunakan beberapa sertifikat, ikuti langkah-langkah berikut:

  1. Buat Secret untuk setiap pasangan sertifikat dan kunci Anda:

     kubectl create secret tls FIRST_SECRET_NAME \
         --cert=FIRST_CERT_FILE \
         --key=FIRST_KEY_FILE
     ```
    
    ```sh
     kubectl create secret tls SECOND_SECRET_NAME \
         --cert=SECOND_CERT_FILE \
         --key=SECOND_KEY_FILE
     ```
    
  2. Dalam manifes Ingress Anda, di bagian spec.tls, cantumkan Secret yang Anda buat. Selain itu, di bagian spec.rules, sertakan kolom host untuk menentukan domain layanan Anda.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-mc-ingress
    spec:
      tls:
      - secretName: FIRST_SECRET_NAME
      - secretName: SECOND_SECRET_NAME
      rules:
      - host: FIRST_DOMAIN
        http:
          paths:
          - pathType: ImplementationSpecific
            backend:
              service:
                name: my-mc-service
                port:
                  number: 60001
      - host: SECOND_DOMAIN
        http:
          paths:
          - pathType: ImplementationSpecific
            backend:
              service:
                name: my-mc-service
                port:
                  number: 60002
    

    Ganti FIRST_DOMAIN dan SECOND_DOMAIN dengan nama domain yang Anda miliki, misalnya example.com dan examplepetstore.com.

Perubahan pada Secret diambil secara berkala, sehingga jika Anda mengubah data di dalam Secret, perubahan tersebut akan memerlukan waktu maksimal 10 menit untuk diterapkan ke load balancer.

Agar dapat mengamankan Ingress terenkripsi HTTPS untuk cluster GKE, lihat contoh Secure Ingress.

Menonaktifkan HTTP

Jika ingin semua traffic antara klien dan load balancer menggunakan HTTPS, Anda dapat menonaktifkan HTTP dengan menyertakan anotasi kubernetes.io/ingress.allow-http dalam manifes Ingress. Tetapkan nilai anotasi ke "false".

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress-2
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: SECRET_NAME
  ...

Manifes ini mencakup SECRET_NAME yang merupakan nama Secret yang Anda buat.

HTTP/2 antara klien dan load balancer

Klien dapat menggunakan HTTP/2 untuk mengirimkan permintaan ke load balancer. Konfigurasi tidak diperlukan.

Mengamankan dan mengoptimalkan traffic antara load balancer dan aplikasi

Anda dapat mengonfigurasi protokol yang digunakan untuk komunikasi antara load balancer dan Pod aplikasi Anda untuk memastikan keamanan end-to-end atau untuk mengoptimalkan performa traffic internal. Meskipun load balancer secara default menggunakan HTTP/1.1 yang tidak terenkripsi untuk koneksi backend, Anda dapat mengaktifkan HTTPS atau HTTP/2 untuk memenuhi persyaratan khusus aplikasi Anda.

HTTPS antara load balancer dan aplikasi

Jika aplikasi Anda, yang berjalan di Pod GKE, dapat menerima permintaan HTTPS, Anda dapat mengonfigurasi load balancer untuk menggunakan HTTPS saat meneruskan permintaan ke aplikasi Anda. Untuk informasi selengkapnya, lihat HTTPS (TLS) antara load balancer dan aplikasi.

Untuk mengonfigurasi protokol yang digunakan antara load balancer dan aplikasi, gunakan anotasi cloud.google.com/app-protocols dalam manifes Service. Manifes Service ini harus menyertakan type: NodePort kecuali jika Anda menggunakan load balancing berbasis container. Jika Anda menggunakan load balancing berbasis container, gunakan type: ClusterIP.

Manifes Service berikut menentukan dua port. Anotasi ini menyatakan bahwa saat load balancer HTTP(S) menargetkan port 80 Service, load balancer tersebut harus menggunakan HTTP. Selain itu, jika load balancer menargetkan port 443 Service, load balancer harus menggunakan HTTPS.

Manifes Service harus menyertakan nilai name dalam anotasi port. Anda hanya dapat mengedit port Service dengan merujuk ke name yang ditetapkan, bukan dengan nilai targetPort-nya.

apiVersion: v1
kind: Service
metadata:
  name: my-service-3
  annotations:
    cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
spec:
  type: NodePort
  selector:
    app: metrics
    department: sales
  ports:
  - name: my-https-port
    port: 443
    targetPort: 8443
  - name: my-http-port
    port: 80
    targetPort: 50001

Menggunakan HTTP/2 antara load balancer dan aplikasi

Jika aplikasi Anda, yang berjalan di Pod GKE, dapat menerima permintaan HTTP/2, Anda dapat mengonfigurasi load balancer untuk menggunakan HTTP/2 saat meneruskan permintaan ke aplikasi Anda.

Untuk mengaktifkan HTTP/2, Anda harus menggunakan anotasi cloud.google.com/app-protocols pada manifes Layanan Kubernetes. Anotasi ini menentukan protokol yang digunakan load balancer untuk berkomunikasi dengan aplikasi Anda. Untuk memastikan load balancer membuat permintaan HTTP/2 yang benar ke backend Anda, backend Anda harus dikonfigurasi dengan SSL.

Berikut adalah contoh manifes Service yang dikonfigurasi untuk HTTP/2:

apiVersion: v1
kind: Service
metadata:
  name: my-http2-service
  annotations:
    cloud.google.com/app-protocols: '{"my-port":"HTTP2"}'
spec:
  type: NodePort
  selector:
    app: my-app
  ports:
  - name: my-port
    protocol: TCP
    port: 443
    targetPort: 8443

Perhatikan hal berikut:

  • Anotasi cloud.google.com/app-protocols ditetapkan ke '{"my-port":"HTTP2"}', yang menginstruksikan load balancer untuk menggunakan HTTP/2 untuk traffic yang dikirim ke port bernama my-port.
  • Port disetel ke 443 dan mengarahkan traffic ke Pod di targetPort 8443.