Como hospedar seu próprio relay RustDesk
Execute hbbs e hbbr no VPS com chave Ed25519, tags de imagem fixas e portas restritas. Calcule a largura de banda do relay antes de contratar o plano.
O que é um servidor relay RustDesk self-hosted
Um servidor relay RustDesk self-hosted consiste em dois daemons num único VPS. hbbs é o servidor de ID e rendezvous: regista o ID de cada cliente e apresenta os dois clientes um ao outro. hbbr é o servidor relay: transporta os bytes da sessão, mas apenas nas sessões que não conseguiram comunicar diretamente. A maioria dos guias instala ambos, configura a ligação entre eles e termina aí. O que se segue é o restante trabalho: a chave que controla o acesso, as portas, a atualização e a largura de banda.
Ambos os daemons são distribuídos na mesma imagem, rustdesk/rustdesk-server, e ambos leem o mesmo par de chaves Ed25519 a partir do mesmo diretório. Ed25519 é um esquema de assinatura com chave pública. Esse par de chaves determina com que clientes o seu servidor comunica. Não existe uma base de dados de utilizadores por trás dele.
hbbs e hbbr: qual daemon consome a sua largura de banda
O tráfego do hbbs é pequeno e constante: registo de IDs e heartbeats, além da breve troca que apresenta dois peers. O serviço funciona todo o dia e quase não gera custos.
O tráfego do hbbr é a própria sessão. Os frames do ecrã seguem num sentido, o teclado e o rato seguem no outro, e cada byte retransmitido chega ao seu VPS e sai novamente. Se o seu fornecedor contabilizar apenas o tráfego de saída, uma sessão retransmitida custa aproximadamente à taxa da sessão. Se contabilizar a transferência total, o custo é aproximadamente o dobro.
O relay é um caminho alternativo, não o caminho normal. O hbbs tenta primeiro ligar diretamente os dois clientes, usando hole punching através do NAT (network address translation) que estiver à frente de cada um. Quando isso funciona, a sessão nunca passa pelo hbbr e o seu limite de transferência não é consumido. Quando um dos lados está atrás de um NAT que atribui uma porta nova por destino, ou de uma firewall que bloqueia o caminho criado pelo hole punching, a sessão passa para o hbbr e cada frame atravessa o seu VPS.
Uma variável de ambiente elimina esta escolha. ALWAYS_USE_RELAY=Y no hbbs força todas as sessões a passar pelo hbbr. A documentação do RustDesk mostra esta variável num dos exemplos de Compose, por isso é frequentemente copiada. Isto torna as ligações mais previsíveis e torna real o seu tráfego de saída. Defina-a porque tomou essa decisão, não porque a copiou e colou.
Quais portas um servidor RustDesk auto-hospedado precisa
Os números das portas abaixo foram verificados na documentação do servidor RustDesk e no repositório rustdesk-server em 17 de agosto de 2026.
- TCP 21115, no hbbs: teste do tipo de NAT.
- UDP 21116, no hbbs: registo do ID e heartbeat. Sem esta porta, o cliente nunca fica online, independentemente das outras portas abertas.
- TCP 21116, no hbbs: perfuração de NAT por TCP e serviço de ligação.
- TCP 21117, no hbbr: relay. Esta é a porta que transporta os dados das sessões, por isso é a porta que gera custos.
- TCP 21118 no hbbs e TCP 21119 no hbbr: WebSocket, utilizado pelo cliente no navegador. Mantenha ambas fechadas se não utilizar esta funcionalidade.
- TCP 21114 é a consola web no RustDesk Server Pro. A compilação de código aberto não escuta nesta porta.
Instale hbbs e hbbr com a tag da imagem fixada
services:
hbbs:
container_name: hbbs
image: rustdesk/rustdesk-server:1.1.16
command: hbbs
volumes:
- ./data:/root
network_mode: "host"
depends_on:
- hbbr
restart: unless-stopped
hbbr:
container_name: hbbr
image: rustdesk/rustdesk-server:1.1.16
command: hbbr -k _
volumes:
- ./data:/root
network_mode: "host"
restart: unless-stoppedmkdir -p ~/rustdesk
cd ~/rustdesk
# save the block above as ~/rustdesk/compose.yml before this line
sudo docker compose up -d
sudo docker compose psAmbos os serviços devem ler running. Confirme que os listeners existem antes de alterar a firewall.
sudo ss -tlnp | grep -E ':2111[5-7]'
sudo ss -ulnp | grep ':21116'Deve ver listeners TCP nas portas 21115, 21116 e 21117, e um listener UDP na porta 21116. A ausência da linha UDP significa que o hbbs não está em execução, porque é nesse listener que os clientes fazem o registo.
Há quatro elementos deliberados nesse ficheiro. A tag é 1.1.16, a release atual em agosto de 2026, publicada em 20 de julho de 2026, e não latest, porque latest significa o que tiver sido publicado mais recentemente e um docker compose pull daqui a seis meses pode fornecer-lhe um servidor que nunca testou. network_mode: "host" associa diretamente os interfaces do host, que é o que a documentação do RustDesk recomenda e o que determina o comportamento da firewall. ./data:/root mapeia o diretório de trabalho da imagem para o host, para que o par de chaves fique num local que possa incluir nas cópias de segurança. hbbr -k _ é a única alteração ao exemplo upstream, porque a predefinição deixa o relay aberto a qualquer pessoa. Se o Compose ainda for novo para si, executar Docker Compose numa VPS explica o formato do ficheiro e os comandos do ciclo de vida.
Se o hbbr passar para um segundo servidor, terá de indicar ao hbbs para onde foi movido: passe -r relay.example.com:21117 ou defina a variável de ambiente RELAY-SERVERS. Num único servidor, não precisa dessa configuração.
O par de chaves Ed25519 controla o acesso
Na primeira inicialização, o hbbs gera id_ed25519 e id_ed25519.pub no diretório de trabalho. Com a montagem acima, os dois ficheiros aparecem no host.
ls -l ~/rustdesk/data/
sudo cat ~/rustdesk/data/id_ed25519.pubid_ed25519.pub contém uma string base64. Essa string deve ser introduzida no campo Key de todos os clientes. id_ed25519 é a parte privada e nunca sai do servidor. A chave pública não é secreta, porque é copiada para a configuração de todos os clientes. A chave privada é secreta: qualquer pessoa que a possua pode configurar um servidor em que os seus clientes confiariam.
Faça agora uma cópia de segurança dos dois ficheiros, antes de configurar vinte clientes.
sudo tar czf ~/rustdesk-keys.tgz -C ~/rustdesk/data id_ed25519 id_ed25519.pub
sudo chmod 600 ~/rustdesk-keys.tgzCopie esse arquivo para fora do servidor. O motivo é mais importante do que qualquer outro passo. Se eliminar ~/rustdesk/data ou reconstruir o serviço num novo VPS sem o copiar, o hbbs gera um novo par de chaves na próxima inicialização. Todos os clientes continuam a ter a chave pública antiga, por isso o hbbs rejeita-os e os clientes ficam offline. Execute sudo cat ~/rustdesk/data/id_ed25519.pub e compare o resultado com o campo Key de qualquer cliente: as duas strings já não coincidem, e essa diferença é a causa de toda a falha. Corrigir o problema implica editar manualmente as definições em todas as máquinas, incluindo as máquinas às quais contava aceder através do RustDesk.
A chave não é a palavra-passe da sessão, e confundir as duas faz com que algumas pessoas ignorem uma delas. A chave determina com que clientes o seu servidor comunica. A palavra-passe permanente ou o código de utilização única na máquina controlada determina quem pode abrir uma sessão nessa máquina. Precisa das duas, e ter uma não compensa a fraqueza da outra.
Por que um relay sem autenticação é um problema
Por predefinição, o hbbr não verifica nada. A documentação de configuração do RustDesk afirma isso diretamente: uma chave vazia permite que clientes sem uma chave correspondente utilizem o relay. O valor vazio existe para que os novos utilizadores não encontrem falhas de incompatibilidade de chaves na primeira execução. O custo é que qualquer pessoa que encontre o seu endereço na porta TCP 21117 pode encaminhar o tráfego da sua sessão através do seu VPS, consumindo o seu limite de transferência e utilizando o seu endereço IP.
command: hbbr -k _ resolve esse problema. O argumento _ indica ao hbbr que deve carregar um par de chaves a partir do seu diretório de trabalho. Como ambos os contentores montam o mesmo ./data, esse é o par que o hbbs já gerou. Nada é copiado manualmente, pelo que não pode ficar dessincronizado.
O volume partilhado é a parte que costuma ser configurada incorretamente. Se der ao hbbr o seu próprio diretório, ele irá gerar um par de chaves diferente. O hbbs e o hbbr deixam então de concordar, todas as sessões encaminhadas falham e as sessões diretas continuam a funcionar. O sintoma é confuso: o RustDesk alcança alguns pares e não outros, dependendo de o hole punching ter sido bem-sucedido. Um ls -l ~/rustdesk/data/ que mostre um único par de id_ed25519 elimina essa possibilidade.
Aponte os clientes para o seu servidor
Em cada máquina, abra o RustDesk, depois Settings, depois Network e depois ID/Relay Server.
- ID Server: o seu hostname, por exemplo
rustdesk.example.com. O cliente usa a porta 21116, a menos que indique outra. - Relay Server: deixe vazio quando o hbbr for executado no mesmo host que o hbbs.
- API Server: deixe vazio. O servidor de código aberto não fornece uma API.
- Key: a string base64 de
id_ed25519.pub, colada exatamente como está, sem espaço no fim.
A janela principal deve indicar que o cliente está pronto. Se isso não acontecer, a porta UDP 21116 não está a chegar ao hbbs, porque o registo e o heartbeat usam UDP e nada mais coloca o ID online.
Restrinja as portas para que o relay não fique exposto como um serviço aberto
Como os contentores usam a rede do host, não existe uma regra de NAT do Docker à frente deles. Por isso, as regras do ufw são aplicadas como esperado.
sudo ufw allow 22/tcp
sudo ufw allow 21115:21117/tcp
sudo ufw allow 21116/udp
sudo ufw enable
sudo ufw status numberedAdicione 21118:21119/tcp apenas se executar o cliente de navegador. Mantenha uma segunda sessão SSH aberta enquanto ativa o ufw. Assim, um erro na regra SSH não o impede de aceder ao seu próprio servidor. O essencial do firewall ufw para um VPS explica as políticas predefinidas e a ordem das regras.
Agora, atenção a esta armadilha. Se trocar para a publicação de portas com um bloco ports:, usado pelo exemplo da imagem alternativa do supervisor RustDesk, o Docker cria as suas próprias regras DNAT. Os pacotes chegam ao contentor sem passar pela cadeia onde as regras do ufw estão configuradas. Um deny do ufw na porta 21117 deixa então de ter efeito, e o relay fica aberto à Internet enquanto ufw status afirma o contrário. As portas publicadas pelo Docker contornam o ufw explica a ordem das cadeias. A rede do host evita completamente este problema. Se publicar uma porta, associe-a a um único endereço, como em "127.0.0.1:21118:21118" atrás de um reverse proxy.
A restrição por endereço de origem só funciona quando os clientes têm endereços estáveis.
sudo ufw allow from 203.0.113.0/24 to any port 21115:21117 proto tcp
sudo ufw allow from 203.0.113.0/24 to any port 21116 proto udpOs portáteis em redes de hotéis não têm endereços estáveis. É precisamente por isso que a key no hbbr desempenha aqui um papel mais importante do que o firewall.
Atualizar uma stack que contém a sua chave
A chave fica no bind mount, não dentro do container. Por isso, a atualização é segura desde que não altere ./data.
- Faça primeiro uma cópia de segurança do diretório de dados:
sudo tar czf ~/rustdesk-data-backup.tgz -C ~/rustdesk data. - Leia as notas da versão da nova tag na página de releases do rustdesk-server.
- Edite
compose.ymle altere ambas as linhasimage:para a nova tag. - Execute
sudo docker compose pulle depoissudo docker compose up -d. - Execute
sudo cat ~/rustdesk/data/id_ed25519.pube confirme que a string é igual à que os seus clientes já têm.
O passo 5 é a verificação mais importante. Uma chave alterada não gera um aviso evidente no servidor e quebra todos os clientes ao mesmo tempo. Para reverter, volte a colocar a tag antiga e execute up -d novamente. Isto só funciona porque fixou a tag: com latest, docker compose pull moveu o nome para a nova imagem e deixou de existir uma tag que identifique a imagem antiga.
A forma habitual de perder a chave não é docker compose down, que não altera um bind mount. O problema ocorre ao migrar para um novo VPS e copiar apenas compose.yml. Copie também ./data.
Monitorize o tráfego de saída num plano com limite de transferência
O hbbr é a única parte desta stack que pode consumir um limite de transferência. A FAQ do RustDesk indica que uma ligação retransmitida, numa sessão com resolução 1920x1080, pode consumir entre 30 KB/s e 3 MB/s, e que o trabalho de escritório simples ronda os 100 KB/s. Estes são valores publicados para uma única sessão, não uma medição da sua configuração. Multiplicados por sessenta horas por mês, duas horas por dia, os valores são os seguintes.
The data behind this chart
[
{
"label": "Low end, 30 KB/s",
"gb_per_month": 6.5
},
{
"label": "Office work, 100 KB/s",
"gb_per_month": 21.6
},
{
"label": "High end, 3 MB/s",
"gb_per_month": 648
}
]À taxa de trabalho de escritório, uma sessão consome cerca de 21.6 GB por mês, o que não será relevante para nenhum plano. No limite superior do intervalo publicado, as mesmas sessenta horas consomem 648 GB, e duas sessões simultâneas a essa taxa ultrapassam um limite de 1 TB durante o mês. O limite inferior é 6.5 GB. Aqui, os gigabytes correspondem a 1000 MB, que é a forma normal de contabilizar os limites de transferência.
O docker stats não apresenta estes dados separadamente, porque um contentor que utiliza a rede do host partilha o namespace de rede do host. Por isso, os respetivos contadores são os contadores do host. Existem duas outras ferramentas que funcionam. O vnstat mede o servidor inteiro:
sudo apt install -y vnstat
sudo systemctl enable --now vnstat
vnstat -mServidor inteiro significa todo o servidor. Se este VPS também executar algo que transfira dados reais, como um dos servidores de fotografias self-hosted que copia as bibliotecas dos telemóveis todas as noites, esses uploads entram no mesmo total mensal que o tráfego do relay. Um servidor multimédia funciona da mesma forma no sentido inverso. Algo como Halcyon, que transforma uma biblioteca Jellyfin numa videoteca dos anos 90 que pode ser explorada transmite conteúdo para quem estiver a assistir, e esse tráfego de saída partilha o limite utilizado pelo relay.
Um contador nftables mede especificamente o relay:
sudo nft add table inet relaymeter
sudo nft add chain inet relaymeter out '{ type filter hook output priority 0 ; }'
sudo nft add rule inet relaymeter out tcp sport 21117 counter
sudo nft list table inet relaymeterEssa regra não toma nenhuma decisão, por isso conta pacotes e bytes sem alterar o que é permitido. Ela fica numa tabela própria, portanto não interfere com o ufw. Não é persistente: coloque as mesmas linhas em /etc/nftables.conf se quiser que volte a ser aplicada depois de um reboot. O contador só aumenta enquanto uma sessão está efetivamente a ser retransmitida. Um contador que continua a aumentar quando nenhuma das suas máquinas está ligada significa que outra pessoa encontrou o seu relay. É precisamente esse o caso que hbbr -k _ existe para impedir. Como não vai ler nft list todas as manhãs, coloque nele um cron job que compare a contagem de bytes com um limite e envie um alerta push quando esse limite for ultrapassado. Para isso, use o seu próprio servidor ntfy.
O hbbr também tem limites de velocidade que pode reduzir. Por predefinição, o SINGLE_BANDWIDTH é de 128 Mb/s por ligação retransmitida e o TOTAL_BANDWIDTH é de 1024 Mb/s para todas as ligações. Definir SINGLE_BANDWIDTH=8 limita uma sessão a cerca de 1 MB/s. Isto limita a velocidade, não o total mensal. Utilize-o para impedir que uma sessão sature a ligação, e não como controlo do orçamento.
Quando não precisa de um relay
Num setup pessoal, a resposta honesta é que talvez não precise de nada disto. Coloque as duas máquinas numa VPN mesh e ligue-se diretamente ao endereço do túnel. Não há hbbs, hbbr, egress do relay nem contentor num VPS para atualizar.
Na máquina que pretende controlar, ative o acesso IP direto nas definições de segurança do RustDesk. O campo da porta usa 21118 por predefinição. Confirme que a porta está em estado de listening antes de tentar ligar-se:
ss -tlnp | grep 21118Em seguida, ligue-se ao endereço VPN desse peer em vez de usar um ID. A FAQ do RustDesk informa que, neste modo, a ligação não é cifrada. Por isso, use-o dentro do túnel e nunca através da Internet pública. É o túnel que fornece a cifragem.
Escolha com base na propriedade das máquinas. Um hbbs e hbbr self-hosted são adequados quando dá suporte a máquinas que não lhe pertencem ou a pessoas que nunca vão instalar um cliente VPN, porque o lado delas da configuração usa um ID e uma palavra-passe. Uma VPN mesh com acesso IP direto é adequada quando todas as máquinas lhe pertencem e podem usar uma chave. WireGuard comparado com Tailscale apresenta as duas formas habituais de criar essa mesh, e executar um desktop remoto num VPS Linux aborda o outro caso, em que a máquina onde pretende obter um ecrã é o próprio servidor.
FAQ
Todas as sessões do RustDesk passam pelo meu relay?
Não. Primeiro, o hbbs tenta ligar diretamente os dois clientes, usando hole punching através do NAT à frente de cada um. Apenas as sessões em que isso falha recorrem ao hbbr, e só essas consomem a sua largura de banda. A exceção é ALWAYS_USE_RELAY=Y no hbbs, que força todas as sessões a passar pelo hbbr, independentemente de estar disponível um caminho direto. Se essa variável estiver definida no seu ficheiro Compose, todos os bytes de todas as sessões serão contabilizados na sua fatura de transferência.
Onde é armazenada a chave do servidor RustDesk e o que acontece se eu a perder?
O hbbs gera id_ed25519 e id_ed25519.pub no seu diretório de trabalho na primeira inicialização. Esse diretório é /root dentro da imagem oficial. Por isso, com o volume montado mostrado acima, os ficheiros aparecem em ./data no host. Faça uma cópia de segurança dos dois ficheiros fora do servidor. Se forem perdidos, o hbbs gera um novo par na inicialização seguinte, e todos os clientes que ainda tenham a chave pública antiga serão recusados. Não há outra forma de recuperação além de editar manualmente o campo Key em cada cliente.
Que portas preciso de abrir para um servidor RustDesk self-hosted?
TCP 21115, 21116 e 21117, além de UDP 21116. O hbbs usa 21115 para o teste do tipo de NAT e 21116 para o registo de IDs e o heartbeat através de UDP, bem como para o hole punching através de TCP. O hbbr usa 21117 para o relay. TCP 21118 e 21119 são as portas WebSocket do cliente no browser. Mantenha-as fechadas se não o utilizar. TCP 21114 pertence à consola Web Pro, que não é necessária na build open source.
Pessoas desconhecidas podem usar o meu relay RustDesk self-hosted?
Sim, se executar o hbbr com a configuração predefinida. A documentação do RustDesk indica que uma chave vazia permite que clientes sem uma chave correspondente utilizem o relay. Assim, qualquer pessoa que descubra o seu hostname e a porta 21117 pode encaminhar tráfego através do seu servidor. Execute o hbbr com -k _ para que carregue o mesmo par de chaves que o hbbs gerou no volume partilhado ./data. Depois disso, apenas os clientes configurados com a sua chave pública poderão utilizar o seu relay.