PostgreSQL
Bancos PostgreSQL no VPS com usuário próprio de privilégio mínimo, TLS e acesso externo limitado por lista de IP.
- Categoria: Servidores e infraestrutura
- Estado: Disponível
- Requisitos: Um VPS ativo com a função
postgresqldisponível; Ser membro com acesso ao VPS para instalar; admin para revelar a credencial, abrir o acesso ou apagar dados - Ferramentas MCP (Só leem):
ver_catalogo_apps,ver_preflight_app,ver_app,ver_acceso_app,ver_operacion_app,listar_motores_db_vps,listar_bases_db_vps - Ferramentas MCP (Escrevem ou modificam):
instalar_app,revelar_credencial_app,cambiar_lista_ip_app,reintentar_operacion_app - Ferramentas MCP (Destrutivas):
revocar_acceso_app,desinstalar_app
O que permite fazer?
Cada banco PostgreSQL é um app: tem seu nome, seu usuário próprio com senha aleatória e, se pedido, acesso pela internet com TLS e lista de IP. O motor é instalado uma única vez por VPS e é compartilhado por todos os seus bancos.
- Criar vários bancos no mesmo motor, cada um isolado dos outros.
- Ver a credencial (usuário, senha e URI de conexão) quando necessário.
- Abrir, alterar ou fechar o acesso pela internet por IP.
- Explorar tabelas e dados pelo gerenciador de bancos de dados.
- Pela aba PostgreSQL do VPS: listar e criar bancos, usuários e permissões.
Quando convém usar?
- Uma aplicação publicada no mesmo VPS que precisa de um banco relacional (conecta por
127.0.0.1:5432). - Um serviço externo (BI, outra nuvem, um computador) que precisa ler o banco com TLS a partir de IPs conhecidos.
Como funciona na ArduMaker?
- Validar: VPS ativo e função
postgresqldo sistema. - Motor: se não estiver instalado, é instalado uma única vez (pacotes
postgresqlepostgresql-contribda distribuição, senha administrativa aleatória guardada criptografada). Se já estava, não é reinstalado nem muda de versão ou senha. - Credencial: é gerado um usuário
app<id>_<hex>com senha aleatória, criptografada na plataforma antes de tocar o VPS. - Papel e banco: o papel é criado
LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION; o banco é criado com esse papel como dono, tudo é revogado dePUBLICe uma linhahostssl <banco> <papel> … scram-sha-256é adicionada aopg_hba.conf, com uma rejeição abaixo para qualquer outro banco. - Verificação: o papel não pode ser superusuário nem criar bancos ou papéis, é dono do seu banco e
PUBLICnão se conecta. Se algo não bater, falhapermisos_no_verificados. - Acesso externo: só se pedido com IPs. O TLS do motor é ativado e a abertura é pedida como operação separada; se ainda não puder abrir, o banco fica instalado assim mesmo e o motivo é registrado.
O SQL viaja codificado no ambiente e entra por stdin; a senha nunca aparece em uma linha de comando nem em um log.
config.external_access decide se o banco sai para a internet: {"ips": [...]} abre só para esses IPs; {"local": true} (ou false) o deixa só dentro do VPS. Se não for informado, pelo painel usa-se o IP de quem instala; via MCP o IP do agente não conta, então sem ips o banco fica local em vez de falhar.
O que muda realmente?
| O quê | Detalhe |
|---|---|
| Motor | Serviço postgresql habilitado, escutando em 127.0.0.1:5432 |
| Banco | Nome [A-Za-z_][A-Za-z0-9_]{0,62}, com maiúsculas como estão (entre aspas) |
| Papel do app | app<id>_<hex> |
pg_hba.conf | Seu bloco hostssl e um reject para os demais bancos |
| TLS (se houver acesso externo) | Certificado próprio em /etc/ardumaker/tls/, ssl=on, TLS 1.2 no mínimo, recarga sem reinício |
Acesso pela internet e lista de IP
Por padrão o motor escuta só dentro do VPS (5432 em 127.0.0.1). Para usar o banco de fora, a ArduMaker publica um endpoint próprio do motor: db-<id do VPS> dentro da zona da plataforma (registro DNS direto, sem proxy), em uma porta reservada entre 61000 e 64999. No host, um proxy leva essa porta ao 5432 do VPS e o firewall só deixa entrar os IPs da lista.
O certificado é próprio desse nome (não um curinga) e é instalado no motor: o PostgreSQL ativa ssl com TLS 1.2 no mínimo e recarrega a configuração sem reiniciar. O usuário do app só entra por TCP com TLS (hostssl) e só no seu banco.
| Regra da lista | Detalhe |
|---|---|
| Formato | IPv4 ou IPv6, com ou sem prefixo; um IP solto é /32 ou /128. Nada de nomes, loopback, link-local nem multicast |
| Amplitude | Prefixo mínimo /24 em IPv4 e /48 em IPv6 por padrão; 0.0.0.0/0 e ::/0 são recusados na lista |
| Tamanho | Até 20 entradas; vazia = fechado para todos |
| Nomes de host | Até 5 (allowed_hosts), com até 8 IPs públicos cada; são resolvidos de novo a cada 5 minutos e uma falha de DNS mantém o último conhecido |
| Aberto a todos | Só com allow_any e confirm_open juntos; a resposta informa em open_to_any |
A lista é do motor, não de cada banco: alterá-la a partir de qualquer banco PostgreSQL muda o acesso de todos os bancos desse motor nesse VPS (a resposta indica com shared_with_engine e affected_apps).
- As regras de firewall que faltam são adicionadas, uma por CIDR (
ufw allow from <cidr> to any port <porta> proto tcp). - Depois as que sobram são removidas e suas conexões abertas são cortadas.
- Só então o listener é criado e verificado: regras iguais à lista, nenhuma regra aberta a qualquer um, listener presente e handshake TLS com o nome correto.
Desinstalar, persistência e cópias
- Sem
delete_data(o normal): o acesso externo próprio é fechado e o app deixa de aparecer como instalado, mas o banco, seu usuário e seus dados ficam no VPS. A próxima reconciliação o mostra como detectado. Nada se perde. - Com
delete_data: true(confirmado duas vezes, só admin):DROP DATABASEe, se o usuário foi criado pelo Apps (app<id>_<hex>), também o papel e sua senha guardada. Nunca um usuário do cliente nem o administrador do motor. - O motor nunca é desinstalado pelo Apps: fica instalado mesmo sem bancos.
- Se o VPS ou o motor não responderem,
desinstalar_appcomforzar=truetenta cada passo uma vez, remove o app e lista emnot_cleanedo que ficou no servidor. - Os dados vivem no disco do VPS e viajam na sua cópia semanal, feita com o VPS ligado. Para uma cópia consistente de um banco específico convém também um dump próprio pelo gerenciador de bancos de dados (exportar) ou com as ferramentas do motor.
Esquema
- App no mesmo VPS:
127.0.0.1:5432 - Cliente externo:
db-<id>:<porta>comsslmode=verify-full - Firewall do host: só os IPs da lista
- Proxy do host: porta 61000–64999 → 5432 do VPS
- PostgreSQL:
hostssl+scram-sha-256, só o seu banco
Resultado esperado
O banco aparece em Apps pendurado no seu motor. ver_acceso_app mostra estado, host, porta, TLS e a lista aplicada; revelar_credencial_app devolve usuário, senha e a URI. A URI só existe quando o acesso externo está pronto:
postgresql://app<id>_<hex>@db-<vps>.<zona>:<puerto>/<base>?sslmode=verify-fullErros e resolução
| Erro | Causa | Tentar de novo? |
|---|---|---|
base_ya_existe | Já existe um banco com esse nome de outro dono; não é sobrescrito nem adotado | Não |
motor_detenido / motor_instalandose / motor_no_instalado | O motor está parado, instalando ou não pôde ser instalado | Sim |
base_no_creada / permisos_no_verificados | O SQL falhou ou as permissões do papel não verificaram | Sim |
lista_ip_invalida / lista_ip_demasiado_amplia | Entrada malformada ou faixa mais ampla que o mínimo; data.invalid diz quais | Corrigindo a lista |
credencial_legacy / cuentas_del_motor_sin_verificar / tls_no_disponible | O motor ainda não cumpre as condições para ser exposto (senhas antigas, contas do cliente não verificadas ou TLS pendente) | Após resolver |
acceso_externo_no_habilitado | O acesso externo não está habilitado para esse tipo na empresa | Não |
cierre_no_verificado | Ao fechar ficou uma regra ou o listener; é informado o que realmente existe | Sim |
Estado e passos de cada operação: ver_operacion_app (inclui se pode ser repetida). Uma operação falha que pode ser repetida é retomada do passo que falhou com reintentar_operacion_app, sem reinstalar o motor. Pedir a lista que já está aplicada não enfileira nada (idempotent: true).
Relação com MCP
Todo o ciclo do banco é operado via MCP com as permissões da pessoa que autorizou o agente. Referência em /mcp/docs e /mcp/bases-de-datos.
- Leitura:
ver_catalogo_apps,ver_preflight_app,listar_apps_empresa,ver_app,ver_acceso_app(host, porta, TLS e lista de IP, sem segredos),ver_operacion_app. - Modificam:
instalar_appcomapp_type: postgres(exigeidempotency_key),cambiar_lista_ip_app(só se o dono for admin; os IPs são informados explicitamente: o IP do agente não é o da pessoa),reintentar_operacion_app,refrescar_apps. - Sensível:
revelar_credencial_app(só admin, não aceitaidempotency_key; a resposta vem marcadasensible: truee a auditoria registra que foi revelado, nunca o valor). - Destrutivas:
revocar_acceso_app(fecha o acesso externo de todo o motor) edesinstalar_app(comdelete_dataapaga os dados; exigeconfirm_delete_data).
Para ler e escrever dados dentro do banco, o agente usa as ferramentas do gerenciador de bancos de dados. Um agente autorizado como somente leitura não vê as ferramentas que modificam nem pode revelar credenciais.