Cloudflare API Token Oluşturma ve Güvenli Kullanım Rehberi
Cloudflare ile çalışan herkes er ya da geç API token meselesine takılır. “Global API Key neden önerilmiyor?”, “Token izinlerini nasıl ayarlayayım?”, “Bu token’ı sunucuda güvenli şekilde saklayabilir miyim?” gibi sorular sysadmin hayatının kaçınılmaz parçası haline geliyor. Bu yazıda bu soruların hepsine yanıt verirken, gerçek dünya senaryolarıyla konuyu somutlaştıracağım.
Neden Global API Key Kullanmamalısınız
Cloudflare hesabınıza ilk girdiğinizde “My Profile > API Tokens” bölümünde iki farklı şey görürsünüz: API Tokens ve Global API Key. Global API Key, tüm Cloudflare hesabınıza tam erişim sağlar. Zone silmekten fatura bilgilerine kadar her şeye. Bu anahtarı bir yerde sızdırdığınızda hesabınızın tamamı ele geçirilmiş olur.
API Token sistemi ise 2019 yılında hayata geçirildi ve çok daha granüler bir izin yönetimi sunuyor. Bir token sadece belirli zone’lardaki DNS kayıtlarını okuyabilir, başka bir token belirli bir zone’a sertifika yönetimi yapabilir. Least privilege prensibinin Cloudflare tarafında uygulaması bu şekilde çalışıyor.
Pratikte fark şu: Bir CI/CD pipeline’ınızda DNS doğrulaması için kullanılan token sızdırıldığında sadece o zone’daki DNS kayıtlarını etkileyebilir. Global API Key sızdırıldığında ise tüm hesabınız risk altına girer.
API Token Oluşturma
Cloudflare Dashboard Üzerinden
Cloudflare dashboard’a giriş yapıp sağ üstteki profil ikonuna tıklayın. My Profile menüsünden API Tokens sekmesine geçin. Burada Create Token butonunu göreceksiniz.
Cloudflare size iki seçenek sunuyor: Hazır şablonlar ya da sıfırdan oluşturma. Hazır şablonlar çoğu zaman işinize yarar ancak izin setini mutlaka kontrol edin. “Edit zone DNS” şablonu DNS kaydı düzenleme için yeterli çoğu durumda.
Sıfırdan token oluştururken dikkat etmeniz gereken alanlar:
- Token name: Anlamlı bir isim verin. “test-token” değil, “prod-certbot-dns-validation” gibi bir isim kullanın
- Permissions: İzin setini olabildiğince kısıtlı tutun
- Zone Resources: Tüm zone’lara değil, spesifik zone’a erişim verin
- IP Address Filtering: Sadece belirli IP’lerden kullanılmasını zorunlu kılın
- TTL: Token’ın geçerlilik süresini belirleyin
API Üzerinden Token Oluşturma
Mevcut bir token’ınız varsa (ya da Global API Key kullanmak zorundaysanız geçici olarak) API üzerinden yeni token oluşturabilirsiniz:
curl -X POST "https://api.cloudflare.com/client/v4/user/tokens"
-H "Authorization: Bearer MEVCUT_TOKEN"
-H "Content-Type: application/json"
--data '{
"name": "certbot-dns-validation",
"policies": [
{
"effect": "allow",
"resources": {
"com.cloudflare.api.account.zone.ZONE_ID": "*"
},
"permission_groups": [
{
"id": "c8fed203ed3043cba015a93ad1616f1f",
"name": "Zone Read"
},
{
"id": "4755a26eedb94da69e1066d98aa820be",
"name": "DNS Write"
}
]
}
],
"not_before": "2024-01-01T00:00:00Z",
"expires_on": "2024-12-31T23:59:59Z"
}'
Zone ID’nizi bulmak için:
curl -X GET "https://api.cloudflare.com/client/v4/zones?name=orneksite.com"
-H "Authorization: Bearer TOKEN"
-H "Content-Type: application/json" | jq '.result[0].id'
Token’ı Test Etme
Oluşturduğunuz token’ın çalışıp çalışmadığını ve doğru izinlere sahip olduğunu kontrol edin:
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify"
-H "Authorization: Bearer YENI_TOKEN"
-H "Content-Type: application/json"
Başarılı yanıt şöyle görünür:
{
"result": {
"id": "token-id-buraya",
"status": "active"
},
"success": true,
"errors": [],
"messages": [
{
"code": 10000,
"message": "This API Token is valid and active",
"type": null
}
]
}
Gerçek Dünya Senaryoları
Senaryo 1: Certbot ile Let’s Encrypt DNS Doğrulaması
Wildcard sertifika alırken DNS-01 challenge kullanmak zorundasınız. Bu durumda Certbot’un Cloudflare DNS üzerinde TXT kaydı oluşturabilmesi gerekiyor.
Önce Certbot Cloudflare eklentisini kurun:
# Ubuntu/Debian
apt install python3-certbot-dns-cloudflare
# Ya da pip ile
pip3 install certbot-dns-cloudflare
Credentials dosyasını oluşturun. Bu dosyaya sadece root erişimi olsun:
mkdir -p /etc/letsencrypt/cloudflare
cat > /etc/letsencrypt/cloudflare/credentials.ini << 'EOF'
dns_cloudflare_api_token = BURAYA_TOKEN_GELECEK
EOF
chmod 600 /etc/letsencrypt/cloudflare/credentials.ini
chown root:root /etc/letsencrypt/cloudflare/credentials.ini
Bu token için sadece DNS Write iznine ihtiyacınız var, o zone için:
certbot certonly
--dns-cloudflare
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini
-d "orneksite.com"
-d "*.orneksite.com"
--preferred-challenges dns-01
Senaryo 2: Ansible ile DNS Yönetimi
Birden fazla zone’da DNS kayıtlarını Ansible ile yönetiyorsanız, token’ı Ansible Vault ile şifreleyerek saklayın:
# Önce vault şifresi dosyası oluşturun
echo "guclu-bir-sifre" > ~/.ansible/vault_pass
chmod 600 ~/.ansible/vault_pass
# Token'ı vault'a ekleyin
ansible-vault encrypt_string 'CLOUDFLARE_TOKEN_BURAYA'
--name 'cloudflare_api_token'
--vault-password-file ~/.ansible/vault_pass
Çıktıyı group_vars/all.yml dosyanıza ekleyin. Ardından playbook’unuzda:
- name: DNS kaydı ekle
community.general.cloudflare_dns:
zone: orneksite.com
record: mail
type: MX
value: mail.orneksite.com
priority: 10
api_token: "{{ cloudflare_api_token }}"
state: present
Bu yaklaşımda token git repository’sine şifreli halde gidiyor. Vault şifresi ise sadece CI/CD sisteminde environment variable olarak tutuluyor.
Senaryo 3: Terraform ile Infrastructure as Code
Cloudflare Terraform provider’ı token bazlı çalışıyor. Token’ı environment variable olarak geçirmek en temiz yöntem:
export CLOUDFLARE_API_TOKEN="BURAYA_TOKEN_GELECEK"
Terraform dosyanızda:
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
variable "cloudflare_api_token" {
description = "Cloudflare API Token"
sensitive = true
}
resource "cloudflare_record" "www" {
zone_id = var.zone_id
name = "www"
value = "192.0.2.1"
type = "A"
ttl = 300
}
terraform.tfvars dosyasını asla git’e commit etmeyin. .gitignore‘a ekleyin:
echo "*.tfvars" >> .gitignore
echo ".terraform/" >> .gitignore
Production’da token’ı Terraform Cloud ya da HashiCorp Vault’tan çekin, düz dosyada tutmayın.
Token Güvenliği: Pratik Önlemler
Environment Variable Yönetimi
Token’ları bash script’lerinizde hard-code etmek en sık yapılan hatalardan biri. Şöyle bir yapı kurun:
#!/bin/bash
# Kötü yöntem - ASLA yapmayın
# CF_TOKEN="abc123xyz"
# İyi yöntem
if [ -z "${CF_API_TOKEN}" ]; then
echo "Hata: CF_API_TOKEN environment variable tanımlı değil"
exit 1
fi
# Token'ı kullan
curl -X GET "https://api.cloudflare.com/client/v4/zones"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json"
Secrets Management Sistemi Kullanımı
Eğer HashiCorp Vault kullanıyorsanız, token’ları oradan dinamik olarak çekin:
# Vault'tan token çek
CF_API_TOKEN=$(vault kv get -field=api_token secret/cloudflare/prod)
# Script boyunca kullan
export CF_API_TOKEN
# Script bitiminde temizle
cleanup() {
unset CF_API_TOKEN
}
trap cleanup EXIT
Token Rotasyonu
Token’ları periyodik olarak rotate etmek iyi bir pratik. Bunu otomatize etmek için:
#!/bin/bash
# token-rotate.sh
OLD_TOKEN="${CF_API_TOKEN}"
ZONE_ID="${CF_ZONE_ID}"
TOKEN_NAME="certbot-prod-$(date +%Y%m)"
# Yeni token oluştur
NEW_TOKEN_RESPONSE=$(curl -s -X POST
"https://api.cloudflare.com/client/v4/user/tokens"
-H "Authorization: Bearer ${OLD_TOKEN}"
-H "Content-Type: application/json"
--data "{
"name": "${TOKEN_NAME}",
"policies": [
{
"effect": "allow",
"resources": {
"com.cloudflare.api.account.zone.${ZONE_ID}": "*"
},
"permission_groups": [
{"id": "4755a26eedb94da69e1066d98aa820be", "name": "DNS Write"}
]
}
]
}")
NEW_TOKEN=$(echo "${NEW_TOKEN_RESPONSE}" | jq -r '.result.value')
if [ -z "${NEW_TOKEN}" ] || [ "${NEW_TOKEN}" == "null" ]; then
echo "Token oluşturma başarısız!"
exit 1
fi
echo "Yeni token oluşturuldu"
# Buradan sonra yeni token'ı Vault ya da secrets manager'a kaydedin
# vault kv put secret/cloudflare/prod api_token="${NEW_TOKEN}"
İzin Grupları Referansı
Cloudflare’in sunduğu temel izin grupları ve ne zaman kullanılacakları:
- Zone Read: Zone bilgilerini okumak için. Monitoring araçları için yeterli
- DNS Read: DNS kayıtlarını listelemek için. Audit amaçlı
- DNS Write: DNS kayıtlarını oluşturmak, güncellemek, silmek için. Certbot ve DNS yönetim araçları için gerekli
- Cache Purge: CDN cache’ini temizlemek için. Deploy pipeline’larında kullanışlı
- Page Rules: Page rule’ları yönetmek için. CI/CD deployment’larında gerekebilir
- SSL and Certificates: Sertifika yönetimi için
- Firewall Services: WAF kural yönetimi için. Güvenlik otomasyonlarında kullanılır
- Workers Scripts: Cloudflare Workers deploy etmek için
- Account Settings Read: Hesap ayarlarını okumak için. Genel olarak gerekmez
Monitoring ve Alerting
Token kullanımını izlemek için Cloudflare’in audit log özelliğini kullanın:
#!/bin/bash
# audit-log-kontrol.sh
# Son 24 saatteki API aktivitelerini çek
SINCE=$(date -u -d '24 hours ago' '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null ||
date -u -v-24H '+%Y-%m-%dT%H:%M:%SZ')
curl -s -X GET
"https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/audit_logs?since=${SINCE}&action_type=delete"
-H "Authorization: Bearer ${CF_API_TOKEN}"
-H "Content-Type: application/json" |
jq '.result[] | {action: .action.type, actor: .actor.email, resource: .resource.type, when: .when}'
Cloudflare ayrıca token üzerinden çok fazla hatalı istek geldiğinde sizi uyarabilir. Dashboard’dan Notifications bölümünde bunu aktive edebilirsiniz.
IP Kısıtlaması Eklemek
Token oluştururken ya da sonradan IP kısıtlaması eklemek güvenlik katmanı sağlar. Örneğin sadece CI/CD sunucunuzun IP’sinden kullanılabilir hale getirin:
curl -X PUT "https://api.cloudflare.com/client/v4/user/tokens/TOKEN_ID"
-H "Authorization: Bearer YONETIM_TOKENI"
-H "Content-Type: application/json"
--data '{
"name": "certbot-prod",
"status": "active",
"policies": [...],
"condition": {
"request.ip": {
"in": ["203.0.113.10/32", "203.0.113.11/32"]
}
}
}'
Dinamik IP’niz varsa bu özelliği kullanmak zorlaşıyor. Bu durumda en azından TTL ayarlayın ve token’ları kısa ömürlü tutun.
Sık Yapılan Hatalar
Token’ı git’e commit etmek: git secret, git-crypt ya da .gitignore kullanın. Bunu bir kez yaparsanız token’ı hemen revoke edin ve yenisini oluşturun. GitHub’un secret scanning özelliği sizi uyarabilir ama iş işten geçmiş olabilir.
Tek token her şeye: “Her şeye izin” veren tek bir token kullanmak yerine amaç bazlı token’lar oluşturun. Certbot için ayrı, Terraform için ayrı, monitoring için ayrı.
Token’ları paylaşmak: Ekip üyeleriyle token paylaşmak yerine her birine ayrı token oluşturun. Birisi ayrıldığında sadece o token’ı revoke etmeniz yeterli olur.
Expiry tarihini unutmak: Token’a expiry tarihi koyup sonra otomasyonunuzun durduğunu fark etmemek yaygın bir sorun. Token expiry’lerini monitoring sisteminize ekleyin.
Hata mesajlarını log’a yazmak: Authorization header’ı ya da token’ın kendisini log dosyasına yazmayın. Uygulama logları genellikle daha az korumalı yerlerde tutuluyor.
Token’ları Revoke Etme
Bir token’ı artık kullanmıyorsanız ya da sızdığını düşünüyorsanız hemen revoke edin:
# Dashboard üzerinden: API Tokens > token yanındaki "..." > Delete
# API üzerinden:
curl -X DELETE "https://api.cloudflare.com/client/v4/user/tokens/TOKEN_ID"
-H "Authorization: Bearer YONETIM_TOKENI"
-H "Content-Type: application/json"
Revoke ettiğiniz token anında geçersiz hale gelir. Bu token’ı kullanan sistemleri yeni token ile güncellemeyi unutmayın.
Sonuç
Cloudflare API Token yönetimi, “oluştur ve unut” zihniyetiyle yaklaşılacak bir konu değil. Least privilege, token rotasyonu ve secrets management üçlüsü bu işin temel direkleri.
Kısaca yapmanız gerekenler şunlar: Her uygulama ya da otomasyon için ayrı, minimum izinli token oluşturun. Token’ları environment variable ya da secrets manager üzerinden geçirin, dosyaya yazmaktan kaçının. IP kısıtlaması ve TTL ekleyerek token’ın potansiyel zararını sınırlandırın. Audit logları takip ederek anormal aktiviteleri erken fark edin. Token rotasyonunu otomatize edin.
Global API Key’i tamamen bir kenara bırakın. Evet, daha kolay görünüyor ama o kolaylık bir güvenlik açığından başka bir şey değil. Birkaç dakika daha harcayıp granüler token oluşturmak uzun vadede çok daha az baş ağrısı demek.
Eğer henüz Hashicorp Vault ya da benzeri bir secrets management sistemi kullanmıyorsanız, küçük ortamlar için bile Ansible Vault ya da basit bir şifreli credential dosyası sistemi kurmak değer. Bu işi ciddiye aldığınızda, Cloudflare API token yönetimi gerçekten sorunsuz çalışan bir parça haline geliyor.
