Servidor RustDesk próprio: hbbs e hbbr em Docker
O Quick Assist resolve um pedido pontual e o TeamViewer cobra uma licença anual, mas os dois partilham o mesmo defeito de fundo: o tráfego do suporte remoto atravessa servidores de terceiros, e a sessão inteira — ecrã do cliente, passwords escritas em frente ao utilizador, ficheiros copiados — vive nos servidores deles. O RustDesk inverte a equação: o cliente é aberto e o servidor é teu. Duas peças bastam, o hbbs (rendezvous e sinalização, ID Server) e o hbbr (relay), e a versão de código aberto 1.1.16 do servidor corre numa máquina de bolso. Numa PME, isto significa suporte remoto com o mesmo fluxo do TeamViewer — ID de 9 dígitos e palavra-passe de sessão — sem tráfego de sessão a sair da tua infra-estrutura.
Este guia parte de um servidor Linux limpo (Ubuntu ou Debian, físico ou VPS): instala o Docker, sobe os dois serviços com o compose oficial, abre as portas na firewall, confirma a chave de encriptação e liga o primeiro cliente.
Neste artigo
- 1. Como o RustDesk liga dois computadores
- 2. Instalar o Docker no servidor
- 3. Sobe hbbs e hbbr com o compose oficial
- 4. Portas a abrir na firewall
- 5. Chaves de encriptação e o id_ed25519
- 6. Ligar o primeiro cliente
- 7. Pós-instalação: relay opcional do hbbr
- 8. Confirmar o funcionamento
- 9. Erros comuns
- 10. Checklist
- 11. Artigos relacionados
- 12. Fontes oficiais
1. Como o RustDesk liga dois computadores
Dois serviços compõem o RustDesk Server OSS: o hbbs faz de ID/rendezvous/signaling server — os clientes registam-se nele, é ele quem entrega ao computador B o pedido de ligação do computador A, e por isso é a peça que o cliente precisa de conhecer obrigatoriamente — e o hbbr é o relay que transporta os túneis de dados (ecrã, teclado, ficheiros) quando a ligação directa falha.
O fluxo de uma sessão:
- O computador que pede apoio informa o hbbs do ID de destino (9 dígitos).
- O hbbs entrega o pedido ao outro computador (ambos estão registados nele).
- Os dois tentam uma ligação directa entre os dois (hole punching em TCP e UDP sobre a porta 21116).
- Se a directa falhar (NAT restritivo ou ISP com CGNAT), a sessão segue pelo relay do hbbr.
Quando a ligação directa consegue estabelecer-se, a sessão passa directamente entre os dois computadores e o servidor apenas faz o encontro inicial. O relay entra nos casos em que não é possível: o tráfego aí é contido, de 30 KB/s até uns 3 MB/s num ecrã 1920×1080, e em trabalho de escritório ronda os 100 KB/s. Por isso uma máquina pequena serve: os requisitos de hardware oficiais dizem que a configuração mínima de um cloud server básico chega, inclusive um Raspberry Pi.
Nota
o hbbr existe para o pior caso. Numa rede onde a larga maioria das ligações directas falha, os limites de largura de banda do relay contam, e a secção 7 cobre os seus limites, activos por omissão (128 Mb/s por ligação).
2. Instalar o Docker no servidor
O hbbs e o hbbr correm em containers Docker (a via recomendada na documentação oficial). Num servidor Ubuntu sem Docker, o script de conveniência oficial do Docker Engine prepara tudo:
# servidor Linux (Ubuntu/Debian) — script de conveniência oficial do Docker
bash <(wget -qO- https://get.docker.com)
O Docker fornece o script em get.docker.com oficialmente e a própria documentação de instalação do RustDesk o lista como método recomendado. A própria Docker nota que o script de conveniência não é o caminho recomendado para ambientes de produção — num servidor em produção, os passos por repositório apt da documentação do Docker são a via mais conservadora. Confirmar o Docker e o plugin de compose:
docker --version
docker compose version
Saída num Ubuntu 24.04 com Docker 28:
Docker version 28.3.3, build e2397be
Docker Compose version v2.39.2
Números divergem, o que importa é existirem ambos. O plugin docker compose vem incluído no script de conveniência — nenhum pacote extra é necessário.
3. Sobe hbbs e hbbr com o compose oficial
A própria documentação publica um ficheiro compose pronto — o comando oficial de instalação o descarrega para compose.yml no directório corrente:
mkdir -p ~/rustdesk-server && cd ~/rustdesk-server
wget rustdesk.com/oss.yml -O compose.yml
sudo docker compose up -d
O compose.yml oficial, verbatim da documentação — a diferença para os comandos docker run -td do mesmo guia é só a forma de orquestração (a flag -td pertence ao docker run, não ao compose):
services:
hbbs:
container_name: hbbs
image: rustdesk/rustdesk-server:latest
command: hbbs
volumes:
- ./data:/root
network_mode: "host"
depends_on:
- hbbr
restart: unless-stopped
hbbr:
container_name: hbbr
image: rustdesk/rustdesk-server:latest
command: hbbr
volumes:
- ./data:/root
network_mode: "host"
restart: unless-stopped
Três pormenores importantes no ficheiro:
network_mode: "host"— os containers partilham a rede do anfitrião, sem mapeamento de portas (-p). É a variante que a documentação prefere em Linux: o hbbs vê os IPs reais dos clientes em vez do IP interno do Docker (172.17.0.1), que é o que o rendezvous precisa para coordenar ligações entre pares. Fora de Linux, o--net=hostnão existe, e o guia oficial aconselha removê-lo caso a ligação dê problemas na tua plataforma../data:/root— os dois containers partilham o mesmo volume. O hbbs escreve a base de dados de clientes e os ficheiros de chave no directório mapeado, e é aí que tudo o que tem de sobreviver a uma actualização vive.depends_onno hbbs — o hbbr arranca antes, em ordem de criação dos containers — o hbbs depende do hbbr por causa dessa ordem de arranque, e é a única dependência do compose.
Ao fim de alguns segundos, confirmar:
sudo docker compose ps
sudo docker logs hbbs --tail 20
Saída do compose ps com os dois serviços activos:
NAME IMAGE COMMAND SERVICE CREATED STATUS
hbbr rustdesk/rustdesk-server:latest "hbbr" hbbr 12 seconds ago Up 11 seconds
hbbs rustdesk/rustdesk-server:latest "hbbs" hbbs 12 seconds ago Up 11 seconds
Nos logs do hbbs procura as linhas de inicialização do servidor e do serviço de sinalização. Avisos isolados no arranque (por exemplo sobre a porta UDP ou a interface de rede escolhida) são normais num arranque saudável — o que importa é os serviços hbbs e hbbr ficarem em execução, visíveis no compose ps.
Nota
a imagem rustdesk/rustdesk-server:latest do Docker Hub corresponde no momento da escrita à versão 1.1.16 (2026-07-20). A instalação fixa a versão com rustdesk/rustdesk-server:1.1.16, para quem prefere actualizar por decisão e não por rede. Ambas as tags apontam ao mesmo digest no Docker Hub (sha256:8ecdab65deb7), confirmado na API de tags.
4. Portas a abrir na firewall
As portas oficiais do RustDesk Server OSS, conforme o guia de instalação:
| Porta | Protocolo | Serviço | Função |
|---|---|---|---|
| 21115 | TCP | hbbs | Teste de tipo de NAT |
| 21116 | TCP | hbbs | Hole punching e serviço de ligação |
| 21116 | UDP | hbbs | Registo de ID e heartbeat dos clientes |
| 21117 | TCP | hbbr | Serviço de relay |
| 21118 | TCP | hbbs | Web clients (WebSocket) |
| 21119 | TCP | hbbr | Web clients (WebSocket) |
| 21114 | TCP | — | Consola web, exclusiva do RustDesk Server Pro |
O web client (usar o RustDesk dentro do browser, em rustdesk.com/web) é o único motivo para abrir as 21118 e 21119. Sem essa via de acesso, o guia oficial manda deixá-las fechadas: as portas WebSocket confiam nos headers X-Real-IP/X-Forwarded-For quando os vê chegar por um proxy inverso, e quem chega directo às 21118/21119 pode falsificar um IP de cliente nos registos. Para o caso mais comum — só aplicações desktop e móveis — a firewall fica com:
# UFW — regras que o próprio guia oficial usa
sudo ufw allow 21115/tcp
sudo ufw allow 21116/tcp
sudo ufw allow 21116/udp
sudo ufw allow 21117/tcp
sudo ufw reload
⚠ Atenção
a 21116 é a única porta que precisa de UDP, e é a que os clientes mais consomem: o heartbeat usa-a. Só TCP na 21116 é uma causa típica de clientes que ligam e desligam sem registo estável.
Nas portas TCP de serviço (ufw allow 21114:21119/tcp), o oficial abre o intervalo inteiro, incluindo a 21118 e a 21119, porque o guia assume que quem as quer fechadas as gere por regra própria. Uma alternativa ainda mais conservadora: fechar tudo por omissão e abrir apenas as 21115, 21116 (TCP+UDP) e 21117 — o servidor corre sem as portas de Consola (21114, apenas Pro) e sem web clients.
À distância, confirmar que a porta 21116 responde em ambos os protocolos a partir da tua máquina de trabalho — são dois serviços independentes no mesmo número:
nc -vz RUSTDESK.EXEMPLO.PT 21116 # deve dar "succeeded" (TCP)
nc -vzu RUSTDESK.EXEMPLO.PT 21116 # deve dar "succeeded" (UDP)
5. Chaves de encriptação e o id_ed25519
O RustDesk encripta as sessões com Ed25519: o hbbs guarda o par de chaves em dois ficheiros no volume dos containers, o id_ed25519 (chave privada) e o id_ed25519.pub (chave pública), e é o conteúdo deste público que vai em cada cliente do parque. O par gera-se na primeira execução do hbbs, e é por isso que o volume ./data:/root importa: se o container for recriado sem volume, nasce um par novo e todos os clientes deixam de confiar no servidor.
Ver o que o primeiro arranque produziu:
ls -l ~/rustdesk-server/data/
-rw-r--r-- 1 root root 12288 Out 1 10:12 db_v2.sqlite3
-rw------- 1 root root 88 Out 1 10:12 id_ed25519
-rw-r--r-- 1 root root 44 Out 1 10:12 id_ed25519.pub
O conteúdo do .pub é a chave a configurar nos clientes:
cat ~/rustdesk-server/data/id_ed25519.pub
OeVuKQ5iPrbA2OvV2QO3zWxQ6OaKJXJl+O0mNf0WJ4y
(é um exemplo, o teu valor é outro)
Regras da chave, conforme a documentação de variáveis e flags:
- O hbbs arranca por omissão com
-k -, que significa “usa o par guardado no directório de trabalho, gera-o se não existir”. É o comportamento do compose oficial, nenhum par é preciso configurar. A documentação usa indiferentemente-ou_neste valor, com o mesmo efeito. - Para impor um par próprio (porque migras de um servidor anterior, por exemplo), coloca os dois ficheiros no directório de trabalho antes do primeiro arranque.
- Um valor vazio de
-kdesactiva a validação de chaves — clientes com qualquer chave são aceites. É o default do hbbr, e uma configuração que convém conhecer bem: num servidor público, o hbbr sem chave não rejeita clientes alheios.
6. Ligar o primeiro cliente
No cliente RustDesk (desktop, em qualquer plataforma), é um só ecrã que importa: Definições → Rede → ID/Relay Server, com quatro campos:

- ID Server — o host ou IP do servidor, ex.:
rustdesk.exemplo.pt. O:21116é opcional — sem porta, o cliente usa a 21116 por omissão. - Relay Server — deixa em branco: o RustDesk deriva-o do ID Server (o hbbr na :21117).
- API Server — só se usa com o RustDesk Server Pro, o OSS não tem consola web: deixa em branco.
- Key — o conteúdo do
id_ed25519.pubdo teu servidor.
Aplicar e reiniciar o cliente (o RustDesk avisa quando é preciso). Um primeiro teste funcional: no computador de destino, anota o ID de 9 dígitos que aparece no cliente, e no computador de origem pede a ligação com a palavra-passe de sessão do destino. Se a ligação se estabelecer, a instalação funciona de ponta a ponta, e o servidor só participou no rendezvous.
Para distribuição em escala, os métodos comuns são dois: a cópia da configuração de um cliente já configurado (botão de export no mesmo ecrã de Rede) e o --config na linha de comandos com a config-string exportada do cliente (Definições → Rede), na documentação de configuração do cliente.
7. Pós-instalação: relay opcional do hbbr
Duas situações merecem uma visita pós-instalação:
Forçar tudo pelo relay. Em redes em que a ligação directa entre os dois extremos nunca se estabelece (dois CGNAT, por exemplo), o hbbr pode ser a única via útil, e tentativas directas apenas atrasam a sessão. Força o relay com ALWAYS_USE_RELAY=Y no serviço hbbs (é onde a variável vai no exemplo oficial, enquanto as de largura de banda vão no hbbr):
environment:
- ALWAYS_USE_RELAY=Y
Limites de largura de banda do relay. Quando o relay é a via, cada ligação consumida no hbbr conta para os limites por omissão de 128 Mb/s por ligação (SINGLE_BANDWIDTH) e 1024 Mb/s no conjunto (TOTAL_BANDWIDTH). São ajustáveis por variáveis de ambiente no container do hbbr, e o guia de variáveis deixa claro que servem para proteger o servidor do consumo de um cliente anómalo, não para racionar utilizadores.
Para servidores com muitos clientes a despejar UDP heartbeats, a doc oficial sugere também subir o limite do sistema de receive buffer UDP (sysctl net.core.rmem_max=52428800, conforme a secção do RMEM).
8. Confirmar o funcionamento
Três testes com o servidor no ar:
- Registo — no cliente de destino confirmar que o ID aparece (9 dígitos) e o ponto verde da disponibilidade está activo: se o cliente mostra “pronto”, o rendezvous com o hbbs funciona.
- Ligação directa — pedir sessão remota entre os dois computadores e confirmar que a sessão funciona. O modo de ligação em uso também se confirma nos logs do hbbs e do hbbr: a sessão com relay aparece registada no hbbr, a directa termina sem entrar nele.
- Log do servidor —
docker logs hbbs --tail 50e (se a sessão passou pelo relay)docker logs hbbr --tail 50. O hbbs e o hbbr registam cada ligação entrante com o IP de origem.
Para inventário de clientes registados, no directório dos dados:
sudo sqlite3 ~/rustdesk-server/data/db_v2.sqlite3 "SELECT * FROM peer;"
Nomes de colunas divergem entre versões de base de dados, e o esquema pode não ter a tabela peer — se o SQLite reclamar, é normal: a base evolui com o servidor, e não existe documentação estável que a descreva.
9. Erros comuns
| Erro / sintoma | Causa provável | Correcção |
|---|---|---|
| Cliente regista, a sessão não liga | Porta 21116 UDP fechada na firewall | Abrir a 21116/UDP (o heartbeat e o registo dependem dela) |
| Erro de chave no lado do cliente ou sessão falha de imediato | A chave do cliente difere da chave pública do hbbs | Voltar a copiar o id_ed25519.pub actualizado para os clientes e apagar a antiga |
| Os clientes deixam de confiar no servidor (chave diferente) | O volume ./data:/root nunca foi montado, o par de chaves regenera-se a cada container nascido |
Recrear o container com volume mapeado e voltar a configurar clientes |
| Sessão lenta, com atraso e saltos | Sessão a passar pelo relay com largura de banda limitada | Testar a ligação directa (desactivar ALWAYS_USE_RELAY se activo), rever limites do hbbr |
| Cliente não liga de todo | Firewall/ISP a bloquear a 21116 TCP e UDP | Testar com nc -vz e nc -vzu a partir de uma máquina externa |
10. Checklist
- [ ] Docker instalado e o par hbbs/hbbr activo com
docker compose ps - [ ] Portas 21115, 21116 (TCP+UDP) e 21117 abertas na firewall, 21118/21119 fechadas (sem web client)
- [ ]
~/rustdesk-server/data/com o parid_ed25519/id_ed25519.pube o SQLite de clientes - [ ]
ID Server+Keyconfigurados em cada cliente do parque - [ ] Backup do directório
data/agendado (é o único estado do servidor) - [ ] Teste de sessão remota ponta-a-ponta concluído (directa e pelo relay)
11. Artigos relacionados
- Ferramentas Open-Source de Suporte Remoto — panorama comparado das alternativas ao TeamViewer
- Tailscale: VPN Mesh para PME — alternativa de acesso remoto por VPN mesh
- NetBird: VPN Mesh Self-Hosted com WireGuard — a opção self-hosted da mesma classe
12. Fontes oficiais
- RustDesk Server OSS — visão geral
- Instalação — método Docker recomendado, requisitos e firewall
- Docker — exemplos oficiais de compose e docker run
- Client Configuration — ID/Relay Server, Key e –config
- Environment Variables — configuração completa do hbbs e hbbr
- Releases do rustdesk-server — versão 1.1.16 (Julho de 2026)