Menggunakan kunci Cloud HSM untuk pemindahan TLS dengan NGINX

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

Kasus penggunaan

Menggunakan kunci Cloud HSM dengan NGINX untuk pemindahan TLS membantu memenuhi kebutuhan keamanan perusahaan berikut:

  • Anda ingin server web NGINX mengalihkan 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 jika aplikasi yang ditujukan untuk masyarakat memerlukan sertifikatnya yang dilindungi oleh 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 artikel Menggunakan kunci Cloud HSM dengan OpenSSL.

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

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

Rekomendasi konfigurasi keamanan

Amankan instance Anda yang menghosting NGINX dengan rekomendasi berikut:

  1. Ikuti petunjuk untuk membuat dan mengaktifkan akun layanan untuk instance untuk 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 pribadi Google.

  4. Konfigurasikan aturan firewall.

  5. Buat Linux VM dan konfigurasikan sebagai berikut:

    • Pilih akun layanan yang benar yang telah 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 disetel ke none.
  6. Beri identitas Anda peran IAP-Secured Tunnel User (roles/iap.tunnelResourceAccessor) pada instance.

Membuat dan mengonfigurasi kunci penandatanganan yang dihosting Cloud KMS

Bagian selanjutnya 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 project Google Cloud Anda, di key ring yang sebelumnya Anda konfigurasi 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"

SSH ke VM menggunakan IAP

Jalankan SSH ke VM Anda menggunakan IAP dengan perintah berikut:

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

Jika mengalami masalah, pastikan Anda menggunakan flag --tunnel-through-iap. Selain itu, konfirmasi bahwa Anda memiliki peran IAP-Secured Tunnel User (roles/iap.tunnelResourceAccessor) pada 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) Anda agar mereka dapat membuat sertifikat untuk Anda. Gunakan sertifikat yang diberikan 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 biasa, 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 digest yang digunakan oleh kunci penandatanganan asimetris. Gunakan -sha256, -sha384, atau -sha512 bergantung pada kuncinya.
  • 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 dari 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 dari 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 tidak benar, atau Anda mungkin tidak memiliki izin yang benar untuk menggunakan kunci penandatanganan Cloud KMS.

Sekarang Anda seharusnya memiliki sertifikat yang terlihat seperti ini:

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

Instal sertifikat Anda untuk NGINX

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

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

Konfigurasi 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 ke dalam log dengan library dengan hal 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 tersebut, lalu 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 Anda

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 pengurangan 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 Anda dan kunci pribadinya di Cloud HSM. Dalam 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;

        # ...
        # ...
}

Menyediakan 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 menyediakannya:

sudo systemctl daemon-reload

Memulai ulang NGINX dengan TLS Offloading

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

sudo systemctl start nginx

Menguji NGINX menggunakan pemindahan TLS ke Cloud HSM Anda

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

openssl s_client -connect localhost:443

Klien harus menyelesaikan handshake SSL dan berhenti sejenak. Klien menunggu masukan 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 sekarang akan menunjukkan operasi ke kunci NGINX_KEY Anda. Untuk melihat log, buka Cloud Logging di konsol cloud Anda. Dalam project yang telah Anda gunakan, tambahkan filter berikut:

resource.type="cloudkms_cryptokeyversion"

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

Konfigurasi opsional

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

Jika Anda perlu menggunakan NGINX sebagai reverse proxy dengan load balancing, pertimbangkan untuk memperbarui 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

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