직방 도어락 로컬 릴레이 서버
1.9K
relay는 직방(삼성SDS) 도어락과 실클라우드 사이를 중계하는 상시 데몬이다(투명
MQTTS+UDP 프록시 — 락은 그대로 두고 전체 트래픽을 관찰하거나, 필요하면 대신 응답한다).
/data 하나로 마운트/opt/zigbang-relay/(경로는 아무 데나 상관없음) 하나에 아래 파일들을 넣고, 이 디렉터리
전체를 컨테이너의 /data에 통째로 마운트한다(볼륨을 여러 개로 쪼개지 않는 이유는 relay의
설정 파일 안 모든 경로가 이 디렉터리 기준 상대경로라서, 디렉터리 하나만 옮기면 그대로
재현되기 때문):
| 경로 | 무엇인가 | 어떻게 생기나 |
|---|---|---|
relay.toml | 설정 파일 | docker/relay.toml.example 편집 |
rules/*.rhai | 메시지 응답 규칙 | docker/rules/ 그대로 복사 |
certs/fullchain.pem, certs/privkey.pem | TLS 인증서 | 2단계에서 발급 |
state/replay.json | 재생 캐시(장애 대응용) | 자동 생성, 미리 안 만들어도 됨 |
logs/ | relay 로그 | 자동 생성 |
relay.toml 작성relay.toml을 아래 내용으로 만들고, 표시된 값들을 실제 값으로 바꾼다:
# 게이트웨이 배포용 relay config (상대경로). 전부 이 파일과 같은 디렉터리(/opt/zigbang-relay 등,
# systemd WorkingDirectory / docker WORKDIR) 기준 — 그 디렉터리 하나만 통째로 배포/마운트하면 됨
# (README.md 참조). 실제 값(도메인/포트)은 설치 후 이 파일에서 편집.
# 규칙: rules/*.rhai(mtime 핫리로드 — 수정시 재시작 불필요). 설계: DESIGN.md(레포 밖 private).
log_level = "info" # error|warn|info|debug|trace
observer = "0.0.0.0:9883" # 평문 MQTT 관찰/명령(로컬신뢰망 전용 — 방화벽으로 막을 것)
# observer_user = "watcher" # 둘 다 설정해야 인증 활성화(CONNECT username/password 검사).
# observer_pass = "바꿀것" # 주석 처리(기본)면 예전처럼 무인증 — 방화벽만으로 막는 셈.
rules_file = "rules"
replay_store = "state/replay.json"
log_dir = "logs"
# TLS: certbot deploy-hook 가 이 디렉터리의 certs/ 로 cert 를 복사해준다(README 참조).
cert_file = "certs/fullchain.pem"
cert_key = "certs/privkey.pem"
cert_name = "relay.example.com" # ← 실제 주입 도메인으로 변경
upstream_insecure = true # 실클라우드로 나갈 때 그쪽 cert 검증 안 함(기술부채, 낮은 우선순위)
answered_ttl_secs = 120
answered_cap = 8192
reconnect_secs = 15
[[route]]
name = "mqtts"
proto = "mqtts"
mode = "proxy" # proxy(순수 통과+관찰, 안전한 기본값) | shadow | decloud
listen = "0.0.0.0:18883"
upstream = "mqtttcp.homeiot.zigbang-iot.com:8883"
[[route]]
name = "holepunch"
proto = "udp"
mode = "proxy"
listen = "0.0.0.0:5683"
upstream = "mqttudp.homeiot.zigbang-iot.com:5683"
listen 포트(18883/5683)는 도어락이 실제로 접속해오는 주소다 — 도어락 등록(provisioning)
때 주입한 serviceUrl/포트가 이 컨테이너를 가리켜야 한다. upstream은 진짜 직방 클라우드
브로커 주소(프로토콜 리버싱으로 확인된 값을 씀). mode는 처음엔 proxy(순수 통과+관찰,
락 동작에 영향 없음)로 시작하는 걸 권장 — shadow/decloud는 더 적극적인 모드다.
rules 배치레포의 rules을 그대로 복사한다:
이 디렉터리에 "락이 어떤 메시지를 보내면 어떻게 응답할지"를 선언하는 규칙 목록이다 — relay
바이너리 자체엔 이런 프로토콜별 로직이 없고 전부 이 파일 소관이라, 파일만 바꿔치기하면
재시작 없이동작이 바뀐다.
도어락은 공인 CA가 발급한 인증서만 수락한다(자체서명은 무조건 거부, 호스트명도 검사함
— 발급받은 도메인과 relay.toml의 cert_name/provision 때 주입한 도메인이 일치해야 함).
그 도메인이 이 컨테이너가 뜬 호스트를 실제로 가리켜야 한다(A레코드로 호스트 IP 직접 지정
권장 — Cloudflare 같은 프록시형 CNAME은 HTTP-01 발급 자체가 막힐 수 있음).
sudo certbot certonly --standalone -d relay.example.com # 최초 발급(도메인 실제 값으로)
sudo install -m 0644 /etc/letsencrypt/live/relay.example.com/fullchain.pem /opt/zigbang-relay/certs/
sudo install -m 0640 /etc/letsencrypt/live/relay.example.com/privkey.pem /opt/zigbang-relay/certs/
자동 갱신 — /etc/letsencrypt/renewal-hooks/deploy/zigbang-relay.sh:
#!/usr/bin/env bash
set -e
D=relay.example.com # ← 실제 도메인
if [[ "$RENEWED_LINEAGE" == *"/$D" ]]; then
install -m 0644 "$RENEWED_LINEAGE/fullchain.pem" /opt/zigbang-relay/certs/fullchain.pem
install -m 0640 "$RENEWED_LINEAGE/privkey.pem" /opt/zigbang-relay/certs/privkey.pem
fi
chmod +x 해두면 certbot이 갱신할 때마다 자동 실행된다. relay는 cert 파일의 mtime을
감시해서 컨테이너 재시작 없이 새 인증서를 바로 반영하므로, 이 훅에 docker restart를
넣을 필요조차 없다.
docker pull 3735943886/zigbang-relay:stable # 항상 최신 정식버전(권장)
# 또는 특정 버전 고정: docker pull 3735943886/zigbang-relay:0.1.0
:latest도 있지만(현재는 :stable과 동일 대상) 워크플로 주석상 프리릴리스(vX.Y.Z-rc.1 등)
태그는 stable/latest를 안 건드리도록 짜여있으니, 뭘 쓸지 헷갈리면 :stable을 쓸 것.
docker run -d --restart=always --name zigbang-relay \
--user $(id -u):$(id -g) \
-p 18883:18883 -p 5683:5683/udp -p 9883:9883 \
-v /opt/zigbang-relay:/data \
3735943886/zigbang-relay:stable
WORKDIR /data + CMD ["relay.toml"]가 이미지에 박혀있어 인자 없이 그대로 /data/relay.toml
을 읽는다. --user $(id -u):$(id -g)로 호스트에서 /opt/zigbang-relay를 소유한 유저 그대로
넘기면 이미지 기본값(10001)과 무관하게 쓰기(state/log)가 바로 됨 — 별도 chown 불필요.
-p 9883(평문 관찰자 포트)은 로컬신뢰망에서만 접근 가능하게 방화벽으로 반드시 막을 것.
docker logs -f zigbang-relay
# 평문 tap (로컬신뢰망 전용, 방화벽으로 외부 차단 필수):
mosquitto_sub -h <게이트웨이> -p 9883 -t '#' -v
Content type
Image
Digest
sha256:1b85657e4…
Size
3.2 MB
Last updated
21 days ago
docker pull 3735943886/zigbang-relay