웹사이트 검색

Ubuntu 20.04에서 Mosquitto MQTT 메시징 브로커를 설치하고 보호하는 방법


이 페이지에서

  1. 전제 조건
  2. 1단계 - Mosquitto 서버 및 클라이언트 설치
  3. 2단계 - MQTT 암호 인증 구성\n
  4. 3단계 - Mosquitto 클라이언트 테스트
  5. 4단계 - SSL 설치
  6. 5단계 - MQTT SSL 구성
  7. 6단계 - SSL 갱신 구성
  8. 7단계 - Websocket 구성
  9. 결론

Mosquitto는 MQTT(Message Queuing Telemetry Transport) 프로토콜을 사용하는 오픈 소스 메시지 브로커입니다. 이 프로토콜은 사물 인터넷(IoT) 장치에 가벼운 통신을 제공하도록 설계되었습니다. 차량의 GPS 추적, 홈 오토메이션, 환경 센서 및 대규모 데이터 수집에 일반적으로 사용됩니다.

MQTT 프로토콜은 TCP/IP 모델 위에서 실행됩니다. 가볍기 때문에 작은 코드 풋프린트를 통해 최소한의 리소스로 장치용 애플리케이션을 만들 수 있습니다. 게시/구독 모델에 의존합니다. 이 모델에서 클라이언트는 채널에 가입한 다른 클라이언트에게 정보를 보내는 브로커 역할을 하는 Mosquitto 서버에 연결합니다.

이 튜토리얼에서는 Mosquitto를 설치하고 통신을 보호하기 위해 SSL을 사용하도록 브로커를 설정합니다.

전제 조건

  • Sudo 권한이 있는 루트가 아닌 사용자가 있는 Ubuntu 20.04 서버.\n
  • 서버를 가리키는 도메인 이름(myqtt.example.com).

1단계 - Mosquitto 서버 및 클라이언트 설치

Ubuntu는 이전 1.6 버전의 Mosquitto와 함께 제공됩니다. 최신 버전을 설치하려면 공식 Mosquitto 저장소를 추가하십시오.

$ sudo add-apt-repository ppa:mosquitto-dev/mosquitto-ppa

Mosquitto 서버와 클라이언트를 설치합니다.

$ sudo apt install mosquitto mosquitto-clients

서버의 상태를 확인하십시오.

$ sudo systemctl status mosquitto
? mosquitto.service - Mosquitto MQTT Broker
     Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2022-01-25 09:18:40 UTC; 25s ago
       Docs: man:mosquitto.conf(5)
             man:mosquitto(8)
   Main PID: 119694 (mosquitto)
      Tasks: 1 (limit: 2274)
     Memory: 1.0M
     CGroup: /system.slice/mosquitto.service
             ??119694 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

Jan 25 09:18:39 <userid> systemd[1]: Starting Mosquitto MQTT Broker...
Jan 25 09:18:40 <userid> systemd[1]: Started Mosquitto MQTT Broker.

2단계 - MQTT 암호 인증 구성

Mosquitto는 mosquitto_passwd라는 암호 파일을 생성하는 유틸리티와 함께 제공됩니다. Mosquitto는 /etc/mosquitto 디렉토리에 모든 구성을 저장합니다.

다음 명령을 실행하여 사용자 이름 username에 대해 /etc/mosquitto/passwd에서 암호화된 암호 파일을 생성합니다. 원하는 비밀번호를 입력하세요.

$ sudo mosquitto_passwd -c /etc/mosquitto/passwd username
Password:
Reenter password:

다음으로 /etc/mosquitto/conf.d 디렉토리 아래에 default.conf 파일을 생성하고 편집을 위해 엽니다.

$ sudo nano /etc/mosquitto/conf.d/default.conf

다음 줄을 붙여넣어 암호 파일의 위치를 지정합니다. 수신기 필드를 생략하면 구성에 관계없이 항상 익명으로 연결됩니다.

listener 1883
password_file /etc/mosquitto/passwd

Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

Mosquitto 서버를 다시 시작하여 변경 사항을 구현하십시오.

$ sudo systemctl restart mosquitto

3단계 - Mosquitto 클라이언트 테스트

사용 사례에 따라 Mosquitto 클라이언트를 사용하여 다양한 주제에 대한 메시지를 보내고 받을 수 있습니다. 클라이언트는 구독자 또는 게시자입니다.

다음 단계는 주제를 구독하는 것입니다. MQTT 프로토콜에서 주제는 연결된 클라이언트에 대한 메시지를 필터링하기 위해 서버/브로커에서 사용하는 문자열을 나타냅니다. 다음은 홈 자동화 애플리케이션에서 사용할 수 있는 몇 가지 샘플 항목입니다.

  • 집/조명/거실
  • 집/조명/주방
  • 홈/조명/master_bedroom\n
  • 홈/조명/kids_bedroom\n

주제를 구독하려면 주제 다음에 mosquitto_sub -t 명령을 실행하십시오. 예를 들어 home/lights/kitchen 주제를 구독하려면 다음 명령을 실행합니다.

$ mosquitto_sub -u username -P YOUR_PASSWORD -t "home/lights/kitchen"

기존 창을 닫지 마십시오. 다음 명령을 사용하여 새 터미널 창을 열고 home/lights/kitchen 주제에 메시지를 게시합니다.

$ mosquitto_pub -u username -P YOUR_PASSWORD -m "ON" -t "home/lights/kitchen"

첫 번째 터미널 창으로 돌아가면 ON 페이로드를 받게 됩니다.

ON

그런 다음 두 번째 터미널에서 동일한 주제에 대한 OFF 메시지를 보냅니다.

$ mosquitto_pub -u username -P YOUR_PASSWORD -m "OFF" -t "home/lights/kitchen"

첫 번째 터미널에는 새로 게시된 메시지가 표시됩니다.

ON
OFF

인증되지 않은 댓글을 보내려고 하면 실패합니다. 예를 들어 다음 명령을 시도하십시오.

$ mosquitto_sub -t "home/lights/sitting_room"
Connection error: Connection Refused: not authorised.

권장되지는 않지만 인증 없이 명령을 실행하려면 /etc/mosquitto/conf.d/default.conf 파일에 다음 행을 추가해야 합니다.

allow_anonymous true

4단계 - SSL 설치

Lets Encrypt를 사용하여 SSL 인증서를 설치하려면 Certbot 도구를 다운로드해야 합니다. 이를 위해 Snapd 패키지 설치 프로그램을 사용합니다.

Snap 설치 프로그램을 설치합니다.

$ sudo apt install snapd

Snapd 버전이 최신인지 확인하세요.

$ sudo snap install core 
$ sudo snap refresh core

Certbot을 설치합니다.

$ sudo snap install --classic certbot

다음 명령을 사용하여 /usr/bin 디렉토리에 대한 심볼릭 링크를 생성하여 Certbot 명령이 실행되도록 합니다.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

SSL 인증서를 생성합니다.

$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m  -d mqtt.example.com

위의 명령은 서버의 /etc/letsencrypt/live/mqtt.example.com 디렉토리에 인증서를 다운로드합니다.

Diffie-Hellman 그룹 인증서를 생성합니다.

$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Lets Encrypt 자동 갱신을 위한 챌린지 웹 루트 디렉터리를 만듭니다.

$ sudo mkdir -p /var/lib/letsencrypt

SSL을 갱신하기 위해 Cron 작업을 생성합니다. 인증서를 확인하고 필요한 경우 갱신하기 위해 매일 실행됩니다. 이를 위해 먼저 /etc/cron.daily/certbot-renew 파일을 생성하고 편집을 위해 엽니다.

$ sudo nano /etc/cron.daily/certbot-renew

다음 코드를 붙여넣습니다.

#!/bin/sh
certbot renew --cert-name mqtt.example.com --webroot -w /var/lib/letsencrypt/

Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

실행 가능하도록 태스크 파일에 대한 권한을 변경하십시오.

$ sudo chmod +x /etc/cron.daily/certbot-renew

5단계 - MQTT SSL 구성

이제 SSL 인증서가 준비되었으므로 이에 대한 Mosquitto 액세스를 제공해야 합니다. 이를 위해 Mosquitto가 액세스할 수 있는 위치에 인증서를 복사해야 합니다.

$ sudo cp /etc/letsencrypt/live/mqtt.example.com/fullchain.pem /etc/mosquitto/certs/server.pem
$ sudo cp /etc/letsencrypt/live/mqtt.example.com/privkey.pem /etc/mosquitto/certs/server.key

/etc/mosquitto/certs 디렉토리의 소유권을 설치 중에 생성된 mosquitto 사용자로 변경합니다.

$ sudo chown mosquitto: /etc/mosquitto/certs

Mosquitto에 SSL 암호화를 활성화하는 다음 단계는 SSL 인증서의 위치를 지정하는 것입니다. 편집을 위해 구성 파일을 엽니다.

$ sudo nano /etc/mosquitto/conf.d/default.conf

파일 끝에 다음 코드를 붙여넣습니다.

. . .
listener 8883
certfile /etc/mosquitto/certs/server.pem
cafile  /etc/ssl/certs/ISRG_Root_X1.pem
keyfile /etc/mosquitto/certs/server.key
dhparamfile /etc/ssl/certs/dhparam.pem

Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다. 파일 끝에 후행 줄 바꿈을 남겨 두십시오.

리스너 8883 부분은 암호화된 리스너를 설정합니다. MQTTS라고 하는 MQTT + SSL의 표준 포트입니다. 다음 네 줄은 SSL 파일의 위치를 지정합니다.

Mosquitto를 다시 시작하여 설정을 업데이트하십시오.

$ sudo systemctl restart mosquitto

포트 8883에 대한 연결을 허용하려면 방화벽을 업데이트해야 합니다.

$ sudo ufw allow 8883

다음으로 mosquitto_pub 명령을 사용하여 기능을 테스트해야 합니다.

$ mosquitto_pub -h mqtt.example.com -t "home/lights/kitchen" -m "hello" -p 8883 --capath /etc/ssl/certs/ -u username -P YOUR_PASSWORD

보시다시피 포트 번호와 SSL 인증서 경로를 포함한 특정 추가 매개변수가 포함되어 있습니다. SSL을 사용해야 할 때마다 항상 전체 호스트 이름, 즉 localhost 대신 mqtt.example.com을 지정해야 합니다. 오류가 발생합니다.

또한 매번 --capath 지시어를 추가해야 합니다. 운영 체제에서 설치한 루트 인증서를 찾도록 Mosquitto 클라이언트에 지시합니다.

6단계 - SSL 갱신 구성

Certbot은 인증서가 만료되기 전에 자동으로 갱신합니다. 그러나 갱신된 인증서를 /etc/mosquitto/certs 디렉터리에 복사하고 Mosquitto 서비스를 다시 시작하라는 지시를 받아야 합니다.

우리는 쉘 스크립트를 생성하여 그렇게 할 것입니다. /etc/letsencrypt/renewal-hooks/deploy 디렉터리에 mosquitto-copy.sh 파일을 만듭니다.

$ sudo nano /etc/letsencrypt/renewal-hooks/deploy/mosquitto-copy.sh

다음 코드를 붙여넣습니다. MY_DOMAIN 변수의 값을 도메인으로 바꿉니다. $ {RENEWED_LINEAGE} 변수는 갱신 중에 /etc/letsencrypt/live/mqtt.example.com 디렉토리를 가리킵니다.

# Set which domain this script will be run for
MY_DOMAIN=mqtt.example.com
# Set the directory that the certificates will be copied to.
CERTIFICATE_DIR=/etc/mosquitto/certs

if [ "${RENEWED_DOMAINS}" = "${MY_DOMAIN}" ]; then
	# Copy new certificate to Mosquitto directory
	cp ${RENEWED_LINEAGE}/fullchain.pem ${CERTIFICATE_DIR}/server.pem
	cp ${RENEWED_LINEAGE}/privkey.pem ${CERTIFICATE_DIR}/server.key

	# Set ownership to Mosquitto
	chown mosquitto: ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key

	# Ensure permissions are restrictive
	chmod 0600 ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key

	# Tell Mosquitto to reload certificates and configuration
	pkill -HUP -x mosquitto
fi

Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

파일을 실행 가능하게 만드십시오.

$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/mosquitto-copy.sh

이 스크립트는 인증서가 성공적으로 갱신될 때마다 자동으로 실행됩니다.

Mosquitto 및 Nginx와 같은 웹 서버를 실행 중인 경우 갱신 전에 서버를 중지하고 완료되면 다시 시작하도록 Certbot에 지시해야 합니다. 이를 수행하려면 etc/letsencrypt/renewal/mqtt.example.com.conf 파일을 여십시오.

$ sudo nano /etc/letsencrypt/renewal/mqtt.example.com.conf

파일 끝에 다음 줄을 추가합니다. 사용 중인 웹 서버에 따라 명령을 변경하십시오.

pre_hook = systemctl stop nginx
post_hook = systemctl start nginx

Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

Certbot 테스트 실행을 실행하여 확인합니다.

$ sudo certbot renew --dry-run

오류가 표시되지 않으면 모든 것이 설정된 것입니다.

7단계 - Websocket 구성

Websockets 기능을 사용하는 Javascript를 사용하여 브라우저 내에서 MQTT 프로토콜을 사용하도록 Mosquitto를 구성할 수 있습니다. 활성화하려면 구성 파일을 엽니다.

$ sudo nano /etc/mosquitto/conf.d/default.conf

파일 끝에 다음 줄을 붙여넣습니다.

. . .
listener 8083
protocol websockets
certfile /etc/mosquitto/certs/server.pem
cafile  /etc/ssl/certs/ISRG_Root_X1.pem
keyfile /etc/mosquitto/certs/server.key
dhparamfile /etc/ssl/certs/dhparam.pem

Ctrl + X를 누르고 메시지가 표시되면 Y를 입력하여 파일을 저장합니다.

포트 번호와 프로토콜 필드를 제외하고는 SSL을 활성화하는 데 사용한 것과 동일한 블록입니다. 8083은 MQTT가 WebSocket을 사용하여 통신하는 데 사용하는 가장 일반적인 포트입니다.

Mosquitto 서비스를 다시 시작하십시오.

$ sudo systemctl restart mosquitto

포트 8083을 엽니다.

$ sudo ufw allow 8083

WebSockets 기능을 테스트하려면 브라우저 기반 MQTT 클라이언트를 사용해야 합니다. 사용 가능한 클라이언트가 많이 있지만 우리의 목적을 위해 HiveMQ Websocket 클라이언트를 사용할 것입니다. 브라우저에서 클라이언트를 시작하면 다음이 표시됩니다.

위의 스크린샷과 같이 표시된 대로 필드를 채웁니다.

  • 호스트는 Mosquitto 서버 mqtt.example.com의 도메인이어야 합니다.\n
  • 포트는 8083이어야 합니다.\n
  • ClientID 필드는 그대로 둘 수 있습니다.\n
  • 사용자 이름은 Mosquitto 사용자 이름이어야 합니다.\n
  • 암호는 위에서 만든 암호여야 합니다.\n
  • SSL 체크박스를 선택합니다.\n

연결 버튼을 누르면 HiveMQ 클라이언트가 Mosquitto 서버에 연결됩니다.

연결되면 주제로 home/lights/kitchen을 입력하고 메시지를 입력한 다음 게시를 누릅니다.

성공적인 연결을 확인하는 메시지가 mosquitto_sub 터미널 창에 표시됩니다.

이는 Websockets 구현이 성공했음을 보여줍니다.

결론

이것으로 Ubuntu 20.04 기반 시스템에서 안전하고 암호로 보호되고 SSL로 암호화된 MQTT 서버 설정을 마칩니다. 질문이 있으시면 아래 의견에 게시하십시오.