Docker ile Otomatik Let’s Encrypt

Web sitelerini, API’ları ve dış dünyaya açılacak neredeyse her sistemi yayına alma aşamasında, kullanıcıların güvenliğini ve servisler arasındaki güvenliği sağlamak için TLS sertifikalarına ihtiyacımız oluyor. Çoğu zaman da, Let’s Encrypt ve benzer TLS sertifika sağlayıcılarından ücretsiz olarak sertifika almak pratik ve hızlı bir çözüm oluyor. Servislerimizi Docker kullanarak yayına aldığımızda ise bizi farklı bir dünya karşılıyor. Yayına alma süreci; sertifika ekleme, değiştirme, güncelleme süreçlerin normalde yaptığımız gibi ilerlemesi zorlaşıyor. Certbot gibi sertifika alma ve Nginx/Apache ayarlarını bu sertifikaya göre otomatik yapan araçlar ise genellikle uzun uzun uğraşmadan kullanılamaz duruma geliyor. Bu yazıda, Docker’a Let’s Encrypt üzerinden nasıl otomatik olarak sertifika aldıracağımızı göreceğiz ve bunu sadece 2 komut kullanarak yapacağız.

Nginx Proxy’nin ayağa kaldırılması

Öncelikle, gelen istekleri karşılaması için bir Nginx ayağa kaldıracağız. Bizim containerlarımıza gelecek istekleri bu container karşılayacak.

Yeni bir container açıldığında, üzerinde web servisi varsa bu containerın dış dünyaya otomatik açılmasını istiyoruz. Mesela peptr.net adresine gelen isteklerin ilgili containera yönlendirilmesini, kubeforscale.com adresine gelenlerin ise farklı bir containera yönlendirilmesini istiyoruz. Nginx konfigürasyonu ile uğraşmadan bunu yapmanın bir yolu var. Nginx-proxy imajını kullanarak bu yönlendirmeyi otomatik olarak yapabiliriz.

Nginx-proxy’nin detaylarına ilgili yazıdan bakabilirsiniz.

docker run \
    --detach \
    --name nginx-proxy \
    --publish 80:80 \
    --publish 443:443 \
    --volume /etc/nginx/certs \
    --volume /etc/nginx/vhost.d \
    --volume /usr/share/nginx/html \
    --volume /var/run/docker.sock:/tmp/docker.sock:ro \
    -e ENABLE_IPV6=true \
    jwilder/nginx-proxy

Bu komut çalıştıktan sonra, Nginx üzerinden trafik yönlendirilmesini istediğimiz containerları çalıştırırken bir parametre eklememiz yeterli oluyor. Örneğini Let’s Encrypt’ten sonra göreceğiz.

Domainler İçin Otomatik Let’s Encrypt Sertifikası

Açılan containerlar önceki başlıkta yazılı olan komut çalıştıktan sonra otomatik olarak istek almaya başlayacaklar. Yani Nginx ayarları otomatik olarak yapılmış olacak. Yine de, TLS üzerinden güvenli haberleşme için eklenen her alan adı için bir sertifika verilmesi veya otomatik olara Let’s Encrypt gibi bir sağlayıcıdan alınması gerekiyor. Bu noktada devreye Let’s Encrypt Nginx Proxy Companion giriyor.

Let’s Encrypt Nginx Proxy Companion ile, açılan containerlara göre Nginx konfigürasyonu yapılırken bir yandan da otomatik olarak Let’s Encrypt’ten sertifika alınıyor. Bu sayede, DNS yönlendirmesini tamamladığınız alan adlarına ait otomatik olarak sertifika alma ve otomatik olarak yenileme şansımız var. Yani yenilemek için de bir şey yapmamız gerekmiyor, gözden kaçan bir sorun olmaması için takibini yapmak yeterli.

docker run \
    --detach \
    --name nginx-proxy-letsencrypt \
    --volumes-from nginx-proxy \
    --volume /var/run/docker.sock:/var/run/docker.sock:ro \
    --env "DEFAULT_EMAIL=example@example.com" \
    jrcs/letsencrypt-nginx-proxy-companion

Bir Containera Let’s Encrypt’ten Otomatik Sertifika Almak

Yazdığımız iki komut gerçekten yeterli! Artık bir containerı Docker ile başlatırken, eğer trafik gelmesini, Nginx’in otomatik yapılandırılmasını, Let’s Encrypt’ten otomatik sertifika alınmasını istiyorsak sadece parametrelerle bunu söyleyebiliyoruz. Örneğin:

docker run -d \
    --name websitem \
    -e "VIRTUAL_HOST=www.peptr.net" \
    -e "LETSENCRYPT_HOST=www.peptr.net" \
    nginx

Bu komut bir Nginx containeri başlatacak. Varsayılan olarak Nginx imajı içerisinde bir karşılama sayfasının bizi beklemesi gerekiyor. Docker’a -e parametreleri ile verdiğimiz iki environment değişkeni görüyoruz. VIRTUAL_HOST ile Nginx konfigürasyonuna hangi domainlerin yazılacağını söylüyoruz. LETSENCRYPT_HOST ile ise sertifikanın hangi domainler için alınacağını söylüyoruz.

Sonuç

Ortam değişkenleri, yani environmentlarını kullanarak istediğimiz alan adlarını Docker’a söyleyebiliyoruz. Bir önceki başlıkta yazan komutu birden çok kez farklı alan adları için çalıştırabiliriz.