"ssl certificate verify failed" MQTT hatası, Python'un TLS handshake sırasında broker'ın sertifikasını reddettiği anlamına gelir. Bu, görevini yapan bir güvenlik özelliğidir ve çözüm neredeyse hiçbir zaman onu kapatmak değildir. Bu rehber, çalıştığı bilinen bir referans olarak 8883 portunda broker.connectmq.com'u kullanarak hata mesajından tam nedeni nasıl okuyacağınızı ve bunu paho-mqtt ile Windows, macOS, Linux ve Docker'da nasıl doğru şekilde düzelteceğinizi gösterir.
Hata Mesajını Okumak
Tam istisna genellikle şöyle görünür:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed:
unable to get local issuer certificate (_ssl.c:1000)
Önemli olan iki noktadan sonraki kısımdır. Yaygın varyantlar farklı nedenlere işaret eder:
| Mesaj ayrıntısı | Anlamı | En olası çözüm |
|---|---|---|
unable to get local issuer certificate |
Python zinciri imzalayan kök CA'yı bulamıyor | CA paketini onarın veya sağlayın |
self-signed certificate in certificate chain |
Bir şey, güvenilmeyen özel bir CA tarafından imzalanmış sertifika sundu | Proxy veya antivirüs denetimi ya da yapılandırmadığınız özel bir broker CA'sı |
Hostname mismatch, certificate is not valid for '...' |
Bağlandığınız ad sertifikada yok | IP yerine doğru hostname ile bağlanın |
certificate has expired |
Saat yanlış veya sunucu sertifikasının süresi dolmuş | Sistem saatini düzeltin veya sunucu sertifikasını yenileyin |
Adım 1: Python'un Broker'ı Doğrulayabildiğini Teyit Edin
Bu kısa betik, paho-mqtt'nin varsayılan olarak kullandığı ayarların aynısını kullanarak TLS'i MQTT olmadan test eder:
import socket
import ssl
HOST, PORT = "broker.connectmq.com", 8883
ctx = ssl.create_default_context()
print("OpenSSL:", ssl.OPENSSL_VERSION)
print("Default verify paths:", ssl.get_default_verify_paths())
with socket.create_connection((HOST, PORT), timeout=10) as sock:
with ctx.wrap_socket(sock, server_hostname=HOST) as tls:
cert = tls.getpeercert()
print("Connected with", tls.version())
print("Issuer:", dict(x[0] for x in cert["issuer"]))
print("Valid until:", cert["notAfter"])
Bu betik aynı hatayla başarısız olursa sorun Python ortamının güven deposunda, saatte veya ağdadır. Başarılı olup MQTT kodunuz başarısız oluyorsa sorun MQTT istemcisinin nasıl yapılandırıldığındadır: yanlış bir ca_certs yolu, IP ile bağlanma veya özel sertifikalı bir broker.
Adım 2: Doğru Bir paho-mqtt TLS Kurulumu Kullanın
paho-mqtt 2.x ile, ConnectMQ dahil herkesçe güvenilen sertifikaya sahip herhangi bir broker'a karşı çalışan temel kurulum şudur:
import ssl
import time
import certifi
import paho.mqtt.client as mqtt
BROKER = "broker.connectmq.com"
TOPIC = "connectmq/demo/a8d2/verify-test"
def on_connect(client, userdata, flags, reason_code, properties):
print("CONNACK:", reason_code)
client.subscribe(TOPIC)
client.publish(TOPIC, "certificate verified")
def on_message(client, userdata, msg):
print("Received:", msg.payload.decode())
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="py-verify-a8d2")
client.on_connect = on_connect
client.on_message = on_message
# certifi, işletim sistemi deposundan bağımsız olarak Mozilla'nın CA paketini içerir
client.tls_set(ca_certs=certifi.where(), cert_reqs=ssl.CERT_REQUIRED)
# Özel ConnectMQ broker:
# client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.connect(BROKER, 8883, keepalive=60)
client.loop_start()
time.sleep(3)
client.loop_stop()
client.disconnect()
Bağımlılıkları pip install "paho-mqtt>=2.0" certifi ile kurun. certifi.where() vermek, davranışı her işletim sisteminde aynı hale getirir; bu da çoğu zaman en hızlı kalıcı çözümdür. CA listeleri zamanla değiştiği için certifi'yi güncel tutun.
Her Platform İçin Çözümler
macOS
python.org'dan alınan Python yükleyicileri kendi OpenSSL'lerini içerir ve macOS Keychain'i kullanmaz. Birlikte gelen betiği çalıştırana kadar hiç CA sertifikaları yoktur; bu da unable to get local issuer certificate hatasını üretir. Yükleyicinin sertifika betiğini çalıştırarak düzeltin:
/Applications/Python\ 3.12/Install\ Certificates.command
Sürüm numarasını kurulumunuzla eşleşecek şekilde ayarlayın. Homebrew Python, Homebrew'un CA paketini kullanır ve genellikle kutudan çıktığı gibi çalışır; çalışmazsa brew reinstall ca-certificates komutunu çalıştırın. certifi.where() değerini açıkça kullanmak her iki durumda da sorunu önler.
Windows
Windows'ta Python sertifikaları Windows sertifika deposundan yükler. Hatalar genellikle iki nedenden birinden kaynaklanır:
- Güncelleme almamış bir makinede güncel olmayan bir kök deposu; bu durumda daha yeni bir kök eksiktir. Windows güncellemelerini yükleyin veya certifi kullanın.
- Antivirüs veya kurumsal bir proxy tarafından yapılan TLS denetimi; bu
self-signed certificate in certificate chainhatasını üretir. Adım 1 betiğinin yazdırdığı issuer'ı kontrol edin; bir güvenlik ürününün adını içeriyorsa o ürün bağlantının arasına giriyordur.
Linux
Python, OpenSSL'in varsayılan yollarını kullanır; bunlar genellikle Debian ve Ubuntu'da /etc/ssl/certs/ca-certificates.crt, Red Hat tabanlı sistemlerde ise /etc/pki/tls/certs/ca-bundle.crt dosyasıdır. Paket eksik veya eskiyse:
# Debian / Ubuntu / Raspberry Pi OS
sudo apt update && sudo apt install --reinstall ca-certificates
sudo update-ca-certificates
# Fedora / RHEL
sudo dnf reinstall ca-certificates
Docker ve Slim İmajlar
python:3.12-slim gibi imajlar genellikle CA sertifikalarını içerir, ancak alpine ve distroless varyantları içermeyebilir. Paketi açıkça ekleyin:
FROM python:3.12-alpine
RUN apk add --no-cache ca-certificates
Ya da imaja certifi kurun ve kodda ona başvurun. OpenSSL'i SSL_CERT_FILE ortam değişkeniyle bir pakete de yönlendirebilirsiniz.
Hostname Uyuşmazlığı Varyantı
Hostname mismatch, client.connect("203.0.113.10", 8883) çağırdığınızda veya sertifikada bulunmayan dahili bir takma ad kullandığınızda ortaya çıkar. TLS, istediğiniz adın sertifikanın Subject Alternative Names listesinde yer aldığını kontrol eder. Broker'ın gerçek hostname'iyle bağlanın. ConnectMQ için bu broker.connectmq.com adresidir. Test için belirli bir IP'yi zorlamanız gerekiyorsa IP ile bağlanmak yerine onu hosts dosyanıza ekleyin.
Özel veya Kendinden İmzalı Broker'lar
Özel bir CA ile kendi broker'ınızı çalıştırıyorsanız, herkese açık CA paketi ona asla güvenmez. Özel CA'yı client.tls_set(ca_certs="my-ca.crt") ile açıkça verin ve broker sertifikasının SAN alanında doğru hostname'i içerdiğinden emin olun. Süreç ve bakım yükü MQTT için kendinden imzalı sertifikalar yazısında açıklanır.
Zinciri OpenSSL ile İncelemek
Python çıktısı yeterli olmadığında OpenSSL, sunucunun gönderdiği tam zinciri ve doğrulamanın nerede durduğunu gösterir:
openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -showcerts </dev/null
Certificate chain bölümünü yukarıdan okuyun: 0 numaralı kayıt broker sertifikasıdır, sonraki kayıtlar ara sertifikalardır ve her i: (issuer) satırı bir sonraki kaydın s: (subject) satırıyla eşleşmelidir. Son Verify return code, OpenSSL'in kendi güven deposunun zinciri kabul edip etmediğini söyler. OpenSSL 0 (ok) deyip Python başarısız oluyorsa Python, OpenSSL'den farklı bir güven deposu kullanıyordur; Adım 1'deki gibi ssl.get_default_verify_paths() çıktısını yazdırmak bunu genellikle ortaya çıkarır. 0 numaralı kaydın issuer'ı antivirüs veya güvenlik duvarı üreticinizin adını içeriyorsa gerçek broker sertifikasına değil, TLS denetimine bakıyorsunuzdur.
Özellikle certifi ile karşılaştırmak için python -c "import certifi; print(certifi.where())" komutunun yazdırdığı yolla -CAfile ekleyin. certifi ile başarı ve onsuz başarısızlık, sorunun işletim sistemi deposunda olduğunu doğrular.
Yapılmaması Gerekenler
Arama sonuçları sıklıkla şu satırları önerir:
client.tls_set(cert_reqs=ssl.CERT_NONE)
client.tls_insecure_set(True)
Bunlar sunucu kimlik doğrulamasını devre dışı bırakarak hatayı ortadan kaldırır. Kimlik bilgileriniz bu durumda, bir saldırgan dahil, yanıt veren herhangi bir sunucuya gider. Kullanacaksanız bile yalnızca bir laboratuvar broker'ına karşı birkaç dakikalık yerel hata ayıklama için kullanın; asla commit edilen kodda değil. MQTT güvenliği en iyi uygulamaları yazısı, broker'ın kimlik doğrulamasının neden şifreleme kadar önemli olduğunu açıklar.
Hızlı Çözüm Kontrol Listesi
certificate verify failedsonrasındaki ayrıntıyı okuyun.- Adım 1 betiğini aynı ortamda çalıştırın.
ca_certsolarakcertifi.where()kullanın veya işletim sistemi deposunu onarın.- IP ile değil hostname ile bağlanın.
- Saat sorunları için
date -uçıktısını kontrol edin. - Proxy'leri tespit etmek için sertifikanın issuer'ına bakın.
- Özel broker'lar için kendi CA dosyanızı sağlayın.
Handshake düzeltildikten sonra hâlâ takılıyorsanız MQTT TLS handshake hatalarını düzeltme rehberimiz portları, SNI'ı ve protokol sürümlerini ele alır; Python MQTT TLS eğitimi ise eksiksiz üretim desenlerini gösterir.
Herkese Açık Sertifikalar Neden Zaman Kazandırır?
Sertifika doğrulama hatalarının çoğu, broker herkesçe güvenilen bir CA'dan alınmış bir sertifika kullandığında ve onu otomatik olarak yenilediğinde ortadan kalkar. ConnectMQ böyle çalışır: 8883 ve 8084 portlarında Let's Encrypt sertifikasına sahip barındırılan bir MQTT broker; böylece standart Python kurulumları onu ek dosya olmadan doğrular. Özel kimlik bilgilerine geçmeden önce bu makaledeki her testi ücretsiz herkese açık MQTT broker üzerinde yeniden üretebilirsiniz.
ConnectMQ ile Başlayın
app.connectmq.com adresinden kaydolun, kredi kartı gerektirmeyen ücretsiz Serverless planı seçin, bir broker oluşturun ve yukarıdaki paho-mqtt örneğini oluşturulan kullanıcı adı, parola ve client ID ile çalıştırın.
Sık Sorulan Sorular
Aynı kod neden Linux'ta çalışıp macOS'ta başarısız oluyor?
python.org macOS derlemesi, "Install Certificates.command" çalıştırılana kadar CA sertifikaları olmadan gelir. Linux Python ise genellikle zaten kurulu olan sistem paketini kullanır.
İşletim sistemi deposu yerine certifi kullanmak güvenli mi?
Evet. certifi, Mozilla'nın özenle seçilmiş kök listesini paketler. Yalnızca pip ile güncel tutun ve özel veya kurumsal CA'ları içermeyeceğini unutmayın.
Bu hata broker'ın ele geçirildiği anlamına mı gelir?
Nadiren. Eksik CA paketleri, yanlış hostname'ler, saat sorunları ve TLS denetimi çok daha yaygındır. Emin olmak için issuer adını kontrol edin.
ConnectMQ sertifika dosyasına ihtiyacım var mı?
Hayır. ConnectMQ herkesçe güvenilen bir Let's Encrypt sertifikası kullanır; bu nedenle certifi veya işletim sistemi deposu gibi standart bir CA paketi yeterlidir.



