BrokerListener를 사용하여 MQTT 브로커 통신 보호
Important
Azure IoT 작업 미리 보기 - Azure Arc에서 지원되는 Azure IoT 작업은 현재 preview로 제공됩니다. 프로덕션 환경에서는 이 미리 보기 소프트웨어를 사용하면 안 됩니다.
일반적으로 릴리스되는 릴리스가 제공되면 새로운 Azure IoT 작업 설치를 배포해야 합니다. 미리 보기 설치는 업그레이드할 수 없습니다.
베타, 미리 보기로 제공되거나 아직 일반 공급으로 릴리스되지 않은 Azure 기능에 적용되는 약관은 Microsoft Azure 미리 보기에 대한 추가 사용 약관을 참조하세요.
네트워크 액세스 및 보안을 사용자 지정하려면 BrokerListener 리소스를 사용합니다. 수신기는 브로커를 네트워크에 노출하는 네트워크 엔드포인트에 해당합니다. 각 Broker 리소스에 대해 하나 이상의 BrokerListener 리소스를 포함할 수 있으므로 각각 액세스 제어가 서로 다른 여러 포트가 있을 수 있습니다.
각 수신기 포트에는 수신기에 연결할 수 있는 사용자와 broker에서 수행할 수 있는 작업을 정의하는 자체 인증 및 권한 부여 규칙이 있을 수 있습니다. BrokerAuthentication 및 BrokerAuthorization 리소스를 사용하여 각 수신기에 대한 액세스 제어 정책을 지정할 수 있습니다. 이러한 유연성을 통해 요구 사항 및 사용 사례에 따라 MQTT 클라이언트의 권한과 역할을 세밀하게 조정할 수 있습니다.
팁
클러스터 IP, TLS 및 서비스 계정 토큰을 사용하여 기본 MQTT broker 배포에만 액세스할 수 있습니다. 클러스터 외부에서 연결하는 클라이언트는 연결하기 전에 추가 구성이 필요합니다.
수신기에는 다음과 같은 특성이 있습니다.
- 최대 세 개의 수신기를 가질 수 있습니다.
loadBalancer
,clusterIp
또는nodePort
서비스 유형당 수신기 하나씩입니다. 기본값으로 명명된 기본 BrokerListener는 서비스 유형clusterIp
입니다. - 각 수신기는 여러 포트를 지원함
- BrokerAuthentication 및 BrokerAuthorization 참조는 포트당
- TLS 구성은 포트당임
- 서비스 이름은 고유해야 함
- 포트가 다른 수신기를 통해 충돌할 수 없습니다.
사용 가능한 설정 목록은 Broker 수신기 API 참조를 참조하세요.
기본 BrokerListener
Azure IoT Operations Preview를 배포할 때 배포는 azure-iot-operations
네임스페이스에 default
이라고 명명된 BrokerListener 리소스도 만듭니다. 이 수신기는 배포 중에도 만들어진 명명된 default
기본 Broker 리소스에 연결됩니다. 기본 수신기는 TLS 및 SAT 인증을 사용하도록 설정된 포트 18883에서 브로커를 노출합니다. TLS 인증서는 cert-manager에서 자동으로 관리됩니다. 권한 부여는 기본적으로 사용하지 않도록 설정됩니다.
수신기를 보거나 편집하려면 다음을 수행합니다.
Azure Portal에서 IoT Operations 인스턴스로 이동합니다.
Azure IoT Operations 리소스에서 MQTT Broker를 선택합니다.
broker 수신기 목록에서 기본 수신기를 선택합니다.
수신기 설정을 검토하고 필요에 따라 변경합니다.
새 broker 수신기 만들기
이 예제에서는 Broker 리소스에 대한 loadbalancer-listener라는 새 BrokerListener 리소스를 만드는 방법을 보여줍니다. BrokerListener 리소스는 클라이언트에서 MQTT 연결을 허용하는 두 개의 포트를 정의합니다.
- 첫 번째 포트는 TLS 및 인증 해제 없이 포트 1883에서 수신 대기합니다. 클라이언트는 암호화나 인증 없이 브로커에 연결할 수 있습니다.
- 두 번째 포트는 TLS 및 인증을 사용하도록 설정한 상태로 포트 18883에서 수신 대기합니다. 인증된 클라이언트만 TLS 암호화를 사용하여 브로커에 연결할 수 있습니다. TLS가
automatic
으로 설정됩니다. 즉, 수신기가 cert-manager를 사용하여 서버 인증서를 가져와서 갱신합니다.
Azure Portal에서 IoT Operations 인스턴스로 이동합니다.
Azure IoT Operations 리소스에서 MQTT Broker를 선택합니다.
LoadBalancer 만들기에 대한 MQTT broker 수신기를>선택합니다. 서비스 유형당 하나의 수신기만 만들 수 있습니다. 동일한 서비스 유형의 수신기가 이미 있는 경우 기존 수신기에 더 많은 포트를 추가할 수 있습니다.
다음 설정을 입력합니다.
설정 Description 이름 BrokerListener 리소스의 이름입니다. 서비스 이름 BrokerListener와 연결된 Kubernetes 서비스의 이름입니다. 서비스 종류 LoadBalancer, NodePort 또는 ClusterIP와 같은 broker 서비스의 유형입니다. 포트 BrokerListener가 MQTT 연결을 수신 대기하는 포트 번호입니다. 인증 인증 리소스 참조입니다. Authorization 권한 부여 리소스 참조입니다. TLS 보안 통신을 위해 TLS를 사용할 수 있는지 여부를 나타냅니다. 자동 또는 수동으로 설정할 수 있습니다. 수신기 만들기를 선택합니다.
자동 인증서 관리로 TLS 구성
자동 인증서 관리를 사용하여 TLS를 사용하도록 설정하려면 수신기 포트에서 TLS 설정을 지정합니다.
cert-manager 설치 확인
자동 인증서 관리를 사용하면 cert-manager를 사용하여 TLS 서버 인증서를 관리합니다. 기본적으로 cert-manager는 이미 azure-iot-operations
네임스페이스에 Azure IoT 작업 미리 보기와 함께 설치되어 있습니다. 계속하기 전에 설치를 확인합니다.
kubectl
을 사용하여 인증서 관리자 앱 레이블과 일치하는 Pod를 확인하는 데 사용합니다.kubectl get pods --namespace azure-iot-operations -l 'app in (cert-manager,cainjector,webhook)'
NAME READY STATUS RESTARTS AGE aio-cert-manager-64f9548744-5fwdd 1/1 Running 4 (145m ago) 4d20h aio-cert-manager-cainjector-6c7c546578-p6vgv 1/1 Running 4 (145m ago) 4d20h aio-cert-manager-webhook-7f676965dd-8xs28 1/1 Running 4 (145m ago) 4d20h
Pod가 준비 및 실행 중으로 표시되면 cert-manager가 설치되고 사용할 준비가 된 것입니다.
팁
설치를 추가로 확인하려면 cert-manager 설명서 설치 확인을 확인합니다. azure-iot-operations
네임스페이스를 사용해야 합니다.
TLS 서버 인증서에 대한 발급자 만들기
인증서 관리자 발급자 리소스는 인증서가 자동으로 발급되는 방법을 정의합니다. Cert-manager 는 기본적으로 여러 발급자 유형을 지원합니다. 또한 고유하게 지원되는 발급자를 넘어 기능을 확장하기 위한 외부 발급자 유형도 지원합니다. MQTT 브로커는 모든 형식의 인증서 관리자 발급자와 함께 사용할 수 있습니다.
Important
초기 배포 중에 Azure IoT Operations는 TLS 서버 인증서에 대한 기본 발급자를 사용하여 설치됩니다. 개발 및 테스트에 이 발급자를 사용할 수 있습니다. 자세한 내용은 Azure IoT Operations의 기본 루트 CA 및 발급자를 참조하세요. 아래 단계는 다른 발급자를 사용하려는 경우에만 필요합니다.
발급자를 만드는 방법은 시나리오에 따라 다릅니다. 다음 섹션에서는 시작하는 데 도움이 되는 예제를 나열합니다.
CA 발급자는 개발 및 테스트에 유용합니다. Kubernetes 비밀에 저장된 인증서 및 프라이빗 키로 구성해야 합니다.
루트 인증서를 Kubernetes 비밀로 설정
기존 CA 인증서가 있는 경우 CA 인증서 및 프라이빗 키 PEM 파일을 사용하여 Kubernetes 비밀을 만듭니다. 다음 명령을 실행하면 루트 인증서를 Kubernetes 비밀로 설정하고 다음 섹션을 건너뛸 수 있습니다.
kubectl create secret tls test-ca --cert tls.crt --key tls.key -n azure-iot-operations
CA 인증서가 없는 경우 cert-manager는 루트 CA 인증서를 생성할 수 있습니다. 인증서 관리자를 사용하여 루트 CA 인증서를 생성하는 것은 자체 서명된 인증서를 사용하여 CA 발급자를 부트스트래핑하는 것으로 알려져 있습니다.
ca.yaml
를 만들어 시작합니다.apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: selfsigned-ca-issuer namespace: azure-iot-operations spec: selfSigned: {} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: selfsigned-ca-cert namespace: azure-iot-operations spec: isCA: true commonName: test-ca secretName: test-ca issuerRef: # Must match Issuer name above name: selfsigned-ca-issuer # Must match Issuer kind above kind: Issuer group: cert-manager.io # Override default private key config to use an EC key privateKey: rotationPolicy: Always algorithm: ECDSA size: 256
다음 명령을 사용하여 자체 서명된 CA 인증서를 만듭니다.
kubectl apply -f ca.yaml
Cert-manager는 기본값을 사용하여 CA 인증서를 만듭니다. 인증서 사양을 수정하여 이 인증서의 속성을 변경할 수 있습니다. 유효한 옵션 목록은 cert-manager 설명서를 참조하세요.
루트 인증서 배포
이전 예제에서는 test-ca
이라는 Kubernetes 비밀에 CA 인증서를 저장합니다. PEM 형식의 인증서는 비밀에서 검색하고 다음 명령을 사용하여 ca.crt
파일에 저장할 수 있습니다.
kubectl get secret test-ca -n azure-iot-operations -o json | jq -r '.data["tls.crt"]' | base64 -d > ca.crt
이 인증서는 모든 클라이언트에서 배포하고 신뢰할 수 있어야 합니다. 예를 들어 mosquitto 클라이언트에 --cafile
플래그를 사용합니다.
CA 인증서를 기반으로 발급자 만들기
Cert-Manager는 이전 단계에서 생성되거나 가져온 CA 인증서를 기반으로 발급자를 필요로 합니다. 다음 파일을 issuer-ca.yaml
과 같이 만듭니다.
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: my-issuer
namespace: azure-iot-operations
spec:
ca:
# Must match secretName of generated or imported CA cert
secretName: test-ca
다음 명령을 사용하여 발급자를 만듭니다.
kubectl apply -f issuer-ca.yaml
이전 명령은 TLS 서버 인증서를 발급하기 위한 발급자를 만듭니다. 발급자의 이름과 종류를 확인합니다. 예제에서 이름 my-issuer
및 종류 Issuer
입니다. 이러한 값은 나중에 BrokerListener 리소스에 설정됩니다.
포트에 대해 TLS 자동 인증서 관리 사용
다음은 자동 인증서 관리를 사용하여 포트 8884에서 TLS를 사용하도록 설정하는 BrokerListener 리소스의 예입니다.
Azure Portal에서 IoT Operations 인스턴스로 이동합니다.
Azure IoT Operations 리소스에서 MQTT Broker를 선택합니다.
수신기를 선택하거나 만듭니다. 서비스 유형당 하나의 수신기만 만들 수 있습니다. 동일한 서비스 유형의 수신기가 이미 있는 경우 기존 수신기에 더 많은 포트를 추가할 수 있습니다.
기존 포트에서 TLS를 선택하거나 새 포트를 추가하여 수신기에 TLS 설정을 추가할 수 있습니다.
다음 설정을 입력합니다.
설정 설명 포트 BrokerListener가 MQTT 연결을 수신 대기하는 포트 번호입니다. 필수입니다. 인증 인증 리소스 참조입니다. Authorization 권한 부여 리소스 참조입니다. TLS 추가 단추를 선택합니다. 발급자 이름 cert-manager 발급자의 이름입니다. 필수입니다. 발급자 종류 cert-manager 발급자의 종류입니다. 필수입니다. 발급자 그룹 cert-manager 발급자의 그룹입니다. 필수입니다. 프라이빗 키 알고리즘 프라이빗 키에 대한 알고리즘입니다. 프라이빗 키 회전 정책 프라이빗 키를 회전하기 위한 정책입니다. DNS 이름 인증서의 DNS 주체 대체 이름입니다. IP 주소 인증서에 대한 주체 대체 이름의 IP 주소입니다. 비밀 이름 X.509 클라이언트 인증서를 포함하는 Kubernetes 비밀입니다. 기간 TLS 서버 인증서의 총 수명은 기본값인 90일입니다. 갱신 전 인증서 갱신을 시작할 때입니다. 저장을 선택하여 TLS 설정을 저장합니다.
TLS를 사용하여 브로커에 연결
서버 인증서가 구성되면 TLS를 사용하도록 설정합니다. mosquitto를 사용하여 테스트하려면:
mosquitto_pub -h $HOST -p 8884 -V mqttv5 -i "test" -t "test" -m "test" --cafile ca.crt
--cafile
인수는 mosquitto 클라이언트에서 TLS를 사용하도록 설정하고 클라이언트가 지정된 파일에서 발급한 모든 서버 인증서를 신뢰하도록 지정합니다. 구성된 TLS 서버 인증서의 발급자를 포함하는 파일을 지정해야 합니다.
$HOST
를 적절한 호스트로 바꿉니다.
- 동일한 클러스터 내에서 연결하는 경우 지정된 서비스 이름(예:
my-new-tls-listener
) 또는 서비스CLUSTER-IP
로 바꿉니다. - 클러스터 외부에서 연결하는 경우
EXTERNAL-IP
서비스입니다.
필요한 경우 인증 방법을 지정해야 합니다.
기본 루트 CA 및 발급자
시작하는 데 도움이 되도록 Azure IoT Operations는 TLS 서버 인증서에 대한 기본 “빠른 시작” 루트 CA 및 발급자를 사용하여 배포됩니다. 개발 및 테스트에 이 발급자를 사용할 수 있습니다. 자세한 내용은 TLS 서버 인증서에 대한 기본 루트 CA 및 발급자를 참조 하세요.
프로덕션의 경우 이전 섹션에서 설명한 대로 신뢰할 수 있는 CA의 인증서를 사용하여 CA 발급자를 구성해야 합니다.
수동 인증서 관리를 사용하여 TLS 구성
특정 TLS 인증서를 사용하도록 MQTT 브로커를 수동으로 구성하려면 Kubernetes 비밀에 대한 참조를 사용하여 BrokerListener 리소스에 지정합니다. 그런 다음 kubectl을 사용하여 배포합니다. 이 문서에서는 테스트를 위해 자체 서명된 인증서를 사용하여 TLS를 구성하는 예제를 보여 줍니다.
단계 CLI를 사용하여 인증 기관 만들기
단계는 사용자 고유의 프라이빗 CA를 만들고 관리할 때 빠르게 시작하고 실행할 수 있는 인증서 관리자입니다.
단계 CLI를 설치하고 루트 인증서 기관(CA) 인증서 및 키를 만듭니다.
step certificate create --profile root-ca "Example Root CA" root_ca.crt root_ca.key
루트 CA에서 서명한 중간 CA 인증서 및 키를 만듭니다.
step certificate create --profile intermediate-ca "Example Intermediate CA" intermediate_ca.crt intermediate_ca.key \ --ca root_ca.crt --ca-key root_ca.key
서버 인증서 만들기
단계 CLI를 사용하여 중간 CA에서 서명한 서버 인증서를 만듭니다.
step certificate create mqtts-endpoint mqtts-endpoint.crt mqtts-endpoint.key \
--profile leaf \
--not-after 8760h \
--san mqtts-endpoint \
--san localhost \
--ca intermediate_ca.crt --ca-key intermediate_ca.key \
--no-password --insecure
여기서 mqtts-endpoint
및 localhost
는 각각 Kubernetes 및 로컬 클라이언트에서 MQTT 브로커의 프런트 엔드에 대한 SAN(Subject Alternative Name)입니다. 인터넷을 통해 연결하려면 외부 IP를 사용하여 --san
을 추가합니다. --no-password --insecure
플래그는 Kubernetes 비밀에 저장되므로 암호 프롬프트를 건너뛰고 프라이빗 키에 대한 암호 보호를 사용하지 않도록 설정하는 테스트에 사용됩니다. 프로덕션의 경우 암호를 사용하고 프라이빗 키를 Azure Key Vault와 같은 안전한 위치에 저장합니다.
인증서 키 알고리즘 요구 사항
EC 및 RSA 키는 모두 지원되지만 체인의 모든 인증서는 동일한 키 알고리즘을 사용해야 합니다. 사용자 고유의 CA 인증서를 가져오는 경우 서버 인증서가 CA와 동일한 키 알고리즘을 사용하는지 확인합니다.
Kubernetes 비밀로 서버 인증서 체인 가져오기
인증서 순서가 중요한 전체 서버 인증서 체인을 만듭니다. 서버 인증서는 파일의 첫 번째 인증서이고 중간은 두 번째입니다.
cat mqtts-endpoint.crt intermediate_ca.crt > server_chain.crt
kubectl을 사용하여 서버 인증서 체인 및 서버 키로 Kubernetes 비밀을 만듭니다.
kubectl create secret tls server-cert-secret -n azure-iot-operations \ --cert server_chain.crt \ --key mqtts-endpoint.key
포트에 TLS 수동 인증서 관리 사용
다음은 수동 인증서 관리를 사용하여 포트 8884에서 TLS를 사용하도록 설정하는 BrokerListener 리소스의 예입니다.
Azure Portal에서 IoT Operations 인스턴스로 이동합니다.
Azure IoT Operations 리소스에서 MQTT Broker를 선택합니다.
수신기를 선택하거나 만듭니다. 서비스 유형당 하나의 수신기만 만들 수 있습니다. 동일한 서비스 유형의 수신기가 이미 있는 경우 기존 수신기에 더 많은 포트를 추가할 수 있습니다.
기존 포트에서 TLS를 선택하거나 새 포트를 추가하여 수신기에 TLS 설정을 추가할 수 있습니다.
다음 설정을 입력합니다.
설정 설명 포트 BrokerListener가 MQTT 연결을 수신 대기하는 포트 번호입니다. 필수입니다. 인증 인증 리소스 참조입니다. Authorization 권한 부여 리소스 참조입니다. TLS 추가 단추를 선택합니다. 비밀 이름 X.509 클라이언트 인증서를 포함하는 Kubernetes 비밀입니다. 저장을 선택하여 TLS 설정을 저장합니다.
TLS를 사용하여 broker에 연결
mosquitto 클라이언트를 사용하여 TLS 연결을 테스트하려면 메시지를 게시하고 매개 변수 --cafile
에 루트 CA 인증서를 전달합니다.
mosquitto_pub -d -h localhost -p 8885 -i "my-client" -t "test-topic" -m "Hello" --cafile root_ca.crt
Client my-client sending CONNECT
Client my-client received CONNACK (0)
Client my-client sending PUBLISH (d0, q0, r0, m1, 'test-topic', ... (5 bytes))
Client my-client sending DISCONNECT
팁
localhost를 사용하려면 호스트 컴퓨터에서 포트를 사용할 수 있어야 합니다. 예: kubectl port-forward svc/mqtts-endpoint 8885:8885 -n azure-iot-operations
. K3d와 같은 일부 Kubernetes 배포를 사용하여 k3d cluster edit $CLUSTER_NAME --port-add 8885:8885@loadbalancer
와 함께 전달된 포트를 추가할 수 있습니다.
참고 항목
broker에 연결하려면 신뢰의 루트를 클라이언트에 배포해야 합니다(신뢰 번들이라고도 함). 이 경우 신뢰의 루트는 자체 서명된 루트 CA가 만든 단계 CLI입니다. 클라이언트가 서버 인증서 체인을 확인하려면 신뢰 루트 배포가 필요합니다. MQTT 클라이언트가 Kubernetes 클러스터의 워크로드인 경우 루트 CA를 사용하여 ConfigMap을 만들고 Pod에 탑재해야 합니다.
MQTT 브로커 인증을 사용하는 경우 사용자 이름, 암호 등을 지정해야 합니다.
서버 인증서에 외부 IP 사용
인터넷을 통해 TLS와 연결하려면 MQTT 브로커의 서버 인증서에 외부 호스트 이름(SAN)이 있어야 합니다. 이는 프로덕션 환경에서 일반적으로 DNS 이름 또는 잘 알려진 IP 주소입니다. 그러나 개발/테스트 중에 배포 전 할당된 호스트 이름 또는 외부 IP를 알 수는 없습니다. 이 문제를 해결하려면 먼저 서버 인증서 없이 수신기를 배포한 다음, 외부 IP를 사용하여 서버 인증서 및 비밀을 만들고 마지막으로 수신기로 비밀을 가져옵니다.
예제 TLS 수신기 manual-tls-listener
를 배포하려고 하지만 참조된 Kubernetes 비밀 server-cert-secret
이 없으면 연결된 서비스가 만들어지지만 Pod는 시작되지 않습니다. 운영자가 수신기에 대한 외부 IP를 예약해야 하기 때문에 서비스가 만들어집니다.
kubectl get svc mqtts-endpoint -n azure-iot-operations
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mqtts-endpoint LoadBalancer 10.X.X.X 172.X.X.X 8885:30674/TCP 1m15s
그러나 이 동작은 예상되며 서버 인증서를 가져오는 동안 이 동작을 그대로 두어도 됩니다. 상태 관리자 로그는 MQTT 브로커가 서버 인증서를 기다리고 있다고 언급합니다.
kubectl logs -l app=health-manager -n azure-iot-operations
...
<6>2023-11-06T21:36:13.634Z [INFO] [1] - Server certificate server-cert-secret not found. Awaiting creation of secret.
참고 항목
일반적으로 분산 시스템에서 Pod 로그는 결정적이지 않으며 주의해서 사용해야 합니다. 이와 같은 정보를 표시하는 올바른 방법은 백로그에 있는 Kubernetes 이벤트 및 사용자 지정 리소스 상태를 사용하는 것입니다. 이전 단계를 임시 해결 방법으로 고려합니다.
프런트 엔드 Pod가 작동하지 않더라도 외부 IP를 이미 사용할 수 있습니다.
kubectl get svc mqtts-endpoint -n azure-iot-operations
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mqtts-endpoint LoadBalancer 10.X.X.X 172.X.X.X 8885:30674/TCP 1m15s
여기에서 이전과 동일한 단계에 따라 --san
의 이 외부 IP를 사용하여 서버 인증서를 만들고 동일한 방식으로 Kubernetes 비밀을 만듭니다. 비밀이 만들어지면 자동으로 수신기로 가져옵니다.