Konsep SSL/TLS #

Sebelum kita melangkah ke konfigurasi teknis di Nginx, kita wajib memahami prinsip dasar yang mendasari protokol SSL/TLS. Tanpa pemahaman konsep yang kuat, parameter konfigurasi seperti ssl_certificate, ssl_protocols, ssl_ciphers, hingga ssl_session_cache hanya akan tampak seperti baris kode yang dihafalkan. Pemahaman mendalam tentang apa yang terjadi di balik koneksi HTTPS membantu kita merancang arsitektur server yang tidak hanya aman dari serangan cyber, tetapi juga memiliki performa yang optimal dan responsif bagi pengguna.

Di artikel ini, kita akan membedah secara tuntas arsitekural keamanan web: mulai dari evolusi protokol SSL ke TLS, cara kerja kriptografi hibrida, visualisasi detail alur handshake TLS 1.2 dan TLS 1.3, mekanisme validasi sertifikat digital melalui Chain of Trust, hingga pentingnya ekstensi SNI (Server Name Indication).

SSL vs TLS: Meluruskan Kesalahpahaman Terminologi #

Dalam percakapan sehari-hari, kita sering mendengar istilah “SSL” digunakan untuk merujuk pada protokol pengamanan koneksi web. Bahkan di Nginx, direktif konfigurasi yang kita gunakan masih memakai nama ssl (misalnya listen 443 ssl atau ssl_protocols). Namun secara teknis, protokol SSL (Secure Sockets Layer) yang asli sudah mati dan tidak lagi digunakan karena memiliki celah keamanan yang fatal.

Mari kita tengok sejarah singkat perkembangan protokol ini untuk memahami perbedaannya:

  • SSL 1.0: Dibuat oleh Netscape pada awal tahun 1990-an, tetapi tidak pernah dirilis ke publik karena cacat keamanan yang sangat parah.
  • SSL 2.0: Dirilis pada tahun 1995. Protokol ini memiliki banyak kelemahan desain, seperti penggunaan algoritma enkripsi yang lemah dan kerentanan terhadap serangan man-in-the-middle (MITM).
  • SSL 3.0: Dirilis pada tahun 1996 untuk memperbaiki SSL 2.0. Meskipun bertahan cukup lama, SSL 3.0 akhirnya dinyatakan tidak aman setelah penemuan kerentanan POODLE (Padding Oracle On Downgraded Legacy Encryption) pada tahun 2014. Penggunaan SSL 3.0 kini telah dilarang sepenuhnya di seluruh dunia.
  • TLS 1.0: Dirilis oleh IETF (Internet Engineering Task Force) pada tahun 1999 sebagai penerus SSL 3.0. Di sinilah namanya berubah menjadi TLS (Transport Layer Security). Secara struktural, TLS 1.0 sangat mirip dengan SSL 3.0, tetapi dengan beberapa perbaikan standar keamanan. Protokol ini kini telah dinyatakan deprecated oleh browser modern.
  • TLS 1.1: Dirilis pada tahun 2006, menambahkan perlindungan terhadap serangan cipher block chaining (CBC). Seperti versi 1.0, versi 1.1 kini sudah tidak lagi didukung oleh browser modern sejak awal tahun 2020.
  • TLS 1.2: Dirilis pada tahun 2008. Ini adalah standar kerja HTTPS yang paling banyak digunakan saat ini. TLS 1.2 memperkenalkan fleksibilitas dalam pemilihan algoritma enkripsi (cipher suites) dan mengganti fungsi hash MD5/SHA-1 yang lemah dengan SHA-256 untuk verifikasi integritas data.
  • TLS 1.3: Dirilis pada tahun 2018. Ini adalah versi terbaru yang membawa perubahan revolusioner. TLS 1.3 membuang algoritma kriptografi yang usang dan rentan, menyederhanakan proses negosiasi (handshake) untuk mengurangi latensi koneksi, dan mengenkripsi lebih banyak bagian dari proses handshake untuk meningkatkan privasi.

Jadi, ketika kita mengonfigurasi “SSL” di Nginx hari ini, yang sebenarnya kita aktifkan adalah TLS v1.2 and/or TLS v1.3. Nginx tetap mempertahankan nama direktif ssl_* semata-mata untuk menjaga kompatibilitas konfigurasi masa lalu (backward compatibility).


Kriptografi Hibrida: Kekuatan di Balik HTTPS #

HTTPS menggunakan pendekatan pintar yang disebut kriptografi hibrida (hybrid cryptography). Untuk mengamankan data yang dikirimkan antara browser dan server, kita membutuhkan kecepatan transfer data yang tinggi sekaligus cara yang aman untuk membagikan kunci enkripsi tanpa bisa diintip oleh pihak ketiga.

Jika kita hanya menggunakan satu metode kriptografi, kita akan menghadapi kendala besar:

  1. Kriptografi Simetris (Symmetric Cryptography): Menggunakan kunci yang sama untuk mengenkripsi dan mendekripsi data. Metode ini sangat cepat dan hemat sumber daya komputasi. Namun, masalah utamanya adalah: bagaimana cara mengirimkan kunci tersebut dari browser ke server dengan aman di awal koneksi tanpa ada orang lain yang menyadapnya?
  2. Kriptografi Asimetris (Asymmetric Cryptography): Menggunakan sepasang kunci yang berbeda, yaitu Public Key (kunci publik yang disebarkan ke semua orang) dan Private Key (kunci rahasia yang disimpan rapat di server). Data yang dienkripsi dengan Public Key hanya bisa didekripsi dengan Private Key yang cocok, dan sebaliknya. Metode ini sangat aman untuk pertukaran informasi, tetapi sangat lambat dan membutuhkan daya komputasi yang besar jika digunakan untuk mengenkripsi seluruh trafik data.

HTTPS menyelesaikan masalah ini dengan menggabungkan keduanya:

  1. Fase Handshake (Asimetris): Di awal koneksi, browser dan server menggunakan kriptografi asimetris (seperti RSA atau Diffie-Hellman) untuk memverifikasi identitas server dan menyepakati sebuah kunci rahasia baru yang acak secara aman. Kunci baru ini disebut Session Key (Kunci Sesi).
  2. Fase Transfer Data (Simetris): Setelah Session Key disepakati secara aman, kriptografi asimetris dihentikan. Untuk sisa koneksi tersebut, browser dan server akan mengenkripsi dan mendekripsi data menggunakan kriptografi simetris (seperti AES-GCM atau ChaCha20-Poly1305) menggunakan Session Key yang sama.

Selain enkripsi untuk kerahasiaan (confidentiality), HTTPS juga menggunakan Message Authentication Code (MAC) atau fungsi hash satu arah (seperti SHA-256) untuk memastikan integritas data (integrity). Ini menjamin bahwa data yang dikirimkan tidak mengalami modifikasi di tengah jalan oleh penyerang (serangan tampering).


TLS Handshake: Analisis Alur Kerja & Perbandingan Versi #

Proses negosiasi di awal koneksi HTTPS disebut dengan TLS Handshake. Pada tahap inilah browser dan server menentukan versi protokol yang akan digunakan, memilih algoritma enkripsi (cipher suites), memverifikasi sertifikat digital server, dan membuat Session Key.

Mari kita bandingkan secara mendalam perbedaan alur kerja antara TLS 1.2 dan TLS 1.3, karena perbedaan ini berdampak langsung pada latensi web server kita.

TLS 1.2 Handshake (2 Round-Trip Times / 2-RTT) #

Dalam TLS 1.2, sebelum data aplikasi pertama dapat dikirimkan, browser dan server harus bertuchar pesan bolak-balik sebanyak dua kali putaran (2-RTT). Ini berarti ada overhead waktu tambahan sebelum website mulai dimuat.

Berikut adalah diagram alur detail dari TLS 1.2 Handshake:

sequenceDiagram
    autonumber
    actor Browser as Browser (Client)
    actor Server as Nginx Server
    
    Note over Browser, Server: RTT 1: Negosiasi Protokol & Pertukaran Kunci
    Browser->>Server: Client Hello (Versi TLS, Cipher List, Client Random)
    Server->>Browser: Server Hello (Pilihan TLS/Cipher, Server Random)
    Server->>Browser: Certificate (Sertifikat Server + Chain CA)
    Server->>Browser: Server Key Exchange (Parameter Diffie-Hellman Ephemeral)
    Server->>Browser: Server Hello Done
    
    Note over Browser: Browser memverifikasi sertifikat server
    
    Note over Browser, Server: RTT 2: Pembuatan Session Key & Selesai
    Browser->>Server: Client Key Exchange (Pre-Master Secret / DH Public Key)
    Browser->>Server: Change Cipher Spec (Mulai enkripsi sekarang)
    Browser->>Server: Finished (Tes enkripsi pertama dari Client)
    
    Note over Server: Server memproses & menghitung Session Key
    
    Server->>Browser: Change Cipher Spec (Mulai enkripsi sekarang)
    Server->>Browser: Finished (Tes enkripsi pertama dari Server)
    
    Note over Browser, Server: Koneksi Terenkripsi Terbentuk (Data Mulai Dikirim)
    Browser->>Server: HTTP Request (Encrypted with Session Key)
    Server->>Browser: HTTP Response (Encrypted with Session Key)

Pada langkah-langkah di atas:

  • Langkah 1 & 2: Browser mengirimkan daftar kapabilitasnya, dan server memilih kombinasi terbaik yang didukung bersama.
  • Langkah 3 & 4: Server mengirimkan identitasnya (sertifikat) dan parameter kunci sementara untuk algoritma pertukaran kunci Diffie-Hellman.
  • Langkah 7 & 8: Browser mengirimkan bagian kuncinya sendiri. Kedua belah pihak kini memiliki informasi yang cukup (Client Random, Server Random, dan Pre-Master Secret) untuk menghasilkan Session Key yang sama secara independen tanpa pernah mengirimkan kunci itu sendiri melalui jaringan.
  • Langkah 9 & 11: Proses pengecekan bahwa kunci yang dibuat oleh kedua belah pihak sudah cocok dan enkripsi berjalan dengan benar.

TLS 1.3 Handshake (1 Round-Trip Time / 1-RTT) #

TLS 1.3 memotong waktu handshake menjadi hanya satu putaran (1-RTT) saja. Penghematan 1-RTT ini sangat terasa pada perangkat mobile atau koneksi internet dengan latensi tinggi.

Bagaimana TLS 1.3 bisa memangkas waktu ini? Browser tidak lagi mengirimkan daftar cipher suites yang sangat panjang dan menunggu server memilih. Di TLS 1.3, pilihan cipher suites telah disederhanakan secara drastis (hanya ada 5 cipher suites utama yang dianggap aman). Browser secara proaktif berasumsi server mendukung salah satu dari algoritma pertukaran kunci terpopuler dan langsung mengirimkan Key Share (bagian kunci asimetrisnya) pada pesan pertama (Client Hello).

Berikut adalah alur TLS 1.3 Handshake:

sequenceDiagram
    autonumber
    actor Browser as Browser (Client)
    actor Server as Nginx Server
    
    Note over Browser, Server: RTT 1: Negosiasi, Pertukaran Kunci, & Verifikasi
    Browser->>Server: Client Hello (Pilihan TLS, Key Share / DH Guess)
    
    Note over Server: Server memproses Key Share, membuat Session Key, & mengenkripsi sisa handshake
    
    Server->>Browser: Server Hello (Pilihan Cipher & Server Key Share)
    Server->>Browser: Encrypted Extensions (Parameter TLS)
    Server->>Browser: Certificate (Sertifikat Server)
    Server->>Browser: Certificate Verify (Tanda tangan digital server membuktikan kepemilikan private key)
    Server->>Browser: Finished (Negosiasi selesai)
    
    Note over Browser: Browser memverifikasi sertifikat & menghitung Session Key
    
    Browser->>Server: Finished (Negosiasi selesai)
    
    Note over Browser, Server: Koneksi Terenkripsi Terbentuk (Data Mulai Dikirim)
    Browser->>Server: HTTP Request (Encrypted with Session Key)
    Server->>Browser: HTTP Response (Encrypted with Session Key)

Perhatikan bahwa pada TLS 1.3:

  • Hanya butuh 1-RTT: Server langsung mengirimkan sertifikat, pembuktian tanda tangan (Certificate Verify), dan pesan Finished segera setelah menerima Client Hello.
  • Enkripsi Handshake: Sesaat setelah pesan Server Hello dikirimkan, sisa pesan handshake di bawahnya (sertifikat, ekstensi, dll.) sudah dikirimkan dalam kondisi terenkripsi menggunakan kunci sementara. Ini mencegah penyadap pasif melihat sertifikat apa yang dikirimkan oleh server, meningkatkan privasi pengguna.
  • Zero-RTT (0-RTT) Session Resumption: Untuk pengguna yang kembali mengunjungi situs kita dalam waktu dekat, TLS 1.3 mendukung fitur 0-RTT. Dengan fitur ini, browser bisa langsung mengirimkan data terenkripsi bersamaan dengan pesan Client Hello tanpa perlu menunggu handshake sama sekali. Namun, fitur ini memiliki risiko serangan replay attack, sehingga di Nginx kita harus berhati-hati sebelum mengaktifkannya.

Sertifikat Digital dan Chain of Trust (Rantai Kepercayaan) #

Sertifikat digital adalah paspor elektronik bagi situs web kita. Tanpa sertifikat digital, enkripsi tetap bisa dilakukan, namun browser tidak akan tahu apakah mereka sedang berbicara dengan server kita yang asli atau server tiruan milik penyerang yang berpura-pura menjadi kita.

Sertifikat digital diterbitkan oleh Certificate Authority (CA). CA bertindak sebagai pihak ketiga tepercaya yang memverifikasi bahwa pemohon sertifikat benar-benar memiliki kendali atas nama domain tersebut.

Anatomi Sertifikat Digital X.509 #

Sertifikat digital mengikuti standar X.509. Komponen penting di dalamnya meliputi:

  • Subject: Nama domain yang dilindungi (misalnya example.com).
  • Subject Alternative Name (SAN): Daftar domain tambahan yang juga dilindungi oleh sertifikat ini (misalnya www.example.com, api.example.com). Browser modern kini mewajibkan keberadaan SAN dan mengabaikan kolom Common Name (CN) lama karena masalah kompatibilitas.
  • Issuer: Nama CA yang menerbitkan dan menandatangani sertifikat tersebut (misalnya Let's Encrypt).
  • Validity Period: Masa berlaku sertifikat (tanggal mulai dan tanggal kedaluwarsa).
  • Public Key: Kunci publik milik server kita yang akan digunakan oleh browser selama handshake.
  • Digital Signature: Tanda tangan digital dari CA yang dibuat menggunakan private key milik CA tersebut. Ini adalah bukti otentik bahwa sertifikat ini sah dan tidak dimodifikasi sejak diterbitkan.

Memahami Chain of Trust (Rantai Kepercayaan) #

Browser kita tidak mungkin menyimpan ribuan sertifikat dari setiap website di seluruh dunia untuk memverifikasi keasliannya. Sebagai gantinya, browser dan sistem operasi hanya menyimpan daftar kecil sertifikat dari CA terpercaya yang disebut Root CA (misalnya DigiCert Root, ISRG Root X1 milik Let’s Encrypt). Daftar ini disimpan di dalam Root Store lokal pada perangkat pengguna.

Ketika kita membeli atau membuat sertifikat, sertifikat server kita (Leaf Certificate) biasanya tidak ditandatangani langsung oleh Root CA demi alasan keamanan. Jika kunci Root CA disalahgunakan, seluruh internet akan berada dalam bahaya. Oleh karena itu, Root CA menandatangani sertifikat Intermediate CA, dan Intermediate CA inilah yang kemudian menandatangani sertifikat server kita.

Browser memverifikasi sertifikat kita dengan menelusuri rantai tanda tangan digital ini ke atas hingga menemukan Root CA yang mereka percayai.

flowchart TD
    subgraph Root Store Browser
        RootCA["Root CA Certificate (Terpercaya secara internal oleh OS/Browser)"]
    end
    
    subgraph Dikirim oleh Nginx Server
        IntermediateCA["Intermediate CA Certificate (Ditandatangani oleh Root CA)"]
        LeafCert["Leaf Certificate / Server Certificate (Ditandatangani oleh Intermediate CA untuk domain kita)"]
    end
    
    RootCA -- "Menandatangani" --> IntermediateCA
    IntermediateCA -- "Menandatangani" --> LeafCert
    
    BrowserCheck{"Browser memverifikasi rantai:"}
    BrowserCheck -->|1. Cek Leaf| LeafCert
    BrowserCheck -->|2. Cek Intermediate| IntermediateCA
    BrowserCheck -->|3. Cocok dengan Root?| RootCA
    
    classDef trust fill:#10b981,stroke:#047857,color:#ffffff;
    classDef serverCert fill:#1e293b,stroke:#3b82f6,color:#ffffff;
    class RootCA trust;
    class IntermediateCA,LeafCert serverCert;

Di sinilah letak pentingnya konfigurasi Nginx kita: Ketika kita mengonfigurasi ssl_certificate di Nginx, kita tidak boleh hanya memasukkan berkas sertifikat server kita saja. Kita harus menggabungkan sertifikat server kita dengan sertifikat Intermediate CA ke dalam satu berkas berkode PEM. Berkas gabungan ini sering disebut Full Chain Certificate (misalnya fullchain.pem pada Let’s Encrypt).

Jika kita lupa menyertakan Intermediate CA dalam konfigurasi Nginx:

  • Beberapa browser modern yang memiliki fitur Authority Information Access (AIA) Chase mungkin akan mencoba mengunduh Intermediate CA yang hilang secara otomatis di latar belakang. Koneksi akan berhasil, tetapi dengan latensi tambahan.
  • Browser lama, aplikasi mobile, atau perintah CLI seperti curl akan langsung menolak koneksi dan menampilkan error keamanan (seperti “certificate signed by unknown authority” atau “untrusted connection”).

Server Name Indication (SNI): Solusi Virtual Hosting HTTPS #

Pada awal perkembangan web server, satu alamat IP publik hanya bisa digunakan untuk melayani satu domain HTTPS saja. Ini adalah keterbatasan besar. Untuk HTTP biasa, Nginx bisa membaca header Host dari request HTTP untuk menentukan server block mana yang harus menangani request tersebut. Namun, pada HTTPS, header Host dikirimkan setelah koneksi terenkripsi terbentuk.

Masalahnya: bagaimana Nginx bisa memilih sertifikat SSL yang benar untuk melakukan enkripsi, jika Nginx baru bisa membaca nama domain yang diminta setelah enkripsi terbentuk?

Tanpa solusi, server terpaksa mengirimkan sertifikat default (yang mungkin tidak cocok dengan domain yang diminta), memicu peringatan keamanan di browser pengguna.

Solusi untuk masalah ini adalah Server Name Indication (SNI), sebuah ekstensi untuk protokol TLS. Dengan SNI, browser menyisipkan nama domain yang ingin dituju (misalnya api.example.com) secara jelas (tanpa enkripsi) di dalam pesan Client Hello pada awal proses handshake.

Alur Proses SNI:
1. Browser  -->  Pesan "Client Hello" (menyertakan info: "Saya ingin mengakses example.com")  --> Nginx
2. Nginx    -->  Membaca nama domain "example.com" dari handshake luar
3. Nginx    -->  Mencari server block example.com dan memuat sertifikat yang sesuai
4. Nginx    -->  Mengirimkan sertifikat example.com ke Browser dalam pesan "Server Hello"
5. Handshake berlanjut dengan kunci yang benar

Berkat SNI, kita bisa mengonfigurasi ratusan website HTTPS yang berbeda, masing-masing dengan sertifikat SSL-nya sendiri, pada satu server Nginx yang hanya memiliki satu alamat IP publik. Nginx secara otomatis menangani SNI di latar belakang tanpa membutuhkan konfigurasi khusus dari kita, asalkan direktif server_name pada masing-masing server block dikonfigurasi dengan benar.


Apa yang Dilindungi (dan Tidak Dilindungi) oleh HTTPS? #

Sebagai administrator sistem, kita harus memahami batas-batas keamanan HTTPS agar tidak memberikan rasa aman palsu (false sense of security).

Bagian Trafik yang Terlindungi (Terenkripsi) #

HTTPS mengenkripsi seluruh lapisan aplikasi (Layer 7) dari model OSI. Bagian-bagian berikut ini terenkripsi sepenuhnya dan tidak dapat dibaca oleh penyadap di jaringan (seperti ISP, admin Wi-Fi publik, atau peretas):

  • URL Path: Seluruh path setelah nama domain (misalnya /akun/setting/ubah-password).
  • Query Parameters: Parameter pencarian di URL (misalnya ?token=rahasia&user=admin).
  • HTTP Headers: Termasuk header sensitif seperti Cookie sesi, Authorization token, dan User-Agent.
  • Request & Response Body: Seluruh data yang dikirimkan lewat form POST, file unggahan, data JSON API, dan konten HTML/gambar yang dikembalikan oleh server.

Bagian Trafik yang Terbuka (Tidak Terlindungi) #

Karena data harus dirutekan melalui jaringan internet dari titik A ke titik B, beberapa metadata tidak dienkripsi karena router di internet membutuhkannya untuk mengirim paket data:

  • Alamat IP: Alamat IP publik asal (pengguna) dan tujuan (server) terlihat jelas di header paket TCP/IP.
  • Port Tujuan: Port komunikasi (biasanya port 443 untuk HTTPS) terlihat jelas.
  • Nama Domain (melalui SNI): Seperti yang kita bahas di bagian SNI, nama domain target dikirimkan tanpa enkripsi pada awal TLS handshake. Siapapun yang menyadap jaringan bisa mengetahui website apa yang kita kunjungi, meskipun mereka tidak tahu halaman spesifik apa yang kita buka di dalam website tersebut.
  • Ukuran dan Pola Data: Meskipun konten data terenkripsi, ukuran total data yang dikirimkan dan waktu pengirimannya tetap terlihat. Teknik analisis trafik tingkat lanjut terkadang bisa menebak aktivitas pengguna hanya berdasarkan ukuran paket data ini.

[!TIP] Jika kita ingin menyembunyikan nama domain yang sedang kita akses dari penyadap jaringan lokal, kita membutuhkan teknologi tambahan seperti Encrypted SNI (ESNI) atau Encrypted Client Hello (ECH), serta DNS over HTTPS (DoH) untuk mencegah kebocoran informasi melalui query DNS.


Ringkasan #

  • TLS adalah standar saat ini: Protokol SSL (v2.0 dan v3.0) sudah tidak aman dan dilarang. Kita harus memastikan Nginx kita dikonfigurasi hanya untuk mendukung TLS 1.2 dan TLS 1.3.
  • Koneksi Hibrida: HTTPS memadukan keunggulan kriptografi asimetris untuk keamanan fase negosiasi (handshake) dan kriptografi simetris untuk kecepatan fase pengiriman data.
  • TLS 1.3 jauh lebih cepat: Dengan memotong alur handshake menjadi 1-RTT, TLS 1.3 mengurangi latensi koneksi secara signifikan dibanding TLS 1.2 yang membutuhkan 2-RTT.
  • Wajib menggunakan Full Chain: Selalu sertifikasi Intermediate CA di berkas konfigurasi Nginx agar rantai kepercayaan (Chain of Trust) terverifikasi utuh di seluruh perangkat pengguna.
  • SNI memungkinkan Virtual Host: Ekstensi SNI mengirimkan nama domain target secara terbuka di awal handshake, memungkinkan Nginx melayani banyak domain HTTPS dengan sertifikat berbeda pada satu IP tunggal.

← Sebelumnya: Health Check   Berikutnya: Self-Signed Certificate →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact