Wildfly Sunucusuna Java 6 ile Https Bağlantı Sorunu

Wildfly (eski adı ile JBoss) sunucusunun son sürümü çalışmak için en az Java 7 sürümüne ihtiyaç duyar ama Java 8 ile de çalıştırabilirsiniz. Java sürümleri de çıktıkları zamana göre en güncel teknolojilerle donatılmaya çalışılır. Java 6 nın çıktığı zamanlarda henüz bilinmeyen bug lar bulundukça yeni Java sürümlerde düzeltilmiştir. Bu buglardan birisi de güvenli bağlantı için kullanılan SSL teknolojisinin v3 sürümünde 2014 yılında Google tarafından bulunan ve POODLE olarak isim verilen bir güvenlik açığı. Bu açık bulunduktan sonra SSLv3'ün kullanılması tavsiye edilmiyor çünkü man in the middle attack diye bilinen yöntemle birinin araya girip iletişime müdahale etmesi ihtimali bulunuyor. Bu yüzden de Java nın yeni sürümlerinde SSLv3 ve daha eski protokoller varsayılan olarak kapalı geliyor. Wildfly gibi yeni sunucular da yine benzer çekincelerle bu tarz bağlantıları desteklemiyorlar.

Yine de Java 6 da çalışan bir istemci üzerinden Wildfly 8 sunucusuna https bağlantısı kurmak isterseniz bunun bir yolu var. Daha önce çalışan https bağlantılarınız birden çalışmaz ve aşağıdaki gibi bir hata ile karşılaşıyorsanız bunun da bir çözümü var:

javax.net.ssl.SSLException: Received fatal alert: unexpected_message

Bu hatanın sebebi Java 6 sürümündeki istemcinin varsayılan olarak TLSv1 ve SSLv2 Handshake protokolüyle bağlantı kurmaya çalışması ve karşı taraftaki sunucunun bu protokolü beklemiyor oluşu.

Öncelikle bu tarz sorunları daha iyi analiz etmek amacıyla Https bağlantısı ile ilgili daha detaylı bilgi toplamak iyi olacaktır. Bu amaçla iki alternatifimiz var:

1) System.setProperty("javax.net.debug", "ssl,handshake");

ya da

2) JVM parametrelerine -Djavax.net.debug=ssl:handshake eklemek ki bu sunucu tarafında daha çok işe yarayacaktır.

Bu değişiklikten sonra istemcide aşağıdaki hata dikkatinizi çekecektir:

TLSv1 Handshake, length = 75
SSLv2 client hello message, length = 101
TLSv1 Alert, length = 2

Bu durumu aşmak için yapmamız gereken hem istemci hem de sunucu için ortak olan SSLv3 üzerinden iletişimi zorlamak olacak.

1) Bunun istemci tarafı her Java uygulaması için ortak olan bir VM parametresi gerektiriyor:

-Dhttps.protocols="SSLv3" (-D ile verdiğimiz parametreler doğrudan JVM içindir)

Örnek olarak daha önce uygulamayı şöyle başlatıyor idiyseniz:

$ java com.test.ugur.TestApp

Bunu şöyle değiştirerek jvm'e e parametre verebiliriz:

$ java -Dhttps.protocols="SSLv3" com.test.ugur.TestApp

2) Sunucu tarafında yapılacak değişiklik ise biraz daha platforma bağımlı. Wildfly 8.2 için bu standalone.xml ya da benzer domain ayar dosyasında

<subsystem xmlns="urn:jboss:domain:undertow:1.2">
            <server name="default-server">
                <https-listener name="default-https" socket-binding="https" security-realm="SSLRealm" verify-client="REQUESTED" />

olan kısımda en sona bir parametre ekleyip şu hale getiriyoruz:

<https-listener name="default-https" socket-binding="https" security-realm="SSLRealm" verify-client="REQUESTED" enabled-protocols="SSLv3,TLSv1,TLSv1.1,TLSv1.2" />

Sunucuyu kapatıp açtığımızda artık SSLv3 de desteklenir hale geliyor.

Bu durumda istemci tarafında bağlantı sırasında loglar şu şekilde görülüyor:

SSLv3 Handshake, length = 75
SSLv3 Handshake, length = 14236
*** ServerHello, SSLv3

Bu durumda TLSv1 kullanıyor da olsak el sıkışma için SSLv2 yerine SSLv3 kullanarak bağlantıyı ortak payda üzerinden sağlamış oluyoruz.

Bu şekilde bağlantı kurabiliyor olsak da bilinen bir güvenlik açığı olduğu için en kısa zamanda daha güvenli sayılan TLSv1 ve daha yeni bir yöntem kullanmaya başlamanızda yarar var.

Bu durumda aşağıdakine benzer bir istemci logu göreceksiniz:

TLSv1 Handshake, length = 147
TLSv1 Handshake, length = 16384
*** ServerHello, TLSv1

Yorumlar

Popüler Yayınlar