Udostępnij za pośrednictwem


Samouczek: uwierzytelnianie klienta TLS, X.509 i autoryzacja kontroli dostępu opartej na atrybutach (ABAC) za pomocą brokera MQTT operacji usługi Azure IoT

Ten samouczek przeprowadzi Cię przez proces konfigurowania brokera MQTT operacji usługi Azure IoT przy użyciu szyfrowania TLS i uwierzytelniania klienta X.509. Zawiera instrukcje krok po kroku i skrypty służące do tworzenia certyfikatów zarówno dla brokera, jak i klientów. W tym samouczku wyjaśniono, jak skonfigurować brokera MQTT przy użyciu różnych głównych urzędów certyfikacji dla klienta i brokera. Obejmuje również konfigurowanie zasad autoryzacji kontroli dostępu opartej na atrybutach (ABAC) na podstawie łańcucha certyfikatów klienta. Na koniec samouczek używa klienta Komara do testowania różnych scenariuszy, aby upewnić się, że konfiguracja działa poprawnie.

Samouczek symuluje środowisko, w którym operacje usługi Azure IoT są instalowane w fabryce Firmy Contoso z urządzeniami wyprodukowanymi przez firmę Fabrikam. Aby umożliwić uwierzytelnianie TLS i X.509:

  • Broker MQTT operacji usługi Azure IoT zainstalowany w fabryce firmy Contoso musi ufać głównemu urzędowi certyfikacji firmy Fabrikam
  • Czujniki firmy Fabrikam, takie jak termostaty, muszą ufać głównemu urzędowi certyfikacji firmy Contoso
  • Każda jednostka musi mieć własny certyfikat liścia wystawiony przez prawidłowy główny urząd certyfikacji

Diagram przedstawiający relację zaufania katalogów głównych serwera i po stronie klienta urzędu certyfikacji.

Wymagania wstępne

Aby wykonać czynności opisane w tym samouczku, potrzebne są następujące elementy:

  • Klaster Kubernetes z włączonym przekazywaniem portów dla portu 8883.
  • Operacje usługi Azure IoT wdrożone bez istniejącego odbiornika modułu równoważenia obciążenia.
  • Dostęp kubectl do klastra w celu utworzenia wpisów tajnych i map konfiguracji platformy Kubernetes.
  • Klient Mosquitto do publikowania i subskrybowania komunikatów MQTT uruchomionych na tej samej maszynie co klaster Kubernetes w celu localhost uzyskania dostępu. Aby nie używać localhostprogramu , zobacz Opcjonalne: użyj prawdziwej nazwy hosta lub adresu IP zamiast localhost sekcji.
  • Krok interfejsu wiersza polecenia w celu utworzenia certyfikatów.

Napiwek

Aby spełnić te wymagania, skorzystaj z przestrzeni kodu szybki start. Przestrzeń kodu szybkiego startu upraszcza proces instalacji, udostępniając te składniki gotowe do użycia.

Ponadto znajomość kryptografii klucza publicznego i terminów, takich jak główny urząd certyfikacji, klucz prywatny i certyfikaty pośrednie, jest przydatna.

Opcjonalnie: użyj rzeczywistej nazwy hosta lub adresu IP zamiast localhost

Aby zachować prostotę tego samouczka, użyjemy metody localhost w celu uzyskania dostępu do brokera MQTT. Takie podejście zapewnia, że certyfikat serwera brokera ma alternatywną nazwę podmiotu (SAN), która jest zgodna z nazwą hosta używaną do uzyskiwania dostępu do brokera. Użycie localhost upraszcza konfigurację, ponieważ sieć SAN jest już poprawnie ustawiona.

W rzeczywistym scenariuszu należy użyć nazwy hosta lub zewnętrznego adresu IP brokera, a nie localhost nawiązać z nim połączenia z innego urządzenia w sieci. W takim przypadku należy określić poprawną nazwę hosta lub adres IP i użyć go jako sieci SAN podczas tworzenia certyfikatu serwera:

  • Jeśli nazwa hosta lub adres IP jest już znany (na przykład za pośrednictwem rekordu DNS lub statycznego adresu IP), użyj go jako sieci SAN podczas tworzenia certyfikatu serwera. Następnie połącz się z brokerem przy użyciu tej nazwy hosta lub adresu IP zamiast localhost.
  • Jeśli nazwa hosta lub adres IP nie jest jeszcze znany, możesz użyć usługi symbolu zastępczego, aby określić zewnętrzny adres IP:
    1. Utwórz usługę LoadBalancer na porcie, który nie jest używany (na przykład 8080):
      kubectl create service loadbalancer placeholder-service --tcp=8080:8080
      
    2. Pobierz zewnętrzny adres IP:
      kubectl get svc placeholder-service
      
    3. Jeśli zewnętrzny adres IP:
      • Pokazuje wartość podobną 192.168.X.X do — użyj tego adresu IP jako sieci SAN podczas tworzenia certyfikatu serwera i wpisu tajnego. Następnie połącz się z brokerem przy użyciu tego adresu IP zamiast localhost.
      • Pokazuje <pending> — używana dystrybucja Kubernetes może nie obsługiwać automatycznego przypisywania zewnętrznego adresu IP. Aby znaleźć zewnętrzny adres IP, wykonaj kroki opisane w dokumentacji platformy Kubernetes dla środowiska dystrybucji i hosta. Może być również konieczne skonfigurowanie przekazywania portów lub sieci VPN w zależności od konfiguracji sieci.
    4. Po określeniu zewnętrznego adresu IP usuń usługę symbolu zastępczego:
      kubectl delete svc placeholder-service
      

Ta metoda gwarantuje, że certyfikat serwera jest zgodny z zewnętrznym adresem IP, umożliwiając bezpieczny dostęp do brokera MQTT.

Przygotowywanie certyfikatów po stronie serwera i pełnego łańcucha

Najpierw utwórz główny urząd certyfikacji po stronie serwera. Ten urząd certyfikacji jest oddzielony od głównego urzędu certyfikacji po stronie klienta, który jest tworzony później. Aby zachować czytelność separacji, nazwijmy wszystko po stronie serwera "Contoso". Aby ułatwić późniejsze kroki, pomijamy hasło do szyfrowania klucza prywatnego. Ta praktyka jest akceptowalna tylko w ustawieniu samouczka.

step certificate create "Contoso Root CA" \
contoso_root_ca.crt contoso_root_ca.key \
--profile root-ca \
--no-password --insecure

Następnie utwórz pośredni urząd certyfikacji podpisany przez ten główny urząd certyfikacji.

step certificate create "Contoso Intermediate CA 1" \
contoso_intermediate_ca.crt contoso_intermediate_ca.key \
--profile intermediate-ca \
--ca ./contoso_root_ca.crt --ca-key ./contoso_root_ca.key \
--no-password --insecure

Na koniec użyj tego pośredniego urzędu certyfikacji, aby podpisać certyfikat serwera dla frontonu brokera MQTT. localhost W tym miejscu znajduje się alternatywna nazwa podmiotu (SAN) używana do tego samouczka.

step certificate create mqtts-endpoint \
mqtts-endpoint.crt mqtts-endpoint.key \
--profile leaf \
--ca ./contoso_intermediate_ca.crt --ca-key ./contoso_intermediate_ca.key \
--bundle \
--san localhost \
--not-after 2400h --no-password --insecure

Z flagą --bundle certyfikat serwera jest powiązany z certyfikatem pośrednim podpisywania. Uzgadnianie protokołu TLS wymaga, aby pakiet zweryfikował pełny łańcuch.

Przygotowywanie certyfikatów po stronie klienta i pełnego łańcucha

Podobnie utwórz główny urząd certyfikacji dla firmy Fabrikam i pośredniego urzędu certyfikacji.

step certificate create --profile root-ca "Fabrikam Root CA" \
fabrikam_root_ca.crt fabrikam_root_ca.key \
--no-password --insecure
step certificate create "Fabrikam Intermediate CA 1" \
fabrikam_intermediate_ca.crt fabrikam_intermediate_ca.key \
--profile intermediate-ca \
--ca ./fabrikam_root_ca.crt --ca-key ./fabrikam_root_ca.key \
--no-password --insecure

Następnie wygeneruj certyfikaty klienta dla termostatu, higrometru, podgrzewacza i żarówki.

# Create a client certificate for the thermostat
step certificate create thermostat thermostat.crt thermostat.key \
--ca ./fabrikam_intermediate_ca.crt --ca-key ./fabrikam_intermediate_ca.key --bundle \
--not-after 2400h --no-password --insecure

# Create a client certificate for the hygrometer
step certificate create hygrometer hygrometer.crt hygrometer.key \
--ca ./fabrikam_intermediate_ca.crt --ca-key ./fabrikam_intermediate_ca.key --bundle \
--not-after 2400h --no-password --insecure

# Create a client certificate for the heater
step certificate create heater heater.crt heater.key \
--ca ./fabrikam_intermediate_ca.crt --ca-key ./fabrikam_intermediate_ca.key --bundle \
--not-after 2400h --no-password --insecure

# Create a client certificate for the lightbulb
step certificate create lightbulb lightbulb.crt lightbulb.key \
--ca ./fabrikam_intermediate_ca.crt --ca-key ./fabrikam_intermediate_ca.key --bundle \
--not-after 2400h --no-password --insecure

Konfigurowanie platformy Kubernetes

Zaimportuj nowo wygenerowany certyfikat serwera i klucz prywatny do wpisu tajnego platformy Kubernetes. Ten wpis tajny służy do późniejszego konfigurowania odbiornika PROTOKOŁU TLS dla brokera MQTT.

kubectl create secret tls broker-server-cert -n azure-iot-operations \
--cert mqtts-endpoint.crt \
--key mqtts-endpoint.key

Ponadto utwórz mapę konfiguracji zawierającą główny urząd certyfikacji firmy Fabrikam (po stronie klienta). Ta mapa konfiguracji jest wymagana, aby broker MQTT ufał mu na potrzeby uwierzytelniania X.509.

kubectl create configmap fabrikam-ca -n azure-iot-operations \
--from-file=client_ca.pem=fabrikam_root_ca.crt

Konfigurowanie brokera MQTT

Następne kroki umożliwiają skonfigurowanie brokera MQTT przy użyciu szyfrowania TLS i uwierzytelniania klienta X.509. Samouczek używa witryny Azure Portal do konfigurowania brokera MQTT.

Uwierzytelnianie

Aby umożliwić klientom uwierzytelnianie przy użyciu certyfikatów X.509 wystawionych przez główny urząd certyfikacji firmy Fabrikam, utwórz zasady uwierzytelniania, które ufają certyfikatowi głównego urzędu certyfikacji firmy Fabrikam i mapuje certyfikaty klienta na atrybuty autoryzacji dla usługi ABAC.

  1. W witrynie Azure Portal przejdź do wystąpienia operacji IoT.

  2. W obszarze Składniki wybierz pozycję Broker MQTT.

  3. Wybierz kartę Uwierzytelnianie.

  4. Wybierz pozycję Utwórz zasady uwierzytelniania.

  5. W polu Nazwa zasad wprowadź wartość x509-auth.

  6. Dodaj nową metodę, wybierając pozycję Dodaj metodę.

  7. Wybierz typ metody X.509 z listy rozwijanej, a następnie wybierz pozycję Dodaj szczegóły , aby skonfigurować metodę.

  8. W okienku szczegółów uwierzytelniania X.509 określ nazwę fabrikam-ca ConfigMap zaufanego certyfikatu urzędu certyfikacji firmy Fabrikam i atrybuty.

    {
      "trustedClientCaCert": "fabrikam-ca",
      "authorizationAttributes": {
        "thermostat": {
          "subject": "CN = thermostat",
          "attributes": {
            "group": "thermostat_group"
          }
        },
        "hygrometer": {
          "subject": "CN = hygrometer",
          "attributes": {
            "group": "hygrometer_group"
          }
        },
        "intermediate": {
          "subject": "CN = Fabrikam Intermediate CA 1",
          "attributes": {
            "manufacturer": "fabrikam"
          }
        }
      }
    }
    
  9. Wybierz pozycję Zastosuj , a następnie pozycję Dodaj , aby zapisać zmiany.

Zrzut ekranu przedstawiający sposób używania witryny Azure Portal do tworzenia metody uwierzytelniania brokera MQTT X.509.

Odbiornik

Korzystając z zasad uwierzytelniania, utwórz odbiornik, który używa zasad uwierzytelniania X.509. Ponadto, ponieważ uwierzytelnianie X.509 wymaga protokołu TLS, skonfiguruj odbiornik do używania utworzonego wcześniej certyfikatu serwera firmy Contoso i klucza prywatnego.

  1. W witrynie Azure Portal przejdź do wystąpienia operacji IoT.

  2. W obszarze Składniki wybierz pozycję Broker MQTT.

  3. Wybierz pozycję Odbiornik brokera MQTT dla pozycji LoadBalancer>Utwórz. Wprowadź następujące ustawienia:

    Ustawienie opis
    Nazwa/nazwisko Wprowadź mqtts-endpoint.
    Service name Nazwa usługi Kubernetes. Pozostaw wartość pustą, aby użyć nazwy mqtts-endpoint odbiornika jako nazwy usługi.
    Typ usługi Moduł LoadBalancer został już wybrany.
  4. W obszarze Porty wprowadź następujące ustawienia dla pierwszego portu:

    Ustawienie opis
    Port Wprowadź wartość 8883
    Uwierzytelnianie Wybierz pozycję x509-auth
    Autoryzacja Wybierz pozycję Brak
    Protokół Wybierz MQTT
    TLS Wybierz Dodaj
  5. W okienku Konfiguracja protokołu TLS wprowadź następujące ustawienia:

    Ustawienie opis
    Tryb TLS Wybieranie ręcznego
    Nazwa wystawcy Wprowadź broker-server-cert
  6. Wybierz pozycję Zastosuj i Utwórz odbiornik.

Zrzut ekranu przedstawiający metodę witryny Azure Portal, aby ustawić odbiornik z portem TLS.

Po upływie minuty lub dwóch zostanie utworzona mqtts-endpoint usługa LoadBalancer.

$ kubectl get service mqtts-endpoint -n azure-iot-operations
NAME             TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
mqtts-endpoint   LoadBalancer   10.43.28.140   XXX.XX.X.X    8883:30988/TCP   104s

Zamiast używać zewnętrznego adresu IP, używamy localhost go do tego samouczka.

Napiwek

Konfiguracja usługi Codespace automatycznie konfiguruje przekazywanie portów dla 8883. Aby skonfigurować inne środowiska, zobacz Używanie przekazywania portów.

Publikowanie komunikatów za pośrednictwem protokołu TLS przy użyciu jednego klienta komara

W tym samym folderze co pliki certyfikatów: contoso_root_ca.crt, thermostat.crti thermostat.keyużyj klienta komara, aby opublikować komunikat. Flaga jest przeznaczony dla Komara --cafile contoso_root_ca.crt do przeprowadzenia weryfikacji certyfikatu serwera.

mosquitto_pub -t "example/topic" -m "example temperature measurement" -i thermostat \
-q 1 -V mqttv5 -d \
-h localhost \
--key thermostat.key \
--cert thermostat.crt \
--cafile contoso_root_ca.crt

Publikowanie powiodło się, ponieważ komar używa certyfikatu klienta, który jest zakorzeniony w pliku fabrikam_root_ca.crt. Broker MQTT ufa temu certyfikatowi, ponieważ x509-auth utworzone wcześniej zasady uwierzytelniania. Ponadto broker MQTT obecnie umożliwia uwierzytelnieni klientom publikowanie w dowolnym temacie.

Client thermostat sending CONNECT
Client thermostat received CONNACK (0)
Client thermostat sending PUBLISH (d0, q1, r0, m1, 'example/topic', ... (31 bytes))
Client thermostat received PUBACK (Mid: 1, RC:0)
Client thermostat sending DISCONNECT

Konfigurowanie autoryzacji do tematów MQTT dla wielu klientów przy użyciu X.509

Aby ograniczyć dostęp do tematów MQTT na podstawie atrybutów certyfikatu klienta, utwórz zasady autoryzacji, które mapuje atrybuty certyfikatu klienta na dozwolone akcje w określonych tematach.

  1. W witrynie Azure Portal przejdź do wystąpienia operacji IoT.

  2. W obszarze Składniki wybierz pozycję Broker MQTT.

  3. Wybierz kartę Autoryzacja.

  4. Wybierz pozycję Utwórz zasady autoryzacji.

  5. W polu Nazwa zasad wprowadź wartość abac-authz.

  6. W obszarze Reguły wprowadź następujące reguły:

    [
      {
        "principals": {
          "attributes": [
            {
              "group": "thermostat_group"
            }
          ]
        },
        "brokerResources": [
          {
            "method": "Connect"
          },
          {
            "method": "Publish",
            "topics": [
              "telemetry/temperature"
            ]
          }
        ]
      },
      {
        "principals": {
          "attributes": [
            {
              "group": "hygrometer_group"
            }
          ]
        },
        "brokerResources": [
          {
            "method": "Connect"
          },
          {
            "method": "Publish",
            "topics": [
              "telemetry/humidity"
            ]
          }
        ]
      },
      {
        "principals": {
          "attributes": [
            {
              "manufacturer": "fabrikam"
            }
          ]
        },
        "brokerResources": [
          {
            "method": "Connect"
          },
          {
            "method": "Publish",
            "topics": [
              "health/heartbeat"
            ]
          }
        ]
      },
      {
        "principals": {
          "usernames": [
            "heater"
          ]
        },
        "brokerResources": [
          {
            "method": "Connect"
          },
          {
            "method": "Subscribe",
            "topics": [
              "telemetry/temperature",
              "telemetry/humidity"
            ]
          }
        ]
      }
    ]
    
  7. Wybierz pozycję Dodaj, aby zapisać zmiany.

Zrzut ekranu przedstawiający witrynę Azure Portal do konfigurowania zasad autoryzacji.

Następnie zaktualizuj odbiornik brokera MQTT, aby używał nowych zasad autoryzacji.

  1. Wybierz kartę Odbiorniki .
  2. Wybierz odbiornik mqtts-endpoint.
  3. W obszarze Porty>8883>Autoryzacja wybierz pozycję abac-authz.
  4. Wybierz pozycję Zapisz.

Zrzut ekranu przedstawiający witrynę Azure Portal na potrzeby łączenia portu z zasadami autoryzacji.

Publikowanie komunikatów w temacie z ograniczeniami

W tej sekcji przetestujemy nowo zastosowane zasady autoryzacji.

Najpierw połącz się z usługą thermostat i spróbuj opublikować w temacie telemetry/humidity:

mosquitto_pub -t "telemetry/humidity" -m "example temperature measurement" -i thermostat \
-q 1 -V mqttv5 -d \
-h localhost \
--key thermostat.key \
--cert thermostat.crt \
--cafile contoso_root_ca.crt

Ponieważ thermostat jest częścią elementu thermostat_group, który nie może publikować w temacie wilgotności, publikowanie kończy się niepowodzeniem.

Client thermostat sending CONNECT
Client thermostat received CONNACK (0)
Client thermostat sending PUBLISH (d0, q1, r0, m1, 'telemetry/humidity', ... (6 bytes))
Client thermostat received PUBACK (Mid: 1, RC:135)
Warning: Publish 1 failed: Not authorized.

Zmień wartość na publikuj na telemetry/temperature, która jest dozwolona, a publikowanie zakończy się pomyślnie. Pozostaw uruchomione polecenie .

mosquitto_pub -t "telemetry/temperature" -m "example temperature measurement" -i thermostat \
-q 1 -V mqttv5 -d \
-h localhost \
--repeat 10000 \
--repeat-delay 3 \
--key thermostat.key \
--cert thermostat.crt \
--cafile contoso_root_ca.crt

Subskrybowanie wiadomości w tematach z ograniczeniami

W oddzielnej sesji terminalu nawiąż połączenie z usługą heater , aby zasubskrybować usługę health/heartbeat.

mosquitto_sub -q 1 -t "health/heartbeat" -d -V mqttv5 \
-i heater \
-h localhost \
--key heater.key \
--cert heater.crt \
--cafile contoso_root_ca.crt

Ponieważ heater subskrypcja nie jest autoryzowana do subskrybowania tematu pulsu, subskrypcja kończy się niepowodzeniem. W tym miejscu kod 135 oznacza brak autoryzacji.

Client heater sending CONNECT
Client heater received CONNACK (0)
Client heater sending SUBSCRIBE (Mid: 1, Topic: health/heartbeat, QoS: 1, Options: 0x00)
Client heater received SUBACK
Subscribed (mid: 1): 135

Przełącz temat subskrypcji na telemetry/temperature, do którego thermostat nadal są wysyłane komunikaty.

mosquitto_sub -q 1 -t "telemetry/temperature" -d -V mqttv5 \
-i heater \
-h localhost \
--key heater.key \
--cert heater.crt \
--cafile contoso_root_ca.crt

Teraz heater zaczyna odbierać komunikaty, ponieważ jest ona autoryzowana przy użyciu nazwy użytkownika.

W innej oddzielnej sesji terminalu opublikuj komunikaty w programie health/heartbeat za pomocą polecenia lightbulb:

mosquitto_pub -q 1 -t "health/heartbeat" -m "example heartbeat" -d -V mqttv5 \
-i lightbulb \
-h localhost \
--repeat 100 \
--repeat-delay 3 \
--key lightbulb.key \
--cert lightbulb.crt \
--cafile contoso_root_ca.crt

Publikowanie powiedzie się, ponieważ lightbulb ma certyfikat pośredni z atrybutem CN = Fabrikam Intermediate CA 1, który jest mapowany na atrybut manufacturer=fabrikam. Klienci z tym atrybutem mogą publikować w programie health/heartbeat. Po rozpoczęciu wysyłania komunikatów heater przez klienta uruchomione wcześniej nie są odbierane niczego.

Czyszczenie zasobów

Aby wyczyścić zasoby utworzone w tym samouczku, usuń odbiornik oraz zasady uwierzytelniania i autoryzacji.

  1. W witrynie Azure Portal przejdź do wystąpienia operacji IoT.
  2. W obszarze Składniki wybierz pozycję Broker MQTT.
  3. Wybierz kartę Odbiorniki .
  4. Zaznacz pole wyboru obok odbiornika mqtts-endpoint .
  5. Wybierz Usuń.
  6. Potwierdź usunięcie.
  7. Wybierz kartę Uwierzytelnianie.
  8. Zaznacz pole wyboru obok pozycji x509-auth.
  9. Wybierz Usuń.
  10. Potwierdź usunięcie.
  11. Wybierz kartę Autoryzacja.
  12. Zaznacz pole wyboru obok pozycji abac-authz.
  13. Wybierz Usuń.
  14. Potwierdź usunięcie.

Ponadto usuń wpis tajny i mapę konfiguracji rozwiązania Kubernetes.

kubectl delete secret broker-server-cert -n azure-iot-operations
kubectl delete configmap fabrikam-ca -n azure-iot-operations

Na koniec usuń wygenerowane wcześniej certyfikaty i klucze.

rm contoso_root_ca.crt contoso_root_ca.key contoso_intermediate_ca.crt contoso_intermediate_ca.key mqtts-endpoint.crt mqtts-endpoint.key
rm fabrikam_root_ca.crt fabrikam_root_ca.key fabrikam_intermediate_ca.crt fabrikam_intermediate_ca.key thermostat.crt thermostat.key hygrometer.crt hygrometer.key heater.crt heater.key lightbulb.crt lightbulb.key