Java microservices ortamında mTLS sertifikalarını kesinti yaratmadan döndürmek için sertifika zinciri, bağlantı havuzu, Kubernetes Secret güncellemesi ve doğrulama metriklerini Spring Boot üzerinden tasarlayın.
Spring Boot'ta Java Microservices için mTLS Sertifika Rotasyonu
Java Microservices'ta mTLS rotasyonunun asıl kırılma noktası
mTLS rotasyonunda sadece yeni PEM veya PKCS12 dosyasını diske yazmak yeterli değildir. TLS kimliği, bağlantı kurulurken seçilir; Apache HttpClient, Reactor Netty veya JDBC sürücüsünün açık tuttuğu TCP bağlantıları eski istemci sertifikasıyla çalışmaya devam eder. Önce sertifika sürelerini ve issuer zincirini CI aşamasında doğrulayın. Aşağıdaki komut, PKCS12 içindeki leaf sertifikanın bitiş tarihini ve Subject Alternative Name değerlerini denetlenebilir hale getirir:
keytool -list -v -keystore client-keystore.p12 -storetype PKCS12 -storepass "$KEYSTORE_PASSWORD" | egrep 'Owner:|Issuer:|Valid from:|SubjectAlternativeName'Rotasyon penceresinde eski ve yeni leaf sertifikaların aynı trust domain içinde doğrulanabilmesi gerekir. Yeni sertifikayı yayınlamadan önce sunucunun truststore'una yeni issuing CA eklenir, ardından istemci sertifikaları döndürülür, en son eski CA kaldırılır. Tersi sıra, iki taraf da yeni zinciri henüz tanımadığı için TLS alert unknown_ca ile kesintiye neden olur.Bu konu, java eğitimi veya java programlama eğitimi müfredatında genellikle KeyStore.load seviyesinde kalır. Üretimde kritik ayrıntı, sertifika dosyasının değil, TLS context ve açık bağlantıların yaşam döngüsüdür. java kursu laboratuvarında bunu görünür kılmak için test CA üretin, iki farklı client sertifikası çıkarın ve bir servisin sadece yeni CA ile imzalı sertifikayı kabul ettiği geçiş senaryosunu Testcontainers ile koşturun. OpenSSL ile hızlı bir zincir kontrolü de yapılabilir:
openssl verify -CAfile trust-bundle.pem -untrusted intermediate-ca.pem client-new.pemBu komutun başarılı olması, uygulamanın mutlaka bağlanacağı anlamına gelmez: Java tarafında hostname doğrulaması, EKU alanı ve SNI de ayrıca değerlendirilir.Spring Boot eğitimi için inbound mTLS: Secret değişimi ve yeniden yükleme
Spring Boot uygulamasının embedded sunucusu başlangıçta keystore okur; Kubernetes Secret içeriğinin volume altında değişmesi, her sunucunun aktif TLS context'ini otomatik olarak değiştirdiği varsayımını güvenli kılmaz. En öngörülebilir dağıtım modeli, immutable Secret adı veya içerik hash'i ile pod rollout tetiklemektir. Deployment pod template'ine sertifika hash'ini annotation olarak eklemek, yalnızca Secret değiştiğinde yeni pod oluşturur:
spec:
template:
metadata:
annotations:
pki.example.com/client-ca-sha256: "${CLIENT_CA_SHA256}"
spec:
volumes:
- name: server-tls
secret:
secretName: orders-api-server-tls
containers:
- name: app
volumeMounts:
- name: server-tls
mountPath: /var/run/tls
readOnly: trueBu yaklaşımda yeni pod readiness kontrolünü geçmeden eski pod kapatılmaz. Sertifika değişimini fark eden ama yarım yüklenmiş bir dosyayı okuyan file watcher tasarımından kaçınır.spring framework katmanında inbound mTLS kimliğini sadece reverse proxy header'ından okumayın. Proxy'nin TLS sonlandırdığı mimaride, istemci sertifikası doğrulamasını proxy yapar ve uygulamaya kimliği imzalı, güvenilir bir kanal üzerinden taşır. TLS uygulamada sonlanıyorsa Spring Security ile X.509 subject'i uygulama yetkisine bağlayın. Aşağıdaki yapılandırma, CN yerine sertifikadaki Subject DN desenini kullanır ve varsayılan anonymous erişimi kapatır:
@Bean
SecurityFilterChain security(HttpSecurity http) throws Exception {
return http
.x509(x509 -> x509
.subjectPrincipalRegex("CN=(.*?)(?:,|$)")
.userDetailsService(deviceUserDetailsService))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health/**").permitAll()
.anyRequest().authenticated())
.build();
}CN tek başına benzersiz kimlik değildir. Sertifika yenileme sırasında CN sabit kalabilir; yetkilendirme için issuer DN, serial number veya SPIFFE URI SAN gibi değişmez bir kimlik şeması belirleyin.Java backend geliştirme tarafında outbound bağlantı havuzunu döndürmek
Outbound mTLS kullanan java backend geliştirme servislerinde en yaygın hata, yalnızca keystore dosyasını güncelleyip aynı HTTP istemcisi havuzunu bırakmaktır. Apache HttpClient 5 ile oluşturulan SSLConnectionSocketFactory ve mevcut pooled bağlantılar eski SSLContext'i taşır. Rotasyon sırasında yeni client oluşturun, uygulama referansını atomik değiştirin, ardından eski havuzda idle bağlantıları kapatın. Aşağıdaki örnek, yeni truststore ve client keystore ile ayrı bir HttpClient üretir:
SSLContext sslContext = SSLContexts.custom()
.loadKeyMaterial(Path.of("/var/run/tls/client.p12").toFile(), keyPassword)
.loadTrustMaterial(Path.of("/var/run/tls/trust.p12").toFile(), trustPassword)
.build();
PoolingHttpClientConnectionManager manager =
PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext))
.build();
CloseableHttpClient next = HttpClients.custom()
.setConnectionManager(manager)
.evictExpiredConnections()
.build();
CloseableHttpClient previous = clientRef.getAndSet(next);
previous.close();Doğrudan previous.close() yalnızca istek kabulünü uygulama katmanında durdurduktan veya aktif istek sayısını sıfırladıktan sonra çağrılmalıdır. Aksi halde devam eden bir response stream'i Connection pool shut down hatasıyla kesilebilir. Pratikte reference-counted bir client wrapper, eski istemciyi aktif lease sayısı sıfıra inince kapatır.Bağlantı havuzundaki eski kimliklerin ne kadar yaşadığını sınırlamak için HTTP keep-alive süresini sertifika rotasyon politikasından kısa tutun. Örneğin istemci sertifikası 24 saatte bir dönüyorsa 5 dakikalık connection TTL, en kötü durumda eski sertifikayla açık kalan bağlantı süresini 5 dakikaya indirir. Bu ayarı körlemesine küçültmek pahalıdır: her yeni TLS bağlantısı sertifika doğrulaması, anahtar değişimi ve çoğu zaman yeni TCP bağlantısı gerektirir. Önce JFR ile TLSHandshake olaylarını kaydedin, sonra TTL değişikliğinin handshake sayısına etkisini ölçün:
jcmd $PID JFR.start name=mtls-rotation settings=profile duration=5m filename=/tmp/mtls.jfr
jfr print --events jdk.TLSHandshake /tmp/mtls.jfrÖnce ve sonra karşılaştırmasında istek sayısı başına handshake adedini, p95 bağlantı kurma süresini ve 5xx oranını aynı yük profili altında kaydedin. Sadece ortalama gecikmeye bakmak, rotasyon anındaki kısa süreli tail latency artışını gizler.Hibernate ORM ve Spring Data JPA işlemlerinde sertifika hatasını sınıflandırma
hibernate orm veya spring data jpa kullanan bir servis, mTLS hatasını çoğu zaman repository çağrısında görür fakat hata veritabanından değil, çağrı zincirindeki uzak bir HTTP bağımlılığından gelebilir. TLS handshake hatasını tekrar denemeden önce exception zincirini ayırın. PKIX path building failed, certificate_unknown ve bad_certificate hataları transient timeout değildir; sabit retry bunları çoğaltır ve connection pool'u gereksiz doldurur. Spring transaction içinde uzak HTTP çağrısı varsa, sertifika rotasyonu sırasında başarısız çağrının açık tuttuğu veritabanı transaction'ı da lock süresini uzatır.
Somut koruma olarak uzak çağrıyı transaction sınırının dışına taşıyın veya işlem süresini ölçülebilir biçimde kısaltın. PostgreSQL için test ortamında aşağıdaki sorgu ile uzun transaction'ları izleyin; p95 değerini rotasyon öncesi ve sırasında karşılaştırın:
SELECT pid,
now() - xact_start AS transaction_age,
state,
wait_event_type,
query
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
ORDER BY transaction_age DESC;Özellikle lazy association serialize edilirken başlayan beklenmedik SQL sorguları, hata dönüş yolunu uzatabilir. Bu nedenle API DTO'sunu transaction içinde açıkça projekte edin; entity graph'ı response katmanına sızdırmak mTLS kaynaklı bir kesintiyi N+1 sorgu yüküyle birleştirebilir.Spring AI, Spring MCP ve Model Context Protocol için güven sınırı
spring ai ile dış araç çağrıları yapan bir uygulamada modelin tool seçimi, ağ erişim yetkisi anlamına gelmemelidir. spring mcp üzerinden bağlanılan bir Model Context Protocol sunucusunu ayrı bir mTLS hedefi olarak ele alın: ayrı client sertifikası, ayrı CA bundle ve hostname allowlist kullanın. Örneğin tool endpoint'ini yapılandırmadan okuyup her URL'ye bağlanmak yerine URI doğrulaması uygulayın:
URI endpoint = URI.create(configuredMcpEndpoint);
if (!"https".equals(endpoint.getScheme()) ||
!endpoint.getHost().endsWith(".tools.internal")) {
throw new IllegalArgumentException("MCP endpoint is outside the approved trust domain");
}Bu kontrol, prompt içeriğinden türetilmiş bir URL'nin SSRF yoluyla metadata servislerine veya farklı bir trust domain'e yönlenmesini engeller. DNS rebinding riskine karşı HTTP istemcisinde proxy, redirect ve IP allowlist politikalarını da ayrıca tanımlayın.java fullstack eğitimi bağlamında kullanıcı arayüzüne sertifika ayrıntılarını taşımak yerine, backend'in sertifika kimliğiyle hangi tool'a eriştiğini denetlenebilir hale getirin. Her MCP çağrısında tool adı, hedef host, sertifika serial numarası, trace id ve sonuç kodunu structured log'a yazın; private key, Authorization header veya tam prompt loglamayın. Rotasyon tatbikatında eski sertifikayla çağrının reddedildiğini ve yeni sertifikayla aynı tool çağrısının başarılı olduğunu curl ile değil, gerçek MCP istemci akışıyla doğrulayın. Böylece LLM katmanının oluşturduğu istek şekli, standart REST sağlık kontrolünden farklı olsa bile TLS politikasının uygulandığı kanıtlanır.
İlgili Eğitim
YTÜSEM İlgili Eğitim
Java Spring Boot ReactJS FullStack Eğitimi (Yıldız Teknik Üniversitesi SEM)
Sık Sorulan Sorular
Spring Boot'ta mTLS sertifikası değişince uygulamayı yeniden başlatmak gerekir mi?
Embedded sunucunun ve kullandığınız HTTP istemcisinin sertifika yeniden yükleme davranışını doğrulamadan hayır varsayımı yapmayın. Kubernetes ortamında Secret hash ile rollout yapmak güvenilir bir temel yaklaşımdır. Outbound tarafta ayrıca yeni SSLContext ile client pool oluşturulmalı ve eski pool, aktif istekler bittikten sonra kapatılmalıdır.
Java microservices ortamında mTLS rotasyonundan sonra eski bağlantılar neden çalışır?
İstemci sertifikası TLS handshake sırasında seçilir. Keep-alive ile açık kalan TCP bağlantısında yeni handshake yapılmadığından keystore dosyası değişse bile eski sertifika kullanılmış oturum sürer. Apache HttpClient veya Reactor Netty havuzuna TTL koyun, rotasyon sonrasında yeni client referansına geçin ve JFR jdk.TLSHandshake olaylarıyla handshake oranını ölçün.
Spring AI ve Spring MCP için Model Context Protocol bağlantısında mTLS nasıl uygulanır?
MCP sunucusunu ayrı bir trust domain kabul edin. Ayrı client keystore, ayrı CA bundle, https zorlaması ve hostname allowlist tanımlayın. Tool çağrılarında hedef host ile sertifika serial numarasını loglayın; modelden gelen URL veya redirect hedefinin ağ politikasını aşmasına izin vermeyin.
Spring Data JPA kullanan serviste certificate_unknown hatasına retry uygulanmalı mı?
Hayır, certificate_unknown ve PKIX doğrulama hataları genellikle yapılandırma veya geçiş sırası problemidir. Bunları transient ağ hatası gibi retry etmek aynı hatayı çoğaltır. Exception sınıfını metrikte ayrı etiketleyin, trust bundle sürümünü kaydedin ve veritabanı transaction'ını uzak HTTP çağrısı boyunca açık tutmayın.
AI / LLM Discovery
Bu makale Opendart Akademi Java eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.


