MQTT Güvenliği

MQTT TLS Handshake Hatası: Nasıl Teşhis Edilir ve Düzeltilir?

MQTT TLS handshake hataları için adım adım sorun giderme rehberi: yanlış portları, eksik CA'ları, SNI sorunlarını, saat kaymasını, TLS sürüm uyuşmazlıklarını ve araya giren proxy'leri openssl s_client ile tespit edin.

Bir istemci ile broker arasındaki bozuk handshake'i ve tanılama terminal çıktısını gösteren MQTT TLS handshake hatası sorun giderme illüstrasyonu
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

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:

  1. İstemci, desteklenen TLS sürümleri, şifreleme takımları ve sunucu adını (SNI) içeren ClientHello'yu gönderir.
  2. Broker seçtiği sürüm ve şifreleme takımıyla birlikte sertifika zincirini gönderir.
  3. İstemci zinciri güvenilen köklere göre doğrular, geçerlilik tarihlerini kontrol eder ve hostname'i eşleştirir.
  4. 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 --cafile vermediğiniz sürece sistem deposunu kullanmaz. Windows'ta ISRG Root X1 PEM'ini indirin ve --cafile ile verin.
  • Minimal Docker imajlarında çoğu zaman ca-certificates paketi 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

  1. Başarısız olan ortamdan -servername ile openssl s_client çalıştırın.
  2. Portun aktarım yöntemiyle eşleştiğini doğrulayın: 1883 şifresiz, 8883 TLS, 8084 güvenli WebSocket.
  3. İstemcinin IP ile değil hostname ile bağlandığını doğrulayın.
  4. Güven deposunun veya CA dosyasının doğru kökü içerdiğini kontrol edin.
  5. Sistem saatini UTC olarak kontrol edin.
  6. Otomatik TLS sürüm anlaşmasına izin verin.
  7. Telefon hotspot'u gibi farklı bir ağdan test ederek proxy'leri ekarte edin.
  8. 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.

İlgili yazılar

MQTT Kimlik Bilgileri Kesintisiz Nasıl Yenilenir?

Bir filo genelinde MQTT kullanıcı adı ve şifrelerini yenilemek için adım adım çift kimlik bilgisi stratejisi: yeni kimlik bilgisini hazırlayın, geri dönüş seçeneğiyle geçiş yapın, doğrulayın ve ancak ondan sonra eskisini iptal edin.

6 dk okuma

MQTT Kimlik Bilgilerini Gömülü Cihazlarda Güvenle Saklamak

ESP32 ve Linux cihazlarda MQTT kullanıcı adı ve şifrelerini korumanın yollarına pratik bir karşılaştırma; şifrelenmiş NVS ve flash şifrelemeden secure element'lere ve TPM destekli systemd kimlik bilgilerine kadar.

6 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.