Connector · Docker
Execute o Connector em um container — sem porta de entrada.
A imagem oficial ghcr.io/termalinapp/termalin-connector executa o Connector do Termalin em um único container em qualquer máquina de uma rede — um NAS, um home lab, um roteador, um cluster Kubernetes, um serviço ECS. Ela se conecta de dentro para fora até o Termalin e alcança os servidores, sites internos e áreas de trabalho daquela rede, sem nenhuma porta de entrada aberta. Cerca de 4 MB, amd64/arm64, roda como uid 10001.
amd64 / arm64 · sem porta de entrada · Pro (ou 14 dias de teste)
01 / por que um container
Um container na rede, nada para abrir.
Um Connector permite que o Termalin alcance uma máquina privada sem porta de entrada e sem chave de longa duração nela. Algumas máquinas são mais fáceis de adicionar como um container do que instalar um binário e um serviço — e algumas só rodam containers. A imagem serve para elas:
- ▸Um NAS ou home lab. Synology, Unraid ou um host Docker na sua LAN — alcance o SSH da própria máquina e qualquer outro servidor, site ou área de trabalho na rede.
- ▸Um roteador. O MikroTik RouterOS 7 roda containers; um deles abriga o Connector para o roteador e tudo o que está atrás dele.
- ▸Kubernetes. Um Deployment de uma réplica alcança os serviços do cluster pelo endereço interno deles.
- ▸AWS ECS / uma VPC. Uma tarefa Fargate ou EC2 apenas com HTTPS de saída — sem load balancer, sem regra de entrada — alcança instâncias privadas, sites internos e áreas de trabalho.
02 / a imagem
Quatro megabytes, sem shell, sem servidor SSH.
A imagem é ghcr.io/termalinapp/termalin-connector:<version> (e :latest), para linux/amd64 e linux/arm64.
- ▸Cerca de 4 MB. O Connector estático, os certificados de CA e nada mais — sem shell, sem gerenciador de pacotes, sem servidor SSH. Ela roda como uid 10001 e mantém a configuração no volume
/data. - ▸Compilada de forma aberta. No repositório público
termalinapp/termalin, apenas a partir dos binários de versão assinados em termal.in — cada um conferido contra o manifesto da versão e sua assinatura antes de entrar. - ▸armv7 ainda não é compilado (ARM de 32 bits). Por enquanto, apenas amd64 e arm64.
03 / início rápido
Cadastre um container com um único docker run.
Obtenha um token de cadastro no painel web (Connectors → Adicionar), depois:
docker run -d --name termalin --restart unless-stopped \ -v termalin:/data \ -e TERMALIN_TOKEN=<token> \ -e TERMALIN_TARGET=192.168.1.10:22 \ -e TERMALIN_USER=deploy \ ghcr.io/termalinapp/termalin-connector
As variáveis:
| Variável | O que faz |
|---|---|
TERMALIN_TOKEN | Token de cadastro; usado só na primeira inicialização, quando o volume ainda não tem configuração. |
TERMALIN_TARGET | host:port do servidor SSH para onde vão os terminais, comandos e arquivos (o host Docker ou outra máquina). Dentro do container, 127.0.0.1 é o próprio container, que não tem servidor SSH. |
TERMALIN_USER | Usuário de login naquele servidor SSH (padrão: o padrão da conta). |
TERMALIN_NAME | Nome no painel web (padrão: o hostname do container — defina --hostname ou isto). |
TERMALIN_SERVER | Padrão: https://termal.in. |
Primeira inicialização: sem configuração em /data e com um token definido, o container se cadastra, imprime a linha de login abaixo e conecta. As inicializações seguintes apenas conectam — o token pode ficar no ambiente, ele não é enviado de novo. Sem configuração e sem token, ele avisa e sai com código 1. docker stop o para na hora. Para cadastrar de novo, remova o volume e inicie com um novo token.
04 / a linha de login
Confie no certificado no destino.
O Connector do container nunca toca no destino. No cadastro, ele imprime a linha que permite que os certificados de curta duração do Termalin para esta conta façam login — e docker exec termalin termalin-agent check a imprime de novo:
cert-authority,principals="termalin-<account id>" ssh-ed25519 AAAA… termalin-connector
Coloque-a no ~/.ssh/authorized_keys do usuário de login no destino (uma linha, arquivo em modo 600, ~/.ssh em 700). Em um servidor que você administra como root, pode em vez disso adicionar TrustedUserCAKeys e AuthorizedPrincipalsFile ao sshd_config dele — o check imprime os dois. Sem isso, terminais e comandos por este Connector são recusados pelo destino; links web e áreas de trabalho não precisam disso. O check também informa se o servidor SSH do destino responde (sshd=up); o status de login é ca=unknown, porque os arquivos do destino não podem ser lidos de dentro do container.
05 / sem servidor SSH
Sites internos e áreas de trabalho, sem nenhum sshd.
Os sites internos e as áreas de trabalho remotas (RDP, VNC) não passam pelo SSH: o backend pede ao Connector para abrir uma conexão com o host:port do próprio site ou da própria área de trabalho, e o Connector conecta lá diretamente. Então um container em uma VPC, um serviço ECS ou uma rede doméstica pode publicar sites internos e áreas de trabalho sem nenhum servidor SSH. A página de banco de dados com uma senha de banco de dados funciona do mesmo jeito, na porta do banco.
- ▸Apenas endereços privados. Os destinos de conexão precisam estar na rede privada — RFC 1918, loopback, link-local, CGNAT
100.64/10(como o Tailscale), ULA de IPv6. O Connector não é um relay para a internet, e endereços de metadados de nuvem (169.254.169.254e afins) são sempre recusados. - ▸Precisa de um servidor SSH no destino: o terminal, o
ssh_exece as outras ferramentas de comando, arquivos por SFTP, as ferramentas de banco de dados sem senha, métricas e backups. DefinaTERMALIN_TARGETe adicione a linha de login lá.
06 / docker compose
O mesmo, como um arquivo compose.
services:
termalin:
image: ghcr.io/termalinapp/termalin-connector:latest
restart: unless-stopped
hostname: office-nas
environment:
TERMALIN_TOKEN: ${TERMALIN_TOKEN}
TERMALIN_TARGET: 192.168.1.10:22
TERMALIN_USER: deploy
volumes:
- termalin:/data
volumes:
termalin: Para alcançar o próprio host Docker, use o endereço de LAN dele, ou no Docker Desktop host.docker.internal:22 (no Linux, adicione extra_hosts: ["host.docker.internal:host-gateway"]).
07 / NAS
Synology e Unraid.
- ▸Synology (Container Manager): Registry → adicione
ghcr.io/termalinapp/termalin-connector, crie um container com as variáveis acima, um volume para/data, “auto restart” ligado. Ative o SSH em Control Panel → Terminal & SNMP para o terminal e definaTERMALIN_TARGET=<NAS address>:22. - ▸Unraid: Docker → Add Container, repositório
ghcr.io/termalinapp/termalin-connector, um caminho/data→/mnt/user/appdata/termalin, as variáveis como variáveis do container. - ▸Uma pasta com bind mount precisa ter permissão de escrita para o uid 10001 (
chown 10001:10001 /mnt/…/termalin); um volume nomeado é configurado pelo Docker para você.
08 / MikroTik RouterOS 7
No próprio roteador.
Roteadores arm64 e x86 por enquanto (ainda sem build para armv7). Ative o pacote container e o device-mode, depois:
/interface/veth add name=veth-termalin address=172.17.0.2/24 gateway=172.17.0.1
/interface/bridge/port add bridge=containers interface=veth-termalin
/container/envs add name=termalin key=TERMALIN_TOKEN value=<token>
/container/envs add name=termalin key=TERMALIN_TARGET value=192.168.88.1:22
/container/mounts add name=termalin-data src=/usb1/termalin dst=/data
/container add remote-image=ghcr.io/termalinapp/termalin-connector:latest \
interface=veth-termalin envlist=termalin mounts=termalin-data \
root-dir=/usb1/termalin-root start-on-boot=yes logging=yes Isso pressupõe uma bridge containers com 172.17.0.1/24 e NAT de saída, como no próprio guia de containers da MikroTik. Aponte para o SSH do próprio roteador (/ip/service enable ssh) ou para qualquer host atrás dele.
09 / Kubernetes
Uma réplica, um Secret, um PVC minúsculo.
apiVersion: v1
kind: Secret
metadata: { name: termalin }
stringData: { token: "<token>" }
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata: { name: termalin-data }
spec:
accessModes: [ReadWriteOnce]
resources: { requests: { storage: 16Mi } }
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: termalin-connector }
spec:
replicas: 1
strategy: { type: Recreate }
selector: { matchLabels: { app: termalin-connector } }
template:
metadata: { labels: { app: termalin-connector } }
spec:
securityContext: { runAsUser: 10001, runAsGroup: 10001, fsGroup: 10001, runAsNonRoot: true }
containers:
- name: connector
image: ghcr.io/termalinapp/termalin-connector:0.2.3
env:
- { name: TERMALIN_TOKEN, valueFrom: { secretKeyRef: { name: termalin, key: token } } }
- { name: TERMALIN_TARGET, value: "10.0.12.7:22" }
- { name: TERMALIN_NAME, value: "k8s-prod" }
securityContext: { readOnlyRootFilesystem: true, allowPrivilegeEscalation: false, capabilities: { drop: [ALL] } }
resources: { requests: { cpu: 10m, memory: 16Mi }, limits: { memory: 64Mi } }
volumeMounts: [{ name: data, mountPath: /data }]
volumes:
- { name: data, persistentVolumeClaim: { claimName: termalin-data } } Os serviços internos são alcançados pelo endereço de cluster deles em um link web — http://grafana.monitoring.svc:3000 resolve pelo DNS do cluster para um endereço privado. Mantenha uma réplica por cadastro: dois pods no mesmo volume seriam o mesmo Connector duas vezes.
10 / AWS ECS
Uma tarefa Fargate ou EC2, só de saída.
Um serviço com desired count 1, a imagem acima, o token do Secrets Manager como TERMALIN_TOKEN e um volume EFS em /data (de propriedade do 10001 — um access point do EFS com uid/gid 10001). HTTPS de saída para termal.in é tudo o que ele precisa — sem load balancer, sem regra de entrada. Os security groups dos destinos precisam deixar a tarefa entrar nas portas usadas (22, 3389, as portas dos sites). O endereço de metadados da tarefa ECS é recusado como todo endereço de metadados.
11 / atualizações e limites
Baixe uma nova tag; o que um container não faz.
- ▸Atualizações. O container nunca se atualiza sozinho — baixe uma nova tag e recrie-o (
docker compose pull && docker compose up -d, ou uma nova tag de imagem no Deployment). O volume mantém o cadastro. O painel web não mostra “Atualizar agora” para ele. - ▸Os recursos de SSH precisam de um destino. Terminal, comandos, arquivos, bancos de dados sem senha, métricas e backups precisam de um servidor SSH no destino e da linha de login lá; a imagem não tem nenhum próprio.
- ▸Um servidor SSH de destino por Connector (
TERMALIN_TARGET); links web e áreas de trabalho podem apontar para qualquer endereço privado. - ▸armv7 (ARM de 32 bits) ainda não é compilado.
Perguntas frequentes
Quais arquiteturas e qual o tamanho da imagem?
Uma imagem multi-arch para linux/amd64 e linux/arm64, de cerca de 4 MB: o Connector estático, os certificados de CA e nada mais — sem shell, sem gerenciador de pacotes, sem servidor SSH. Ela roda como uid 10001 e mantém a configuração no volume /data. armv7 (ARM de 32 bits) ainda não é compilado.
De onde vem a imagem?
Ela é compilada de forma aberta, no repositório público termalinapp/termalin, apenas a partir dos binários de versão assinados publicados em termal.in — cada um conferido contra o manifesto da versão e sua assinatura antes de entrar na imagem.
Preciso de um servidor SSH dentro ou ao lado do container?
Não para sites internos, áreas de trabalho remotas (RDP/VNC) nem a página de banco de dados — essas vão direto ao host:port do próprio destino pelo Connector, então um container em uma VPC ou numa rede doméstica pode publicá-las sem nenhum sshd em lugar algum. Já um terminal, comandos, arquivos por SFTP, as ferramentas de banco de dados sem senha, métricas e backups precisam de um servidor SSH no destino (TERMALIN_TARGET) e da linha de login adicionada lá — a própria imagem não tem nenhum.
Como atualizo o container?
O container nunca se atualiza sozinho. Baixe uma nova tag e recrie-o — docker compose pull && docker compose up -d, ou uma nova tag de imagem no Deployment. O volume /data mantém o cadastro, então você não cadastra de novo. O painel web não mostra “Atualizar agora” para um container.
Quanto custa e de qual plano preciso?
O Connector é um recurso hospedado, então precisa de uma conta Termalin no Pro ou nos 14 dias de teste. A imagem é gratuita para baixar; não há limite de quantos Connectors você adiciona.
Alcance a rede inteira a partir de um único container.
Um token, um docker run, sem porta de entrada. Em um NAS, um roteador, Kubernetes ou ECS.
Pro (ou 14 dias de teste) · Sites internos · Áreas de trabalho remotas