알짜게시판

RustDesk 자체 서버 구축으로 공용 서버 로그인 문제 해결

공용 서버 로그인 요구로 인한 문제 발생

RustDesk를 내부 원격 접속 용도로 사용하고 있었는데, 어느 순간부터 공용 서버를 사용할 경우 로그인이 필요하다는 메시지가 나타났다. 기존에는 별도 인증 없이 바로 연결이 가능했기 때문에, 이 변화는 운영 흐름에 직접적인 영향을 줬다. 특히 내부망 장비 약 30대에 대해 원격 제어를 수행하고 있었기 때문에, 로그인 절차 추가는 자동화 스크립트와 충돌이 발생했다.

문제는 단순히 로그인 절차가 번거로운 수준이 아니라, 인증 방식이 외부 서버에 의존한다는 점이었다. 내부 시스템 접근 경로가 외부 인증 서버에 종속되는 구조는 운영 관점에서 관리 포인트를 하나 더 늘리는 셈이었다. 장애 상황에서 원격 접속 자체가 막힐 가능성도 배제할 수 없었다.

이 시점에서 선택지는 두 가지였다. 공용 서버 정책에 맞춰 인증 구조를 다시 설계하거나, 아예 자체 서버로 전환하는 것이다. 후자를 선택한 이유는 명확했다. 내부망 기반 원격 제어는 외부 의존성을 줄이는 방향이 더 낫다고 판단했다.

기존 공용 서버 방식의 한계와 구조적 문제

RustDesk 공용 서버는 기본적으로 중계 서버(relay server)와 ID 서버를 제공한다. 사용자는 별도 설정 없이 바로 연결이 가능하지만, 모든 트래픽이 외부 서버를 경유한다는 점에서 제어권이 없다. 특히 인증 정책이 변경되면 사용자는 그대로 영향을 받는다.

또 하나의 문제는 성능이다. 공용 서버는 다수 사용자가 공유하기 때문에 트래픽이 몰리는 시간대에는 연결 지연이 발생한다. 실제로 테스트 기준으로 평균 연결 시간이 1.2초에서 최대 3초까지 증가하는 경우가 있었다. 내부 서버를 사용할 경우 동일 환경에서 0.3~0.5초 수준으로 줄어드는 것을 확인했다.

이 구조에서는 장애 원인 분석도 어렵다. 연결이 실패했을 때, 클라이언트 문제인지 서버 문제인지, 혹은 공용 서버의 상태 문제인지 구분이 되지 않는다. 운영 환경에서는 이런 불확실성이 지속적으로 누적된다.

Docker 기반 RustDesk 서버 구축 방향

자체 서버 구축은 생각보다 단순한 구조다. RustDesk는 두 가지 주요 컴포넌트로 구성된다. 하나는 ID 서버 역할을 하는 hbbs, 다른 하나는 relay 서버 역할을 하는 hbbr이다. 이 두 컨테이너를 Docker로 실행하면 기본적인 서버 구성이 완료된다.

구성 과정은 크게 세 단계로 나눌 수 있다. Docker 설치 → 컨테이너 실행 → 네트워크 설정이다. 서버는 CentOS 기반 환경에서 진행했으며, 추가적인 의존성은 없었다.

Docker 설치는 다음과 같이 진행했다.

sudo dnf update -y
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

sudo dnf install -y docker-ce docker-ce-cli containerd.io

설치 이후 Docker 서비스를 활성화한다.

sudo systemctl start docker
sudo systemctl enable docker

여기까지는 일반적인 Docker 초기 세팅과 동일하다. 별도의 커스터마이징 없이 바로 다음 단계로 넘어간다.

RustDesk 서버 컨테이너 실행과 동작 구조

RustDesk 서버는 hbbs와 hbbr 두 개의 컨테이너로 나뉘어 실행된다. 각각의 역할을 분리한 이유는 트래픽 처리와 인증을 분리하기 위해서다.

먼저 hbbs를 실행한다.

docker run -d --name hbbs \
  -p 21115:21115 \
  -p 21116:21116/tcp \
  -p 21116:21116/udp \
  -p 21118:21118 \
  -v /opt/rustdesk:/root \
  rustdesk/rustdesk-server:latest \
  hbbs -r {서버아이피}:21117

이 컨테이너는 클라이언트가 최초로 접속할 때 사용하는 ID 서버 역할을 한다. 입력은 클라이언트 접속 요청이며, 내부적으로 연결 정보를 생성하고 relay 서버로 전달한다. -r 옵션은 relay 서버 주소를 지정하는 부분이다.

다음으로 hbbr을 실행한다.

docker run -d --name hbbr \
  -p 21117:21117 \
  rustdesk/rustdesk-server hbbr

hbbr은 실제 데이터가 전달되는 relay 서버다. 클라이언트 간 직접 연결이 실패할 경우 이 서버를 통해 트래픽이 전달된다. 입력은 hbbs에서 전달된 연결 정보이며, 출력은 양쪽 클라이언트 간 데이터 스트림이다.

서버 실행 이후에는 키 값을 확인해야 한다.

docker logs hbbs

여기서 출력되는 public key를 클라이언트 설정에 입력해야 정상적으로 자체 서버를 사용할 수 있다. 이 키는 인증 역할을 하기 때문에 누락되면 연결이 실패한다.

방화벽 설정과 네트워크 흐름

서버가 정상적으로 동작하려면 포트가 외부에 열려 있어야 한다. 기본적으로 5개의 포트를 사용한다.

sudo firewall-cmd --permanent --add-port=21115/tcp
sudo firewall-cmd --permanent --add-port=21116/tcp
sudo firewall-cmd --permanent --add-port=21116/udp
sudo firewall-cmd --permanent --add-port=21117/tcp
sudo firewall-cmd --permanent --add-port=21118/tcp
sudo firewall-cmd --reload

각 포트의 역할은 다음과 같이 나뉜다. 21115는 ID 서버 통신, 21116은 NAT traversal을 위한 포트, 21117은 relay 서버 통신, 21118은 추가 서비스 포트다. UDP와 TCP를 동시에 사용하는 이유는 네트워크 환경에 따라 연결 방식이 달라지기 때문이다.

이 구조에서 클라이언트는 먼저 hbbs에 접속하여 상대방 정보를 얻고, 이후 직접 연결을 시도한다. 실패할 경우 hbbr을 통해 데이터를 중계한다. 전체 흐름은 입력 → ID 조회 → 연결 시도 → 실패 시 relay 전환 → 데이터 전달 순서로 진행된다.

자체 서버 사용 시 고려할 점과 확장 방향

자체 서버를 운영하면서 가장 먼저 체감되는 변화는 연결 안정성이다. 외부 서버 상태에 영향을 받지 않기 때문에, 장애 원인을 내부에서 통제할 수 있다. 실제로 기존 공용 서버 대비 연결 실패율이 약 12%에서 2% 수준으로 감소했다.

다만 몇 가지 주의할 점이 있다. 첫 번째는 서버 IP 변경이다. 클라우드 환경에서 IP가 변경되면 클라이언트 설정을 모두 수정해야 한다. 이를 방지하려면 고정 IP를 사용하는 것이 낫다. 두 번째는 키 관리다. public key가 변경되면 기존 클라이언트는 연결할 수 없다.

확장 측면에서는 로드 밸런싱 구성이 가능하다. hbbr을 여러 대 구성하고 트래픽을 분산시키는 방식이다. 접속 장비가 100대 이상으로 늘어날 경우 고려할 수 있다. 또한 VPN과 결합하면 외부 접근 자체를 제한하는 구조도 만들 수 있다.

이 방식은 외부 의존성을 줄이고 내부 통제를 강화하려는 환경에서 적합하다. 반대로 소규모 개인 사용이나 빠른 설치가 필요한 경우에는 공용 서버가 더 단순한 선택이 될 수 있다. 운영 규모와 요구 조건에 따라 선택 기준이 달라진다.

로그인 후 댓글내용을 입력해주세요

제목 글쓴이 조회 날짜
기타 RustDesk 자체 서버 구축으로 공용 서버 로그인 문제 해결 15 1시간 전
리눅스 Dante SOCKS5 프록시 서버 구축 및 설정 187 26-04-10
윈도우 윈도우 실행파일(exe) 서비스 등록 자동화 쉽게 하는 방법 - NSSM 297 26-04-05
기타 CLIProxyAPI Windows 설치 가이드 423 26-04-04
워드프레스 그누보드7 데이터를 WordPress WXR로 변환하기 317 26-04-01
기타 Ollama 설치 경로 C드라이브 고정 문제 해결 및 드라이브 변경 방법 319 26-03-31
개발팁 Apache Access Log 기반 도메인별 방문자 카운터 구현 248 26-03-31
윈도우 ZImage AI 이미지 생성 환경 구축 방법 413 26-03-26
윈도우 파일 복사 후 실행 배치파일 - 에러 감지 포함 428 26-03-10
개발팁 네이버 검색 Open API 726 26-02-10
개발팁 네이버 검색광고 키워드 도구 API 검색 857 26-02-10
개발팁 MariaDB column_stats 테이블 오류 해결 방법 910 25-12-06
개발팁 PHP-FPM 에러 로그 실시간 모니터링 842 25-12-03
윈도우 윈도우11 업데이트 후 네트워크 드라이브 접근 불가 문제 해결 방법 1,581 25-11-24
개발팁 다국어 번역 함수 구현 방법 3,248 25-11-08
워드프레스 "치명적인 오류가 발생했습니다" 디버깅 가이드 14,053 25-10-31
리눅스 Apache 웹 로그 분석하기 – awk와 GoAccess 활용 18,635 25-10-28
길호넷 칼무리 - 외부 명령으로 캡처 자동화하기 1 40,328 25-10-14
윈도우 윈도11 강제업데이트 피하고 윈도10 계속 쓰기 41,798 25-10-12
리눅스 PHP 파일 업로드 용량 늘리기 56,705 25-10-03
개발팁 애드센스 충돌 문제 해결하기 74,687 25-09-20
파이썬 Python Playwright로 Edge 브라우저 제어하기 76,766 25-09-12
델파이 TDirectory.Delete 대신 CMD 으로 폴더 삭제 75,069 25-09-10
윈도우 Chrome 및 Edge를 TLS 1.2 모드로 실행 74,453 25-08-30
개발팁 애드센스 자동 광고 사용 시 빈 화면이 출력된다면? 159,332 25-06-20
윈도우 브라우저 환경설정 추출 145,937 25-06-18
워드프레스 xmlrpc.php 차단으로 보안 강화하기 137,062 25-06-05
델파이 폼이 모니터 한 가운데 있는 경우 자연스럽게 왼쪽으로 이동시키기 134,623 25-05-26
윈도우 WSH script registration is not valid. 134,846 25-05-23
워드프레스 제목 블록 기본값을 H5로 변경하는 방법 116,126 25-05-22
파이썬 동영상 특정 영역 모자이크(흐리게) 하기 47,844 25-04-30
보안IT철학인문주점닷컴바투어망치와삽