IoT Eğitimleri

Python MQTT TLS: paho-mqtt ile 8883 Portunda Güvenli Bağlantı

Python MQTT trafiğinizi paho-mqtt ve 8883 portunda TLS ile şifreleyin: sistem CA deposunu kullanın, host adı doğrulamasını açık tutun, yaygın sertifika hatalarını düzeltin ve yalnızca web portları açıksa güvenli WebSocket üzerinden bağlanın.

8883 portundaki bir broker'a python mqtt tls bağlantısını gösteren bir Python betiği üzerinde asma kilit
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

Python MQTT TLS, kullanıcı adınızı, parolanızı ve sensör verilerinizi internet üzerinden düz metin olarak göndermek ile şifreli ve kimliği doğrulanmış şekilde göndermek arasındaki farktır. Bu eğitimde paho-mqtt'yi işletim sisteminizin güvenilir CA sertifikalarını kullanarak 8883 portunda bağlanacak şekilde yapılandıracak, host adı doğrulamasını açık tutacak ve çoğu kişiyi durduran sertifika hatalarını düzelteceksiniz. Tüm örnekler, herkesçe güvenilen bir Let's Encrypt sertifikası sunan broker.connectmq.com adresine bağlanır; bu yüzden özel CA dosyalarına gerek yoktur.

TLS, MQTT için Ne Yapar

MQTT'nin kendisinde şifreleme yoktur. 1883 portunda kimlik bilgilerinizi içeren CONNECT paketi dahil her şey okunabilir baytlar halinde iletilir. TLS, TCP bağlantısını sarar ve size üç garanti verir:

  1. Gizlilik: ağ yolundaki hiç kimse payload'ları veya parolaları okuyamaz.
  2. Bütünlük: hiç kimse iletimdeki mesajları fark edilmeden değiştiremez.
  3. Sunucu kimlik doğrulaması: istemciniz bir sahtekârla değil, gerçekten istediği broker ile konuştuğunu doğrular.

Üçüncü madde, insanların yanlışlıkla devre dışı bıraktığı maddedir. Doğrulama olmadan şifreleme, sizi pasif dinleyicilere karşı korur ama kendi sertifikasını sunan aktif bir saldırgana karşı korumaz. MQTT güvenliği en iyi uygulamaları rehberi genel resmi ele alır; bu yazı istemci tarafını doğru yapılandırmaya odaklanır.

ConnectMQ her broker'da şu portları sunar:

Port Aktarım Şifreli Python'dan kullanım
1883 TCP üzerinden MQTT Hayır Yalnızca yerel testler
8883 TLS üzerinden MQTT Evet Üretim için varsayılan
8083 WebSocket üzerinden MQTT Hayır Python'dan nadiren gerekir
8084 Güvenli WebSocket üzerinden MQTT, yol /mqtt Evet Yalnızca web portlarına izin verildiğinde

Ön Gereksinimler

python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install "paho-mqtt>=2.0"

Herhangi bir Python kodu yazmadan önce broker sertifikasının makinenizden doğrulandığını kontrol edin. Bu komut zinciri ve doğrulama sonucunu gösterir:

openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -brief </dev/null

Verification: OK ifadesini arayın. OpenSSL burada zaten başarısız oluyorsa sorun kodunuzda değil, sisteminizin CA deposunda veya ağdadır.

Minimal Python MQTT TLS İstemcisi

Bunu tls_client.py olarak kaydedin ve k7f3q2 değerini kendi rastgele dizginizle değiştirin:

import ssl
import time
import uuid

import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
PORT = 8883
TOPIC = "connectmq/demo/k7f3q2/secure"


def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print(f"Connect failed: {reason_code}")
        return
    sock = client.socket()
    print(f"Connected over {sock.version()} using {sock.cipher()[0]}")
    client.subscribe(TOPIC, qos=1)


def on_message(client, userdata, msg):
    print(f"{msg.topic}: {msg.payload.decode()}")


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"tls-{uuid.uuid4().hex[:8]}")
client.on_connect = on_connect
client.on_message = on_message

# İşletim sisteminin güvenilir CA'larını kullan, geçerli bir sertifika iste
# ve BROKER ile eşleştiğini doğrula. Bu güvenli varsayılandır.
client.tls_set(cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS_CLIENT)

client.connect(BROKER, PORT, keepalive=60)
client.loop_start()
time.sleep(2)
client.publish(TOPIC, "hello over TLS", qos=1)
time.sleep(2)
client.disconnect()
client.loop_stop()

Çalıştırdığınızda Connected over TLSv1.3 using TLS_AES_256_GCM_SHA384 gibi bir çıktı, ardından da mesajınızın geri geldiğini görmelisiniz.

tls_set() ne yapar

ca_certs argümanı olmadan çağrıldığında tls_set(), platformun varsayılan güvenilir sertifikalarını yükleyen, sunucunun geçerli bir sertifika sunmasını zorunlu kılan ve sertifikadaki adın connect() fonksiyonuna verdiğiniz host ile eşleştiğini kontrol eden bir SSL context oluşturur. Yukarıdaki açık cert_reqs ve tls_version argümanları varsayılan değerlerdir; niyetin bir sonraki okuyucuya açık olması için yazılmıştır.

Tam kontrol istiyorsanız context'i kendiniz oluşturup verin:

context = ssl.create_default_context()
context.minimum_version = ssl.TLSVersion.TLSv1_2
client.tls_set_context(context)

ssl.create_default_context() host adı kontrolünü ve sertifika doğrulamasını etkinleştirir; minimum sürüm ayarlamak ise eski protokolleri reddeder. tls_set() veya tls_set_context() fonksiyonlarından birini kullanın, ikisini birden değil.

Özel Bir Broker için Kimlik Bilgileri Eklemek

TLS gönderdiğiniz kimlik bilgilerini korur; bu yüzden ikisini her zaman birlikte kullanın. ConnectMQ portalında oluşturulmuş bir broker ile:

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()
client.connect("broker.connectmq.com", 8883, keepalive=60)

Portalda gösterilen host adını ve client ID'yi kullanın; broker, client ID'leri verdiği kimlik bilgilerine bağlar. Gizli bilgileri kaynak kontrolüne eklemek yerine ortam değişkenlerinden (os.environ["MQTT_PASSWORD"]) yükleyin.

Python'dan Güvenli WebSocket

Bazı ağlar standart web portları dışındaki her şeyi engeller. paho, MQTT'yi aynı TLS doğrulamasıyla 8084 portunda güvenli WebSocket üzerinden tünelleyebilir:

client = mqtt.Client(
    mqtt.CallbackAPIVersion.VERSION2,
    client_id=f"wss-{uuid.uuid4().hex[:8]}",
    transport="websockets",
)
client.ws_set_options(path="/mqtt")
client.tls_set()
client.connect("broker.connectmq.com", 8084, keepalive=60)

Geri kalan her şey, yani callback'ler, abonelikler ve publish işlemleri aynı kalır. WebSocket üzerinden MQTT yazısı bu aktarımın ne zaman mantıklı olduğunu açıklar.

Yaygın TLS Hatalarını Düzeltmek

TLS hatalarının çoğu birkaç nedene dayanır. Hata mesajınızı bu tabloyla eşleştirin:

Hata Olası neden Çözüm
CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate Python güvenilir CA'ları bulamıyor Aşağıdaki CA deposu çözümlerine bakın
Hostname mismatch, certificate is not valid for '...' IP adresi veya bir takma adla bağlandınız Tam broker host adıyla bağlanın
certificate is not yet valid veya certificate has expired Cihaz saati yanlış Bağlanmadan önce saati NTP ile senkronize edin
WRONG_VERSION_NUMBER TLS istemcisi düz 1883 portuyla konuşuyor 8883 portunu kullanın
Bağlantı takılıyor, sonra zaman aşımına uğruyor Düz istemci TLS portu 8883 ile konuşuyor veya port engellenmiş tls_set() çağırın veya 8084 portunu deneyin

Eksik bir CA deposunu düzeltmek

  • python.org'dan kurulan Python ile macOS: bu Python, sistem anahtar zincirine erişim olmadan gelir. Python uygulama klasöründeki "Install Certificates.command" betiğini çalıştırın veya paho'yu certifi'ye yönlendirin: pip install certifi, ardından client.tls_set(ca_certs=certifi.where()).
  • Slim Docker imajları: CA paketini kurun, örneğin Debian tabanlı imajlarda apt-get install -y ca-certificates.
  • TLS denetimi yapan kurumsal ağlar: bir proxy sertifikaları kendi sertifikalarıyla değiştirebilir. Doğrulamayı devre dışı bırakmak yerine BT ekibinden kurumsal kök CA'yı isteyin ve ca_certs= ile verin.
  • Gömülü Linux: CA paketini güncelleyin; çok eski imajlar Let's Encrypt'in bağlandığı ISRG Root X1 sertifikasını içermeyebilir.

TLS'i asla doğrulamayı kapatarak "düzeltmeyin"

client.tls_insecure_set(True) çağırma veya cert_reqs=ssl.CERT_NONE geçme tavsiyeleriyle karşılaşacaksınız. Her ikisi de hatayı, herkesten gelen herhangi bir sertifikayı kabul ederek ortadan kaldırır; bu da sunucu kimlik doğrulamasını sessizce yok eder. Bunları yalnızca kendi laboratuvar ağınızda hızlı bir teşhis için kullanın, dağıtılan kodda asla kullanmayın.

Ayrıca broker'ın uç (leaf) sertifikasını istemcinize sabitlemekten (pinning) kaçının. Let's Encrypt sertifikaları düzenli olarak yenilenir; bu yüzden sabitlenmiş bir sertifika bir sonraki yenilemede bozulur. Bunun yerine, varsayılan deponun yaptığı gibi CA'ya güvenin.

Üretim Kontrol Listesi

TLS kullanan bir Python istemcisini dağıtmadan önce her maddeyi doğrulayın:

  1. Her yerde 8883 portu (veya WebSocket ile 8084) kullanılıyor; hiçbir şey 1883'e geri düşmüyor.
  2. tls_set() veya tls_set_context(), tls_insecure_set(True) olmadan çağrılıyor.
  3. İstemci asla IP adresiyle değil, host adıyla bağlanıyor.
  4. Cihaz, açılışta NTP ile senkronize edilen doğru bir saat tutuyor.
  5. Cihazdaki CA paketi korunuyor ve işletim sistemiyle birlikte güncelleniyor.
  6. Kimlik bilgileri ortam değişkenlerinden veya bir gizli bilgi deposundan geliyor.
  7. Yeniden bağlanma mantığı yerinde; paho-mqtt yeniden bağlanma rehberi sağlam bir desen gösterir.

Sırada Ne Var

paho'da yeniyseniz paho mqtt python eğitimi publish ve subscribe temellerini ele alır; aiomqtt ve asyncio rehberi ise asenkron bir istemciye nasıl tls_context geçileceğini gösterir. Diğer dillerdeki istemciler için MQTT istemci kütüphanelerine genel bakış ekosistemler arasındaki TLS desteğini karşılaştırır. Python ssl modülü dokümantasyonu burada kullanılan her context seçeneği için başvuru kaynağıdır.

MQTT Trafiğinizi ConnectMQ ile Güvenceye Alın

ConnectMQ, 8883 portunda TLS ve 8084 portunda güvenli WebSocket'in kutudan çıktığı gibi etkin olduğu, otomatik yönetilen bir Let's Encrypt sertifikasıyla desteklenen tam yönetilen bir MQTT hizmetidir; böylece Python istemcileriniz broker'ı zaten sahip oldukları CA deposuyla doğrular. Herkese açık MQTT test broker'ında test edin, ardından üretilen kimlik bilgileriyle özel bir bulut MQTT broker'ına geçin. Serverless planında ücretsiz broker'ınızı oluşturun, kredi kartı gerekmez.

Sık Sorulan Sorular

TLS ile bağlanmak için bir CA sertifikası indirmem gerekir mi?

Hayır. Broker, güncel işletim sistemlerinin güvendiği bir köke bağlanan bir Let's Encrypt sertifikası kullanır; bu yüzden varsayılan CA deposuyla tls_set() çalışır.

TLS üzerinden MQTT hangi portu kullanır?

Standart port 8883'tür. ConnectMQ ayrıca /mqtt yoluyla 8084 portunda güvenli WebSocket üzerinden MQTT sunar.

IP adresiyle bağlandığımda python mqtt tls neden başarısız oluyor?

Host adı doğrulaması, sertifikadaki adı bağlandığınız host ile karşılaştırır. Bir IP adresi broker'ın adıyla eşleşmez, dolayısıyla kontrol tasarım gereği başarısız olur; host adını kullanın.

MQTT istemcimi güvenceye almak için TLS yeterli mi?

TLS bağlantıyı korur, ancak yine de güçlü, cihaza özel kimlik bilgilerine ve dikkatli bir topic tasarımına ihtiyacınız vardır. TLS'i broker portalından alınan benzersiz kimlik bilgileriyle birleştirin.

İlgili yazılar

Test, Betik ve Hata Ayıklama için En İyi MQTT CLI Araçları

mosquitto_pub/sub, MQTTX CLI, HiveMQ MQTT CLI, MQTT.js CLI, curl ve mqttui'nin uygulamalı karşılaştırması; betik yazma ve hata ayıklama için doğru aracı seçebilmeniz için aynı test broker.connectmq.com üzerinde çalıştırıldı.

7 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.