MQTT güvenliği, çoğu ekibin bildiği ama teslim tarihi baskısı altında yine de atladığı bir avuç alışkanlığa dayanır. Bu rehber, onları herhangi bir kuruluma uygulayabileceğiniz 12 maddelik bir kontrol listesine dönüştürüyor; Python'da ve komut satırında TLS doğrulaması için kopyala-yapıştır kodla birlikte. Her madde için ConnectMQ gibi yönetilen bir broker'ın sizin için zaten neler yaptığını ve hâlâ sizin işiniz olan kısmı da belirtiyoruz.
MQTT Güvenliği Neden Kendi Kontrol Listesini Gerektirir?
MQTT hafif olacak şekilde tasarlandı. Protokolün kendisi CONNECT içinde bir kullanıcı adı ve parola alanı tanımlar; şifreleme, yetkilendirme ve kötüye kullanım koruması gibi geri kalan her şeyi broker'a ve ağ katmanına bırakır. Bu esneklik kısıtlı cihazlar için harikadır; ancak aynı zamanda bir MQTT kurulumunun tam olarak en zayıf yapılandırma tercihi kadar güvenli olduğu anlamına gelir.
Tipik başarısızlık senaryoları sıkıcı ve önlenebilirdir:
- Açık internet üzerinden 1883 portunda düz TCP konuşan cihazlar.
- Her cihazın firmware'ine gömülmüş tek bir ortak parola.
- Yalnızca topic adı üzerinden veri sızdıran
customers/jane.doe@example.com/locationgibi topic'ler. - Her payload'a güvenen ve bozuk girdide çöken (ya da daha kötüsü) subscriber'lar.
- Bir TLS hatasını sertifika doğrulamasını kapatarak "düzelten" client'lar.
Broker'ların mesajları nasıl yönlendirdiğine yeniyseniz önce MQTT Broker Nedir? yazısıyla başlayın ve buraya dönün.
Bir Bakışta MQTT Güvenliği Kontrol Listesi
| # | Uygulama | Sizin sorumluluğunuz | ConnectMQ'nun sağladığı |
|---|---|---|---|
| 1 | Her zaman TLS kullanın | 8883 / 8084'e bağlanın | 8883'te TLS, 8084'te WSS, Let's Encrypt sertifikası |
| 2 | Gerçek veriyi public alanın dışında tutun | Üretimde portal kimlik bilgilerini kullanın | Kiracı topic'leri public alandan izole |
| 3 | Broker/cihaz başına benzersiz kimlik bilgileri | Tek bir parolayı her yerde kullanmayın | Broker başına üretilen kullanıcı adı, parola ve client ID |
| 4 | Client ID'leri kısıtlayın | Verilen ID'yi ve soneklerini kullanın | Yalnızca verilen client ID ve _suffix varyantları kabul edilir |
| 5 | Sırları cihazlarda güvenle saklayın | Şifreli depolama, Git'te sır yok | — |
| 6 | Hiçbir şey sızdırmayan topic'ler tasarlayın | Topic adlarında kişisel veri yok | Çok kiracılı izolasyon |
| 7 | Her payload'u doğrulayın | Subscriber'larda şema kontrolleri | Plan başına mesaj boyutu limitleri |
| 8 | Hız limitleri ve kotalar uygulayın | Publisher'ları kısın | Plan bazlı kotalar, 0x97 Quota exceeded reason code'u |
| 9 | Brute force ve bağlantı sellerine karşı savunun | Hatalarda geri çekilin (back off) | Tekrarlanan hatalı kimlik bilgilerinden sonra IP engelleme, bağlantı seli koruması |
| 10 | Bağlantı durumunu izleyin | Beklenmeyen kopmalarda alarm verin | $SYS/broker/connection/{clientId}/state |
| 11 | Client'larda sertifikaları doğrulayın | Doğrulamayı asla kapatmayın | Herkesçe güvenilen sertifika zinciri |
| 12 | Topic seviyesinde yetkilendirin | Broker'ları veya uygulamaları güven sınırına göre ayırın | Kiracı seviyesinde izolasyon |
Yazının geri kalanı her maddeyi tek tek ele alıyor.
1. Her Zaman TLS Kullanın (8883 ve 8084 Portları)
1883 portundaki düz MQTT; kullanıcı adlarını, parolaları ve payload'ları açık metin olarak gönderir. Yol üzerindeki herkes (bir kafenin Wi-Fi'ı, ele geçirilmiş bir router, aynalanmış bir switch portu) bunları okuyabilir ve tekrar oynatabilir. TLS, bağlantıyı şifreleyip broker'ın kimliğini kanıtlayarak bu sorunu çözer.
ConnectMQ'da her broker şunları kabul eder:
mqtts://broker.connectmq.com:8883üzerinde TLS üzerinden MQTTwss://broker.connectmq.com:8084/mqttüzerinde güvenli WebSocket üzerinden MQTT
Her ikisi de Let's Encrypt sertifikası kullanır; bu yüzden standart işletim sistemi güven depoları ona zaten güvenir. 1883 ve 8083 portlarını yalnızca geliştirme amaçlı kabul edin. Tarayıcı uygulamaları zaten WSS kullanmak zorundadır; eksiksiz bir örnek için WebSocket üzerinden MQTT yazısına bakın.
2. Gerçek Veriyi Asla Public Alana Koymayın
broker.connectmq.com, denemeler için anonim bir public alan sunar: kullanıcı adı olmadan, benzersiz bir client ID ile bağlanırsınız ve hemen yayın yapıp abone olabilirsiniz. Öğrenmek için harikadır ve tamamen herkese açıktır. Doğru topic'e abone olan herkes mesajlarınızı okuyabilir.
Public alanın kuralları:
- Başkalarıyla çakışmamak için
connectmq/demo/<your-random-id>/...gibi rastgele bir önek kullanın. - Asla kişisel veri, kimlik bilgisi, konum veya bir foruma yazmayacağınız hiçbir şeyi yayınlamayın.
- Gerçek kullanıcılar veya gerçek cihazlar devreye girmeden önce portal kimlik bilgilerine geçin.
ConnectMQ'da kimliği doğrulanmış kiracılar izoledir: topic'leri diğer kiracılara veya public alana görünmez; public client'lar da yalnızca diğer public client'ları görür. Ayrıntılar ücretsiz public MQTT broker rehberimizde.
3. Broker ve Cihaz Başına Benzersiz Kimlik Bilgileri Kullanın
Bir filo genelinde paylaşılan tek bir parola, firmware imajlarından birinin çıkarılmasının tüm cihazları tehlikeye atması demektir. Filonun geri kalanına dokunmadan iptal edilebilen kimlik bilgilerini hedefleyin.
ConnectMQ portalında (https://app.connectmq.com) oluşturduğunuz her broker için bir kullanıcı adı, parola ve client ID üretilir. Üretilen sırlar klasik zayıf seçimlerden (admin/admin, iot123) kaçınır ve ortamları ayrı tutar: kimlik bilgilerini paylaşmak yerine staging için bir broker, üretim için başka bir broker oluşturun.
Broker ne olursa olsun, bir cihaz hizmetten çıkarıldığında kimlik bilgilerini yenileyin ve üretim sırlarını asla destek kayıtlarına, sohbetlere veya ekran görüntülerine yapıştırmayın.
4. Client ID'leri Kısıtlayın
MQTT client ID'si bir oturumu tanımlar. Herkes herhangi bir client ID ile bağlanabiliyorsa, bir cihazın ID'sini bilen saldırgan onu çevrimdışı bırakabilir (yinelenen bir ID bağlandığında broker mevcut oturumu keser) veya kalıcı oturumunu ele geçirebilir.
ConnectMQ, kimliği doğrulanmış bağlantıları broker için verilen client ID ve onun _suffix varyantlarıyla sınırlar. Verilen ID'niz YOUR_CLIENT_ID ise YOUR_CLIENT_ID_sensor1, YOUR_CLIENT_ID_dashboard gibi ID'lerle bağlanabilirsiniz, ancak rastgele ID'lerle bağlanamazsınız. Bu size öngörülebilir, denetlenebilir oturum adları sağlar ve yabancıların oturumlarınızı taklit etmesini engeller.
Pratik ipucu: Soneki cihazdaki sabit bir değerden, örneğin seri numarası veya MAC adresinden türetin; böylece yeniden bağlanmalar aynı oturumu kullanır.
5. Sırları Cihazlarda Güvenle Saklayın
Kimlik bilgilerinin cihazda bir yerde durması gerekir. O yeri pratik olarak mümkün olduğunca erişilmez kılın:
- Kimlik bilgilerini kaynak kontrolüne commit etmeyin. Ayrı, git tarafından yok sayılan bir yapılandırma başlığı veya ortam dosyası kullanın.
- Platformun korumalı depolamasını mümkün olduğunda kullanın (ESP32'de şifreli flash / NVS şifreleme, gateway'lerde TPM veya secure element, sunucularda bir secrets manager).
- Sırların kolayca dökülememesi için üretim firmware'inde debug portlarını ve seri konsolları devre dışı bırakın.
- Sırları ortak bir imaja derlemek yerine üretim sırasında cihaz başına yazan bir provizyon adımı planlayın.
6. Bilgi Sızdırmayan Topic'ler Tasarlayın
Topic adları meta veridir ve meta veri sızar. Payload'lar şifreli olsa bile hospital/ward3/patient-4471/heart-rate gibi bir topic, onu gözlemleyebilen herkese çok şey anlatır.
Yönergeler:
- İsim, e-posta veya adres yerine opak tanımlayıcılar (
site-07/dev-3fa9/telemetry) kullanın. - İzinler ve wildcard'lar yönetilebilir kalsın diye
site/area/line/device/kindgibi tutarlı bir hiyerarşi koruyun. - Üretimdeki tüketicilerde
#gibi geniş wildcard aboneliklerden kaçının; ihtiyacınız olana abone olun. - Seviye sayısını makul tutun. Örneğin public alan en fazla 8 topic seviyesine izin verir.
7. Her Payload'u Doğrulayın
Broker baytları taşır; JSON'unuzun düzgün olup olmadığını veya 9.000 °C'lik bir sıcaklığın makul olup olmadığını bilmez. Her subscriber, gelen payload'ları güvenilmeyen girdi olarak ele almalıdır.
import json
ALLOWED_KEYS = {"temperature", "humidity", "ts"}
def parse_telemetry(raw: bytes):
if len(raw) > 4096:
raise ValueError("payload too large")
data = json.loads(raw.decode("utf-8"))
if not isinstance(data, dict) or not set(data) <= ALLOWED_KEYS:
raise ValueError("unexpected fields")
t = float(data["temperature"])
if not -40.0 <= t <= 125.0:
raise ValueError("temperature out of range")
return data
Reddedin, loglayın ve devam edin. Payload içeriğini asla doğrudan SQL'e, kabuk komutlarına veya HTML'e aktarmayın. ConnectMQ plan başına maksimum mesaj boyutlarını uygular (örneğin ücretsiz Serverless planında 256 KB ve public alanda 64 KB); bu en kötü durumu sınırlar, ancak şema doğrulaması sizin işiniz olmaya devam eder.
8. Hız Limitleri ve Kotalar Uygulayın
Olabildiğince hızlı yayın yapan hatalı bir firmware döngüsü, kendi yazdığınız bir hizmet reddi (DoS) saldırısıdır. Cihaz tarafında kısıtlayın (değişiklikte veya sabit aralıkla yayın yapın) ve broker'ın da limit uygulamasını bekleyin.
ConnectMQ, plan ve alan bazında kotalar uygular. Örneğin public alan, client başına saniyede 10 mesaja ve 10 aboneliğe izin verir. MQTT 5'te bir client bir kotayı aştığında broker 0x97 Quota exceeded reason code'u ile yanıt verir; yoğun yük altında 0x89 Server busy ile yanıt verebilir. Bu kodları açıkça ele alın: sıkı bir döngüde yeniden denemek yerine geri çekilin, loglayın ve alarm verin. MQTT 5 özellikleri rehberi reason code'ları daha ayrıntılı açıklar.
9. Brute Force ve Bağlantı Sellerine Karşı Koruyun
İnternete açık broker'lar sürekli parola tahmini denemeleri ve yeniden bağlanma fırtınalarıyla karşılaşır. ConnectMQ'da:
- Tekrarlanan hatalı kimlik bilgisi denemelerinden sonra IP adresleri engellenir.
- Bağlantı selleri geçici yasaklamaları tetikler.
- Uyarlanabilir aşırı yük koruması, ani yük artışlarında kümenin yanıt verebilir kalmasını sağlar.
Client tarafında jitter'lı üstel geri çekilme (exponential backoff) uygulayın. Bir ağ aksaklığından sonra tüm filo aynı anda yeniden bağlanırsa meşru cihazlar bile bir sel gibi görünür.
10. Bağlantı Durumunu $SYS ile İzleyin
Göremediğiniz şeyi güvenceye alamazsınız. ConnectMQ, her client'ın bağlantı durumunu $SYS/broker/connection/{clientId}/state üzerinde yayınlar: client bağlandığında 1, bağlantı kesildiğinde 0. Bir izleme servisinden abone olun ve beklenmeyen kopmalarda veya alışılmadık saatlerde bağlanan bir cihazda alarm verin.
mosquitto_sub -h broker.connectmq.com -p 1883 -i monitor-7c2e \
-t '$SYS/broker/connection/my-device-7c2e/state' -v
# $SYS/broker/connection/my-device-7c2e/state 1
# $SYS/broker/connection/my-device-7c2e/state 0
Sisteminizin geri kalanının düzensiz bağlantı kesilmelerinden haberdar olması için bunu MQTT Last Will mesajlarıyla birleştirin.
11. Her Client'ta Sertifikaları Doğrulayın
Sertifika doğrulaması olmayan TLS, bilinmeyen bir tarafa yapılan şifrelemedir. Araya giren bir saldırgan herhangi bir sertifika sunabilir ve client kimlik bilgilerini ona memnuniyetle gönderir. Ne yazık ki "doğrulamayı kapat", TLS hataları için yaygın bir kopyala-yapıştır çözümüdür.
Python (ssl modülüyle paho-mqtt 2.x)
import ssl
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, reason_code, properties):
print("Connected:", reason_code)
ctx = ssl.create_default_context() # sistem CA'ları, hostname kontrolü açık
ctx.minimum_version = ssl.TLSVersion.TLSv1_2
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set_context(ctx)
client.on_connect = on_connect
client.connect("broker.connectmq.com", 8883)
client.loop_forever()
ctx.check_hostname = False, ssl.CERT_NONE veya client.tls_insecure_set(True) ile asla ürün göndermeyin.
mosquitto_pub ve mosquitto_sub
Linux'ta CLI'ı sistem CA dizinine yönlendirin. Herhangi bir platformda ise ISRG Root X1 sertifikasını (isrgrootx1.pem) Let's Encrypt'ten indirip --cafile ile verebilirsiniz:
# Linux: sistem CA deposu
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-u YOUR_USERNAME -P YOUR_PASSWORD -i YOUR_CLIENT_ID_cli \
-t "site-07/#" -v
# Herhangi bir işletim sistemi: açık kök sertifika
mosquitto_pub -h broker.connectmq.com -p 8883 --cafile isrgrootx1.pem \
-u YOUR_USERNAME -P YOUR_PASSWORD -i YOUR_CLIENT_ID_pub \
-t "site-07/dev-3fa9/telemetry" -m '{"temperature":22.5}'
Hostname veya zincir eşleşmezse bağlantı başarısız olur. Bu başarısızlık bir hata değil, özelliktir.
12. Gereken Yerde Topic Seviyesinde Yetkilendirin
Genel bir MQTT uygulaması olarak en az yetki ilkesi topic'ler için de geçerlidir: bir sıcaklık sensörü yalnızca kendi telemetri topic'ine yayın yapmalı ve yalnızca kendi komut topic'ine abone olmalıdır. Birçok mimari bunu topic seviyesinde yetkilendirme kurallarıyla veya farklı güven seviyelerindeki cihazları ayrı kimlik bilgileri ve ayrı broker'lar arkasına yerleştirerek uygular.
ConnectMQ'da izolasyon sınırı kiracıdır: bir kiracının topic'leri asla başka bir kiracıya veya public alana görünmez. Cihaz grupları arasında kesin bir ayrıma ihtiyacınız varsa portalda onlar için ayrı broker'lar oluşturun ve uygulama seviyesindeki kontrolleri (kimin hangi komutu gönderebileceği) backend'inizde tutun.
Uçtan Uca Güvenli Bir Bağlantı
Hepsini bir araya getirirsek, üretime hazır bir ConnectMQ client'ı; sertifika doğrulaması açıkken 8883 portuna (veya WSS 8084'e) bağlanır, portalda üretilen kimlik bilgileri ve YOUR_CLIENT_ID_<device> biçiminde bir client ID ile kimlik doğrular, opak topic'lere makul bir hızda yayın yapar, 0x97 ve 0x89'da geri çekilir ve $SYS üzerinden izlenir.
Cihaz tarafında adım adım bir anlatım için, sketch'in TLS ile güvenceye alınmış bir sürümüyle biten ESP32 MQTT eğitimine bakın.
ConnectMQ ile Başlayın
ConnectMQ; TLS ve WSS uç noktaları, üretilen kimlik bilgileri, client ID kısıtlamaları, kiracı izolasyonu ve kötüye kullanım korumasını kutudan çıktığı gibi sunar; böylece ekibiniz MQTT güvenliğinin yalnızca sizin sahiplenebileceğiniz kısımlarına odaklanabilir. https://app.connectmq.com adresinde ücretsiz Serverless planında bir broker oluşturun (kredi kartı gerekmez) ve ilk güvenli client'ınızı dakikalar içinde bağlayın.
Sık Sorulan Sorular
MQTT varsayılan olarak güvenli mi?
Hayır. MQTT protokolü kimlik doğrulama alanlarını tanımlar, ancak şifreleme ve yetkilendirmeyi broker'a ve taşıma katmanına bırakır. Güvenli hale getirmek için TLS'e, güçlü cihaz başına kimlik bilgilerine ve makul broker limitlerine ihtiyacınız vardır.
Güvenli MQTT için hangi portu kullanmalıyım?
TLS üzerinden MQTT için 8883'ü, güvenli WebSocket (WSS) üzerinden MQTT için 8084'ü kullanın. ConnectMQ'da her ikisi de herkesçe güvenilen bir Let's Encrypt sertifikası kullanır.
broker.connectmq.com'un public alanını üretimde kullanabilir miyim?
Hayır. Public alan anonimdir ve topic'lerinize abone olan herkes tarafından okunabilir. Gerçek her veri için ConnectMQ portalından alınan kimlik bilgilerini kullanın; kimliği doğrulanmış kiracılar public alandan ve birbirlerinden izoledir.
0x97 reason code'u ne anlama gelir?
0x97, "Quota exceeded" (kota aşıldı) için MQTT 5 reason code'udur. ConnectMQ, bir client bir plan veya alan limitini aştığında bunu döndürür; client'ınız hemen yeniden denemek yerine geri çekilmelidir.
Test için sertifika doğrulamasını kapatmak sorun olur mu?
Yalnızca atılacak bir geliştirme makinesinde; dağıtılan firmware'de veya üretim kodunda asla. Doğrulamayı kapatmak, TLS kullanmanın asıl nedeni olan ortadaki adam (man-in-the-middle) saldırılarına karşı korumayı ortadan kaldırır.



