Regras do Rediacc
Cada repositório Rediacc corre dentro de um ambiente isolado com o seu próprio daemon Docker, volume LUKS encriptado e intervalo de IPs dedicado. Estas regras garantem que a sua aplicação funciona correctamente dentro desta arquitectura.
Rediaccfile
- Cada repositorio precisa de um Rediaccfile, um script bash com funcoes de ciclo de vida.
- Funcoes de ciclo de vida:
up(),down(). Opcional:info(). up()inicia os seus servicos.down()para-os.info()fornece informacoes de estado (estado do contentor, logs recentes, saude).- O Rediaccfile e carregado (sourced) pelo renet; tem acesso a variaveis de shell, nao apenas a variaveis de ambiente.
Variaveis de ambiente disponiveis no Rediaccfile
| Variavel | Exemplo | Descricao |
|---|---|---|
REDIACC_WORKING_DIR | /mnt/rediacc/mounts/abc123/ | Caminho raiz do repositorio montado |
REDIACC_NETWORK_ID | 6336 | Identificador de isolamento de rede |
REDIACC_REPOSITORY | abc123-... | GUID do repositorio |
{SVCNAME}_IP | HEARTBEAT_IP=127.0.24.195 | IP de loopback por servico (nome do servico em maiusculas) |
Rediaccfile Minimal
#!/bin/bash
_compose() {
renet compose -- "$@"
}
up() {
_compose up -d
}
down() {
_compose down
}
Compose
- Use
renet compose, nuncadocker compose, o renet injeta isolamento de rede, host networking, IPs de loopback e labels de servico. - NAO defina
network_modeno seu ficheiro compose; o renet forcanetwork_mode: hostem todos os servicos. Qualquer valor que defina sera sobrescrito. - NAO defina labels
rediacc.*, o renet injeta automaticamenterediacc.network_id,rediacc.service_iperediacc.service_name. - Os mapeamentos
ports:sao ignorados em modo host networking. Adicione a labelrediacc.service_portpara routing HTTP (servicos sem esta label nao obtem rotas HTTP). Use as labelsrediacc.tcp_ports/rediacc.udp_portspara reencaminhamento TCP/UDP. - As politicas de reinicio (
restart: always,on-failure, etc.) sao seguras de usar; o renet remove-as automaticamente para compatibilidade com CRIU. O watchdog do router recupera automaticamente os contentores parados com base na politica original guardada em.rediacc.json. - As configuracoes perigosas sao bloqueadas por padrao:
privileged: true,pid: host,ipc: hoste bind mounts do host para caminhos de sistema sao rejeitados. Userenet compose --unsafepara substituir por sua propria conta e risco.
Variaveis de ambiente dentro dos contentores
O renet injeta-as automaticamente em cada contentor:
| Variavel | Descricao |
|---|---|
SERVICE_IP | IP de loopback dedicado deste contentor |
REDIACC_NETWORK_ID | ID de isolamento de rede |
Nomenclatura de servicos e routing
- O nome do servico no compose torna-se o prefixo do URL de rota automatica.
- Repositorios grand:
https://{service}.{repo}.{machine}.{baseDomain}(por exemplo,https://myapp.marketing.server-1.example.com). - Repositorios fork:
https://{service}-fork-{tag}.{repo}.{machine}.{baseDomain}(por exemplo,https://myapp-fork-staging.marketing.server-1.example.com). O separador-fork-evita colisoes de URL com nomes de servico do repositorio grand. O URL do fork usa sempre o certificado wildcard existente do repositorio pai, pelo que nao e necessario um novo certificado. - Para dominios personalizados, use labels Traefik (mas atencao: os dominios personalizados NAO sao compativeis com forks; o dominio pertence ao repositorio grand).
Networking
- Cada repositorio tem o seu proprio daemon Docker em
/var/run/rediacc/docker-<networkId>.sock. - Cada servico tem um IP de loopback unico dentro de uma subnet /26 (por exemplo,
127.0.24.192/26). - O binding e automatico: os servicos podem fazer bind a
0.0.0.0oulocalhost; o kernel reescreve transparentemente o endereco para o IP de loopback atribuido ao servico. O binding explicito via${SERVICE_IP}ainda funciona, mas ja nao e necessario. - Os health checks podem usar
localhostou${SERVICE_IP}. Exemplo:healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] - As conexoes entre repositorios sao bloqueadas pelo kernel: o kernel bloqueia automaticamente conexoes para IPs de loopback fora da subnet
/26do repositorio. Um servico num repositorio nao consegue aceder a servicos de outro repositorio. Uma exceção: as conexões de um fork para a sub-rede do pai são redirecionadas de forma transparente para os serviços do próprio fork (mesmo serviço, cópia dos dados do fork), nunca para o pai. Repositórios não relacionados continuam bloqueados. - Comunicação entre serviços: use nomes de serviço (ex.:
db,redis); o renet injeta automaticamente cada nome de serviço como um hostname que resolve para o IP correto. Nomes DNS do Docker NÃO funcionam em modo host, mas nomes de serviço via/etc/hostsfuncionam. Evite embutir${DB_IP}ou similares em ficheiros de configuração persistentes (ex.: strings de conexão guardadas numa base de dados): um fork redireciona os IPs herdados do pai diretamente para os seus próprios serviços, mas o redirecionamento cobre apenas um passo de linhagem; um fork de um fork ainda carrega IPs do avô que não levam a lado nenhum. Nomes de serviço resolvem sempre corretamente em cada repositório. - Conflitos de portas sao impossiveis entre repositorios; cada um tem o seu proprio daemon Docker e intervalo de IPs.
- Reencaminhamento de portas TCP/UDP: adicione labels para expor portas nao HTTP:
labels: - "rediacc.tcp_ports=5432,3306" - "rediacc.udp_ports=53"
Armazenamento
- Todos os dados Docker sao guardados dentro do repositorio encriptado; o
data-rootdo Docker esta em{mount}/.rediacc/docker/datadentro do volume LUKS. Volumes nomeados, imagens e camadas de contentores sao todos encriptados, incluidos nos backups e clonados automaticamente. - Bind mounts para
${REDIACC_WORKING_DIR}/...sao recomendados para maior clareza, mas volumes nomeados tambem funcionam com seguranca.volumes: - ${REDIACC_WORKING_DIR}/data:/data # bind mount (recomendado) - pgdata:/var/lib/postgresql/data # volume nomeado (tambem seguro) - O volume LUKS e montado em
/mnt/rediacc/mounts/<guid>/. - Os snapshots BTRFS capturam o ficheiro de suporte LUKS completo, incluindo todos os dados em bind mount.
- O datastore e um ficheiro de pool BTRFS de tamanho fixo no disco do sistema. Use
rdc machine query --name <name> --systempara ver o espaco livre efectivo. Expanda comrdc datastore resize.
CRIU (Migracao ao Vivo)
- Opt-in via label: adicione
rediacc.checkpoint=trueaos contentores que pretende fazer checkpoint. Os contentores sem esta label (bases de dados, caches) iniciam de raiz e recuperam pelos seus proprios mecanismos (WAL, LDF, AOF). repo down --checkpointguarda o estado do processo antes de parar; o proximorepo uprestaura automaticamente. Este e o fluxo principal na mesma maquina, verificado como funcional.backup push --checkpointcaptura a memoria do processo em execucao e o estado do disco para contentores com label, depois transfere o volume para outra maquina. Restaure na maquina de destino viarepo up.repo fork --checkpointcaptura o estado dos processos do pai em execução e clona o checkpoint junto com o fork via CoW. Orepo updo fork restaura os processos enquanto o pai continua em execução, na mesma máquina. Processos restaurados que referenciam endereços loopback do pai (sockets vinculados, IPs de serviço em memória) são redirecionados de forma transparente para os endereços próprios do fork, então eles falam com a cópia de dados do fork, nunca com a do pai.repo updetecta automaticamente dados de checkpoint e restaura se encontrados. Use--skip-checkpointpara forcar inicio limpo.- Restauro com consciencia de dependencias: usa
depends_ondo compose para iniciar primeiro as bases de dados (aguarda que fiquem saudaveis) e depois restaura os contentores da aplicacao com CRIU. - As conexoes TCP ficam obsoletas apos o restauro; as aplicacoes devem tratar
ECONNRESETe reconectar. O CRIU nao preserva o estado de conexoes TCP activas apos o restauro em nenhum fluxo suportado. - O modo experimental do Docker e activado automaticamente nos daemons por repositorio.
- O CRIU e instalado durante
rdc config machine setup. /etc/criu/runc.confe configurado comtcp-establishedpor padrao.- As configuracoes de seguranca do contentor sao injectadas automaticamente para contentores com label: o
renet composeadiciona o seguinte aos contentores comrediacc.checkpoint=true:cap_add:CHECKPOINT_RESTORE,SYS_PTRACE,NET_ADMIN(conjunto minimo para CRIU no kernel 5.9+)security_opt:apparmor=unconfined(o suporte AppArmor do CRIU ainda nao e estavel upstream)userns_mode: host(o CRIU necessita de acesso ao namespace init para/proc/pid/map_files)
- Os contentores sem a label correm com uma postura de seguranca mais limpa (sem capacidades extra).
- O perfil seccomp padrao do Docker e preservado; o CRIU usa
PTRACE_O_SUSPEND_SECCOMP(kernel 4.3+) para suspender temporariamente os filtros durante checkpoint/restore. - NAO defina manualmente as capacidades CRIU no seu ficheiro compose; o renet trata disso com base na label.
- Consulte o template heartbeat para uma implementacao de referencia compativel com CRIU.
Padroes de aplicacao compativeis com CRIU
- Trate
ECONNRESETem todas as conexoes persistentes (pools de bases de dados, websockets, filas de mensagens). - Use bibliotecas de pool de conexoes que suportem reconexao automatica.
- Adicione
process.on("uncaughtException")como rede de seguranca para erros de socket obsoletos de objectos de biblioteca internos. - As politicas de reinicio sao geridas automaticamente pelo renet (removidas para CRIU; o watchdog trata da recuperacao).
- Evite depender do DNS do Docker; use IPs de loopback para comunicacao entre servicos.
Politicas de seguranca do host por SO
Nos cinco SOs de servidor com suporte oficial (consulte Requisitos), o daemon Docker por repositorio e os contentores que executa usam labels de contentor padrao. rdc config machine setup nao instala uma politica SELinux personalizada nem um perfil AppArmor. Isto e intencional: o trade-off e que os processos de contentor funcionam sob a politica de rotulo do SO anfitrao por defeito, nao sob um perfil de confinamento especifico do Rediacc. Se o seu modelo de ameaca exigir controles de acesso obrigatorio ao nivel do contentor, configure-os ao nivel do anfitrao antes de implementar.
- Ubuntu 24.04 / openSUSE Leap 16.0: AppArmor esta activo por padrao. Os contentores correm sob o perfil docker-container padrao. A unica excepcao e o CRIU (
apparmor=unconfinedpara contentores comrediacc.checkpoint=true, conforme a nota acima). - Fedora 43 / Oracle Linux 10: SELinux corre em modo enforcing por padrao. Os contentores recebem o contexto
container_tpadrao. Nao e necessaria instalacao de politica adicional. Se um passo de configuracao falhar com negacoes AVC, consulte Resolucao de Problemas -> Negacoes SELinux. - Debian 13: AppArmor esta disponivel mas nao e aplicado por padrao em todos os dominios. Os contentores continuam a usar o perfil docker-container.
Bottom line: rdc e renet detectam automaticamente o SO em execucao e produzem o mesmo isolamento por repositorio nas cinco distribuicoes com suporte. Nao e necessaria nenhuma flag de postura de seguranca por SO.
Seguranca
- A encriptacao LUKS e obrigatoria para repositorios padrao. Cada repositorio tem a sua propria chave de encriptacao.
- As credenciais sao guardadas na configuracao do CLI (
~/.config/rediacc/rediacc.json). Perder a configuracao significa perder o acesso aos volumes encriptados. - Nunca coloque credenciais em controlo de versao. Use
env_filee gere segredos emup(). - Isolamento de repositorios: o daemon Docker, a rede e o armazenamento de cada repositorio estao totalmente isolados de outros repositorios na mesma maquina.
- Isolamento de agentes: os agentes de IA operam em modo apenas fork por padrao. Cada repositorio tem a sua propria chave SSH com aplicacao de sandbox do lado do servidor (
sandbox-gatewayForceCommand). Todas as conexoes estao em sandbox com Landlock LSM, OverlayFS home overlay e TMPDIR por repositorio. O acesso ao sistema de ficheiros entre repositorios e bloqueado pelo kernel. sudoesta desactivado dentro de uma sandbox de repositorio por concepcao. O isolamento do sistema de ficheiros Landlock requerNoNewPrivs, o que impede qualquer elevacao de privilegios, pelo quesudofalhara comno new privileges flag is set. O utilizador proprietario do repositorio ja tem as permissoes necessarias para tudo dentro do mount e do socket Docker do repositorio. Para operacoes genuinamente privilegiadas (instalacao de pacotes no host, ajuste do kernel), execute-as fora da sandbox ou a partir de uma funcaoup()do Rediaccfile executada pelo caminho de infraestrutura.- O bridge networking do Docker esta desactivado nos daemons por repositorio. O
daemon.json(FlavorRediacc) de cada repositorio tem"bridge": "none"e"iptables": false, portanto um simplesdocker run <image>cria um contentor com apenas uma interface de loopback e sem conectividade de saida. Isto nao e um bug; e assim que o isolamento entre repositorios e aplicado: os hooks eBPF ao nivel do kernel que bloqueiam um repositorio de aceder aos IPs de loopback de outro repositorio so se aplicam a contentores que vivem no namespace de rede do host. Para servicos de producao, userenet compose, que injetanetwork_mode: hostautomaticamente. Para contentores ad-hoc numa shell, passe--network hostexplicitamente. (Os daemons Hub por utilizador (FlavorHub, ambientes de desenvolvimento) sao a excecao: activambridge="docker0"eiptables=truepara que os contentores executados pelo utilizador tenham conectividade de saida normal.)
Deployment
rdc repo upmonta automaticamente o volume LUKS se nao estiver montado e depois executaup()em todos os Rediaccfiles.rdc repo downexecutadown()e para o daemon Docker.rdc repo down --unmounttambem fecha o volume LUKS (bloqueia o armazenamento encriptado).- Forks (
rdc repo fork) criam um clone CoW (copy-on-write) com um novo GUID e networkId, em tempo constante independentemente do tamanho do repositorio. O reflink BTRFS duplica os metadados da imagem, nao os dados, pelo que um repositorio de 100 GB e clonado nos mesmos segundos que um de 1 GB. O fork partilha a chave de encriptacao do pai. - Takeover (
rdc repo takeover --name <fork> -m <machine>) substitui os dados do repositorio grand pelos dados de um fork. O grand mantem a sua identidade (GUID, networkId, dominios, autostart, cadeia de backup). Os dados antigos de producao sao preservados como um fork de backup. Use para: testar actualizacao no fork, verificar e depois fazer takeover para producao. Reverta comrdc repo takeover --name <backup-fork> -m <machine>. - As rotas do proxy demoram cerca de 3 segundos a ficar activas apos o deployment. O aviso “Proxy is not running” durante
repo upe informativo em ambientes de operacoes/desenvolvimento. rdc repo uperdc repo fork --upmostram o padrao de URL para servicos com labelrediacc.service_portno final do deployment. Substitua{service}pelo nome do servico exposto para obter o URL exacto. Os servicos semrediacc.service_port(bases de dados, workers) nao obtem rotas e nao sao mostrados.
Erros Comuns
- Usar
docker composeem vez derenet compose; os contentores nao obterao isolamento de rede. - As politicas de reinicio sao seguras; o renet remove-as automaticamente e o watchdog trata da recuperacao.
- Usar
privileged: true; nao e necessario, o renet injeta capacidades CRIU especificas em vez disso. - Incorporar IPs brutos em ficheiros de configuracao persistentes; use nomes de servico para conexoes, de modo a manter o isolamento de fork intacto.
- Usar
rdc term connect -ccomo alternativa a comandos que falharam; reporte bugs em vez disso. repo deleterealiza uma limpeza completa, incluindo IPs de loopback e unidades systemd. Executerdc machine prune --name <name>para limpar residuos de eliminacoes antigas.