MQTT Güvenliği

MQTT TLS Yapılandırması: 8883 Portu İçin Pratik Rehber

MQTT TLS'in gerçekte nasıl çalıştığını, istemcilerin neyi doğrulaması gerektiğini ve 8883 portunda şifreli bağlantı için Python, Node.js, ESP32 ve mosquitto istemcilerini nasıl yapılandıracağınızı öğrenin.

8883 portunda şifreli mesaj göndermeden önce broker sertifika zincirini doğrulayan bir IoT cihazını gösteren MQTT TLS yapılandırması 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

Doğru bir MQTT TLS yapılandırması, MQTT'yi düz metin bir protokolden internet üzerinde güvenle çalıştırabileceğiniz bir protokole dönüştürür. Bu rehberde istemcinin handshake sırasında gerçekte neyi doğruladığını, hangi ayarların önemli olduğunu ve Python, Node.js, ESP32 ile komut satırı istemcilerini 8883 portu üzerinden bağlanacak şekilde nasıl yapılandıracağınızı öğreneceksiniz. Her örnek gerçek bir broker'a bağlanır; böylece okurken test edebilirsiniz.

MQTT Neden TLS'e İhtiyaç Duyar?

MQTT'nin kendisinde şifreleme yoktur. 1883 portunda, kullanıcı adı ve parola dahil CONNECT paketi okunabilir baytlar halinde gider; her PUBLISH payload'u da öyle. Aynı Wi-Fi'daki herkes, ele geçirilmiş bir router veya meraklı bir internet servis sağlayıcısı bu trafiği okuyabilir, hatta değiştirebilir. Gizli dinlemenin ötesindeki tehditlerin geniş bağlamını isterseniz MQTT güvenliği en iyi uygulamaları genel bakışımızı okuyun.

TLS (Transport Layer Security), herhangi bir MQTT baytı alınıp verilmeden önce TCP bağlantısını şifreli ve kimliği doğrulanmış bir tünele sarar. MQTT hiç değişmez; broker yalnızca farklı bir portu, geleneksel olarak 8883'ü dinler ve istemci önce bir TLS handshake gerçekleştirir. Bu size üç özellik kazandırır:

  • Gizlilik: Trafik şifrelenir; kimlik bilgileri ve payload'lar aktarım sırasında okunamaz.
  • Bütünlük: Kurcalanmış paketler tespit edilir ve bağlantı düşürülür.
  • Sunucu kimlik doğrulaması: İstemci, bir sahtekârla değil gerçek broker ile konuştuğunu kanıtlar.

Özensiz yapılandırmayla en sık bozulan üçüncü özelliktir ve bu makalenin geri kalanının odak noktası da odur.

İstemcinin Handshake Sırasında Doğruladıkları

İstemciniz bir TLS bağlantısı açtığında broker, sertifikasını ve varsa ara sertifikaları gönderir. İstemci ardından şu kontrolleri yapar:

  1. Güven zinciri: Sunucu sertifikası bir ara sertifika tarafından, o da istemcinin zaten güvendiği bir kök CA tarafından (CA deposu veya sizin sağladığınız bir CA dosyası) imzalanmış olmalıdır.
  2. Geçerlilik süresi: Geçerli zaman, sertifikanın "not before" ve "not after" tarihleri arasında olmalıdır. Gerçek zaman saati olmayan cihazların bağlanmadan önce NTP'ye ihtiyaç duymasının nedeni budur.
  3. Hostname eşleşmesi: Bağlandığınız hostname, sertifikanın Subject Alternative Name listesinde bulunmalıdır. Bir hostname için verilmiş sertifikaya IP adresiyle bağlanmak başarısız olur ve olması da gerekir.
  4. Anahtar sahipliği: Handshake, broker'ın sertifikayla eşleşen özel anahtara sahip olduğunu kanıtlar.

İlgili iki ayrıntı insanları sıklıkla tökezletir. Birincisi SNI (Server Name Indication): İstemci, birden fazla adı barındıran bir sunucunun doğru sertifikayı sunabilmesi için hostname'i handshake içinde gönderir. Modern kütüphaneler, bir hostname verdiğinizde SNI'ı otomatik olarak gönderir. İkincisi, bazı kütüphanelerde hostname doğrulaması zincir doğrulamasından ayrıdır. Hostname kontrolü devre dışıysa bir istemci, yanlış alan adı için verilmiş tamamen geçerli bir sertifikayı kabul edebilir; bu da TLS'in amacını boşa çıkarır.

Bir Bakışta MQTT TLS Yapılandırma Ayarları

Aşağıdaki tablo yaygın aktarım yöntemlerini portlara ve URL şemalarına eşler. Gösterilen portlar ConnectMQ'nun ve geleneğe uyan çoğu broker'ın kullandığı portlardır.

Aktarım Port URL şeması Şifreli Tipik istemci
TCP üzerinden MQTT 1883 mqtt:// Hayır Yalnızca laboratuvar testleri
TLS üzerinden MQTT 8883 mqtts:// Evet Cihazlar, backend'ler, CLI
WebSocket üzerinden MQTT 8083 ws:// Hayır Yerel tarayıcı testleri
Güvenli WebSocket üzerinden MQTT 8084 wss:// (yol /mqtt) Evet Tarayıcılar, kısıtlayıcı ağlar

Güven çapası (trust anchor) için üç seçeneğiniz vardır:

  • Sistem CA deposu: Python, Node.js, Go ve çoğu masaüstü veya sunucu istemcisi için varsayılandır. Broker herkesçe güvenilen bir sertifika kullandığında çalışır.
  • Açık CA dosyası: Kök CA'yı içeren bir PEM dosyası verirsiniz. Özel CA'lar ve çoğu mikrodenetleyici için gereklidir.
  • Sabitleme (pinning): Yalnızca belirli bir CA'ya veya anahtara güvenirsiniz. Daha güçlü ama daha kırılgandır; ESP32 sertifika sabitleme rehberimize bakın.

ConnectMQ broker'ı, tüm yaygın işletim sistemlerinde ve Python (certifi aracılığıyla) ile Node.js'in CA paketlerinde bulunan ISRG Root X1 köküne zincirlenen bir Let's Encrypt sertifikası kullanır. Masaüstü ve sunucularda normalde hiçbir CA dosyası sağlamanız gerekmez.

Kod Yazmadan Önce Bağlantıyı Test Etmek

Uygulama koduna dokunmadan önce ağ yolunu ve sertifikayı OpenSSL ile doğrulayın:

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

Verification: OK ifadesini ve üzerinde anlaşılan protokol sürümünü arayın. Burada bir doğrulama hatası görürseniz hiçbir istemci kütüphanesi de başarılı olmaz; MQTT TLS handshake hatalarını düzeltme yazımız her hatayı tek tek ele alır.

Ardından mosquitto istemcileriyle gerçek bir MQTT gidiş-dönüşü deneyin. İki terminal açın ve benzersiz bir topic öneki seçin:

# Terminal 1: sistem CA dizinini kullanarak TLS üzerinden subscribe (Linux/macOS)
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -i tls-sub-7f3a -t "connectmq/demo/7f3a/#" -v

# Terminal 2: TLS üzerinden publish
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -i tls-pub-7f3a -t "connectmq/demo/7f3a/hello" -m "encrypted hello"

Windows'ta mosquitto sistem deposunu okuyamaz; bu yüzden ISRG Root X1 PEM dosyasını Let's Encrypt'ten indirin ve --cafile isrgrootx1.pem ile verin. Ücretsiz herkese açık MQTT broker anonim bağlantıları kabul eder; dolayısıyla bu komutlar hemen çalışır. Herkese açık alanın herkes tarafından okunabildiğini unutmayın ve oraya asla gerçek veri göndermeyin.

Python İstemci Yapılandırması (paho-mqtt 2.x)

paho-mqtt 2.x ile argümansız tls_set() sistemin varsayılan CA sertifikalarını yükler, hostname kontrolünü etkinleştirir ve geçerli bir sertifika ister. Tam olarak istediğiniz budur.

import ssl
import time
import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
PORT = 8883
TOPIC = "connectmq/demo/7f3a/python"

def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    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="py-tls-7f3a")
client.on_connect = on_connect
client.on_message = on_message

# Sistem CA deposu, sertifika zorunlu, hostname doğrulanır,
# iki tarafın da desteklediği en yeni TLS sürümü
client.tls_set(cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS_CLIENT)

# Özel bir ConnectMQ broker için portaldaki kimlik bilgilerini ekleyin:
# client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")

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

Platformunuzun CA deposu bozuk veya güncel değilse bunun yerine ca_certs=certifi.where() verin. Bir hatayı asla tls_insecure_set(True) ile "düzeltmeyin"; bu, hostname kontrolünü devre dışı bırakır ve sunucu kimlik doğrulamasını sessizce ortadan kaldırır. Yaygın Python hataları için MQTT'de SSL CERTIFICATE_VERIFY_FAILED yazısına bakın.

Node.js İstemci Yapılandırması (MQTT.js v5)

MQTT.js, Node'un yerleşik TLS yığınını kullanır; bu yığın varsayılan olarak Node ile gelen Mozilla CA listesine göre doğrulama yapar ve hostname'i doğrular.

const mqtt = require("mqtt");

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: "node-tls-7f3a",
  protocolVersion: 5,
  // Özel bir broker için:
  // username: "YOUR_USERNAME",
  // password: "YOUR_PASSWORD",
  rejectUnauthorized: true, // varsayılan; üretimde asla false yapmayın
});

const topic = "connectmq/demo/7f3a/node";

client.on("connect", () => {
  console.log("Connected over TLS");
  client.subscribe(topic, { qos: 1 }, () => {
    client.publish(topic, "hello from Node.js", { qos: 1 });
  });
});

client.on("message", (t, payload) => {
  console.log(`${t}: ${payload.toString()}`);
  client.end();
});

client.on("error", (err) => console.error("MQTT error:", err.message));

Özel bir CA'ya güvenmeniz gerekiyorsa seçeneklere ca: fs.readFileSync("ca.pem") ekleyin. Tarayıcıda wss://broker.connectmq.com:8084/mqtt kullanın; sertifika doğrulamasını tarayıcı sizin için yapar.

ESP32 İstemci Yapılandırması

Mikrodenetleyicilerin bir işletim sistemi CA deposu yoktur; bu nedenle kök sertifikayı gömersiniz. Arduino core ile WiFiClientSecure ve PubSubClient şöyle görünür:

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <time.h>

const char* WIFI_SSID = "your-ssid";
const char* WIFI_PASS = "your-password";
const char* BROKER = "broker.connectmq.com";

// letsencrypt.org'dan alınan tam ISRG Root X1 PEM'ini buraya yapıştırın
static const char ROOT_CA[] = R"EOF(
-----BEGIN CERTIFICATE-----
...ISRG Root X1 certificate body...
-----END CERTIFICATE-----
)EOF";

WiFiClientSecure net;
PubSubClient mqtt(net);

void setup() {
  Serial.begin(115200);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) delay(250);

  // Sertifika tarihlerini kontrol etmek için geçerli bir saat gerekir
  configTime(0, 0, "pool.ntp.org");
  while (time(nullptr) < 1700000000) delay(250);

  net.setCACert(ROOT_CA);
  mqtt.setServer(BROKER, 8883);
}

void loop() {
  if (!mqtt.connected()) {
    if (mqtt.connect("esp32-tls-7f3a")) {
      mqtt.publish("connectmq/demo/7f3a/esp32", "hello over TLS");
    } else {
      Serial.printf("MQTT connect failed, state=%d\n", mqtt.state());
      delay(5000);
    }
  }
  mqtt.loop();
}

Özel bir broker için mqtt.connect("YOUR_CLIENT_ID", "YOUR_USERNAME", "YOUR_PASSWORD") kullanın. ESP32 ile SSL üzerinden MQTT eğitimi bellek kullanımını ve yeniden bağlanma davranışını daha ayrıntılı ele alır.

Üretim Kontrol Listesi

  1. Laboratuvar dışındaki her yerde 8883 portunu (tarayıcılar için 8084) kullanın; üretim istemcileri için şifresiz 1883'ü devre dışı bırakın veya güvenlik duvarıyla engelleyin.
  2. Sertifika zincirini "her şeyi kabul et" yerine güvenilen bir köke göre doğrulayın.
  3. Hostname doğrulamasını açık tutun ve her zaman IP ile değil hostname ile bağlanın.
  4. Gömülü cihazlarda handshake'ten önce saati (NTP) senkronize edin.
  5. Leaf sertifikalar sık değiştiği için leaf sertifikaya değil kök CA'ya güvenin.
  6. Kimlik bilgilerini yalnızca TLS üzerinden gönderin ve kaynak kodun dışında saklayın.
  7. CA değişikliklerine hazırlıklı olun: güvenilen kökü kablosuz (OTA) olarak güncellenebilir yapın.
  8. Başarısız bağlantıları izleyin; tekrarlanan TLS veya kimlik doğrulama hataları genellikle yanlış yapılandırmaya veya saldırıya işaret eder.

Sunucu Tarafını Yönetilen Bir Broker'a Bırakın

TLS'in broker tarafı, işin daha az eğlenceli yarısıdır: sertifika edinmek, süreleri dolmadan yenilemek, protokol sürümlerini ve şifreleme takımlarını seçmek ve istemcileri düşürmeden listener'ları yeniden başlatmak. Yönetilen bir MQTT broker bu işi ortadan kaldırır. ConnectMQ, 8883'te TLS'i ve 8084'te güvenli WebSocket'i otomatik yenilenen Let's Encrypt sertifikalarıyla sonlandırır; böylece istemcilerinizin yalnızca yukarıda gösterilen standart yapılandırmaya ihtiyacı olur. Barındırma seçeneklerini karşılaştırıyorsanız bulut MQTT broker rehberimiz artıları ve eksileri açıklar.

ConnectMQ ile Başlayın

app.connectmq.com adresinde ücretsiz bir hesap oluşturun, kredi kartı gerektirmeyen Serverless (Free) planı seçin, bir broker oluşturun ve oluşturulan kullanıcı adını, parolayı ve client ID'yi kopyalayın. Yukarıdaki istemcilerden herhangi birini bu kimlik bilgileriyle 8883 portuna yönlendirin; dakikalar içinde şifreli ve kimliği doğrulanmış bir MQTT bağlantınız olur.

Sık Sorulan Sorular

TLS üzerinden MQTT, şifresiz MQTT'den daha yavaş mı?

Handshake, bağlantı açılırken ek gidiş-dönüşler ve CPU yükü getirir; ancak MQTT bağlantıları uzun ömürlüdür, bu yüzden kararlı durumdaki ek yük küçüktür. Her mesaj için yeniden bağlanmak yerine bağlantıları açık tutun ve oturumları yeniden kullanın.

TLS üzerinden MQTT kullanmak için istemci sertifikasına ihtiyacım var mı?

Hayır. Çoğu dağıtım, sunucu tarafı TLS ile şifreli tünel içinde gönderilen bir kullanıcı adı ve parolayı kullanır. İstemci sertifikaları (mutual TLS), bazı kendi barındırılan broker'ların desteklediği ek bir seçenektir.

ConnectMQ için hangi CA sertifikasına ihtiyacım var?

Broker sertifikası Let's Encrypt tarafından verilir ve ISRG Root X1'e zincirlenir. Masaüstü ve sunucu istemcileri buna zaten güvenir; gömülü cihazlar bu kök PEM'i gömmelidir.

IP adresiyle bağlandığımda istemcim neden başarısız oluyor?

Sertifika IP adreslerini değil hostname'leri listeler; bu nedenle hostname doğrulaması başarısız olur. Her zaman broker.connectmq.com veya broker'ınızın hostname'ini kullanarak bağlanın.

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