Mosquitto MQTT 브로커 완벽 구축 가이드 (SSL/TLS 적용) [김팔복TV]

김팔복 2026. 4. 23. 오전 8:24:15
조회 10 추천 0 댓글 0

MQTT

MQTT는 IoT나 실시간 데이터 전송에서 많이 쓰이는 가벼운 메시징 프로토콜입니다.

Mosquitto

Mosqutto는 그 MQTT를 중간에서 연결해주는 브로커 서버입니다.


진행 순서

  1. mqtt:// (port: 1883) 기본 MQTT

  2. ws:// (port:9001) WebSocket

  3. SSL 인증서 발급 (Certbot)

  4. mqtts:// (port:8883)

  5. wss:// (port:443)

  6. 1883, 9001 포트 차단 (인증서가 적용되지 않은 포트는 차단)


사전 준비

시작하기 전에 몇가지 사전 준비가 필요합니다.

먼저 서버에서 사용할 포트들을 미리 열어줘야 합니다.

  • 포트(port) 허용
    • 80 (Certbot / HTTP)
    • 443 (HTTPS / WSS)
    • 1883 (MQTT)
    • 8883 (MQTTS)
    • 9001 (WebSocket)

ufw 방화벽이 있다면

sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 1883
sudo ufw allow 8883
sudo ufw allow 9001

도메인 준비 (예: mqtt.example.com)
도메인이 서버 IP를 가리키도록 DNS 설정 필요
SSL 인증서를 발급받기 위해서는 도메인이 반드시 필요합니다.


MQTT 설치 및 기본 MQTT (port: 1883)

1. Mosquitto 설치

👉 Mosquitto MQTT Broker

sudo apt update
sudo apt install mosquitto mosquitto-clients -y

mosquitto는 MQTT 브로커 서버
mosquitto-clients는 테스트용 pub/sub 클라이언트 도구

2. 계정 / 비밀번호 생성

sudo mosquitto_passwd -c /etc/mosquitto/passwd {{생성할 id: mqtt-test}}

👉 비번 입력
[mqtt-test: 87654321]

-c 옵션은 비밀번호 파일을 새로 생성할 때 사용
이미 파일이 있으면 -c 없이 사용자 추가

권한

sudo chown mosquitto:mosquitto /etc/mosquitto/passwd
sudo chmod 640 /etc/mosquitto/passwd

Mosquitto 프로세스가 읽을 수 있도록 권한 설정

3. 설정 파일 - MQTT 1883 설정

sudo nano /etc/mosquitto/conf.d/10-mqtt-1883.conf

아래 설정 값을 추가합니다.

listener 1883
protocol mqtt
allow_anonymous false
password_file /etc/mosquitto/passwd

listener 1883 : 1883 포트에서 MQTT 수신
protocol mqtt : 일반 MQTT 프로토콜 사용
allow_anonymous false : 익명 접속 차단
password_file : 계정/비밀번호 인증 사용

기타 커스텀 설정

sudo nano /etc/mosquitto/conf.d/20-custom.conf

아래 내용 입력

max_keepalive 60
max_queued_messages 500
  • max_keepalive : 클라이언트가 사용할 수 있는 최대 keepalive 값을 제한하는 옵션 너무 긴 keepalive 연결을 제한해서 죽은 연결 정리에 도움을 줌 다만 이 옵션은 “무조건 60초 뒤 끊는다”는 의미는 아니고, 허용 가능한 최대 keepalive 값을 제한하는 옵션입니다.
    • 죽은 클라이언트 자동 정리
    • 유령 연결 방지
  • max_queued_messages : 클라이언트가 바로 받지 못한 QoS 1/2 메시지를 서버가 큐에 저장할 수 있는 최대 개수 느린 클라이언트로 인한 메모리 사용 증가를 방지
    • 오프라인/지연 클라이언트 대응
    • 서버 메모리 보호
# 재시작
sudo systemctl restart mosquitto

# 상태
sudo systemctl status mosquitto

4. Test

mosquitto_sub -h {{서버IP}} -t {{topic}} -u {{계정 : mqtt-test}} -P {{비번}}
mosquitto_pub -h {{서버IP}} -t {{topic}} -m "hello MQTT" -u {{계정 : mqtt-test}} -P {{비번}}

mosquitto_sub -h localhost -p 1883 -t test -u mqtt-test -P 87654321
mosquitto_pub -h localhost -p 1883 -t test -m "hello MQTT" -u mqtt-test -P 87654321


ws:// (port:9001) WebSocket

WebSocket은 브라우저 환경에서 MQTT를 사용하기 위한 방식입니다.
(브라우저는 TCP 기반 MQTT에 직접 연결할 수 없기 때문)

브라우저에서 사용하지 않을 경우 설정하지 않아도 됩니다.

1. 설정

sudo nano /etc/mosquitto/conf.d/30-ws-9001.conf
listener 9001
protocol websockets
allow_anonymous false
password_file /etc/mosquitto/passwd
  • per_listener_settings true
    👉 listener(포트)별로 설정을 따로 적용하기 위한 옵션
  • listener 9001
    👉 웹소켓 전용 포트
  • protocol websockets
    👉 HTTP 기반 WebSocket으로 MQTT 사용
  • allow_anonymous false
    👉 인증 필수
  • password_file
    👉 기존 MQTT 계정 그대로 사용
sudo nano /etc/mosquitto/mosquitto.conf
# include_dir /etc/mosquitto/conf.d 위에 추가

per_listener_settings true

listener마다 인증/권한 설정을 따로 적용하게 하는 설정

2. 적용

sudo systemctl restart mosquitto
ss -lntp | grep 9001

👉 9001 포트 떠야 정상

3. 테스트

WebSocket은 브라우저 기반 or GUI툴 필요
MQTTX 툴 강력 추천

MQTTX 공식 사이트 : https://mqttx.app/

접속 정보

  • Protocol: ws
  • Host: 서버IP
  • Port: 9001
  • Username: mqtt-test
  • Password: 87654321

SSL 인증서 생성 (nginx + certbot)

1. 개요

왜 Nginx + certbot 을 사용하냐?

무료 SSL 인증서를 발급받기 위해 Let's Encrypt를 사용하고,
인증서 발급과 갱신을 편하게 관리하기 위해 nginx와 certbot을 사용합니다.

실제 MQTT 통신은 Mosquitto가 처리하고,
nginx는 인증서 발급 및 관리 용도로만 사용합니다.

장점

  • 무료 SSL 인증서 발급 가능 (Let’s Encrypt)
  • 90일마다 자동 갱신

2. nginx 설치

sudo apt install nginx -y

3. nginx 도메인 설정

sudo nano /etc/nginx/sites-available/mqtt

아래 내용 추가

server {
    listen 80;
    server_name mqtt.example.com;

    location / {
        return 200 "ok";
    }
}
sudo ln -s /etc/nginx/sites-available/mqtt /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

4. Certbot 설치

Certbot은 Let's Encrypt와 연동하여 SSL 인증서를 자동으로 발급/갱신해주는 도구입니다.

참고 : https://www.youtube.com/watch?v=RhGMiC2cAMI

# snap 설치
sudo apt update
sudo apt install snapd -y

# snapd 자체를 최신으로 갱신
sudo snap install core
sudo snap refresh core
# Certbot 스냅 설치 (스냅 권한 문제를 피해 --classic 옵션 사용)
sudo snap install certbot --classic
# /snap/bin/certbot 경로에 설치되었기 때문에,
# 전통적인 경로(/usr/bin/certbot)로도 실행할 수 있게 링크를 겁니다.
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# 버전 확인
certbot --version

5. SSL 인증서 생성

sudo certbot --nginx -d {{도메인 예: mqtt.example.com}}

인증서 확인

ls /etc/letsencrypt/live/mqtt.example.com/

6. certbot 인증서 복사 및 재갱신때 마다 다시 복사

sudo nano /etc/letsencrypt/renewal-hooks/deploy/mosquittto.sh

아래 내용 추가

#!/bin/bash
cp /etc/letsencrypt/live/mqtt.exmaple.com/fullchain.pem /etc/mosquitto/certs/
cp /etc/letsencrypt/live/mqtt.exmaple.com/privkey.pem /etc/mosquitto/certs/

chown mosquitto:mosquitto /etc/mosquitto/certs/*
chmod 600 /etc/mosquitto/certs/*

systemctl restart mosquitto
# 실행 권한
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/mosquitto.sh

# 1회 실행
sudo sh /etc/letsencrypt/renewal-hooks/deploy/mosquitto.sh

설명
/etc/letsencrypt/renewal-hooks/deploy 이 폴더에 넣으면 인증서 갱신 성공 후 자동 실행됨
즉 certibot 의 인증서가 새로 생성될 때 마다 /etc/mosquitto/certs 폴더에 인증서를 복사하고
mosquitto를 재시작 합니다.

🔥 포인트 정리

  • 무료 SSL ✔
  • 90일 마다 SSL 갱신 ✔
  • 자동 갱신 ✔
  • 자동 재시작 ✔

90일짜리 인증서지만 자동 갱신 + 자동 재시작으로 신경 쓸 필요 없음


mqtts:// (port: 8883) SSL 적용

1. 개요

이제 발급받은 SSL 인증서를 Mosquitto에 적용해서
암호화된 MQTT 통신 (mqtts://) 을 구성합니다.

기존 mqtt:// (1883)과 달리,
모든 데이터는 TLS를 통해 암호화되어 전송됩니다.

2. mosquitto 설정

sudo nano /etc/mosquitto/conf.d/40-mqtts-8883.conf
listener 8883
protocol mqtt

allow_anonymous false
password_file /etc/mosquitto/passwd

cafile /etc/mosquitto/certs/fullchain.pem
certfile /etc/mosquitto/certs/fullchain.pem
keyfile /etc/mosquitto/certs/privkey.pem

listener 8883
👉 SSL 적용된 MQTT 포트

protocol mqtt
👉 일반 MQTT 프로토콜 + TLS 적용

cafile
👉 인증서 체인 (CA)

certfile
👉 서버 인증서

keyfile
👉 개인키

3. 적용

sudo systemctl restart mosquitto

이제 mqtts로 접속하면 TLS를 통해 암호화된 상태로 통신하게 됩니다.

4. 테스트

MQTTX 툴 강력 추천

MQTTX 공식 사이트 : https://mqttx.app/

접속 정보

  • Protocol: mqtts
  • Host: mqtt.example.com (도메인)
  • Port: 8883
  • Username: mqtt-test
  • Password: 87654321

※ mqtts 연결 시 SSL 인증서 검증이 수행됩니다.
TLS 인증서는 도메인 기준으로 발급되기 때문에 IP로 접속하면 인증서 검증에 실패할 수 있습니다.
Host는 반드시 도메인을 사용하세요.


wss:// (WebSocket + SSL) 적용

1. 개요

이제 WebSocket(ws://)에 SSL을 적용해서
보안 WebSocket (wss://) 을 구성합니다.

기존 ws:// (9001)은 암호화되지 않은 상태였지만,
wss://는 HTTPS 기반으로 암호화된 통신을 제공합니다.

🧠 구조 이해 (중요)

클라이언트 (wss://)
        ↓
      nginx (SSL 처리)
        ↓
ws://127.0.0.1:9001 (mosquitto)

👉 핵심:

  • SSL은 nginx가 처리
  • mosquitto는 기존 ws 그대로 사용

2. Nginx 설정

sudo nano /etc/nginx/sites-available/mqtt

아래 내용 추가

server {
    ... 기존 설정

    # WebSocket (wss) 설정 추가
    location /mqtt {
        proxy_pass http://127.0.0.1:9001;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }
}

※ nginx에서 /mqtt 경로로 설정했기 때문에,
클라이언트에서도 동일하게 path를 /mqtt로 설정해야 합니다.

3. 테스트

MQTTX 툴 강력 추천

MQTTX 공식 사이트 : https://mqttx.app/

접속 정보

  • Protocol: wss
  • Host: mqtt.example.com (도메인)
  • Port: 443
  • Username: mqtt-test
  • Password: 87654321
  • path: /mqtt

※ nginx에서 /mqtt 경로로 설정했기 때문에,
클라이언트에서도 동일하게 path를 /mqtt로 설정해야 합니다.

※ SSL 인증서 검증을 위해 반드시 도메인으로 접속해야 합니다.
(IP 사용 시 연결이 실패할 수 있습니다)


인증서가 적용되지 않은 포트 차단

mqtt:// → 1883 차단
ws:// → 9001 차단

mqtts:// → 8883 사용
wss:// → 443 사용

왜 차단해야 하는가?

mqtt:// (1883)과 ws:// (9001)은 SSL/TLS가 적용되지 않은
평문 통신입니다.

즉, 아이디/비밀번호 및 메시지 내용이
암호화되지 않은 상태로 그대로 네트워크에 전송됩니다.

이로 인해 발생할 수 있는 문제

  • 계정 정보 노출 (아이디 / 비밀번호 탈취)
  • 메시지 데이터 도청
  • 중간자 공격 (MITM, Man-In-The-Middle)

반면,
mqtts:// (8883)과 wss:// (443)는 TLS 기반 암호화 통신으로
데이터가 안전하게 보호됩니다.

결론

암호화되지 않는 포트(1883, 9001)는 반드시 차단하고,
mqtts 와 wss만 사용하는 것을 권장합니다.


Mosquitto 로그

1. 로그

실제 로그 위치

/var/log/mosquitto/mosquitto.log

실시간 로그 보기

sudo tail -f /var/log/mosquitto/mosquitto.log

👉 가장 많이 쓰는 명령

2. 로그 로테이션

👉 로그 계속 쌓이면 디스크 터짐

logrotate 설정 파일

sudo nano /etc/logrotate.d/mosquitto
/var/log/mosquitto/mosquitto.log {
        rotate 3
        daily
        compress
        delaycompress
        size 10M
        nocreate
        missingok
        postrotate
                if invoke-rc.d mosquitto status > /dev/null 2>&1; then \
                        invoke-rc.d mosquitto reload > /dev/null 2>&1; \
                fi;
        endscript
}

위 설정 간략 설명

✔ 하루마다 또는 10MB 초과 시 분리
✔ 최대 3개의 로그 파일 보관
✔ 오래된 로그는 자동 삭제
✔ 로그 파일 자동 압축
✔ 로그 변경 시 mosquitto 자동 reload

[ 주의할 점 ]

size 10M 옵션이 포함되어 있기 때문에
로그가 빠르게 쌓이는 경우 하루에도 여러 번 로그가 분리될 수 있습니다.

이 경우 rotate 3 설정으로 인해
로그 보관 기간이 짧아질 수 있습니다.

[ 실무 추천 ]

size 설정을 제거하면
로그 크기와 관계없이 하루 1개 로그 파일이 생성되고
rotate 3 설정으로 약 3일 동안 로그를 보관하는 효과를 얻을 수 있습니다.

#mqtt #mosquitto #팔복소프트 #김팔복 #김팔복TV #예천

댓글 0