14.4.5. Genel bir sunucunun doğrulanması (istemci olarak kamera)¶
Önceki sayfada istemcinin “kök sertifikaya zaten sahip olması” hakkında anlatılan her şey tarayıcılar, telefonlar ve PC’ler için geçerlidir – ancak kamera için geçerli değildir. MicroPython’un ssl modülü yerleşik bir güven deposu olmadan gelir: yeni flash edilmiş bir kamera hiçbir CA’ya güvenmez ve varsayılan değer (ssl.CERT_NONE) hiçbir şeyi doğrulamaz ve ortadaki adam saldırısına tamamen açıktır. Bu nedenle, kamera genel bir TLS sunucusuna (bir HTTPS API’si, bir MQTT aracısı, …) dışa doğru bağlanan istemci olduğunda ve o sunucuyu gerçekten doğrulamasını istediğinizde, güven çapasını kendiniz sağlamalısınız.
Mekanizma, Kendinden imzalı sertifikalar sayfasındaki kendinden imzalı istemci örneğiyle aynıdır; tek fark, yüklediğiniz dosyanın eşin kendi sertifikası yerine gerçek bir CA sertifikası olmasıdır:
Sunucunun zincirini çapalayan CA sertifikasını edinin. “Çapalamak”, güven başlangıç noktanız olarak seçtiğiniz, sunucunun zincirinin tepesindeki (ya da yakınındaki) sertifika anlamına gelir. Bir TLS sunucusu, yaprak sertifikasını ve genellikle ara sertifika(lar)ını gönderir; kökünü asla göndermez. O güven çapasını kendiniz ve sunucudan bağımsız olarak edinmelisiniz – bir sunucunun size verdiği her şeye basitçe güvenmek, doğrulamanın tüm amacını boşa çıkarır.
Önce sunucunun sertifikasını gerçekte hangi CA’nın verdiğini öğrenin. Örneğin,
openmv.ioiçin:openssl s_client -connect openmv.io:443 -showcerts < /dev/nullCertificate chainbloğu her sertifikayı konusu (s:) ve veren makamıyla (i:) birlikte listeler; daha yeni OpenSSL ayrıca burada göz ardı edebileceğiniza:(anahtar türü) vev:(geçerlilik) satırlarını da yazdırır:Certificate chain 0 s:CN=openmv.io i:C=US, O=Let's Encrypt, CN=E8 1 s:C=US, O=Let's Encrypt, CN=E8 i:C=US, O=Internet Security Research Group, CN=ISRG Root X1
0 numaralı giriş yaprak sertifikadır (
openmv.io),E8ara sertifikası tarafından verilmiştir. 1 numaralı giriş,ISRG Root X1kökü tarafından verilen o ara sertifikadır. En üstteki girişin veren makamı (i:) kökü adlandırır – buradaISRG Root X1. (Ara sertifika, başka yerlerde görmüş olabileceğinizR10/R11yerineE8‘dir çünküopenmv.iobir ECDSA sertifikası kullanır; Let’s Encrypt, ECDSA yapraklarınıEserisi ara sertifikalarıyla, RSA yapraklarını iseRserisi olanlarla imzalar. Her ikisi deISRG Root X1‘e zincirlenir.)OpenSSL ayrıca
depth=satırlarını yazdırır ve köküVerification: OKile bildirebilir. Bu, yalnızca sizin PC’nizISRG Root X1‘e zaten güvendiği için olur – sunucu onu göndermedi (bir sunucu kökünü asla göndermez) ve hiçbir güven deposu olmayan kamera da ona sahip olmayacaktır. Onu sağlamanız gerekmesinin nedeni tam olarak budur.O kökü, CA’nın kendi yayınladığı köklerden indirin. Let’s Encrypt tüm köklerini Let’s Encrypt sertifikaları sayfasında kataloglar; ISRG Root X1 için doğrudan dosya isrgrootx1.pem adresindedir (ayrıca önceden kodlanmış olarak isrgrootx1.der biçiminde de sunarlar). Diğer CA’lar köklerini benzer bir “kök sertifikalar” / “depo” sayfasında yayınlar; kanonik genel küme Mozilla CA programıdır (CCADB). Parmak izini CA’nın yayınladığı değerle karşılaştırarak doğru dosyayı aldığınızı onaylayın (
.derindirdiyseniz-inform DERekleyin):openssl x509 -in isrgrootx1.pem -noout -subject -fingerprint -sha256Bir kökü izlemek yerine, ara sertifikayı doğrudan
-showcertsçıktısından kopyalayabilir (ikinci-----BEGIN CERTIFICATE-----bloğu), ona güvenebilir ve CA ara sertifikayı her döndürdüğünde – kökten çok daha sık – yenilemeniz gerektiğini kabul edebilirsiniz (aşağıdaki ödünleşime bakın).Onu DER’e dönüştürün, tam olarak öncekiyle aynı şekilde:
openssl x509 -in isrgrootx1.pem -outform DER -out ca.derca.derdosyasını kameraya (dosya sistemi veya ROMFS) kopyalayın ve güven çapası olarak yükleyin:import socket import ssl import ntptime ntptime.settime() # validity check needs the clock addr = socket.getaddrinfo("api.example.com", 443)[0][-1] sock = socket.socket() sock.connect(addr) ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.verify_mode = ssl.CERT_REQUIRED ctx.load_verify_locations(cafile="ca.der") ssock = ctx.wrap_socket(sock, server_hostname="api.example.com")
server_hostnameburada gereklidir: SNI’yi yönlendirir ve sunucu sertifikasınınsubjectAltNamealanına karşı kontrol edilen addır.
Tüyo
Yaygın durum kısayolu. Let’s Encrypt en yaygın kullanılan genel CA’dır ve hem RSA hem de ECDSA sertifikaları şu anda ISRG Root X1’e zincirlenir (yukarıdaki openmv.io örneğinin gösterdiği gibi). Kameranızın konuştuğu sunucular Let’s Encrypt kullanıyorsa, incelemeyi tamamen atlayabilirsiniz: kameraya yalnızca isrgrootx1.der koyun ve onu load_verify_locations ile yükleyin.
Bu, TLS’in her sitede çalışmasını sağlamaz. Sertifikası farklı bir CA’dan (DigiCert, Google Trust Services, Amazon, Sectigo, …) gelen bir sunucu yine doğrulamada başarısız olur ve kamera ssl.SSLContext başına tek bir DER sertifikasına güvendiği için, bir tarayıcının yaptığı gibi her kökü paketleyemezsiniz. Şüpheye düştüğünüzde, sunucunun gerçek CA’sını yukarıda gösterildiği gibi belirleyin ve o köke güvenin.
Hangi sertifikaya güveneceğiniz bir ödünleşimdir:
Kök (önerilir). Uzun ömürlüdür – genellikle onlarca yıl – bu yüzden
ca.dernadiren değişir. mbedTLS’in yaprak → ara sertifika → güvendiğiniz kök yolunu oluşturabilmesi için sunucunun ara sertifikasını göndermesini gerektirir; doğru yapılandırılmış hemen hemen her genel sunucu bunu yapar.Ara sertifika. Bu da çalışır ve bir sunucu ara sertifikayı atlasa bile çalışmaya devam eder, ancak ara sertifikalar köklerden çok daha sık döndürülür, bu yüzden
ca.derdosyasını daha sık yenilemeniz gerekir.Yaprak sertifikanın kendisi (sertifika sabitleme/pinning). En sıkı seçenektir, ancak yaprak her yenilemede değişir – Let’s Encrypt için kabaca her 90 günde bir – bu nedenle bu yalnızca sunucuyu da kontrol ettiğinizde ve yeni sabiti her kameraya senkronize olarak gönderebildiğinizde anlamlıdır. Kendinden imzalı istemci örneğinin yaptığı tam olarak budur.
Not
ssl.SSLContext.load_verify_locations(), tek bir DER kodlu CA sertifikası alır, bu yüzden kamera bir seferde tam olarak bir çapaya güvenir. Farklı CA’lar altındaki sunuculara ulaşmak için her çapa başına ayrı bir ssl.SSLContext kullanın. Ve bu sertifikanın kendisi de sonunda süresi dolacağı veya CA tarafından döndürüleceği için, onu cihazdaki diğer sertifikalar gibi ele alın.