Bir MQTT TLS handshake hatası ortaya çıktığında bağlantı MQTT daha başlamadan kopar ve çoğu istemci kütüphanesi bunu işe yaramaz bir mesajla bildirir. Bu rehber, nedeni openssl s_client ile dakikalar içinde nasıl izole edeceğinizi gösterir, ardından neredeyse her hatanın arkasındaki altı sorunu ele alır: yanlış port, eksik CA, SNI, saat kayması, TLS sürüm uyuşmazlığı ve araya giren proxy'ler. Tüm testler 8883 portunda broker.connectmq.com'a karşı çalışır; böylece çalıştığı bilinen bir uç noktayı kendinizinkiyle karşılaştırabilirsiniz.
Bir TLS Handshake'inde Ne Olur?
İstemciniz MQTT CONNECT paketini göndermeden önce broker ile bir TLS handshake'ini tamamlamalıdır:
- İstemci, desteklenen TLS sürümleri, şifreleme takımları ve sunucu adını (SNI) içeren ClientHello'yu gönderir.
- Broker seçtiği sürüm ve şifreleme takımıyla birlikte sertifika zincirini gönderir.
- İstemci zinciri güvenilen köklere göre doğrular, geçerlilik tarihlerini kontrol eder ve hostname'i eşleştirir.
- Her iki taraf anahtarları türetir ve şifreli trafiğe geçer.
Herhangi bir adımdaki hata bağlantıyı kapatır. MQTT kütüphaneniz ardından A TLS error occurred (mosquitto), ssl.SSLError (Python), ECONNRESET veya bir sertifika hatası (Node.js) ya da state=-2 (ESP32'de PubSubClient) gibi bir şey gösterir. İhtiyacınız olan alttaki nedendir ve OpenSSL bunu doğrudan gösterir. Doğru temel ayarlar için MQTT TLS yapılandırması rehberimize bakın.
Adım 1: Handshake'i openssl s_client ile Yeniden Üretin
Bunu başarısız olan istemciyle aynı makineden veya ağdan çalıştırın:
openssl s_client -connect broker.connectmq.com:8883 \
-servername broker.connectmq.com -showcerts </dev/null
Sağlıklı bir sonuç şuna benzer satırlarla biter:
Verify return code: 0 (ok)
ve üzerinde anlaşılan protokolü ve şifreleme takımını gösterir. OpenSSL başarılı olup uygulamanız başarısız oluyorsa sorun uygulamanın yapılandırmasındadır (CA yolu, hostname, kütüphane seçenekleri). OpenSSL de başarısız oluyorsa sorun ağda, güven deposunda veya saattedir. Bu tek karşılaştırma arama alanını yarıya indirir.
Kullanışlı varyantlar:
# Protokol, şifreleme takımı ve doğrulamanın kısa özeti
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -brief </dev/null
# Gömülü bir cihazın yapacağı gibi belirli bir CA dosyasına göre doğrulama
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com \
-CAfile isrgrootx1.pem </dev/null
# Sertifika tarihlerini ve adlarını inceleme
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName
MQTT TLS Handshake Hatası: Belirtiler ve Nedenler
| Belirti | Olası neden | Çözüm |
|---|---|---|
wrong version number veya packet length too long |
TLS istemcisi şifresiz bir portla (1883) konuşuyor | TLS için 8883 portunu kullanın |
| Bağlantı askıda kalır, sonra zaman aşımına uğrar | 8883 portunda şifresiz MQTT istemcisi veya güvenlik duvarı tarafından engellenen port | İstemcide TLS'i etkinleştirin; erişilebilirliği test edin |
unable to get local issuer certificate (kod 20) |
İstemci kök CA'ya güvenmiyor | Doğru CA paketini yükleyin veya ona yönlendirin |
self-signed certificate in certificate chain (kod 19) |
Araya giren proxy veya antivirüs sertifikayı değiştiriyor | Denetimi atlayın veya proxy CA'sına bilinçli olarak güvenin |
certificate is not yet valid (kod 9) |
Cihaz saati geride | Bağlanmadan önce saati NTP ile senkronize edin |
certificate has expired (kod 10) |
Saat ileride veya sunucu sertifikasının süresi gerçekten dolmuş | Cihaz saatini ve sunucu tarihlerini kontrol edin |
Hostname mismatch / IP address mismatch |
IP ile veya yanlış adla bağlanma | Sertifikadaki hostname ile bağlanın |
no protocols available / unsupported protocol |
İstemci, sunucunun sunmadığı TLS sürümleriyle sınırlı | İstemcide TLS 1.2 veya daha yenisine izin verin |
alert handshake failure |
Ortak şifreleme takımı yok veya SNI eksik | TLS kütüphanesini güncelleyin; SNI gönderin |
Neden 1: Yanlış Port veya Şema
En yaygın hata budur. 1883 portu şifresiz MQTT konuşur; 8883 portu ise ilk bayttan itibaren TLS bekler. İstemciniz 1883'e karşı TLS başlatırsa, sunucunun yanıtı bir TLS kaydı olmadığı için OpenSSL wrong version number bildirir. Şifresiz bir istemci 8883'e bağlanırsa broker asla gelmeyecek bir ClientHello'yu bekler ve bağlantı sonunda kapanır.
URL şemanızı da kontrol edin. MQTT.js'te mqtt:// şifresiz, mqtts:// ise TLS anlamına gelir; tarayıcılarda wss://broker.connectmq.com:8084/mqtt kullanın. Python'da TLS'i etkinleştiren tls_set() çağrısıdır; yalnızca portu değiştirmek yeterli değildir.
Portun hiç erişilebilir olup olmadığını kontrol etmek için:
# Linux/macOS
nc -vz broker.connectmq.com 8883
# Windows PowerShell
Test-NetConnection broker.connectmq.com -Port 8883
Kurumsal ve misafir ağları sıklıkla 8883'ü engeller. Engelliyse 8084 üzerinden güvenli WebSocket yaygın bir geçici çözümdür; bkz. WebSocket üzerinden MQTT.
Neden 2: Eksik veya Yanlış CA Sertifikası
Doğrulama hatası 20, istemcinin güvenilen bir köke zincir oluşturamadığı anlamına gelir. Tipik durumlar:
- mosquitto istemcileri,
--capath /etc/ssl/certs(Linux) veya--cafilevermediğiniz sürece sistem deposunu kullanmaz. Windows'ta ISRG Root X1 PEM'ini indirin ve--cafileile verin. - Minimal Docker imajlarında çoğu zaman
ca-certificatespaketi eksiktir. - Gömülü cihazlara yanlış kök, eksik bir PEM veya kök yerine leaf sertifika verilmiştir.
- macOS'ta python.org'dan kurulan Python, sertifika yükleyicisinin bir kez çalıştırılmasını gerektirir; ayrıntılar MQTT'de SSL CERTIFICATE_VERIFY_FAILED yazısındadır.
ConnectMQ'nun broker sertifikası Let's Encrypt tarafından verilir; bu nedenle güncel her sistem güven deposu gerekli kökü zaten içerir.
Neden 3: Eksik SNI
Server Name Indication, sunucuya hangi hostname'i istediğinizi söyler. Yük dengelemeli ve çok kiracılı uç noktalar, SNI eksik olduğunda varsayılan bir sertifika sunabilir veya handshake'i reddedebilir. Çoğu kütüphane, bir hostname ile bağlandığınızda SNI'ı otomatik gönderir. Sorunlar, kod önce IP adresini çözümleyip IP'ye bağlandığında veya çok eski TLS yığınları kullanıldığında ortaya çıkar. İstemci kütüphanesine her zaman hostname'i verin ve OpenSSL testlerinde her zaman -servername ekleyin.
Neden 4: Saat Kayması
Sertifikalar yalnızca iki tarih arasında geçerlidir. Ağ saati olmayan bir Raspberry Pi, NTP'yi tamamlamamış bir ESP32 veya eski bir anlık görüntüden geri yüklenmiş bir sanal makine günlerce veya on yıllarca sapmış olabilir. Linux'ta date -u ile kontrol edin; mikrodenetleyicilerde TLS bağlantısını açmadan önce NTP'yi bekleyin. ESP32 sertifika sabitleme rehberi hazır bir NTP bekleme döngüsü içerir.
Neden 5: TLS Sürümü veya Şifreleme Takımı Uyuşmazlığı
Eski firmware, eski Java çalışma zamanları veya Python'un ssl.PROTOCOL_TLSv1 gibi sabit kodlanmış ayarlar, yalnızca modern sunucuların devre dışı bıraktığı sürümleri sunabilir. Bir sunucunun hangi sürümleri kabul ettiğini test edin:
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -tls1_2 </dev/null
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -tls1_3 </dev/null
İstemcinizi tek bir sürüme sabitlemek yerine otomatik olarak anlaşacak şekilde yapılandırın (örneğin Python'da ssl.PROTOCOL_TLS_CLIENT). TLS 1.3 üzerinden MQTT yazımız sürüm ve şifreleme takımı seçimlerini daha ayrıntılı açıklar.
Neden 6: TLS Denetimi ve Proxy'ler
Bazı kurumsal güvenlik duvarları ve antivirüs ürünleri, kendi sertifikalarını sunarak TLS'in arasına girer. Belirti, doğrulama hatası 19 ve güvenlik ürününe ait bir sertifika veren (issuer) adıdır. Ağ ekibinizden broker hostname'ini muaf tutmasını isteyin veya denetim zorunluysa kuruluşun CA'sına yalnızca o ortamda açıkça güvenin. Bir proxy'yi aşmak için doğrulaması devre dışı bırakılmış cihazları asla sahaya göndermeyin.
Sistematik Kontrol Listesi
- Başarısız olan ortamdan
-servernameileopenssl s_clientçalıştırın. - Portun aktarım yöntemiyle eşleştiğini doğrulayın: 1883 şifresiz, 8883 TLS, 8084 güvenli WebSocket.
- İstemcinin IP ile değil hostname ile bağlandığını doğrulayın.
- Güven deposunun veya CA dosyasının doğru kökü içerdiğini kontrol edin.
- Sistem saatini UTC olarak kontrol edin.
- Otomatik TLS sürüm anlaşmasına izin verin.
- Telefon hotspot'u gibi farklı bir ağdan test ederek proxy'leri ekarte edin.
- Hatalı kimlik bilgileri veya client ID çakışması gibi MQTT düzeyindeki hataları ancak handshake başarılı olduktan sonra ayıklayın.
Son madde önemlidir: başarılı bir handshake'in ardından bir CONNACK reason code'uyla gelen bağlantı kesilmesi TLS değil, kimlik doğrulama veya protokol sorunudur.
Yönetilen Bir Broker ile Daha Az Handshake Sorunu
Kendi barındırılan broker'lardaki pek çok TLS olayı sunucu tarafından kaynaklanır: süresi dolmuş sertifikalar, eksik zincirler veya bir yükseltmeden sonra yanlış yapılandırılmış bir listener. Tam yönetilen bir MQTT hizmeti bu sorumluluğu sağlayıcıya devreder. ConnectMQ, otomatik yenilenen Let's Encrypt sertifikalarıyla 8883'te TLS ve 8084'te güvenli WebSocket sunar; böylece bir handshake başarısız olursa istemci tarafına bakmanız gerektiğini bilirsiniz. Herhangi bir istemciyi önce herkese açık MQTT test broker'ına karşı test edebilirsiniz; bulut MQTT broker rehberimiz ise barındırılan broker'ların üretime nasıl oturduğunu ele alır.
ConnectMQ ile Başlayın
app.connectmq.com adresinde Serverless planla, kredi kartı olmadan ücretsiz bir broker oluşturun, oluşturulan kimlik bilgilerini kopyalayın ve kendi cihaz kodunuzu ayıklamadan önce broker'ın çalıştığını doğrulamak için portaldaki tarayıcı içi MQTT istemcisini kullanın.
Sık Sorulan Sorular
mosquitto_sub neden yalnızca "A TLS error occurred" diyor?
mosquitto istemcileri OpenSSL ayrıntısını gizler. Tam doğrulama hatasını görmek için aynı host, port ve CA dosyasıyla openssl s_client çalıştırın.
Yanlış bir kullanıcı adı veya parola TLS handshake hatasına yol açabilir mi?
Hayır. Kimlik bilgileri handshake'ten sonra, MQTT CONNECT alışverişi içinde kontrol edilir. Bir kimlik bilgisi sorunu TLS hatası olarak değil, CONNACK reddi olarak görünür.
İstemcim evdeki Wi-Fi'da çalışıyor ama ofiste çalışmıyor. Neden?
Ofis ağı muhtemelen 8883 portunu engelliyor veya TLS trafiğini denetliyor. Test-NetConnection veya nc ile test edin ve 8084 portunda güvenli WebSocket'i deneyin.
Bağlanabilmek için sertifika doğrulamasını devre dışı bırakmalı mıyım?
Hayır. Doğrulamayı devre dışı bırakmak asıl sorunu gizler ve sahte broker'lara karşı korumayı ortadan kaldırır. Bunun yerine CA'yı, hostname'i veya saati düzeltin.



