PKI Altyapısı: Kurumsal Sertifika Yönetimi Rehberi

Kurumsal ortamlarda güvenli iletişimin temeli, iyi tasarlanmış bir PKI (Public Key Infrastructure) altyapısına dayanır. Pek çok sistem yöneticisi SSL sertifikalarını sadece “web sunucusuna yüklenen bir şey” olarak görse de, gerçekte PKI çok daha derin ve kritik bir altyapı bileşenidir. Yanlış yapılandırılmış bir PKI, tüm kurumun güvenlik duruşunu tehlikeye atabilir. Bu yazıda sıfırdan kurumsal PKI kurulumu, sertifika yaşam döngüsü yönetimi ve yaygın hatalardan kaçınma konularını ele alacağız.

PKI Nedir ve Neden Önemlidir?

PKI, dijital sertifikaların oluşturulması, dağıtılması, yönetilmesi ve iptal edilmesini sağlayan bir sistemler bütünüdür. Temelde üç bileşenden oluşur:

  • Root CA (Kök Sertifika Otoritesi): Güven zincirinin başı. Offline tutulur, fiziksel güvenlik altında.
  • Intermediate CA (Ara Sertifika Otoritesi): Günlük işlemleri yürüten, online olan CA.
  • End-entity sertifikaları: Sunucular, kullanıcılar veya cihazlar için düzenlenen son sertifikalar.

Kurumsal PKI’nın faydaları sadece HTTPS ile sınırlı değil. VPN kimlik doğrulama, e-posta imzalama (S/MIME), kod imzalama, 802.1X ağ erişim kontrolü ve iç servisler arası mTLS bunların başında gelir.

Root CA Kurulumu: Offline ve Güvenli

Root CA asla ağa bağlı olmamalıdır. Bu bir öneri değil, zorunluluktur. Çoğu kurumda Root CA, şifrelenmiş bir USB veya air-gapped bir makine üzerinde tutulur ve yılda birkaç kez, yalnızca Intermediate CA sertifikalarını imzalamak için devreye alınır.

OpenSSL ile Root CA Oluşturma

Önce dizin yapısını hazırlayalım:

mkdir -p /root/ca/{certs,crl,newcerts,private,requests}
chmod 700 /root/ca/private
touch /root/ca/index.txt
echo 1000 > /root/ca/serial
echo 1000 > /root/ca/crlnumber

Root CA yapılandırma dosyasını oluşturalım:

cat > /root/ca/openssl.cnf << 'EOF'
[ ca ]
default_ca = CA_default

[ CA_default ]
dir               = /root/ca
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand
private_key       = $dir/private/ca.key.pem
certificate       = $dir/certs/ca.cert.pem
crlnumber         = $dir/crlnumber
crl               = $dir/crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30
default_md        = sha256
name_opt          = ca_default
cert_opt          = ca_default
default_days      = 3650
preserve          = no
policy            = policy_strict

[ policy_strict ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
default_bits        = 4096
distinguished_name  = req_distinguished_name
string_mask         = utf8only
default_md          = sha256
x509_extensions     = v3_ca

[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ crl_ext ]
authorityKeyIdentifier=keyid:always
EOF

Root CA private key ve sertifikasını oluşturalım:

# Private key oluştur (4096-bit, şifreli)
openssl genrsa -aes256 -out /root/ca/private/ca.key.pem 4096
chmod 400 /root/ca/private/ca.key.pem

# Self-signed root sertifikası oluştur (10 yıl geçerli)
openssl req -config /root/ca/openssl.cnf 
    -key /root/ca/private/ca.key.pem 
    -new -x509 -days 3650 
    -sha256 -extensions v3_ca 
    -out /root/ca/certs/ca.cert.pem 
    -subj "/C=TR/ST=Istanbul/O=ŞirketAdı/OU=IT Security/CN=Şirket Root CA"

chmod 444 /root/ca/certs/ca.cert.pem

# Sertifikayı doğrulayalım
openssl x509 -noout -text -in /root/ca/certs/ca.cert.pem

Intermediate CA Kurulumu

Intermediate CA günlük operasyonlar için kullanılır ve online olabilir. Root CA’nın private key’ine göre çok daha az kritik olsa da, yine de HSM (Hardware Security Module) veya en azından şifreli depolama ile korunmalıdır.

# Intermediate CA için dizin yapısı (farklı sunucuda)
mkdir -p /etc/pki/intermediate/{certs,crl,csr,newcerts,private}
chmod 700 /etc/pki/intermediate/private
touch /etc/pki/intermediate/index.txt
echo 1000 > /etc/pki/intermediate/serial
echo 1000 > /etc/pki/intermediate/crlnumber

# Intermediate CA key oluştur
openssl genrsa -aes256 -out /etc/pki/intermediate/private/intermediate.key.pem 4096
chmod 400 /etc/pki/intermediate/private/intermediate.key.pem

# CSR oluştur
openssl req -config /etc/pki/intermediate/openssl.cnf 
    -new -sha256 
    -key /etc/pki/intermediate/private/intermediate.key.pem 
    -out /etc/pki/intermediate/csr/intermediate.csr.pem 
    -subj "/C=TR/ST=Istanbul/O=ŞirketAdı/OU=IT Security/CN=Şirket Intermediate CA"

# Bu CSR'ı Root CA'ya götür ve imzalat (offline işlem)
# Root CA makinesinde:
openssl ca -config /root/ca/openssl.cnf 
    -extensions v3_intermediate_ca 
    -days 1825 -notext -md sha256 
    -in intermediate.csr.pem 
    -out intermediate.cert.pem

# Sertifika zincirini oluştur
cat /etc/pki/intermediate/certs/intermediate.cert.pem 
    /root/ca/certs/ca.cert.pem > 
    /etc/pki/intermediate/certs/ca-chain.cert.pem

Sunucu Sertifikası Düzenleme

Artık gerçek dünyada kullanacağımız sunucu sertifikalarını Intermediate CA ile imzalayabiliriz.

# Sunucu için private key ve CSR oluştur
openssl req -newkey rsa:2048 -nodes 
    -keyout /etc/ssl/private/webserver.key 
    -out /etc/ssl/certs/webserver.csr 
    -subj "/C=TR/ST=Istanbul/O=ŞirketAdı/CN=web.sirket.com"

# SAN (Subject Alternative Name) ile sertifika imzalama
# san.cnf dosyası oluştur
cat > /tmp/san.cnf << EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name

[req_distinguished_name]

[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = web.sirket.com
DNS.2 = www.web.sirket.com
DNS.3 = api.sirket.com
IP.1 = 192.168.1.100
EOF

# Intermediate CA ile imzala
openssl ca -config /etc/pki/intermediate/openssl.cnf 
    -extensions v3_req 
    -extfile /tmp/san.cnf 
    -days 365 -notext -md sha256 
    -in /etc/ssl/certs/webserver.csr 
    -out /etc/ssl/certs/webserver.cert.pem

Sertifika Yaşam Döngüsü Yönetimi

Sertifika yönetiminin en zorlu kısmı burası. Bir kurumda onlarca, belki yüzlerce sertifika olduğunu düşünün. Her birinin farklı son kullanma tarihleri var. Birini kaçırmak, gece yarısı üretim kesintisine yol açabilir.

Sertifika İzleme Script’i

#!/bin/bash
# cert_monitor.sh - Sertifika son kullanma tarihlerini izle

ALERT_DAYS=30
CERT_DIRS=("/etc/ssl/certs" "/etc/nginx/ssl" "/etc/apache2/ssl")
LOG_FILE="/var/log/cert_monitor.log"
SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"

check_cert_expiry() {
    local cert_file="$1"
    local hostname="$2"
    
    if [ ! -f "$cert_file" ]; then
        echo "HATA: $cert_file bulunamadı" | tee -a "$LOG_FILE"
        return
    fi
    
    # Son kullanma tarihini al
    expiry_date=$(openssl x509 -enddate -noout -in "$cert_file" 2>/dev/null | cut -d= -f2)
    expiry_epoch=$(date -d "$expiry_date" +%s 2>/dev/null)
    current_epoch=$(date +%s)
    days_remaining=$(( (expiry_epoch - current_epoch) / 86400 ))
    
    echo "$(date): $cert_file - $days_remaining gün kaldı" >> "$LOG_FILE"
    
    if [ "$days_remaining" -le "$ALERT_DAYS" ]; then
        message="⚠️ SERTIFIKA UYARISI: $cert_file sertifikasının süresi $days_remaining gün içinde doluyor! Host: $hostname"
        echo "$message" | tee -a "$LOG_FILE"
        
        # Slack bildirimi gönder
        curl -s -X POST -H 'Content-type: application/json' 
            --data "{"text":"$message"}" 
            "$SLACK_WEBHOOK"
    fi
}

# Uzak sunuculardaki sertifikaları kontrol et
check_remote_cert() {
    local host="$1"
    local port="${2:-443}"
    
    expiry_date=$(echo | openssl s_client -connect "$host:$port" 
        -servername "$host" 2>/dev/null | 
        openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
    
    if [ -z "$expiry_date" ]; then
        echo "HATA: $host:$port bağlantısı kurulamadı" | tee -a "$LOG_FILE"
        return
    fi
    
    expiry_epoch=$(date -d "$expiry_date" +%s)
    current_epoch=$(date +%s)
    days_remaining=$(( (expiry_epoch - current_epoch) / 86400 ))
    
    echo "$(date): $host:$port - $days_remaining gün kaldı" >> "$LOG_FILE"
    
    if [ "$days_remaining" -le "$ALERT_DAYS" ]; then
        echo "⚠️ UYARI: $host:$port için $days_remaining gün kaldı!" | tee -a "$LOG_FILE"
    fi
}

# Lokal sertifikaları kontrol et
for dir in "${CERT_DIRS[@]}"; do
    if [ -d "$dir" ]; then
        find "$dir" -name "*.pem" -o -name "*.crt" | while read -r cert; do
            check_cert_expiry "$cert" "$(hostname)"
        done
    fi
done

# Uzak sunucuları kontrol et
REMOTE_HOSTS=(
    "web.sirket.com"
    "api.sirket.com"
    "mail.sirket.com:465"
    "vpn.sirket.com:1194"
)

for host_port in "${REMOTE_HOSTS[@]}"; do
    host=$(echo "$host_port" | cut -d: -f1)
    port=$(echo "$host_port" | cut -s -d: -f2)
    check_remote_cert "$host" "${port:-443}"
done

Sertifika İptal (CRL ve OCSP)

Bir sertifikanın güvenliği ihlal edildiğinde veya bir çalışan kurumdan ayrıldığında, sertifikayı iptal etmek zorundasınız:

# Sertifika iptal etme
openssl ca -config /etc/pki/intermediate/openssl.cnf 
    -revoke /etc/pki/intermediate/newcerts/1001.pem 
    -crl_reason keyCompromise

# Yeni CRL oluştur
openssl ca -config /etc/pki/intermediate/openssl.cnf 
    -gencrl 
    -out /etc/pki/intermediate/crl/intermediate.crl.pem

# CRL'yi DER formatına çevir (bazı sistemler ister)
openssl crl -in /etc/pki/intermediate/crl/intermediate.crl.pem 
    -outform DER 
    -out /var/www/html/pki/intermediate.crl

# CRL içeriğini doğrula
openssl crl -in /etc/pki/intermediate/crl/intermediate.crl.pem 
    -noout -text | grep -A 5 "Revoked"

OCSP Responder Kurulumu

CRL dosyaları büyük ortamlarda şişer ve her kontrolde tam dosyayı indirmek verimsizdir. OCSP (Online Certificate Status Protocol) bu sorunu çözer:

# OCSP signing sertifikası oluştur
openssl req -config /etc/pki/intermediate/openssl.cnf 
    -new -newkey rsa:2048 -nodes 
    -keyout /etc/pki/ocsp/ocsp.key.pem 
    -out /etc/pki/ocsp/ocsp.csr.pem 
    -subj "/C=TR/O=ŞirketAdı/CN=OCSP Responder"

openssl ca -config /etc/pki/intermediate/openssl.cnf 
    -extensions ocsp 
    -days 365 -notext -md sha256 
    -in /etc/pki/ocsp/ocsp.csr.pem 
    -out /etc/pki/ocsp/ocsp.cert.pem

# OCSP responder'ı başlat
openssl ocsp 
    -port 2560 
    -text 
    -CA /etc/pki/intermediate/certs/ca-chain.cert.pem 
    -index /etc/pki/intermediate/index.txt 
    -rkey /etc/pki/ocsp/ocsp.key.pem 
    -rsigner /etc/pki/ocsp/ocsp.cert.pem 
    -ignore_err &

# OCSP sorgulama testi
openssl ocsp 
    -CAfile /etc/pki/intermediate/certs/ca-chain.cert.pem 
    -url http://ocsp.sirket.com:2560 
    -resp_text 
    -issuer /etc/pki/intermediate/certs/intermediate.cert.pem 
    -cert /etc/ssl/certs/webserver.cert.pem

Windows Active Directory ile Entegrasyon

Kurumsal ortamlarda genellikle Windows ADCS (Active Directory Certificate Services) de devrede olur. Linux PKI altyapınızın Windows istemcilere güvenmesi için Root CA sertifikasını Group Policy ile dağıtabilirsiniz. Ancak Linux sistemlerde bunu elle yapmak da gerekebilir:

# Kurumsal Root CA sertifikasını Linux sistemlere dağıt
# Sertifikayı kopyala
sudo cp /tmp/sirket-root-ca.crt /usr/local/share/ca-certificates/sirket-root-ca.crt

# Sertifika deposunu güncelle (Debian/Ubuntu)
sudo update-ca-certificates

# RHEL/CentOS için
sudo cp /tmp/sirket-root-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust extract

# Doğrulama
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt 
    /etc/ssl/certs/webserver.cert.pem

Otomatik Yenileme: cert-manager ve Let’s Encrypt

İç PKI için cert-manager kullanmak, Kubernetes ortamlarında sertifika yönetimini dramatik biçimde kolaylaştırır. Let’s Encrypt dış sertifikalar için, kendi CA’nız ise iç servisler için kullanılabilir:

# Kubernetes'te cert-manager kurulumu
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml

# Kendi CA'nızı kullanan ClusterIssuer
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: sirket-internal-ca
spec:
  ca:
    secretName: sirket-root-ca-secret
EOF

# Certificate objesi oluştur
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: webserver-cert
  namespace: production
spec:
  secretName: webserver-tls
  duration: 8760h  # 1 yıl
  renewBefore: 720h  # 30 gün önce yenile
  subject:
    organizations:
      - SirketAdı
  commonName: web.sirket.com
  dnsNames:
    - web.sirket.com
    - api.sirket.com
  issuerRef:
    name: sirket-internal-ca
    kind: ClusterIssuer
EOF

Yaygın Hatalar ve Kaçınma Yolları

PKI konusunda yıllar içinde gördüğüm ve yaşadığım en sık hataları sıralayayım:

  • Root CA’yı online tutmak: Root CA’nın private key’i ele geçirilirse tüm PKI altyapısı çöker. Mutlaka offline tutun.
  • SAN olmadan sertifika kesmek: Modern tarayıcılar ve istemciler artık sadece CN alanına bakmıyor. Tüm sertifikalara Subject Alternative Name ekleyin.
  • Sertifika izleme yapmamak: En sık karşılaşılan sorun budur. Cron job veya Prometheus + Blackbox Exporter ile izleme şart.
  • CRL dağıtım noktası tanımlamamak: Sertifikalarınıza cdp (CRL Distribution Point) ekleyin, aksi takdirde iptal mekanizması çalışmaz.
  • Private key güvenliğini ihmal etmek: Private key’leri 600 izinle saklayın, asla log’a yazmayın, versiyon kontrol sistemlerine eklemeyin.
  • Wildcard sertifikalara aşırı güvenmek: *.sirket.com sertifikası kullanışlı görünür ama güvenlik açısından risklidir. Bir private key’in sızması tüm alt domainleri etkiler.
  • Sertifika zincirini eksik yapılandırmak: Sunucunuzda sadece son sertifikayı değil, tam zinciri (intermediate dahil) sunun.

Prometheus ile PKI İzleme

Üretim ortamında sertifika durumunu Prometheus ile izlemek hayat kurtarır:

# x509-certificate-exporter kurulumu (Helm ile)
helm repo add enix https://charts.enix.io
helm install x509-certificate-exporter enix/x509-certificate-exporter 
    --namespace monitoring 
    --set secretsExporter.enabled=true 
    --set hostPathsExporter.daemonSets.certFiles.hostPathVolumeMount.mountPath=/etc/ssl

# Prometheus alert kuralı ekle
cat > /etc/prometheus/rules/cert_alerts.yml << 'EOF'
groups:
  - name: certificate_alerts
    rules:
      - alert: CertificateExpiringSoon
        expr: x509_cert_not_after - time() < 86400 * 30
        for: 1h
        labels:
          severity: warning
        annotations:
          summary: "Sertifika {{ $labels.subject_CN }} 30 gün içinde doluyor"
          description: "{{ $labels.filepath }} dosyasındaki sertifika {{ $value | humanizeDuration }} içinde geçersiz olacak"
      
      - alert: CertificateExpired
        expr: x509_cert_not_after - time() < 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Sertifika {{ $labels.subject_CN }} süresi doldu!"
EOF

Sonuç

PKI altyapısı kurmak ilk etapta karmaşık görünebilir ama doğru yapılandırıldığında yıllarca sorunsuz çalışan, güvenli bir temel oluşturur. Önemli olan birkaç nokta şunlar: Root CA’nızı offline tutun ve fiziksel güvenliğini sağlayın, sertifika yaşam döngüsünü otomatize edin, mutlaka izleme mekanizması kurun ve tüm adımları belgelendirin.

Kurumsal PKI bir kez kurulup unutulan bir sistem değil, düzenli bakım ve denetim gerektiren canlı bir altyapıdır. Özellikle çalışan ayrılmaları, sistem değişiklikleri ve güvenlik olaylarında sertifika iptal prosedürlerinizin işleyip işlemediğini düzenli olarak test edin. Bir gün gerçekten ihtiyaç duyduğunuzda bunun sadece kağıt üzerinde işlediğini keşfetmek istemezsiniz.

Bu yazıda anlattıklarımı üretim ortamına uygulamadan önce test ortamında deneyin ve kendi kurumunuzun politika ve gereksinimlerine göre uyarlayın. PKI konusunda sorularınız veya farklı senaryolarınız varsa, yorumlarda buluşalım.

Yorum yapın