Mosquitto MQTT 브로커 완벽 구축 가이드 (SSL/TLS 적용) [김팔복TV]
MQTT
MQTT는 IoT나 실시간 데이터 전송에서 많이 쓰이는 가벼운 메시징 프로토콜입니다.
Mosquitto
Mosqutto는 그 MQTT를 중간에서 연결해주는 브로커 서버입니다.
진행 순서
mqtt:// (port: 1883) 기본 MQTT
ws:// (port:9001) WebSocket
SSL 인증서 발급 (Certbot)
mqtts:// (port:8883)
wss:// (port:443)
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 #예천