DeepSeek Harness no VPS privado com túnel SSH
Instale o DeepSeek Harness num VPS Linux, fixe a versao npm, entenda plugins e aceda à interface web na porta 3080 por túnel SSH sem expor o serviço.
O que é o DeepSeek Harness
O DeepSeek Harness (dsh) é um runtime de agentes Node.js que pode executar num VPS (servidor privado virtual). A forma segura de o executar é ligá-lo a 127.0.0.1 e aceder-lhe pelo navegador através de um túnel SSH (secure shell). Disponibiliza uma interface web (user interface) na porta 3080, em vez de funcionar num terminal. Esse servidor web não exige uma palavra-passe própria. Por isso, publicar a porta 3080 dá a qualquer pessoa que a encontre acesso a um agente que lê os seus ficheiros e executa comandos com o seu utilizador Linux.
A DeepSeek lançou-o em 13 August 2026 sob a licença MIT, como o pacote npm @deepseek-ai/dsh. O projeto descreve-se como uma versão de pré-visualização para programadores e indica que são esperadas alterações incompatíveis. Todos os números de versão abaixo correspondem a um snapshot de August 2026. Consulte o repositório antes de copiar qualquer parte para um sistema importante.
Uma ideia está presente em todo o design: tudo é um plugin. O adaptador do modelo, o registo de ferramentas, o log da sessão, a sandbox, o scheduler e o próprio ciclo do agente são plugins carregados num contexto partilhado. Qualquer um deles pode ser substituído. Não existe um núcleo privilegiado que os plugins apenas complementem. É isso que torna o harness interessante para testar. É também aí que reside o único risco real.
Um harness não é um modelo
O harness executa o ciclo do agente. O raciocínio acontece num modelo noutro local, por isso nada funciona até lhe fornecer uma chave de API (interface de programação de aplicações) ou o endereço de um endpoint de modelo alojado por si.
Configure isso na interface, em Settings e depois em Models. O catálogo inclui cartões prontos para os principais fornecedores de API (DeepSeek, OpenAI, Anthropic), nos quais cola uma chave. "Add a custom provider" é a opção mais interessante: recebe um ID do fornecedor, um nome de apresentação, um URL base, um protocolo de API e uma credencial, e comunica através do protocolo compatível com OpenAI. Assim, qualquer gateway ou servidor local que implemente esse protocolo funciona. Os fornecedores personalizados também podem consultar o endpoint compatível com OpenAI GET /models para preencher automaticamente a lista de modelos.
É assim que aponta o harness para um modelo no mesmo VPS. O Ollama disponibiliza uma API compatível com OpenAI em http://127.0.0.1:11434/v1/ e requer que o campo da chave de API seja preenchido com qualquer texto, ollama por convenção, porque o campo é obrigatório e depois é ignorado. A questão mais difícil é saber se um modelo suficientemente pequeno para caber no seu VPS é adequado para executar um agente. A diferença entre o Ollama e o vLLM como servidor local de modelos determina quanta RAM será consumida.
As chaves introduzidas na interface são apenas de escrita. O harness armazena-as em $DSH_HOME/.credentials.yaml e mantém apenas uma referência à credencial em settings.yaml. $DSH_HOME usa ~/.dsh por predefinição. Trate esse ficheiro como um ficheiro de palavras-passe, porque é isso que ele é: qualquer pessoa que o consiga ler pode gastar o seu orçamento de API.
O que é necessário antes da instalação
- uma VPS com Ubuntu 24.04 ou outra distribuição Linux atual, com acesso SSH
- Node.js 22.19 ou mais recente da linha 22.x, ou Node.js 24 ou superior, que é a versão usada pelo projeto para compilar e testar
- uma conta de utilizador normal, não
root, porque o agente executa comandos de shell com a conta que iniciou o processo pnpmno PATH se pretende instalar plugins, porque o comando do plugin executa comandos através dele- a porta 3080 fechada na firewall e na firewall de rede separada do seu fornecedor
O pacote nodejs do Ubuntu é mais antigo do que o necessário para o harness. Por isso, instale o Node a partir do NodeSource ou do nvm, em vez de usar apt install nodejs. Se a VPS for nova, proteger o SSH antes de qualquer outra coisa demora dez minutos e vale a pena, porque o túnel de que dependerá só é tão seguro quanto o servidor SSH que está por trás dele.
Instalar o DeepSeek Harness numa VPS, fixado numa versão
node --version
npx @deepseek-ai/dsh@0.1.0-rc.6 webnpx transfere o pacote e executa o binário dsh. web é um alias de --profile web, que inicia a aplicação Web, e o processo mostra o endereço em que está à escuta. O valor predefinido é http://127.0.0.1:3080.
Fixe a versão. npx @deepseek-ai/dsh web resolve, no momento da execução, aquilo para que a etiqueta latest aponta, e o projeto já lançou vários candidatos a versão e informa que serão introduzidas alterações incompatíveis. 0.1.0-rc.6 é aquilo para que latest apontava em 13 August 2026. Uma versão fixada garante que o sistema configurado hoje se comporta da mesma forma no próximo mês. Assim, uma atualização passa a ser uma decisão sua, em vez de uma surpresa.
Para utilização diária, instale-o uma vez em vez de voltar a resolver a versão em cada arranque.
npm install -g @deepseek-ai/dsh@0.1.0-rc.6
dsh --profile web --helpVale a pena executar essa segunda linha, porque o launcher e a aplicação Web têm conjuntos de opções separados. dsh --help mostra as opções próprias do launcher. dsh --profile web --help mostra as opções aceites pela aplicação Web. É aí que estão --port, --host e --trusted-host, que pode ser repetida.
Agora confirme em que endereço está à escuta.
ss -tlnp | grep 3080A coluna do endereço local deve apresentar 127.0.0.1:3080. Se apresentar 0.0.0.0:3080, a interface Web está acessível a partir da Internet. Pare o processo antes de fazer qualquer outra coisa.
Por que nunca deve publicar a porta 3080
O servidor Web não tem uma camada de autenticação. A configuração define o host e a porta de escuta, e essa é toda a superfície exposta. O controlo de acesso para implementações fora do loopback é uma definição separada de host confiável. Essa definição não é uma tela de login.
Agora considere o que está por trás dessa porta. O agente edita ficheiros no workspace e executa comandos shell, enquanto as credenciais do seu provider ficam guardadas no disco, junto dele. Portanto, uma porta 3080 aberta é um shell remoto com uma interface de chat, executado com o utilizador que o iniciou e com a sua API key associada. Ninguém precisa de um exploit para tirar partido disso. Basta conhecer o número da porta, e os scanners encontram portas poucas horas depois de um host ficar online.
A CLI (interface de linha de comandos) confirma isto. A partir de 0.1.0-rc.6, ela não suporta deliberadamente --host 0.0.0.0 e termina com um erro de utilização, em vez de arrancar. Essa recusa é uma funcionalidade. Não procure um patch que a remova.
Há duas outras implementações razoáveis quando um túnel não é adequado. Coloque o servidor numa rede overlay privada, para que tenha um endereço para o qual apenas os seus próprios dispositivos possam encaminhar tráfego. É isso que um servidor de controlo Headscale autoalojado fornece. Em alternativa, coloque à frente um reverse proxy que autentique o pedido antes de este chegar à porta 3080, por exemplo um servidor de single sign-on Authentik a executar forward auth. Um reverse proxy sem autenticação à frente não é um controlo de segurança. É apenas um URL mais longo.
Aceder à interface Web através de um túnel SSH
Execute isto no seu portátil, não no servidor.
ssh -N -L 3080:127.0.0.1:3080 you@your-server-L abre a porta 3080 no seu portátil e encaminha tudo o que se ligar a ela através da sessão SSH encriptada. A parte 127.0.0.1:3080 é resolvida no servidor, por isso a ligação chega ao harness através do loopback, exatamente como se estivesse sentado diante da máquina. -N indica que não deve iniciar uma shell remota, porque pretende apenas o encaminhamento.
Depois, abra http://127.0.0.1:3080 no navegador local. Se a porta 3080 já estiver ocupada no seu portátil, altere o número do lado esquerdo: ssh -N -L 3180:127.0.0.1:3080 you@your-server. Em seguida, aceda a http://127.0.0.1:3180. O número do lado esquerdo é local e o número do lado direito pertence ao servidor. Por isso, apenas o número do lado esquerdo deve ser alterado.
Guarde isto em ~/.ssh/config e deixe de o escrever.
Host dsh
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519
LocalForward 3080 127.0.0.1:3080Depois disso, ssh -N dsh inicia o túnel. Quando o navegador indica que a ligação foi recusada, normalmente significa que o túnel está ativo, mas não existe nada a escutar no outro lado, porque o SSH encaminha a porta independentemente de o harness estar a ser executado. Verifique o servidor com o comando ss acima.
Mantenha o harness em execução depois de terminar a sessão
Um comando npx termina com a shell. Um serviço de utilizador systemd continua em execução e inicia novamente o harness depois de uma falha ou de um reboot.
loginctl enable-linger $USER
mkdir -p ~/.config/systemd/user
command -v dshenable-linger é importante porque os serviços de utilizador normalmente param quando termina a última sessão. Sem esta opção, o harness termina assim que fechar o túnel. Use o caminho absoluto apresentado por command -v dsh na unidade, porque o systemd não pesquisa o PATH que a sua shell de início de sessão cria.
[Unit]
Description=DeepSeek Harness web UI
After=network-online.target
[Service]
Type=simple
WorkingDirectory=%h/projects/site
ExecStart=/usr/local/bin/dsh web
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.targetWorkingDirectory não é apenas uma questão estética. O processo dsh usa o diretório a partir do qual foi iniciado como localização predefinida no sistema de ficheiros. Por isso, um serviço iniciado no diretório errado fornece ao agente o workspace predefinido incorreto. Ainda pode escolher o workspace na interface.
systemctl --user daemon-reload
systemctl --user enable --now dsh
systemctl --user status dshUma unidade que se recusa a iniciar quase sempre tem um caminho ExecStart incorreto ou uma versão do Node que o binário rejeita. journalctl --user -u dsh -n 50 indica qual dos dois problemas ocorreu. O mesmo padrão aplica-se a manter qualquer agente de programação em execução num VPS, e os modos de falha são idênticos.
O que um plugin pode fazer
Um plugin é um módulo que adiciona serviços, eventos tipados e efeitos reversíveis a um contexto partilhado. Os pontos de extensão são a parte que deve ser lida com atenção:
- registar um fornecedor de modelos em
ctx.llm - adicionar ferramentas disponíveis para o modelo em
ctx.tools - fornecer o backend de shell usado por
ctx.shell - fornecer acesso ao sistema de ficheiros ou políticas através de
ctx.fs - registar comandos do utilizador em
ctx.commands - executar trabalho em segundo plano através de
ctx.jobs - envolver processos iniciados com um backend
ctx.sandbox - intercetar pedidos e chamadas de ferramentas através dos eventos
agent/*etools/* - expandir o estado persistente da sessão
- controlar a interface através de
ctx.agents
Leia essa lista como um atacante a leria. Um plugin pode fornecer a camada do sistema de ficheiros e a camada de shell. Também pode ficar entre o modelo e cada chamada de ferramenta que este fizer. Não existe nenhuma caixa de diálogo de permissões entre um plugin e esses pontos de integração, porque um plugin é código Node normal carregado no mesmo processo que todo o resto. Instalar um plugin significa executar código de terceiros com as permissões do seu agente. As permissões do agente são as permissões do seu utilizador Unix.
Esta é a mesma decisão de confiança que toma quando liga um servidor MCP a um agente numa VPS, em que MCP significa protocolo de contexto do modelo. É também por isso que executar um agente de programação com segurança numa VPS começa pela conta em que ele é executado, e não pelo modelo, e por que razão os ataques à cadeia de fornecimento do npm afetam tanto os servidores: o passo de instalação é a intrusão, e não é apresentada nenhuma solicitação de confirmação.
De onde vêm os plugins
Os plugins ficam nos perfis. Um perfil é uma composição nomeada armazenada em $DSH_HOME, que por predefinição é ~/.dsh, e cada diretório de perfil contém os plugins externos que instala. A CLI gere-os encaminhando os seus argumentos diretamente para pnpm, utilizando o diretório do perfil como diretório de trabalho.
dsh plugin --profile web add github:deepseek-harness/turtle-ui
dsh plugin --profile web remove turtle-uiComo os argumentos chegam a pnpm sem alterações, add, remove, update e why comportam-se como em qualquer projeto pnpm, e um plugin pode ser um pacote npm ou uma referência do GitHub. pnpm tem de existir primeiro no PATH. No Node 22 e posteriores, corepack enable pnpm coloca-o nesse local.
A descoberta funciona através de um tópico do GitHub. Os autores dos plugins adicionam o tópico dsh-plugin ao seu repositório, e consultar esse tópico é a forma de encontrar os plugins disponíveis. Um tópico é um rótulo que o autor aplica ao próprio repositório. Ninguém o revê nem o valida, e a página do tópico ordena os repositórios pelo número de estrelas, que mede popularidade, não segurança.
Quatro práticas tornam isto controlável. Leia o código-fonte antes de instalar, porque a maioria dos plugins é suficientemente pequena para ser lida em dez minutos. Fixe a versão ou o commit exato em vez de acompanhar uma branch. Execute o harness com um utilizador que não seja proprietário de mais nada, num VPS que esteja disposto a reconstruir. Dê ao agente a sua própria chave de API, com o seu próprio limite de gastos, separada da chave utilizada pelos serviços de produção.
Se preferir comparar arquiteturas antes de escolher uma, o harness multiagente Omnigent resolve o mesmo problema com uma estrutura diferente, e os compromissos tornam-se evidentes quando os plugins entram em cena.
O que falha primeiro
Node é demasiado antigo. O projeto requer Node 22.19 e versões mais recentes da linha 22.x, ou Node 24 e posteriores, e a CI testa essas versões. Um runtime mais antigo falha no arranque porque o código usa sintaxe e APIs que ele não suporta. Execute node --version antes de qualquer outra coisa.
A porta 3080 já está ocupada. Pode ser um segundo harness, um processo antigo ou outra aplicação que também utiliza a porta 3080. Encontre o processo com ss -tlnp | grep 3080. Depois, pare-o ou inicie o harness noutra porta com dsh web --port 3180. --port pertence à aplicação Web, por isso deve ser executado depois de web.
O browser não consegue ligar-se através do túnel. Confirme que acedeu a 127.0.0.1 e não ao endereço público do servidor, porque a porta encaminhada existe apenas no seu portátil. Depois, confirme que o harness está a escutar no servidor, porque o SSH cria o encaminhamento independentemente de existir ou não uma resposta no extremo remoto.
dsh plugin falha imediatamente. O comando é um wrapper de pnpm. Por isso, a ausência do binário pnpm interrompe-o antes de qualquer trabalho de plugins.
O agente não consegue ver o seu projeto. Por predefinição, o workspace corresponde ao diretório onde o processo foi iniciado. Assim, uma unidade cujo WorkingDirectory seja o seu diretório pessoal fornece esse diretório ao agente. Escolha o workspace na interface ou corrija a unidade e recarregue-a.
FAQ
É seguro expor a interface web do DeepSeek Harness na porta 3080?
Não. O servidor web não tem autenticação própria, e o agente por trás dele edita ficheiros e executa comandos shell com o utilizador que iniciou o processo. A chave de API do seu fornecedor também fica armazenada no mesmo disco. Mantenha o listener em 127.0.0.1 e aceda-lhe através de um túnel SSH. Uma rede overlay privada ou um reverse proxy que autentique todos os pedidos antes de estes chegarem à porta também funciona. A partir da versão 0.1.0-rc.6, a CLI recusa --host 0.0.0.0 e termina com um erro de utilização. Isso indica o que os autores pensam desta configuração.
Preciso de uma chave de API da DeepSeek ou posso usar um modelo local?
Ambas as opções funcionam, porque o harness é um runtime, não um modelo. Em Settings e depois em Models, pode colar uma chave no cartão de um fornecedor do catálogo. Também pode escolher "Add a custom provider" e indicar-lhe uma URL base que utilize o protocolo compatível com OpenAI. Um servidor Ollama local responde em http://127.0.0.1:11434/v1/ e aceita qualquer cadeia no campo da chave de API. As chaves são guardadas em $DSH_HOME/.credentials.yaml, que por predefinição aponta para ~/.dsh/.credentials.yaml.
O que recebe realmente um plugin do DeepSeek Harness ao ser instalado?
As permissões da conta que executa o harness. Um plugin é código Node carregado no mesmo processo. Os pontos de extensão incluem o backend shell, a camada do sistema de ficheiros, o registo de ferramentas e os eventos que envolvem cada chamada de ferramenta. Nada isola um plugin dessas interfaces, exceto se o próprio plugin fornecer o sandbox. Leia o código-fonte antes de instalar. Execute o harness com um utilizador que não seja proprietário de nada que considere importante.
Que versão devo instalar e continuará a funcionar?
Instale uma versão exata, por exemplo npx @deepseek-ai/dsh@0.1.0-rc.6 web. Era essa a versão para a qual a tag latest apontava em 13 August 2026. O projeto identifica-se como uma developer preview e indica que são esperadas alterações incompatíveis. Por isso, um comando sem versão fixada pode comportar-se de forma diferente de um dia para o outro. Consulte o repositório antes de atualizar. Conte também com alterações nas chaves de configuração e nas interfaces dos plugins enquanto a versão continuar a começar por 0.