Ubuntu ve Nginx Üzerinde Let's Encrypt ile SSL Kurulumu

Let's Encrypt, an itibariyle herkese açık, beta aşamasında olan, mozilla öncülüğünde, birçok şirketin destekleriyle geliştirilmiş olan bedava SSL/TLS sağlayıcısıdır. Firefox, Chrome, Safari gibi önde gelen tüm tarayıcılar tarafından tanınan bu sertifikayı yüklemek de gayet basit.

Bu makalede daha önceden letsencrypt'in kendi client'ı ile nasıl kurulum yapılabileceğini anlatmıştım ancak daha sonradan Github üzerinden kaynak kodlarını inceleyebileceğiniz acme-tiny ile daha zahmetsiz kurulum yapılabildiğini deneyimledim ve dolayısıyla da oradaki talimatlara göre anlatımı yapacağım.

Öncelikli olarak, sertifikayı yükleyebilmeniz için, alan adınız üzerinden .well-known/acme-challenge/ adresini sunabilmeniz lazım, bunun için de alttaki komutları gerçeklemeniz gerek.
$ mkdir -p /var/www/challenges/
$ sudo nano /etc/nginx/sites-available/default
Alttaki bloğu ekleyin ve şimdilik bu dosyayı bu şekilde kaydedin.
server {
    listen          80;
    server_name     alanadiniz.com;
    # Let's Encrypt
    location /.well-known/acme-challenge/ {
        alias /var/www/challenges/;
        try_files $uri $uri/ =404;
    }
    location / {
        return 301 https://$server_name$request_uri;
    }
}
Sonrasında, öncelikli olarak üstteki ayarların geçerli olabilmesi için nginx ayarlarını tekrar yükledin ve ardından sertifika dosyalarını sunacağınız klasörleri oluşturup acme-tiny scriptini indirin.
$ sudo service nginx reload
$ mkdir -p /etc/ssl/letsencrypt/alanadiniz.com
$ cd /etc/ssl/letsencrypt
$ wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
Sonrasında, sırasıyla, hesabınız için private key, alan adınız için CSR(Certificate Signing Request) oluşturup, acme-tiny ile imzalanmış sertifikanızı oluşturun ve son olarak da nginx için domainininize özel olan sertifika ile letsencrypt'in sağladığı sertifikayı birleştirin.
$ openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:4096 -out /etc/ssl/letsencrypt/account.key
$ openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -out /etc/ssl/letsencrypt/domain.key
Eğer alanadınızı www.alanadiniz.com, hem de alanadiniz.com olarak kaydetmek istiyorsanız(yönlendirme yapacaksanız gerekli) alttaki gibi belirtmeniz lazım.
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:alanadiniz.com,DNS:www.alanadiniz.com")) > alanadiniz.com/domain.csr
Sadece alanadiniz.com'u kaydetmek için ise alttaki komut yeterli
$ openssl req -new -sha256 -key /etc/ssl/letsencrypt/domain.key -subj "/CN=alanadiniz.com" -out /etc/ssl/letsencrypt/alanadiniz.com/domain.csr
Devamında da alttaki komutları çalıştırmanız lazım
$ python acme_tiny.py --account-key /etc/ssl/letsencrypt/account.key --csr /etc/ssl/letsencrypt/alanadiniz.com/domain.csr --acme-dir /var/www/challenges > /etc/ssl/letsencrypt/alanadiniz.com/signed.crt
$ wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > /etc/ssl/letsencrypt/chain.pem
$ cat /etc/ssl/letsencrypt/alanadiniz.com/signed.crt /etc/ssl/letsencrypt/chain.pem > fullchain.pem
An itibariyle sertifikanız hazır, bunu nginx'e tanıtması kaldı.
$ sudo nano /etc/nginx/sites-available/default
Sadece alanadiniz.com'u kaydedittiyseniz, alttaki bloklar yeterli. Sadece alanadiniz.com'u kendi alanadiniz ile değiştirin.
# HTTP'yi HTTPS'e yonlendir
server {
    listen          80;
    server_name     alanadiniz.com;

    # Let's Encrypt'in kendini updatelemesi icin burasi lazim
    location /.well-known/acme-challenge/ {
        alias /var/www/challenges/;
        try_files $uri $uri/ =404;
    }

    location / {
        return 301 https://$server_name$request_uri;
    }
}

# SSL Sunucu Bloğu

server {
    server_name alanadiniz.com;
    listen 443 ssl;

    # TLS
   ssl_certificate /etc/ssl/letsencrypt/fullchain.pem;
   ssl_certificate_key /etc/ssl/letsencrypt/domain.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    # Optimizasyon
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 20m;
    
    # Cipher
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/ssl/letsencrypt/fullchain.pem;
    
    # HSTS
    add_header Strict-Transport-Security max-age=31536000;

    # Diger Ayarlariniz
}
Eğer hem www'lu hem de www'suz olarak alanadınızı kaydettiyseniz, her ikisi için de ssl bloğunu tanımlamanız lazım.
# HTTP'yi HTTPS'e yonlendir

server {
    listen          80;
    server_name     www.alanadiniz.com alanadiniz.com;

    # Let's Encrypt'in kendini updatelemesi icin burasi lazim
    location /.well-known/acme-challenge/ {
        alias /var/www/challenges/;
        try_files $uri $uri/ =404;
    }

    location / {
        return 301 https://$server_name$request_uri;
    }
}

# SSL Sunucu Bloğu - www
server {
    server_name www.alanadiniz.com;
    listen 443 ssl;

    # yonlendirmek isterseniz alttaki satiri ekleyin
    return 301 https://alanadiniz.com$request_uri;

    # TLS
    ssl_certificate /etc/ssl/letsencrypt/fullchain.pem;
    ssl_certificate_key /etc/ssl/letsencrypt/domain.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    # Optimizasyon
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 20m;

   # Cipher
   ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/ssl/letsencrypt/fullchain.pem;  

    # HSTS
    add_header Strict-Transport-Security max-age=31536000;
}

# SSL Sunucu Bloğu - www'suz
server {
    server_name alanadiniz.com;
    listen 443 ssl;

    # TLS
    ssl_certificate /etc/ssl/letsencrypt/fullchain.pem;
    ssl_certificate_key /etc/ssl/letsencrypt/domain.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    # Optimizasyon
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 20m;   

    # Cipher
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/ssl/letsencrypt/fullchain.pem;

# HSTS
    add_header Strict-Transport-Security max-age=31536000;

    # Diger Ayarlariniz
}
Son olarak üstteki yapılandırmayı kaydedip, Nginx'i yeniden başlatmanız lazım.
$ sudo service nginx restart
An itibariyle SSL'in kurulmuş olması lazım. Eğer adımları eksiksiz takip ettiyseniz, bir problem olma olasılığı düşük, emin olmak için de bu site üzerinde, alan adınızı yazarak kontrol edebilirsiniz. Örnek olarak da bu sitenin sonuçlarını inceleyebilirsiniz.

Buraya birkaç not eklemek istiyorum, eğer güvenliğe önem veriyor ve herhangi bir SSL testinden A+ notunu almak istiyorsanız birkaç ayar yapmanız lazım. Bunların yanında eğer Internet Explorer 6 ve Windows XP'yi de desteklemek istiyorsanız, ssl_ciphers'i alttaki gibi değiştirmeniz lazım. Daha detaylı bilgi için mozilla'nın hazırladığı linki inceleyebilirsiniz. Ancak en azından aklınızda bulunması için belirtmek isterim ki AES dışındaki tüm cipherler, örneğin DES, 3DES, RC4 veya MD5 yeteri kadar güvenli bulunmuyor.
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
Güvenlik seviyesini arttırmak için, öncelikli olarak Diffie Hellman yapılandırmasını güçlendirmemiz lazım. Bunun için alttaki komutu çalıştırın, muhtemelen 10 dakikadan fazla sürecektir, o yüzden sabretmeniz önemli.
$ openssl dhparam -out /etc/ssl/private/dhparams_4096.pem 4096
Daha sonrasında da SSL bloğuna/bloklarınıza alttaki satırı eklemeniz lazım.
ssl_dhparam /etc/ssl/private/dhparams_4096.pem;
Geriye bir tek Let's Encrypt'in kendisini otomatik olarak upgrade etmesini sağlamak kaldı. Bunun sebebi de sertifikaların ömrünün sadece 90 gün olması. Let's encrypt'i yüklediğimiz dizine dönüp, orada renew.sh adında bir shell script dosyası oluşturalım.
$ cd /etc/ssl/letsencrypt && nano renew.sh
Dosyayı da alttaki gibi düzenleyin, dizin(sunucunun çalıştığı root dizin) ve alanadiniz.com kısımlarını düzenlemeyi unutmayın.
#!/usr/bin/sh
python /etc/ssl/letsencrypt/acme_tiny.py --account-key /etc/ssl/letsencrypt/account.key --csr /etc/ssl/letsencrypt/alanadiniz.com/domain.csr --acme-dir /var/www/challenges/ > /tmp/signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > /etc/ssl/letsencrypt/chain.pem
cat /tmp/signed.crt /etc/ssl/letsencrypt/chain.pem > /etc/ssl/letsencrypt/fullchain.pem
service nginx reload
Ayrıca dosyayı çalıştırılabilir(executable) hale getirin.
$ chmod +x renew.sh
Son olarak da bunu crontab'a eklemesi kaldı. Onun için de,
$ crontab -e
Gelen ekranda da alttaki gibi ekleyebilirsiniz. Alttaki ayara göre, her ayın 5'inde, saat 00:01'de let's encrypt sertifikanız güncellenecek ve logları da /var/log/letsencrypt-renewal.log olarak kaydedilecek.
1 0 5 * * /bin/sh /etc/ssl/letsencrypt/renew.sh >> /var/log/letsencrypt-renewal.log
Eğer tüm adımları takip ettiyseniz A+ nota sahip, her ay kendisini otomatik olarak yenileyen SSL kurulumunu tamamlamış oldunuz.