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

18 Ocak 2016

Let's Encrypt herkese açık olarak Mozilla öncülüğünde birçok şirketin destekleriyle geliştirilmiş bedava SSL/TLS sağlayıcısıdır. Firefox, Chrome, Safari gibi önde gelen tüm tarayıcılar tarafından desteklenen bu sertifikayı yüklemek ise gayet basittir. Bu makalede ise nginx yüklü Ubuntu sunucuda Let's Encrypt SSL sertifikasının kurulumunu Github üzerinden kaynak kodlarını inceleyebileceğiniz acme-tiny adlı ufak bir script aracılığı ile yapacağız.

acme-tiny ve Sunucu Ayarları

Öncelikli olarak, sertifikayı yükleyebilmeniz ve acme-tiny ile doğrulama yapabilmeniz için alan adınız üzerinden .well-known/acme-challenge/ adresini sunabilmeniz gerekmektedir. Bu sebeple alttaki komutlar ile sunucu ayarlarınızı gerçeklemeniz lazımdır.

$ 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

SSL Sertifikası Oluşturma

Let's Encrypt aracılığı ile SSL sertifikasını oluşturmak için, 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şturup, son olarak da nginx için domainininize özel olan sertifika ile Lets Encrypt'in sağladığı sertifikayı birleştirmeniz gerekmektedir.

$ 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 alan adı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ı.

nginx SSL Blokları

Yeni oluşturduğunuz SSL sertifikasını kullanabilmek için, bu sertifikayı nginx SSL bloğunda belirtmeniz gerekir.

$ 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.

Opsiyonel: Ekstra SSL Güvenliği

Eğer güvenliğe önem veriyor ve herhangi bir SSL testinden A+ notunu ya da puanını 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;

Opsiyonel: Otomatik SSL Yenileme

Let's Encrypt ile oluşturulan SSL sertifikalarını otomatik olarak yenilemek isteyebilirsiniz. Bunun sebebi de sertifikaların ömrünün sadece 90 gün olması. Bunun için 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.