MQTT Güvenliği

MQTT Hız Sınırlama ve DoS Koruması Rehberi

MQTT broker'larının bağlantı taşkınlarına, yayın fırtınalarına ve aşırı büyük payload'lara karşı nasıl savunma yaptığı, yönetilen bir broker'ın hangi limitleri uyguladığı ve bu limitlere saygı duyan istemcilerin nasıl yazılacağı.

Normal IoT cihazları mesaj göndermeye devam ederken bir yayın fırtınasını yavaşlatan broker'ı gösteren MQTT hız sınırlama diyagramı
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

MQTT hız sınırlama, bir broker'ın kendisini ve kullanıcılarını çok fazla, çok hızlı veya çok büyük veri gönderen istemcilerden korumasının yoludur. Bu yazı MQTT'deki başlıca hizmet engelleme (DoS) kalıplarını, broker'ların bunlara karşı kullandığı limitleri, ConnectMQ'nun kotaları ve flood korumasını nasıl uyguladığını ve sorunu büyütmek yerine geri çekilen istemcilerin nasıl yazılacağını açıklıyor. Hız limiti olaylarının çoğu saldırganlardan değil hatalı firmware'den kaynaklanır; bu yüzden her iki taraf da önemlidir.

MQTT Neden Hız Sınırlamaya İhtiyaç Duyar?

Bir MQTT broker paylaşılan bir kaynaktır. Her bağlantı bellek, her mesaj CPU ve bant genişliği tüketir, her abonelik de yönlendirme işi ekler. Limitler olmadan hatalı davranan tek bir istemci, aynı broker'daki diğer tüm istemciler için hizmeti bozabilir.

Tehdit yalnızca kötü niyetli değildir. Aşırı yüklenmenin yaygın nedenleri şunlardır:

  • Dakikada bir yerine sıkı bir döngüde yayın yapan bir firmware hatası.
  • Bir ağ aksaklığından sonra gecikmesiz bir yeniden bağlanma döngüsünün tüm filoda tekrarlanması.
  • Yanlışlıkla büyük ikili veri blokları yayınlayan bir kamera veya günlükleyici.
  • Yoğun bir broker'da # topic'ine abone olup her mesajı dağıtan bir pano.
  • Ardı ardına bağlantı açan kimlik bilgisi tahmin denemeleri.

Hız sınırlama bu arızaları kesintilerden, kontrol altına alınmış ve görünür hatalara dönüştürür.

MQTT'deki Başlıca DoS Kalıpları

Kalıp Ne olur Tipik savunma
Bağlantı taşkını Her biri bir el sıkışma ve bellek tüketen çok sayıda TCP/TLS bağlantısı hızla açılır IP başına bağlantı hızı limitleri, tenant başına maksimum bağlantı, IP engelleme
Yeniden bağlanma fırtınası Binlerce cihaz bir kesintiden sonra aynı anda yeniden bağlanır İstemci tarafında jitter ile üstel geri çekilme
Yayın fırtınası Bir istemci saniyede beklenenden çok daha fazla mesaj gönderir İstemci başına mesaj hızı limitleri, kötüye kullanımda bağlantıyı kesme
Aşırı büyük payload'lar Devasa mesajlar bellek ve bant genişliği tüketir Maksimum paket boyutu
Abonelik patlaması Bir istemci çok sayıda abonelik veya geniş wildcard'lar oluşturur İstemci başına maksimum abonelik, topic derinliği limitleri
Retained veya oturum şişmesi Çok sayıda retained topic veya kuyrukta mesaj bekleyen uzun ömürlü oturumlar Retained message limitleri, session expiry
Yavaş tüketiciler Yetişemeyen aboneler kuyrukların büyümesine yol açar Kuyruk limitleri, QoS seçimleri, message expiry
Kimlik bilgisi tahmini Tekrarlanan başarısız girişler Başarısız giriş yavaşlatma ve IP engelleme

Broker'lar Limitleri Nasıl Uygular?

Bağlantı Düzeyinde Limitler

Kötüye kullanımı durdurmanın en ucuz yeri, bir istemcinin kimliği doğrulanmadan öncesidir. Broker'lar tek bir IP'nin saniyede kaç bağlantı açabileceğini sınırlar, hesap veya plan başına toplam bağlantıları kısıtlar ve kimlik doğrulamada tekrar tekrar başarısız olan kaynakları engeller. Bir TLS el sıkışması görece maliyetlidir; bu yüzden bu aşamada yavaşlatmak belleğin yanı sıra CPU'yu da korur.

Mesaj Düzeyinde Limitler

Bağlantı kurulduktan sonra broker, istemci başına saniyedeki mesajları ve saniyedeki baytları izleyebilir. Bir istemci bütçeyi aştığında broker'ın birkaç seçeneği vardır: işlemeyi geciktirmek, mesajları düşürmek, bir reason code ile reddetmek veya istemcinin bağlantısını kesmek. MQTT 5 bunu MQTT 3.1.1'e göre çok daha şeffaf hâle getirir.

Paket Boyutu Limitleri

Her broker'ın bir maksimum paket boyutu vardır. MQTT 5 her iki tarafın da bunu duyurmasına izin verir: broker CONNACK içinde Maximum Packet Size gönderir ve istemciler asla daha fazlasını göndermemelidir. Limitin üzerindeki bir mesaj protokol hatasıdır ve genellikle bağlantının kesilmesiyle sonuçlanır.

Abonelik ve Topic Limitleri

İstemci başına abonelik ve topic derinliği üzerindeki üst sınırlar, istemcilerin sınırsız yönlendirme işi oluşturmasını engeller.

Yardımcı Olan MQTT 5 Özellikleri

MQTT 5, limitleri gizemli olmaktan çıkarıp açık hâle getiren birkaç mekanizma ekledi. MQTT 5 özellikleri genel bakışı bunları daha ayrıntılı ele alır.

  • Reason code'lar. Bir broker, veriyi sessizce düşürmek yerine bir PUBACK veya DISCONNECT üzerinde 0x97 Quota exceeded ya da 0x96 Message rate too high ile yanıt verebilir. İstemciler nedeni günlüğe kaydedip yavaşlayabilir.
  • Receive Maximum. Her iki taraf da aynı anda kaç onaylanmamış QoS 1 ve QoS 2 mesajını kabul edeceğini duyurur; bu da temel bir akış kontrolü sağlar.
  • Maximum Packet Size. CONNECT ve CONNACK içinde duyurulur; böylece aşırı büyük mesajlar reddedilmek yerine baştan önlenir.
  • Message expiry. Eski mesajlar çevrimdışı aboneler için birikmek yerine atılır.
  • Session expiry. Terk edilmiş oturumlar otomatik olarak temizlenir.
  • Server Keep Alive. Broker, bir istemcinin keep-alive aralığını geçersiz kılabilir.

MQTT 3.1.1'de limit uygulayan bir broker genellikle yalnızca mesajları düşürebilir veya bağlantıyı kapatabilir; istemci de genel bir ağ hatası görür.

ConnectMQ'daki Limitler

ConnectMQ, paylaşılan kümelerindeki tenant'ları korumak için limitleri birkaç katmanda uygular:

  • Plan başına kotalar. Ücretsiz Serverless planı en fazla 25 bağlantıya, QoS 1'e kadar ve 256 KB mesajlara izin verir. Ücretli Serverless planı bunu en fazla 1.000 bağlantıya, QoS 2'ye ve 1 MB mesajlara yükseltir. Dedicated ve BYOC kurulumları izole altyapıda çalışır.
  • Kota bildirimi. Bir kota aşıldığında MQTT 5 istemcileri 0x97 (quota exceeded) reason code'unu alır; böylece bir limiti ağ hatasından ayırt edebilirsiniz.
  • Kötüye kullanım amaçlı bağlantı ve mesaj kalıplarına karşı flood koruması.
  • Tekrarlanan başarısız girişlerden sonra IP engelleme.
  • Bir tenant'ın trafiğinin başka bir tenant'ın topic'lerine ulaşamaması için tenant izolasyonu.

Herkese açık test broker'ı broker.connectmq.com, herkese açık olduğu için istemci başına daha sıkı limitlere sahiptir: mesaj başına 64 KB, istemci başına saniyede 10 mesaj, istemci başına 10 abonelik, 8 topic seviyesi ve en fazla 30 dakikalık session expiry. Bir test bu limitlere takılıyorsa bu, iş yükünü özel bir broker'a taşımanız için güçlü bir işarettir. Ücretsiz herkese açık MQTT broker yazısı ayrıntıları listeler.

Limitlere Saygı Duyan İstemciler Yazmak

Sunucu tarafı limitler hikâyenin yalnızca yarısıdır. İyi davranan istemcilerden oluşan bir filo, sahip olabileceğiniz en iyi DoS korumasıdır.

  1. Yeniden bağlanırken geri çekilin. Cihazların bir kesintiden sonra aynı anda yeniden bağlanmaması için rastgele jitter ile üstel geri çekilme kullanın.
  2. Toplu gönderin ve birleştirin. Gecikme izin veriyorsa on mesaj yerine on ölçüm içeren tek bir mesaj gönderin.
  3. Her döngüde değil, değişiklikte yayın yapın. Küçük dalgalanmaların trafik oluşturmaması için ölü bantlar (deadband) ekleyin.
  4. Duyurulan paket boyutuna uyun. Maximum Packet Size değerini CONNACK özelliklerinden okuyun.
  5. Reason code'ları ele alın. 0x97 ve 0x96'yı günlüğe kaydedin ve hemen yeniden denemek yerine yayın hızınızı düşürün.
  6. Abonelikleri dar tutun. # topic'ine değil, ihtiyacınız olan topic'lere abone olun.
  7. Benzersiz client ID'ler kullanın. Aynı ID'yi paylaşan iki cihaz, bir taşkın gibi görünen sonsuz bir döngüde birbirini düşürür.

İşte geri çekilme uygulayan, kota reason code'larını ele alan ve kendi yayın hızını sınırlayan, paho-mqtt 2.x kullanan bir Python istemcisi:

import json
import random
import time
import paho.mqtt.client as mqtt

HOST, PORT = "broker.connectmq.com", 8883
CLIENT_ID = f"rate-demo-{random.randint(1000, 9999)}"
TOPIC = f"connectmq/demo/{CLIENT_ID}/telemetry"
MAX_RATE = 2.0  # saniyedeki mesaj sayısı, herkese açık broker limitinin oldukça altında

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID,
                     protocol=mqtt.MQTTv5)
client.tls_set()
# Özel bir broker için ekleyin: client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.reconnect_delay_set(min_delay=1, max_delay=120)  # üstel geri çekilme

slow_down_until = 0.0

def on_connect(c, userdata, flags, reason_code, properties):
    print("connected:", reason_code)
    if properties and hasattr(properties, "MaximumPacketSize"):
        print("broker max packet size:", properties.MaximumPacketSize)

def on_publish(c, userdata, mid, reason_code, properties):
    global slow_down_until
    if reason_code.is_failure:
        print(f"publish {mid} refused: {reason_code}")
        if reason_code.value in (0x96, 0x97):
            slow_down_until = time.time() + 30  # 30 sn duraklat

def on_disconnect(c, userdata, flags, reason_code, properties):
    print("disconnected:", reason_code)

client.on_connect = on_connect
client.on_publish = on_publish
client.on_disconnect = on_disconnect

client.connect(HOST, PORT, keepalive=60)
client.loop_start()

interval = 1.0 / MAX_RATE
try:
    while True:
        if time.time() < slow_down_until:
            time.sleep(1)
            continue
        payload = json.dumps({"t": round(20 + random.random(), 2), "ts": int(time.time())})
        client.publish(TOPIC, payload, qos=1)
        time.sleep(interval)
except KeyboardInterrupt:
    client.loop_stop()
    client.disconnect()

Aynı ilkeler firmware için de geçerlidir. Bir ESP32'de her yeniden bağlanma denemesinden önce jitter içeren bir gecikme koyun ve publish() fonksiyonunu asla zamanlayıcısız bir döngüden çağırmayın; ESP32 MQTT eğitimi engellemeyen bir kalıp gösterir.

Hız Limiti Sorunlarını İzlemek

İstemci günlüklerinizde ve broker panolarınızda şu sinyallere dikkat edin:

  • Aynı anda birçok cihazda bağlantı kopmalarında ani artışlar.
  • Aynı istemciden tekrarlanan 0x97 veya 0x96 reason code'ları.
  • Birkaç saniyelik bir döngüde bağlanan, yayın yapan ve bağlantıyı kesen cihazlar.
  • Yapılandırılmış raporlama aralığıyla uyuşmayan bir mesaj hızı.

ConnectMQ'da portal panosu ve canlı topic gezgini çok konuşan bir istemciyi fark etmenize yardımcı olur; $SYS/broker/connection/{clientId}/state de belirli bir istemcinin bağlantı durumunu izlemenizi sağlar.

Daha Büyük Bir Plana Ne Zaman Geçmeli?

Limitlere takılan şey bir hata değil de meşru trafikse, çözüm istemcileri daha da kısıtlamak değil kapasitedir. Belirtiler arasında bağlı cihaz sayısında istikrarlı büyüme, QoS 2 ihtiyacı veya 256 KB'ın üzerindeki payload'lar yer alır. Yönetilen MQTT broker rehberi serverless ve dedicated seçeneklerin nasıl farklılaştığını açıklar; açıkta kalan MQTT broker'lar hakkındaki ilgili yazı da limitsiz kendi barındırılan broker'ların neden risk olduğunu gösterir.

ConnectMQ ile Başlayın

app.connectmq.com adresinde kredi kartı gerekmeden ücretsiz Serverless planında bir broker oluşturun, yukarıdaki istemciyi oluşturulan kimlik bilgilerinizle bağlayın ve kotaların ve reason code'ların pratikte nasıl davrandığını görün. Daha geniş rehberlik için MQTT güvenliği en iyi uygulamaları yazısını okuyun.

Sık Sorulan Sorular

MQTT reason code 0x97 ne anlama gelir?

"Quota exceeded" (kota aşıldı) anlamına gelir. Broker istemciye izin verilen bir limiti aştığını söylüyordur; bu yüzden istemci hemen yeniden denemek yerine yavaşlamalıdır.

MQTT 3.1.1 hız limiti geri bildirimini destekliyor mu?

Doğrudan desteklemez. MQTT 3.1.1'de PUBACK üzerinde reason code yoktur; bu yüzden bir broker yalnızca mesajları düşürebilir veya bağlantıyı kesebilir. Açık geri bildirim almak için istemcileri MQTT 5'e yükseltin.

Cihazda da hız sınırlaması yapmalı mıyım?

Evet. İstemci tarafında yavaşlatma, toplu gönderim ve yeniden bağlanma geri çekilmesi olayların çoğunu önler ve sizi broker limitlerinin rahatça içinde tutar.

Yeniden bağlanma fırtınası nedir?

Birçok cihazın aynı anda bağlantısını kaybedip hepsinin hemen yeniden denemesiyle ortaya çıkar. Rastgele jitter ile üstel geri çekilme, yeniden bağlanmaları zamana yayar.

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