Let’s Encrypt adalah salah satu Otoritas Sertifikasi (CA - Certificate Authority) yang dapat mengeluarkan sertifikat SSL. Pada sisi web host (hosting website) kita menggunakan ACME protocol untuk memperbarui sertifikat yang diberikan oleh Let’s Encrypt.
Dalam tutorial ini, kita menggunakan Wildcard SSL yang berfungsi untuk mengaktifkan ssl ke domain dan seluruh sub domain yang kita punya. Pada tutorial ini kita menggunakan domain contoh.com

Install Paket pendukung Let’s Encrypt

Install paket yang dibutuhkan oleh let’s encrypt

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update

Install Certbot

Install Certbot nginx

$ sudo apt-get install certbot python-certbot-nginx 

Generate Sertifikat Wildcard

Untuk menghasilkan sertifikat jalankan perintah certbot

$ sudo certbot --server https://acme-v02.api.letsencrypt.org/directory -d *.contoh.com --manual --preferred-challenges dns-01 certonly
Pada saat dijalankan akan muncul beberapa konfirmasi.

  • Masukkan email yang akan menjadi notifikasi ketika ssl telah habis masa berlakunya.
  • Menyetujui syarat dan ketentuan (Accept)
  • Izin untuk membagikan email ke EFF
  • Informasi mengenai IP Address akan di-logged

Setelah itu, masukkan recrod DNS TXT pada provider dns yang digunakan. Untuk

Please deploy a DNS TXT record under the name
_acme-challenge.contoh.com with the following value:

jM0Hwzb38cb_3zdb9safweb4J-K8qJtv1A1LUr64EXZ

Before continuing, verify the record is deployed.
Sebelum menekan Enter untuk lanjut, terlebih dahulu buat record DNS TXT dengan value yang diberikan dari Let’s Encrypt di atas untuk verifikasi bahwa kita adalah pemilik domain contoh.com yang sah.
Karena disini kita generate untuk root domain dan subdomain, maka Let’s encrypt akan memberikan 2 sertifikat yang harus dimasukkan ke dalam dashboard pengelola domain contoh.com. Oleh karena itu kita harus menmasukkan 2 DNS TXT, contoh salah satu isi DNS TXT.

  • Host : _acme-challenge
  • Tipe : TXT
  • Alamat/Value : jM0Hwzb38cb_3zdb9safweb4J-K8qJtv1A1LUr64EXZ

Setelah membuat record DNS TXT, maka sertifikat telah selesai di-download dan biasanya akan disimpan dalam folder /etc/letsencrypt/contoh.com/

Challenge

Untuk mendapatkan sertifikat dari Let’s Encrypt (CA), kita harus melewati challenge untuk membuktikan bahwa domain tersebut benar kita pengelolanya. Berikut challenge yang dilakukan:

  • Meletakkan file khusus di lokasi khusus pada website (HTTP-01)
  • Membuat DNS record khusus di sistem DNS provider (DNS-01)

Penjelasan lebih lengkap mengenai Challenge bisa dilihat pada halaman resmi Certbot dan Lets Encrypt

Troubleshoot Sertifikat

Pada saat generate sertifikat terkadang Let’s Encrypt tidak langsung membuat beberapa file khusus seperti:

  • options-ssl-nginx.conf
  • ssl-dhparams.pem

Oleh karena itu file tersebut harus dibuat manual. Untuk file options-ssl-nginx.conf

$ sudo vi /etc/letsencrypt/options-ssl-nginx.conf
Isi file
ssl_session_cache shared1m;
ssl_session_timeout 1440m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305ECDHE-ECDSA-AES128-GCM-SHA256ECDHE-ECDSA-AES256-GCM-SHA384DHE-RSA-AES128-GCM-SHA256ECDHE-ECDSA-AES128-SHA256ECDHE-ECDSA-AES128-SHAECDHE-RSA-AES128-SHAECDHE-ECDSA-AES256-SHADHE-RSA-AES128-SHA256DHE-RSA-AES256-SHA256ECDHE-ECDSA-DES-CBC3-SHAEDH-RSA-DES-CBC3-SHAAES256-GCM-SHA384AES256-SHA256AES256-SHA!DSS";
Untuk file kedua di-generate manual dengan perintah berikut
$ sudo openssl dhparam -out /etc/letsencrypt/ssl-dhparams.pem 2048
Sesuaikan letak file ssl-dhparams.pem yang akan digunakan dalam konfig nginx.

Konfigurasi Nginx untuk menggunakan SSL

Konfigurasi Nginx untuk menggunakan SSL dari Let’s Encrypt. Pertama buat file konfigurasi untuk root domain contoh.com dalam folder /etc/nginx/sites-available/. Kode berikut akan mengarahkan semua trafik yang ke port 80 otomatis ke port 443.

server {
    if ($host = www.contoh.com) {
        return 301 https://$host$request_uri;
    } 
    if ($host = contoh.com) {
        return 301 https://$host$request_uri;
    } 
    listen 80;
    server_name contoh.com www.contoh.com;
    return 404;
}
server {
  listen 443 ssl;
  server_name contoh.com www. contoh.com;

  access_log /var/log/nginx/contohcom.access.log;
  error_log /var/log/nginx/contohcom.error.log;
  
  ssl_certificate /etc/letsencrypt/live/contoh.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/contoh.com/privkey.pem;
  include /etc/letsencrypt/options-ssl-nginx.conf;
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
  
  root /var/www/html/webcontoh;
  index index.html index.htm index.nginx-debian.html;
  
  location / {
    #try_files $uri $uri/ =404;
	try_files $uri $uri/ /index.html;
  }
}
Kemudian buat file konfigurasi untuk sub domain tes.contoh.com
server {
    if ($host = tes.contoh.com) {
        return 301 https://$host$request_uri;
    }
    listen 80;
    server_name tes.contoh.com;
    return 404;
}
server {
  listen 443 ssl;
  server_name tes.contoh.com;

  access_log /var/log/nginx/tes.contoh.access.log;
  error_log /var/log/nginx/tes.contoh.error.log;
  
  ssl_certificate /etc/letsencrypt/live/contoh.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/contoh.com/privkey.pem;
  include /etc/letsencrypt/options-ssl-nginx.conf;
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
  
  root /var/www/html/tescontoh;
  index index.html index.htm index.nginx-debian.html;
  
  location / {
    #try_files $uri $uri/ =404;
	try_files $uri $uri/ /index.html;
  }
}
Setelah itu lakukan link ke folder /etc/nginx/sites-enabled/
$ sudo ln -s /etc/nginx/sites-available/contoh.com /etc/nginx/sites-enabled
$ sudo ln -s /etc/nginx/sites-available/tes.contoh.com /etc/nginx/sites-enabled

Pengujian SSL

Lakukan pengujian konfigurasi nginx

$ sudo nginx -t
Jika berhasil restart konfigurasi nginx
$ sudo systemctl restart nginx
Tes website yang telah dipasang ssl di SSL Labs

Pembaruan SSL

Sertifikat dari Let’s Encrypt hanya berlaku selama 90 hari dan harus diperbarui. Untuk memperbarui sertifikat secara otomatis bisa menggunakan cron.
Tetapi sertifikat wildcard yang di-generate dengan cara manual (karena DNS Provider belum mendukung plugin dari Let’s Encrypt) maka untuk memperbarui sertifikat tersebut harus menjalankan kembali perintah generate sertifikat secara manual dan menambahkan kembali record TXT seperti cara diawal.
Jika dijalankan secara otomatis, meskipun sudah ditambahkan opsi --manual maka akan muncul pesan error seperti berikut.

$ sudo certbot renew --dry-run --manual
...
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)
...
Untuk mengotomatisasikan pembaruan sertifikat DNS provider dan ACME client harus mendukung plugin dari Let’s Encrypt. Oleh karena itu pembaruan ssl di sini hanya dapat dilakukan secara manual dengan perintah.
$ sudo certbot certonly --manual -d contoh.com -d *.contoh.com