Sistem yöneticiliğinde sertifika yönetimi, özellikle iç altyapıda kendi CA’nızı kurmak istediğinizde, kaçınılmaz olarak openssl komutuyla yüzleşmek anlamına gelir. Uzun parametreleri, kriptik hata mesajları ve onlarca farklı kullanım senaryosuyla openssl başlangıçta ürkütücü görünebilir. Ama bir kez mantığını kavradığınızda, bu araç inanılmaz derecede güçlü ve esnek bir yapı sunuyor. Bu yazıda sıfırdan başlayarak kendi Certificate Authority’nizi oluşturacak, sunucu sertifikaları imzalayacak ve gerçek hayatta karşılaşacağınız senaryoları ele alacağız.
Temel Kavramlar: CA, CSR ve Sertifika Zinciri
Başlamadan önce zihinsel modeli oturtmak lazım. SSL/TLS dünyasında üç temel aktör var:
- CA (Certificate Authority): Sertifikaları imzalayan ve güven kaynağı olan otorite. Kendi altyapınız için self-signed bir root CA oluşturabilirsiniz.
- CSR (Certificate Signing Request): Sertifika almak isteyen tarafın oluşturduğu istek dosyası. İçinde public key ve kimlik bilgileri bulunur.
- Sertifika (.crt/.pem): CA tarafından imzalanmış, kullanıma hazır sertifika dosyası.
Akış şu şekilde işler: Önce bir private key oluşturursunuz, bu key ile CSR yaratırsınız, CSR’yi CA’ya gönderirsiniz (ya da kendiniz imzalarsınız), CA sertifikayı imzalar ve size geri döner. Prodüksiyon ortamında bu CA genellikle Let’s Encrypt veya DigiCert gibi güvenilir bir otorite olurken, internal sistemlerde kendi CA’nızı kurabilirsiniz.
Root CA Oluşturma
İlk adım olarak kendi Root CA’mızı oluşturalım. Bu CA, daha sonra imzalayacağımız tüm sertifikaların güven kaynağı olacak.
# CA için dizin yapısını oluştur
mkdir -p /opt/myca/{certs,crl,newcerts,private}
chmod 700 /opt/myca/private
touch /opt/myca/index.txt
echo 1000 > /opt/myca/serial
# CA private key oluştur (4096-bit RSA)
openssl genrsa -aes256 -out /opt/myca/private/ca.key.pem 4096
chmod 400 /opt/myca/private/ca.key.pem
Burada -aes256 parametresi private key’i şifreli saklamak için kullanılıyor. CA key’i için bu şifreleme önerilir çünkü bu dosya ele geçirilirse tüm altyapınız tehlikeye girer. Sunucu sertifikaları için ise genellikle şifresiz key tercih edilir (servis restart’larında sorun çıkmasın diye).
Şimdi root CA sertifikasını oluşturalım:
openssl req -key /opt/myca/private/ca.key.pem
-new -x509
-days 7300
-sha256
-extensions v3_ca
-out /opt/myca/certs/ca.cert.pem
-subj "/C=TR/ST=Istanbul/L=Istanbul/O=MyCompany/OU=IT/CN=MyCompany Root CA"
-x509: Bu parametre direkt sertifika oluşturur, CSR oluşturmaz. Sadece CA sertifikaları için kullanılır. -days 7300: 20 yıl geçerlilik süresi. Root CA’lar genellikle uzun ömürlü olur. -subj: Interaktif soru sormadan subject bilgisini komut satırından geçirir.
Oluşan sertifikayı doğrulayalım:
openssl x509 -in /opt/myca/certs/ca.cert.pem -noout -text | head -50
Intermediate CA Oluşturma (Opsiyonel ama Önerilen)
Prodüksiyon ortamlarında root CA’yı direkt kullanmak yerine bir intermediate (ara) CA kullanmak güvenlik açısından çok daha iyi bir pratik. Root CA’yı offline tutup intermediate CA ile imzalama işlemleri yapabilirsiniz. Root CA ele geçirilirse tüm altyapı çöker, ama intermediate CA ele geçirilirse sadece o CA’yı revoke edip yeni bir tane oluşturursunuz.
# Intermediate CA dizini
mkdir -p /opt/myca/intermediate/{certs,crl,csr,newcerts,private}
chmod 700 /opt/myca/intermediate/private
touch /opt/myca/intermediate/index.txt
echo 1000 > /opt/myca/intermediate/serial
# Intermediate CA key
openssl genrsa -aes256 -out /opt/myca/intermediate/private/intermediate.key.pem 4096
# Intermediate CA için CSR oluştur
openssl req -key /opt/myca/intermediate/private/intermediate.key.pem
-new -sha256
-out /opt/myca/intermediate/csr/intermediate.csr.pem
-subj "/C=TR/ST=Istanbul/L=Istanbul/O=MyCompany/OU=IT/CN=MyCompany Intermediate CA"
# Root CA ile imzala
openssl ca -config /opt/myca/openssl.cnf
-extensions v3_intermediate_ca
-days 3650
-notext
-md sha256
-in /opt/myca/intermediate/csr/intermediate.csr.pem
-out /opt/myca/intermediate/certs/intermediate.cert.pem
Sunucu Sertifikası Oluşturma ve İmzalama
Artık günlük işlerinizde en sık yapacağınız şeye geldik: bir web sunucusu ya da servis için sertifika oluşturmak. Diyelim ki api.sirket.local ve web.sirket.local için sertifika gerekiyor.
Modern tarayıcılar Subject Alternative Names (SAN) olmadan sertifikaları reddediyor. Bu yüzden SAN desteği için bir config dosyası kullanmak şart.
# SAN destekli CSR config dosyası oluştur
cat > /tmp/api-sirket-local.cnf << EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext
[dn]
C = TR
ST = Istanbul
L = Istanbul
O = MyCompany
OU = IT
CN = api.sirket.local
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = api.sirket.local
DNS.2 = api-internal.sirket.local
IP.1 = 192.168.1.50
EOF
# Private key oluştur (şifresiz, servis için)
openssl genrsa -out /tmp/api.sirket.local.key 2048
# CSR oluştur
openssl req -new
-key /tmp/api.sirket.local.key
-out /tmp/api.sirket.local.csr
-config /tmp/api-sirket-local.cnf
CSR içeriğini kontrol etmek her zaman iyi bir alışkanlık:
openssl req -in /tmp/api.sirket.local.csr -noout -text | grep -A 10 "Subject Alternative"
Şimdi CSR’yi CA ile imzalayalım:
openssl x509 -req
-in /tmp/api.sirket.local.csr
-CA /opt/myca/intermediate/certs/intermediate.cert.pem
-CAkey /opt/myca/intermediate/private/intermediate.key.pem
-CAcreateserial
-out /tmp/api.sirket.local.crt
-days 365
-sha256
-extfile /tmp/api-sirket-local.cnf
-extensions req_ext
-CAcreateserial: İlk imzalamada serial dosyası yoksa oluşturur. -extfile ve -extensions: SAN bilgilerini sertifikaya eklemek için şart. Bu iki parametre olmadan SAN’lar sertifikaya geçmez, sadece CSR’de kalır.
Sertifika Zinciri Oluşturma
Intermediate CA kullanıyorsanız, chain (zincir) sertifikası oluşturmanız gerekiyor. Nginx, Apache ve çoğu servis full chain ister:
# Full chain sertifika oluştur
cat /tmp/api.sirket.local.crt
/opt/myca/intermediate/certs/intermediate.cert.pem
/opt/myca/certs/ca.cert.pem > /tmp/api.sirket.local.fullchain.pem
Zinciri doğrulamak için:
openssl verify -CAfile /opt/myca/certs/ca.cert.pem
-untrusted /opt/myca/intermediate/certs/intermediate.cert.pem
/tmp/api.sirket.local.crt
Çıktıda OK görüyorsanız zincir düzgün kurulmuş demektir.
Wildcard Sertifika Oluşturma
Birden fazla subdomain için tek sertifika kullanmak istiyorsanız wildcard sertifika işinizi kolaylaştırır. *.sirket.local şeklinde bir sertifika tüm alt domainleri kapsar.
cat > /tmp/wildcard-sirket.cnf << EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext
[dn]
C = TR
ST = Istanbul
O = MyCompany
CN = *.sirket.local
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = *.sirket.local
DNS.2 = sirket.local
EOF
openssl genrsa -out /tmp/wildcard.sirket.local.key 2048
openssl req -new
-key /tmp/wildcard.sirket.local.key
-out /tmp/wildcard.sirket.local.csr
-config /tmp/wildcard-sirket.cnf
openssl x509 -req
-in /tmp/wildcard.sirket.local.csr
-CA /opt/myca/intermediate/certs/intermediate.cert.pem
-CAkey /opt/myca/intermediate/private/intermediate.key.pem
-CAcreateserial
-out /tmp/wildcard.sirket.local.crt
-days 365
-sha256
-extfile /tmp/wildcard-sirket.cnf
-extensions req_ext
Wildcard sertifikalarda dikkat edilmesi gereken nokta şu: *.sirket.local sadece bir seviye alt domaini kapsar. Yani web.sirket.local için geçerlidir, ama app.web.sirket.local için geçerli değildir. Eğer ikinci seviyeye de ihtiyacınız varsa SAN’a ayrıca eklemeniz lazım.
PKCS#12 (PFX) Formatına Dönüştürme
Windows sunucuları, IIS ve bazı Java uygulamaları PEM formatı yerine PKCS#12 formatını tercih eder. Dönüşüm için:
openssl pkcs12 -export
-out /tmp/api.sirket.local.pfx
-inkey /tmp/api.sirket.local.key
-in /tmp/api.sirket.local.crt
-certfile /opt/myca/intermediate/certs/intermediate.cert.pem
-name "api.sirket.local"
Komut size bir export password soracak. Bu şifreyi IIS veya ilgili uygulamaya sertifikayı import ederken kullanacaksınız.
Tersine, PFX’ten PEM’e dönüşüm de lazım olabilir:
# Private key çıkar
openssl pkcs12 -in /tmp/api.sirket.local.pfx -nocerts -nodes -out /tmp/extracted.key
# Sertifikaları çıkar
openssl pkcs12 -in /tmp/api.sirket.local.pfx -nokeys -out /tmp/extracted.crt
Sertifika Bilgilerini İnceleme ve Debug
Bir sertifikayla ilgili sorun yaşadığınızda veya süresi ne zaman dolacağını kontrol etmek istediğinizde bu komutları kullanırsınız:
# Sertifika detaylarını görüntüle
openssl x509 -in /tmp/api.sirket.local.crt -noout -text
# Sadece geçerlilik tarihlerini gör
openssl x509 -in /tmp/api.sirket.local.crt -noout -dates
# Sadece SAN'ları gör
openssl x509 -in /tmp/api.sirket.local.crt -noout -text | grep -A2 "Subject Alternative"
# Fingerprint
openssl x509 -in /tmp/api.sirket.local.crt -noout -fingerprint -sha256
# Uzak sunucunun sertifikasını incele
echo | openssl s_client -connect api.sirket.local:443 -servername api.sirket.local 2>/dev/null | openssl x509 -noout -text
# Sertifika kaç gün sonra expire oluyor?
openssl x509 -in /tmp/api.sirket.local.crt -noout -enddate |
awk -F= '{print $2}' |
xargs -I{} date -d "{}" +%s |
xargs -I{} bash -c 'echo $(( ({} - $(date +%s)) / 86400 )) days remaining'
Gerçek Hayat Senaryosu: Şirket İçi HTTPS Altyapısı
Diyelim ki şirket içinde çalışan bir monitoring stack’iniz var: Grafana, Prometheus ve Alertmanager. Bunların hepsini HTTPS ile çalıştırmak istiyorsunuz ve tüm geliştiricilerin tarayıcısının bu sertifikalara güvenmesini sağlamak istiyorsunuz.
Süreç şöyle işler:
İlk olarak Root CA sertifikanızı tüm istemci makinelere trust store’a ekleyin. Ubuntu/Debian için:
# CA sertifikasını sisteme ekle
sudo cp /opt/myca/certs/ca.cert.pem /usr/local/share/ca-certificates/mycompany-root-ca.crt
sudo update-ca-certificates
# Doğrulama
ls -la /etc/ssl/certs/ | grep mycompany
CentOS/RHEL için:
sudo cp /opt/myca/certs/ca.cert.pem /etc/pki/ca-trust/source/anchors/mycompany-root-ca.crt
sudo update-ca-trust extract
Chrome ve Firefox kendi trust store’unu kullandığından, bu tarayıcılar için CA’yı ayrıca import etmeniz gerekebilir. Firefox’ta about:preferences#privacy > Sertifikalar > Sertifikaları Yönet bölümünden import yapabilirsiniz.
Artık Nginx için konfigurasyon:
server {
listen 443 ssl;
server_name grafana.sirket.local;
ssl_certificate /etc/nginx/ssl/grafana.sirket.local.fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/grafana.sirket.local.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
}
Sertifika Yenileme Süreci
Sertifikaların expire olması sysadminler için en klasik “neden sistem çalışmıyor” senaryolarından biridir. Yenileme sürecini otomatize etmek için basit bir script:
#!/bin/bash
# cert-renew.sh - Sertifika yenileme scripti
CERT_FILE="/etc/nginx/ssl/api.sirket.local.crt"
KEY_FILE="/etc/nginx/ssl/api.sirket.local.key"
CA_CERT="/opt/myca/intermediate/certs/intermediate.cert.pem"
CA_KEY="/opt/myca/intermediate/private/intermediate.key.pem"
CSR_CONFIG="/opt/myca/configs/api-sirket-local.cnf"
DAYS_THRESHOLD=30
# Kaç gün kaldı?
EXPIRY=$(openssl x509 -in "$CERT_FILE" -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
echo "Sertifika süresi: $DAYS_LEFT gün kaldı"
if [ "$DAYS_LEFT" -lt "$DAYS_THRESHOLD" ]; then
echo "Sertifika yenileniyor..."
# Yeni key ve CSR oluştur
openssl genrsa -out "${KEY_FILE}.new" 2048
openssl req -new -key "${KEY_FILE}.new" -out /tmp/renewal.csr -config "$CSR_CONFIG"
# İmzala
openssl x509 -req
-in /tmp/renewal.csr
-CA "$CA_CERT"
-CAkey "$CA_KEY"
-CAcreateserial
-out "${CERT_FILE}.new"
-days 365
-sha256
-extfile "$CSR_CONFIG"
-extensions req_ext
# Dosyaları taşı
mv "$KEY_FILE" "${KEY_FILE}.bak"
mv "$CERT_FILE" "${CERT_FILE}.bak"
mv "${KEY_FILE}.new" "$KEY_FILE"
mv "${CERT_FILE}.new" "$CERT_FILE"
# Nginx reload
systemctl reload nginx
echo "Sertifika başarıyla yenilendi"
else
echo "Yenileme gerekmiyor"
fi
Bu scripti cron’a ekleyebilirsiniz:
# Her gün sabah 9'da çalıştır
0 9 * * * /opt/scripts/cert-renew.sh >> /var/log/cert-renew.log 2>&1
Sık Yapılan Hatalar ve Çözümleri
SAN olmadan sertifika oluşturmak: Modern Chrome ve Firefox CN üzerinden doğrulama yapmaz, SAN şart. Sertifikanızı -extfile ile oluştururken SAN eklemediğinizde tarayıcı sertifikayı reddeder.
Private key ve sertifika uyumsuzluğu: Nginx başlarken “key values mismatch” hatası alırsanız şunu çalıştırın:
# Modulus değerleri eşleşmeli
openssl x509 -noout -modulus -in sertifika.crt | md5sum
openssl rsa -noout -modulus -in private.key | md5sum
İki çıktı aynıysa key ve sertifika eşleşiyordur.
CA bundle sırası yanlış: Full chain dosyasında önce sunucu sertifikası, sonra intermediate, en son root CA gelmelidir. Sıra yanlış olursa bazı istemciler güven zincirini doğrulayamaz.
Expire olan CA sertifikası: CA sertifikanız expire olursa CA tarafından imzalanmış tüm sertifikalar geçersiz sayılır. Root CA sürelerini takvime not etmek ve öncesinde yeni bir CA oluşturarak migration planlamak önemlidir.
Sonuç
OpenSSL ile sertifika yönetimi başlangıçta karmaşık görünse de temel akışı bir kez kavradıktan sonra oldukça sistematik hale geliyor. Kendi CA’nızı kurmak, özellikle şirket içi servisler için hem maliyet açısından hem de kontrol açısından büyük avantaj sağlıyor. Kritik noktalara dikkat çekmek gerekirse: CA private key’inizi şifreli ve güvenli bir yerde saklayın, SAN’ları asla atlamamayı alışkanlık haline getirin, intermediate CA kullanarak root CA’yı offline tutun ve sertifika expire tarihlerini mutlaka monitoring sistemine ekleyin.
Bu yazıdaki komutları bir iç servis için test ortamında uygulayarak başlamanızı öneririm. Prodüksiyona geçmeden önce sertifika zincirinin doğru çalıştığını, SAN’ların doğru tanımlandığını ve anahtar uzunluklarının güncel standartları karşıladığını kontrol edin. 2048-bit RSA hala yaygın olsa da, yeni kurulumlarda 4096-bit ya da ECDSA (elliptic curve) tercih etmek gelecek için daha sağlam bir tercih olacaktır.