다음을 통해 공유


자습서: Azure IoT Operations MQTT Broker를 사용한 TLS, X.509 클라이언트 인증 및 ABAC(특성 기반 액세스 제어) 권한 부여

이 자습서에서는 TLS 암호화 및 X.509 클라이언트 인증을 사용하여 Azure IoT Operations MQTT broker를 설정하는 방법에 대해 설명합니다. 여기에는 broker와 클라이언트 모두에 대한 인증서를 만들기 위한 단계별 지침 및 스크립트가 포함됩니다. 이 자습서에서는 클라이언트 및 브로커에 대해 다른 루트 CA(인증 기관)를 사용하여 MQTT broker를 구성하는 방법을 설명합니다. 또한 클라이언트 인증서 체인을 기반으로 하는 ABAC(특성 기반 액세스 제어) 권한 부여 정책 설정에 대해서도 설명합니다. 마지막으로 이 자습서에서는 모기 클라이언트를 사용하여 다양한 시나리오를 테스트하여 설치가 제대로 작동하는지 확인합니다.

이 자습서는 Fabrikam에서 제조한 디바이스를 사용하여 Contoso 팩터리에 Azure IoT Operations가 설치된 환경을 시뮬레이션합니다. TLS 및 X.509 인증이 작동하도록 하려면 다음을 수행합니다.

  • Contoso 팩터리에 설치된 Azure IoT Operations MQTT Broker는 Fabrikam 루트 CA를 신뢰해야 합니다.
  • 자동 온도 조절기와 같은 Fabrikam 센서는 Contoso 루트 CA를 신뢰해야 합니다.
  • 각 엔터티에는 올바른 루트 CA에서 발급한 자체 리프 인증서가 있어야 합니다.

서버 및 클라이언트 쪽 인증 기관 루트의 신뢰 관계를 보여 주는 다이어그램

필수 조건

이 자습서를 수행하려면 다음이 필요합니다.

이러한 요구 사항을 충족하려면 빠른 시작 코드 영역을 사용합니다. 빠른 시작 코드스페이스는 이러한 구성 요소를 기본적으로 제공하여 설치 프로세스를 간소화합니다.

또한 공개 키 암호화 및 루트 CA, 프라이빗 키 및 중간 인증서와 같은 용어를 잘 알고 있으면 유용합니다.

선택 사항: 대신 실제 호스트 이름 또는 IP 주소 사용 localhost

이 자습서를 간단하게 유지하기 위해 MQTT 브로커에 액세스하는 데 사용합니다 localhost . 이 방법을 사용하면 broker의 서버 인증서에 broker에 액세스하는 데 사용되는 호스트 이름과 일치하는 SAN(주체 대체 이름)이 있습니다. localhost SAN이 이미 올바르게 설정되어 있기 때문에 설정을 간소화합니다.

실제 시나리오에서는 브로커의 호스트 이름 또는 외부 IP를 대신 localhost 사용하고 네트워크의 다른 디바이스에서 연결합니다. 이 경우 올바른 호스트 이름 또는 IP 주소를 확인하고 서버 인증서를 만들 때 SAN으로 사용해야 합니다.

  • 호스트 이름 또는 IP 주소가 이미 알려진 경우(예: DNS 레코드 또는 고정 IP를 통해) 서버 인증서를 만들 때 SAN으로 사용합니다. 그런 다음 , 대신 해당 호스트 이름 또는 IP를 사용하여 broker에 연결합니다 localhost.
  • 호스트 이름 또는 IP 주소를 아직 알 수 없는 경우 자리 표시자 서비스를 사용하여 외부 IP 주소를 확인할 수 있습니다.
    1. 사용되지 않는 포트(예: 8080)에서 LoadBalancer 서비스를 만듭니다.
      kubectl create service loadbalancer placeholder-service --tcp=8080:8080
      
    2. 외부 IP를 검색합니다.
      kubectl get svc placeholder-service
      
    3. 외부 IP인 경우:
      • 서버 인증서 및 비밀을 만들 때 해당 IP를 SAN으로 사용하는 것과 같은 192.168.X.X 값을 표시합니다. 그런 다음 , 대신 해당 IP를 사용하여 broker에 연결합니다 localhost.
      • 표시 <pending> - 사용하는 Kubernetes 배포는 외부 IP를 자동으로 할당하는 것을 지원하지 않을 수 있습니다. 외부 IP를 찾으려면 배포 및 호스트 환경에 대한 Kubernetes 설명서의 단계를 따릅니다. 네트워크 설정에 따라 포트 전달 또는 VPN을 구성해야 할 수도 있습니다.
    4. 외부 IP를 결정한 후 자리 표시자 서비스를 삭제합니다.
      kubectl delete svc placeholder-service
      

이 메서드는 서버 인증서가 외부 IP 주소와 일치하도록 하여 MQTT 브로커에 대한 보안 액세스를 허용합니다.

서버 쪽 인증서 및 전체 체인 준비

먼저 서버 쪽 루트 CA를 만듭니다. 이 CA는 나중에 만들어지는 클라이언트 쪽 루트 CA와는 별개입니다. 분리를 명확하게 유지하기 위해 모든 서버 쪽의 이름을 "Contoso"로 지정합니다. 이후 단계를 더 쉽게 수행하려면 프라이빗 키를 암호화하기 위한 암호를 건너뜁니다. 이 연습은 자습서 설정에서만 허용됩니다.

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

그런 다음, 이 루트 CA에서 서명한 중간 CA를 만듭니다.

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

마지막으로 이 중간 CA를 사용하여 MQTT broker의 broker 프런트 엔드에 대한 서버 인증서에 서명합니다. localhost 다음은 자습서에 사용되는 SAN(주체 대체 이름)입니다.

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

플래그를 사용하여 --bundle 서버 인증서는 서명 중간 인증서와 함께 번들로 제공됩니다. TLS 핸드셰이크를 사용하려면 번들이 전체 체인을 확인해야 합니다.

클라이언트 쪽 인증서 및 전체 체인 준비

마찬가지로 Fabrikam 및 중간 CA에 대한 루트 CA를 만듭니다.

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

그런 다음 자동 온도 조절기, hygrometer, 히터 및 전구에 대한 클라이언트 인증서를 생성합니다.

# 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

Kubernetes 구성

새로 생성된 서버 인증서 및 프라이빗 키를 Kubernetes 비밀로 가져옵니다. 이 비밀은 나중에 MQTT 브로커에 대한 TLS 수신기를 구성하는 데 사용됩니다.

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

또한 Fabrikam(클라이언트 쪽) 루트 CA를 포함하도록 구성 맵을 만듭니다. 이 구성 맵은 MQTT 브로커가 X.509 인증을 위해 신뢰하는 데 필요합니다.

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

MQTT broker 구성

다음 단계에서는 TLS 암호화 및 X.509 클라이언트 인증을 사용하여 MQTT broker를 구성합니다. 이 자습서에서는 Azure Portal을 사용하여 MQTT 브로커를 구성합니다.

인증

클라이언트가 Fabrikam 루트 CA에서 발급한 X.509 인증서를 사용하여 인증할 수 있도록 하려면 Fabrikam 루트 CA 인증서를 신뢰하고 클라이언트 인증서를 ABAC의 권한 부여 특성에 매핑하는 인증 정책을 만듭니다.

  1. Azure Portal에서 IoT Operations 인스턴스로 이동합니다.

  2. 구성 요소 아래에서 MQTT Broker를 선택합니다.

  3. 인증 탭을 선택합니다.

  4. 인증 정책 만들기를 선택합니다.

  5. 정책 이름에 .를 입력합니다x509-auth.

  6. 메서드 추가를 선택하여 새 메서드를 추가합니다.

  7. 드롭다운 목록에서 X.509 메서드 유형을 선택한 다음, 세부 정보 추가를 선택하여 메서드를 구성합니다.

  8. X.509 인증 세부 정보 창에서 Fabrikam 신뢰할 수 있는 CA 인증서 ConfigMap 이름 fabrikam-ca 및 특성을 지정합니다.

    {
      "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. 적용을 선택한 다음 추가를 선택하여 변경 내용을 저장합니다.

Azure Portal을 사용하여 MQTT broker X.509 인증 방법을 만드는 방법을 보여 주는 스크린샷

listener

인증 정책을 사용하여 X.509 인증 정책을 사용하는 수신기를 만듭니다. 또한 X.509 인증에는 TLS가 필요하므로 이전에 만든 Contoso 서버 인증서 및 프라이빗 키를 사용하도록 수신기를 구성합니다.

  1. Azure Portal에서 IoT Operations 인스턴스로 이동합니다.

  2. 구성 요소 아래에서 MQTT Broker를 선택합니다.

  3. LoadBalancer 만들기에 대한 MQTT broker 수신기를>선택합니다. 다음 설정을 입력합니다.

    설정 Description
    이름 mqtts-endpoint를 입력합니다.
    서비스 이름 Kubernetes 서비스의 이름입니다. 수신기 이름을 서비스 이름으로 mqtts-endpoint 사용하려면 비워 둡니다.
    서비스 종류 LoadBalancer가 이미 선택되어 있습니다.
  4. 포트에서 첫 번째 포트에 대해 다음 설정을 입력합니다.

    설정 설명
    포트 8883 입력
    인증 x509 인증 선택
    Authorization 없음 선택
    프로토콜 MQTT 선택
    TLS 추가 선택
  5. TLS 구성 창에서 다음 설정을 입력합니다.

    설정 설명
    TLS 모드 수동 선택
    발급자 이름 broker-server-cert을 입력합니다.
  6. 적용수신기 만들기를 선택합니다.

TLS 포트를 사용하여 수신기를 설정하는 Azure Portal 메서드를 보여 주는 스크린샷.

1~2분 후에 mqtts-endpoint 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

외부 IP를 사용하는 대신 자습서에 사용합니다 localhost .

코드스페이스 구성은 8883에 대한 포트 전달을 자동으로 설정합니다. 다른 환경을 설정하려면 포트 전달 사용을 참조 하세요.

단일 모기 클라이언트를 사용하여 TLS를 통해 메시지 게시

인증서 파일과 동일한 폴더에서 : contoso_root_ca.crt, thermostat.crtthermostat.key, 모기 클라이언트를 사용하여 메시지를 게시합니다. 플래그는 --cafile contoso_root_ca.crt 서버 인증서 확인을 수행하는 모기에 대한 것입니다.

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

모기가 루트 fabrikam_root_ca.crt에 있는 클라이언트 인증서를 사용하므로 게시가 성공합니다. MQTT 브로커는 이전에 만든 인증 정책 때문에 이 인증서를 x509-auth 신뢰합니다. 또한 MQTT 브로커는 현재 인증된 클라이언트가 모든 토픽에 게시할 수 있도록 허용합니다.

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

X.509를 사용하여 여러 클라이언트에 대한 MQTT 토픽에 대한 권한 부여 구성

클라이언트 인증서 특성에 따라 MQTT 토픽에 대한 액세스를 제한하려면 클라이언트 인증서 특성을 특정 항목에 대해 허용된 작업에 매핑하는 권한 부여 정책을 만듭니다.

  1. Azure Portal에서 IoT Operations 인스턴스로 이동합니다.

  2. 구성 요소 아래에서 MQTT Broker를 선택합니다.

  3. Authorization 탭을 선택합니다.

  4. 권한 부여 정책 만들기를 선택합니다.

  5. 정책 이름에 .를 입력합니다abac-authz.

  6. 규칙에 따라 다음 규칙을 입력합니다.

    [
      {
        "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. 추가를 선택하여 변경 내용을 저장합니다.

권한 부여 정책을 설정하기 위한 Azure Portal을 보여 주는 스크린샷

그런 다음 새 권한 부여 정책을 사용하도록 MQTT broker 수신기를 업데이트합니다.

  1. 수신기 탭을 선택합니다.
  2. mqtts-endpoint 수신기를 선택합니다.
  3. 포트>8883>권한 부여에서 abac-authz를 선택합니다.
  4. 저장을 선택합니다.

권한 부여 정책에 포트를 연결하기 위한 Azure Portal을 보여 주는 스크린샷

제한된 토픽에 메시지 게시

이 섹션에서는 새로 적용된 권한 부여 정책을 테스트합니다.

먼저 다음 항목telemetry/humiditythermostat 연결하고 게시해 봅니다.

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

thermostat 습도 토픽에 게시할 수 없는 부분thermostat_group이므로 게시가 실패합니다.

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.

게시를 변경하여 telemetry/temperature허용되고 게시가 성공합니다. 명령을 실행 상태로 둡니다.

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

제한된 토픽에 대한 메시지 구독

별도의 터미널 세션에서 구독에 연결 heater 합니다 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

heater 하트비트 토픽을 구독할 권한이 없으므로 구독이 실패합니다. 여기서 코드 135는 권한이 없음을 의미합니다.

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

구독 토픽을 telemetry/temperaturethermostat 메시지를 계속 보내는 항목으로 전환합니다.

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

이제 heater 사용자 이름으로 권한이 부여되어 메시지를 받기 시작합니다.

다른 별도의 터미널 세션에서 다음lightbulb사용하여 메시지를 게시합니다health/heartbeat.

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

특성에 매핑되는 중간 인증서가 있으므로 lightbulb 게시에 성공합니다manufacturer=fabrikam.CN = Fabrikam Intermediate CA 1 해당 특성을 가진 클라이언트는 에 게시할 health/heartbeat수 있습니다. 클라이언트가 메시지 heater 보내기를 시작하면 이전에 시작된 항목은 아무 것도 수신하지 않습니다.

리소스 정리

이 자습서에서 만든 리소스를 정리하려면 수신기와 인증 및 권한 부여 정책을 삭제합니다.

  1. Azure Portal에서 IoT Operations 인스턴스로 이동합니다.
  2. 구성 요소 아래에서 MQTT Broker를 선택합니다.
  3. 수신기 탭을 선택합니다.
  4. mqtts-endpoint 수신기 옆에 있는 확인란을 선택합니다.
  5. 삭제를 선택합니다.
  6. 삭제를 확인합니다.
  7. 인증 탭을 선택합니다.
  8. x509 인증 옆에 있는 확인란을 선택합니다.
  9. 삭제를 선택합니다.
  10. 삭제를 확인합니다.
  11. Authorization 탭을 선택합니다.
  12. abac-authz 옆에 있는 확인란을 선택합니다.
  13. 삭제를 선택합니다.
  14. 삭제를 확인합니다.

또한 Kubernetes 비밀 및 구성 맵을 삭제합니다.

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

마지막으로 이전에 생성된 인증서 및 키를 삭제합니다.

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