Menggunakan kunci Cloud HSM untuk offload TLS dengan NGINX

Panduan ini memberikan petunjuk untuk menyiapkan NGINX agar dapat menggunakan kunci Cloud HSM untuk offloading TLS di Debian 11 (Bullseye). Anda mungkin perlu mengubah perintah ini agar berfungsi dengan OS atau distribusi Linux Anda.

Anda dapat menemukan versi blueprint berbasis Terraform dari tutorial ini di repositori GitHub kms-solutions.

Kasus penggunaan

Menggunakan kunci Cloud HSM dengan NGINX untuk offloading TLS membantu mengatasi kebutuhan keamanan perusahaan berikut:

  • Anda ingin server web NGINX men-offload operasi kriptografi TLS ke Cloud HSM.
  • Anda tidak ingin menyimpan kunci pribadi sertifikat di sistem file lokal instance Compute Engine yang menghosting aplikasi web Anda.
  • Anda harus memenuhi persyaratan peraturan yang mewajibkan aplikasi yang ditampilkan kepada publik untuk melindungi sertifikatnya dengan HSM yang memiliki sertifikasi FIPS 140-2 Level 3.
  • Anda ingin menggunakan NGINX untuk membuat reverse proxy dengan penghentian TLS untuk melindungi aplikasi web Anda.

Sebelum memulai

Sebelum melanjutkan, selesaikan langkah-langkah di Menggunakan kunci Cloud HSM dengan OpenSSL.

Setelah penyiapan OpenSSL selesai, pastikan nginx versi terbaru telah diinstal:

sudo apt-get update
sudo apt-get install libengine-pkcs11-openssl opensc nginx

Rekomendasi konfigurasi keamanan

Amankan instance yang menghosting NGINX dengan rekomendasi berikut:

  1. Ikuti petunjuk untuk membuat dan mengaktifkan akun layanan untuk instance guna menghosting NGINX.

    1. Tetapkan peran berikut:
      • roles/cloudkms.signerVerifier
      • roles/cloudkms.viewer
  2. Konfigurasi kebijakan organisasi sebagai berikut untuk membatasi IP eksternal dan pembuatan kunci akun layanan.

    • constraints/compute.vmExternalIpAccess
    • constraints/iam.disableServiceAccountKeyCreation
  3. Buat subnet kustom yang mengaktifkan akses Google pribadi.

  4. Mengonfigurasi aturan firewall.

  5. Buat VM Linux dan konfigurasikan sebagai berikut:

    • Pilih akun layanan yang benar yang Anda buat sebelumnya.
    • Pilih jaringan yang Anda buat sebelumnya.
      • Tambahkan label yang sesuai untuk aturan firewall apa pun.
      • Pastikan subnet memiliki kolom "IP eksternal" yang ditetapkan ke none.
  6. Berikan peran IAP-Secured Tunnel User (roles/iap.tunnelResourceAccessor) kepada identitas Anda di instance.

Membuat dan mengonfigurasi kunci penandatanganan yang dihosting Cloud KMS

Bagian berikutnya menjelaskan langkah-langkah yang diperlukan untuk membuat dan mengonfigurasi kunci penandatanganan yang dihosting Cloud KMS.

Membuat kunci penandatanganan yang dihosting Cloud KMS

Buat kunci penandatanganan EC-P256-SHA256 Cloud KMS di projectGoogle Cloud , di key ring yang sebelumnya Anda konfigurasikan untuk OpenSSL:

gcloud kms keys create NGINX_KEY \
  --keyring "KEY_RING" --project "PROJECT_ID" \
  --location "LOCATION" --purpose "asymmetric-signing" \
  --default-algorithm "ec-sign-p256-sha256" --protection-level "hsm"

Menghubungkan SSH ke VM menggunakan IAP

Gunakan SSH ke VM Anda menggunakan IAP dengan perintah berikut:

gcloud compute ssh INSTANCE \
  --zone ZONE --tunnel-through-iap

Jika Anda mengalami masalah, pastikan Anda menggunakan flag --tunnel-through-iap. Selain itu, pastikan Anda memiliki peran IAP-Secured Tunnel User (roles/iap.tunnelResourceAccessor) di instance untuk identitas yang diautentikasi dengan gcloud CLI.

Membuat sertifikat dengan OpenSSL

Untuk lingkungan produksi, buat permintaan penandatanganan sertifikat (CSR). Pelajari lebih lanjut dengan membaca contoh untuk membuat CSR. Berikan CSR ke certificate authority (CA) agar mereka dapat membuat sertifikat untuk Anda. Gunakan sertifikat yang disediakan oleh CA Anda di bagian berikutnya.

Misalnya, Anda dapat membuat sertifikat yang ditandatangani sendiri dengan kunci penandatanganan yang dihosting Cloud KMS. Untuk melakukannya, OpenSSL memungkinkan Anda menggunakan URI PKCS #11, bukan jalur reguler, yang mengidentifikasi kunci berdasarkan labelnya (untuk kunci Cloud KMS, labelnya adalah nama CryptoKey).

openssl req -new -x509 -days 3650 -subj '/CN=CERTIFICATE_NAME/' \
  DIGEST_FLAG -engine pkcs11 -keyform engine \
  -key PKCS_KEY_TYPE=KEY_IDENTIFIER > CA_CERT

Ganti kode berikut:

  • CERTIFICATE_NAME: nama untuk sertifikat.
  • DIGEST_FLAG: algoritma ringkasan yang digunakan oleh kunci penandatanganan asimetris. Gunakan -sha256, -sha384, atau -sha512, bergantung pada kunci.
  • PKCS_KEY_TYPE: jenis ID yang digunakan untuk mengidentifikasi kunci. Untuk menggunakan versi kunci terbaru, gunakan pkcs11:object dengan nama kunci. Untuk menggunakan versi kunci tertentu, gunakan pkcs11:id dengan ID resource lengkap versi kunci.
  • KEY_IDENTIFIER: ID untuk kunci. Jika Anda menggunakan pkcs11:object, gunakan nama kunci—misalnya, NGINX_KEY. Jika Anda menggunakan pkcs11:id, gunakan ID resource lengkap kunci atau versi kunci—misalnya, projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/NGINX_KEY/cryptoKeyVersions/KEY_VERSION.
  • CA_CERT: jalur tempat Anda ingin menyimpan file sertifikat.

Jika perintah gagal, PKCS11_MODULE_PATH mungkin telah ditetapkan dengan salah, atau Anda mungkin tidak memiliki izin yang benar untuk menggunakan kunci penandatanganan Cloud KMS.

Sekarang Anda akan memiliki sertifikat yang terlihat seperti ini:

-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----

Menginstal sertifikat untuk NGINX

Jalankan perintah berikut untuk membuat lokasi untuk menempatkan sertifikat publik Anda:

sudo mkdir /etc/ssl/nginx
sudo mv CA_CERT /etc/ssl/nginx

Mengonfigurasi lingkungan Anda untuk menggunakan library PKCS #11

Bagian berikutnya menjelaskan langkah-langkah yang diperlukan untuk menyiapkan dan menguji lingkungan Anda.

Menyiapkan konfigurasi library untuk NGINX

Izinkan NGINX mencatat operasi mesin PKCS #11-nya ke dalam log dengan library berikut:

sudo mkdir /var/log/kmsp11
sudo chown www-data /var/log/kmsp11

Buat file konfigurasi library kosong dengan izin yang sesuai untuk NGINX.

sudo touch /etc/nginx/pkcs11-config.yaml
sudo chmod 744 /etc/nginx/pkcs11-config.yaml

Edit file konfigurasi kosong dan tambahkan konfigurasi yang diperlukan seperti yang ditunjukkan dalam cuplikan berikut:

# cat /etc/nginx/pkcs11-config.yaml
---
tokens:
  - key_ring: "projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING"
log_directory: "/var/log/kmsp11"

Menguji konfigurasi OpenSSL

Jalankan perintah berikut:

openssl engine -tt -c -v pkcs11

Anda akan melihat output yang mirip dengan berikut ini:

(pkcs11) pkcs11 engine
 [RSA, rsaEncryption, id-ecPublicKey]
     [ available ]
     SO_PATH, MODULE_PATH, PIN, VERBOSE, QUIET, INIT_ARGS, FORCE_LOGIN

Mengonfigurasi NGINX untuk menggunakan Cloud HSM

Izinkan offload TLS dengan mengedit beberapa file NGINX. Pertama, edit file /etc/nginx/nginx.conf di dua tempat untuk menambahkan beberapa perintah guna mengonfigurasi NGINX agar menggunakan PKCS #11.

Setelah blok event dan sebelum blok http, tambahkan perintah berikut:

ssl_engine pkcs11;
env KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml;

Dalam file /etc/nginx/nginx.conf yang sama, konfigurasikan perintah SSL untuk menggunakan sertifikat dan kunci pribadinya di Cloud HSM. Di blok http, tambahkan atribut berikut:

ssl_certificate "/etc/ssl/nginx/CA_CERT";
ssl_certificate_key "engine:pkcs11:PKCS_KEY_TYPE=KEY_IDENTIFIER";
ssl_protocols TLSv1.2 TLSv1.3; # Consider changing the default to only TLS1.2 or newer

# Consider defining the `ssl_ciphers` to use ciphers approved by your security teams and handle
# appropriate client compatibility requirements.

File /etc/nginx/nginx.conf Anda akan terlihat seperti berikut:

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

ssl_engine pkcs11;
env KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml;

http {

        #...
        #...

        # SSL configuration
        ssl_certificate "/etc/ssl/nginx/CA_CERT";
        ssl_certificate_key "engine:pkcs11:pkcs11:object=NGINX_KEY";
        ssl_protocols TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        # ssl_ciphers YOUR_CIPHERS
        ssl_prefer_server_ciphers on;

        #...
        #...

}

Mengonfigurasi NGINX untuk memproses traffic TLS

Edit file /etc/nginx/sites-enabled/default untuk memproses traffic TLS. Hapus tanda komentar pada konfigurasi SSL di blok server. Perubahan yang dihasilkan akan terlihat seperti contoh berikut:


server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # SSL configuration
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;

        # ...
        # ...
}

Memberikan variabel lingkungan ke layanan NGINX

Jalankan perintah berikut:

sudo systemctl edit nginx.service

Di editor yang dihasilkan, tambahkan baris berikut dan ganti LIBPATH dengan nilai untuk lokasi tempat Anda menginstal libkmsp11.so:

[Service]
Environment="GRPC_ENABLE_FORK_SUPPORT=1"
Environment="KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml"
Environment="PKCS11_MODULE_PATH=LIBPATH/libkmsp11-1.0-linux-amd64/libkmsp11.so"

Setelah mengonfigurasi nilai ini, Anda harus menjalankan perintah berikut untuk menyediakan nilai tersebut:

sudo systemctl daemon-reload

Memulai ulang NGINX dengan Offloading TLS

Jalankan perintah berikut agar NGINX dimulai ulang dan menggunakan konfigurasi yang telah diupdate:

sudo systemctl start nginx

Menguji NGINX menggunakan offload TLS ke Cloud HSM Anda

Gunakan openssl s_client untuk menguji koneksi ke server NGINX dengan menjalankan perintah berikut:

openssl s_client -connect localhost:443

Klien harus menyelesaikan handshake SSL dan menjeda. Klien menunggu input dari Anda seperti yang ditunjukkan berikut:

# completes SSL handshake
# ...
# ...
# ...
    Verify return code: 18 (self signed certificate)
# ...
    Max Early Data: 0
---
read R BLOCK

# When the client pauses, it’s waiting for instructions.
# Have the client get the index.html file in the root path (“/”), by typing the following:

GET /

# Press enter.
# You should now see the default NGINX index.html file.

Log audit Anda kini akan menampilkan operasi ke kunci NGINX_KEY Anda. Untuk melihat log, buka Cloud Logging di konsol cloud Anda. Di project yang telah Anda gunakan, tambahkan filter berikut:

resource.type="cloudkms_cryptokeyversion"

Setelah menjalankan kueri, Anda akan melihat operasi kunci asimetris ke kunci NGINX_KEY.

Konfigurasi opsional

Anda mungkin perlu membuat Load Balancer Jaringan passthrough eksternal untuk mengekspos server NGINX dengan IP eksternal.

Jika Anda perlu menggunakan NGINX sebagai reverse proxy dengan load balancing, pertimbangkan untuk mengupdate file konfigurasi NGINX. Pelajari lebih lanjut cara mengonfigurasi NGINX sebagai reverse proxy dengan membaca HA Semua Aktif untuk NGINX Plus di Google Cloud Platform.

Langkah berikutnya

Sekarang Anda telah mengonfigurasi server NGINX untuk menggunakan offloading TLS ke Cloud HSM.