Bizi Takip Edin!

Azure Application Gateway Üzerindeki Let’s Encrypt Sertifikalarını Yenilemek

Azure Application Gateway Üzerindeki Let’s Encrypt Sertifikalarını Yenilemek

Azure üzerindeki projelerimizde API yönetimi ve SSL sonlandırma için Azure Application Gateway servisini kullanıyoruz. SSL sertifikaları için ise aksi yönde iyi bir gerekçe olmadıkça Let’s Encrypt tercih ediyoruz. Let’s Encrypt sertifikaları 90 günlük geçerlilik süresine sahip olduğu ve Application Gateway üzerindeki sertifikaların yenilenmesini elle yaptığımız için bu iş düzenli bir “angarya” olarak önümüze çıkıp duruyordu.

Her “eeh, yeter” dediğimde yaptığım araştırmalar sonucunda hiç de hoşuma gitmeyen çözümler ile karşılaştım. Kimisi bir Azure Automation hesabı açıp, en son 2 yıl önce güncellenmiş bir Powershell betiğini kopyalayıp yapıştırmamı, kimisi bu işe özel bir sanal makine yaratıp, işlemi burada yapmamı ve bu süreci otomatikleştirmemi, kimisi de Azure Devops kullanmamı öneriyordu. Kendimize uygun bir çözüm bulmak için kolları sıvamaktan başka çare yoktu.

 

Manuel süreç

Çözüme geçmeden önce sorundan da bahsetmek gerekiyor. Azure üzerindeki servislerimizin tamamı App Service platformu üzerinde Docker konteynerleri olarak çalışıyor. Dolayısıyla sıradan sanal makineler gibi SSH yapabileceğimiz veya crontab tanımlayabileceğimiz bir ortama sahip değiliz. SSL sertifikalarımızın geçerlilik sürelerini takip edip yakın zamanda geçersiz hale gelecek sertifikalar için aşağıdaki adımları uygulaman gerekiyordu:

  1. Kendi bilgisayarımda certbot imajını kullanarak yeni bir konteyner yaratmak
  2. “certbot certonly –manual” ile yeni sertifika alma sürecini başlatmak
  3. Doğrulama kodunu kopyalayarak yeni bir dosya yaratmak
  4. Let’s Encrypt sunucuları tarafından isteğimin onaylanabilmesi için yarattığım dosyayı Azure Blob Storage üzerinde herkese açık bir konteynere koymak
  5. Sertifikayı alıp “openssl” ile “pfx” olarak kaydetmek
  6. Terraform projemizdeki eski “pfx” dosyasını yenisiyle değiştirmek
  7. Terraform değişikliklerini uygulamak

En hafif tabiriyle iğrenç ve hataya çok açık bir süreç izliyordum. Terraform değişiklik planında uygulanmamış bir değişikliği gözden kaçırmak son derece kolaydı ve ciddi sonuçlara yol açabilirdi (bir Azure Application Gateway değişikliği için Terraform’un çıkarttığı planı hiç gördünüz mü?). Aynı zamanda hiçbir şekilde belgelendirilmemiş bir süreçti, zira ne zaman bir belge yazmaya kalksam “eeh, yeter” deyip süreci otomatikleştirme araştırmaları yapmaya koyuluyordum.

 

Let’s Encrypt güncelleme çözümümüz

Her şey, certbot’un “–manual-auth-hook” özelliğini keşfetmemle kolaylaştı. Bu keşif ile birlikte sürecin tamamını Gitlab CI kullanarak otomatikleştirebildim. “–manual-auth-hook” seçeneğinin yaptığı şey çok basit: Let’s Encrypt’ten dönen doğrulama kodunu belirlediğimiz betiğe yönlendiriyor ve kendi doğrulama mekanizmamızı oluşturmamıza olanak tanıyor. Doğrulama için aşağıdaki gibi bir betik yazdım:

#!/bin/sh

ACME_CHALLENGE_DIR=.well-known/acme-challenge
ACME_CHALLENGE_PATH="$ACME_CHALLENGE_DIR"/"$CERTBOT_TOKEN"

mkdir -p "$ACME_CHALLENGE_DIR"
echo "$CERTBOT_VALIDATION" > "$ACME_CHALLENGE_PATH"

az storage blob upload \
    --connection-string "$ACME_CHALLENGE_BLOB_CONNECTION_STRING" \
    --container-name "$ACME_CHALLENGE_BLOB_CONTAINER_NAME" \
    --file "$ACME_CHALLENGE_PATH" \
    --name "$ACME_CHALLENGE_PATH

Hali hazırda Let’s Encrypt doğrulama isteklerini karşılamak için Blob Storage adresine yönlendirme kurallarımız tanımlıydı. Yukarıdaki betikle de doğrulama sürecini otomatikleştirdikten sonra tek yapmam gereken adımları bir sıraya koymak oldu:

stages:
  - letsencrypt

renew:
  stage: letsencrypt
  image:
    name: certbot/certbot:latest
    entrypoint: [""]
  script:
    - apk update
    - apk add gcc make python3-dev musl-dev openssl-dev
    - python -m venv venv
    - source venv/bin/activate
    - pip install --upgrade pip setuptools wheel
    - pip install azure-cli
    - az login -u $AZ_ACCOUNT_EMAIL -p $AZ_ACCOUNT_PASSWORD
    - az account set --subscription $AZ_SUBSCRIPTION_ID
    - certbot certonly --manual --preferred-challenges=http --manual-auth-hook letsencrypt/blob_acme_challenge.sh -d $DOMAIN -m $CERTBOT_CONTACT_EMAIL --agree-tos --non-interactive --manual-public-ip-logging-ok
    - openssl pkcs12 -export -out $DOMAIN.pfx -inkey /etc/letsencrypt/live/$DOMAIN/privkey.pem -in /etc/letsencrypt/live/$DOMAIN/cert.pem -certfile /etc/letsencrypt/live/$DOMAIN/chain.pem -password env:PFX_PASSWORD
    - az network application-gateway ssl-cert update --resource-group $AZ_RESOURCE_GROUP_NAME --gateway-name $AZ_APP_GATEWAY_NAME --name $DOMAIN --cert-file $DOMAIN.pfx --cert-password $PFX_PASSWORD
  only:
    - web
    - api

Hepsi bu kadar! Artık kendi kendini belgeleyen ve herkesin rahatlıkla yapabileceği bir sürecimiz oldu.

Süreç, GitLab arayüzünden tetiklenebilir:

Let's Encrypt güncellemesini GitLab üzerinden tetikleyebilirsiniz.

Tarayıcı değil de terminal insanıysanız gitlabci aracılığıyla yenilemeyi tetikleyebilirsiniz:

$ gitlabci pipeline create group/project master -e DOMAIN=api.example.com

Gelecekte periyodik tetikleme özelliğini de kullanabilir ve insan faktörünü tamamen devre dışı bırakabiliriz. Bunun için Application Gateway’de gereksiz değişiklikler yapılmasının önüne geçmek gerekiyor. Yine de şu anki haliyle dahi hoşuma giden ve bize uygun bir çözüm bulduğumuzu düşünüyorum.

Ege Güneş

Ege Güneş, İstanbul Üniversitesi Hukuk Fakültesi'nden mezun oldu. Günlük yaşamında özgür yazılımlardan yana ve Linux kullanıyor. Favori dağıtımıysa Fedora.

1 Yorum

Yorum Yaz

Yorum
İsim
E-Posta
Website