Moon Flower Society > Serviço Próprio de DNS Autoritativo
Uma arquitetura prática para criar um serviço independente de DNS autoritativo com PowerDNS, PostgreSQL, painel web, API, receitas DNS, ACME, backup e monitoramento.
Posted June 27, 2026. Markdown. Tags: dns, infraestrutura, homelab, powerdns, automação, indie-web.
Este documento organiza a ideia de criar um serviço próprio de DNS autoritativo: nameservers próprios, painel simples, API de automação, receitas prontas e operação segura.
A proposta é bonita, útil e tecnicamente viável. Mas o ponto central é simples: DNS é infraestrutura crítica. Se for feito com preguiça, não vira independência; vira uma máquina elegante de derrubar os próprios serviços.
| Campo | Decisão recomendada |
|---|---|
| Tipo de serviço | DNS autoritativo, não resolver recursivo |
| Software DNS | PowerDNS Authoritative |
| Banco | PostgreSQL |
| Nameservers | ns1 e ns2 em VPS diferentes |
| Painel | Web simples, com validações fortes |
| Automação | API própria + tokens com escopo |
| Certificados | DNS-01 para wildcard via Certbot/Caddy |
| Monitoramento | Uptime Kuma, Prometheus, Grafana e exporters |
| MVP | Domínio laboratório, nunca domínio crítico |
DNS próprio é liberdade, mas também responsabilidade operacional. O MVP precisa provar estabilidade antes de tocar em domínio importante.
Este projeto serve para criar um serviço próprio de hospedagem DNS autoritativa.
Na prática, ele permite que uma pessoa, empresa, comunidade ou projeto controle diretamente os registros DNS dos seus domínios usando nameservers próprios, em vez de depender totalmente de provedores externos para responder oficialmente por esses registros.
Exemplo com domínio fictício:
krikri.zone
Em um provedor DNS comum, os nameservers de krikri.zone poderiam ser algo como:
ns1.provedor.example
ns2.provedor.example
Neste projeto, a ideia é ter nameservers próprios:
ns1.krikri.zone
ns2.krikri.zone
ou, em uma arquitetura mais separada:
ns1.dns.krikri.zone
ns2.dns.krikri.zone
A partir daí, esses servidores passam a responder oficialmente por registros como:
krikri.zone. A 203.0.113.10
www.krikri.zone. CNAME krikri.zone.
mail.krikri.zone. A 203.0.113.20
krikri.zone. MX 10 mail.krikri.zone.
_acme-challenge.krikri.zone. TXT "token-de-validacao"
O serviço não é um resolver público como 1.1.1.1, 8.8.8.8 ou 9.9.9.9.
Ele é um servidor DNS autoritativo, ou seja, responde oficialmente pelas zonas delegadas a ele.
Em termos simples:
Resolver público:
usado por pessoas e computadores para perguntar "qual é o IP deste domínio?"
Servidor autoritativo:
usado pela internet para descobrir a resposta oficial de um domínio.
Este projeto quer resolver o segundo caso.
O objetivo é construir uma plataforma própria de DNS autoritativo com:
O diferencial não deve ser apenas “ter DNS próprio”. Isso, sozinho, não é produto.
O diferencial real deve ser:
A versão mínima do projeto deve permitir:
Exemplo de uso com krikri.zone:
1. O domínio krikri.zone é registrado normalmente em um registrador.
2. No registrador, são criados glue records para ns1.krikri.zone e ns2.krikri.zone.
3. Os nameservers do domínio são alterados para ns1.krikri.zone e ns2.krikri.zone.
4. O painel do serviço passa a controlar a zona krikri.zone.
5. Registros A, AAAA, CNAME, MX, TXT, CAA e outros são gerenciados pelo painel/API.
6. Certificados wildcard podem ser emitidos automaticamente com desafio DNS-01.
Inicialmente, o público-alvo deve ser o próprio operador do serviço.
Ou seja: primeiro construir para uso pessoal, em domínios não críticos.
Depois, se o serviço ficar estável, poderia atender:
Para uso comercial amplo, o nível de responsabilidade sobe muito. DNS é infraestrutura crítica. Um erro pode derrubar sites, e-mails, certificados e serviços federados.
Para o exemplo krikri.zone, o projeto deve começar como ferramenta interna/laboratório. Só depois de estabilidade real, backup testado, monitoramento e rollback funcional faria sentido pensar em uso por terceiros.
Algumas ideias de nome:
Krikri DNS
Zone Garden
DNS Garden
Krikri Zones
Krikri Zonekeeper
A estética pode seguir uma linha:
Uma boa direção seria algo como:
Zone Garden — um jardim de zonas DNS com receitas prontas, automação segura e painel simples.
Ou:
Krikri DNS — DNS hosting autoritativo para projetos indie, fediverse, e-mail próprio e certificados wildcard.
Um servidor DNS autoritativo é aquele que responde oficialmente por uma zona.
Exemplo:
krikri.zone
Se o domínio estiver delegado para:
ns1.krikri.zone
ns2.krikri.zone
então esses nameservers respondem oficialmente por registros como:
www.krikri.zone
mail.krikri.zone
_acme-challenge.krikri.zone
Não confundir com resolver recursivo.
Resolvers como:
1.1.1.1
8.8.8.8
9.9.9.9
são usados por clientes para consultar a internet. Eles perguntam aos servidores autoritativos e devolvem a resposta ao usuário.
Este projeto não é sobre criar um resolver público. É sobre hospedar DNS autoritativo.
Exemplo:
ns1.krikri.zone
ns2.krikri.zone
Esses hosts precisam apontar para IPs públicos de servidores que rodam software DNS autoritativo.
Se o nameserver está dentro do próprio domínio que ele ajuda a resolver, é preciso criar glue records no registrador.
Exemplo:
krikri.zone
Nameservers:
ns1.krikri.zone
ns2.krikri.zone
Problema circular:
Para saber o IP de
ns1.krikri.zone, eu preciso consultarkrikri.zone. Mas para consultarkrikri.zone, eu preciso saber onde estáns1.krikri.zone.
Solução: no registrador do domínio, cadastrar hosts de nameserver:
ns1.krikri.zone → IP_DA_VPS_1
ns2.krikri.zone → IP_DA_VPS_2
Isso são os glue records.
Uma zona é o conjunto de registros de um domínio.
Exemplo de zona:
$ORIGIN krikri.zone.
$TTL 3600
@ IN SOA ns1.krikri.zone. hostmaster.krikri.zone. (
2026062701 ; serial
3600 ; refresh
900 ; retry
1209600 ; expire
3600 ; minimum
)
@ IN NS ns1.krikri.zone.
@ IN NS ns2.krikri.zone.
@ IN A 203.0.113.10
www IN CNAME krikri.zone.
mail IN A 203.0.113.20
@ IN MX 10 mail.krikri.zone.
Existem duas rotas principais.
BIND 9 é uma opção clássica para servidores DNS autoritativos. Ele trabalha muito bem com arquivos de zona e é excelente para aprendizado profundo de DNS.
Vantagens:
Desvantagens:
BIND pode ser usado com dynamic update via RFC 2136, mas a experiência de construir um painel e uma API completos em cima dele é menos direta do que com PowerDNS.
Para este projeto, a recomendação principal é usar PowerDNS Authoritative com PostgreSQL.
Vantagens:
Desvantagens:
Recomendação honesta:
Para um serviço próprio com painel web, API, receitas e automação, PowerDNS + PostgreSQL é a melhor escolha inicial.
Arquitetura inicial:
┌───────────────────────────┐
│ app.dns.krikri.zone │
│ Painel Web + API própria │
└────────────┬──────────────┘
│
▼
┌───────────────────────────┐
│ PostgreSQL │
│ users/zones/records/logs │
└────────────┬──────────────┘
│
▼
┌─────────────────────────────────────────┐
│ PowerDNS Authoritative │
│ ns1 + ns2 lendo banco/replicação │
└─────────────────────────────────────────┘
│
▼
Internet DNS
Arquitetura com dois servidores:
┌──────────────────────────────────────┐
│ VPS 1 │
│ │
│ ns1.krikri.zone │
│ PowerDNS Authoritative │
│ PostgreSQL primary │
│ API/painel opcional │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│ VPS 2 │
│ │
│ ns2.krikri.zone │
│ PowerDNS Authoritative │
│ PostgreSQL replica ou AXFR │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│ VPS 3 opcional │
│ │
│ painel web │
│ worker de receitas │
│ backups │
│ monitoramento │
└──────────────────────────────────────┘
Não usar ns1 e ns2 no mesmo servidor. Isso só simula redundância, mas não entrega redundância real.
Errado:
ns1.krikri.zone → 203.0.113.10
ns2.krikri.zone → 203.0.113.10
Correto:
ns1.krikri.zone → 203.0.113.10
ns2.krikri.zone → 198.51.100.20
Ideal:
ns1.krikri.zone → VPS A / provedor A / região A
ns2.krikri.zone → VPS B / provedor B / região B
Responsáveis por responder consultas DNS autoritativas.
Sugestão:
ns1.krikri.zone
ns2.krikri.zone
Software recomendado:
PowerDNS Authoritative
Alternativa:
BIND 9
Recomendado:
PostgreSQL
Funções:
Funções:
Funções:
Responsável por tarefas assíncronas:
Monitorar:
Ferramentas possíveis:
Uptime Kuma
Prometheus
Grafana
node_exporter
blackbox_exporter
PowerDNS exporter
Backup obrigatório de:
Política recomendada:
backup diário local
backup diário remoto
retenção de 7 dias
retenção semanal de 4 semanas
retenção mensal de 6 meses
Se usar PowerDNS, parte do modelo de dados vem do próprio schema do PowerDNS. Mesmo assim, o painel próprio deve ter tabelas de aplicação.
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
name TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE app_zones (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id),
name TEXT NOT NULL UNIQUE,
status TEXT NOT NULL DEFAULT 'active',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE api_tokens (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id),
zone_id BIGINT REFERENCES app_zones(id),
name TEXT NOT NULL,
token_hash TEXT NOT NULL,
scopes JSONB NOT NULL DEFAULT '[]',
allowed_names JSONB NOT NULL DEFAULT '[]',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
last_used_at TIMESTAMPTZ
);
CREATE TABLE audit_logs (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT REFERENCES users(id),
zone_id BIGINT REFERENCES app_zones(id),
action TEXT NOT NULL,
old_value JSONB,
new_value JSONB,
ip INET,
user_agent TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE applied_recipes (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id),
zone_id BIGINT NOT NULL REFERENCES app_zones(id),
recipe_name TEXT NOT NULL,
recipe_version TEXT NOT NULL,
applied_records JSONB NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
GET /api/zones
POST /api/zones
GET /api/zones/:zone
DELETE /api/zones/:zone
GET /api/zones/:zone/records
POST /api/zones/:zone/records
PUT /api/zones/:zone/records/:id
DELETE /api/zones/:zone/records/:id
GET /api/recipes
GET /api/recipes/:recipe
POST /api/zones/:zone/apply-recipe
GET /api/tokens
POST /api/tokens
DELETE /api/tokens/:id
POST /api/lego/present
POST /api/lego/cleanup
Payload para present:
{
"fqdn": "_acme-challenge.krikri.zone.",
"value": "token-do-letsencrypt",
"ttl": 120
}
Payload para cleanup:
{
"fqdn": "_acme-challenge.krikri.zone.",
"value": "token-do-letsencrypt"
}
Autenticação:
Authorization: Bearer TOKEN
Regras obrigatórias:
_acme-challenge;Uma das funções mais úteis do serviço é permitir emissão de certificados wildcard via DNS-01.
Exemplo:
*.krikri.zone
Fluxo:
Caddy/Certbot pede certificado wildcard
↓
Let's Encrypt exige TXT em _acme-challenge.dominio.com
↓
Caddy/Certbot chama API do serviço DNS
↓
Serviço cria TXT no PowerDNS
↓
Let's Encrypt consulta o TXT
↓
Certificado é emitido
↓
Serviço remove o TXT
Exemplo conceitual:
#!/usr/bin/env bash
set -euo pipefail
: "${KRIKRIDNS_API_BASE:?Missing KRIKRIDNS_API_BASE}"
: "${KRIKRIDNS_API_TOKEN:?Missing KRIKRIDNS_API_TOKEN}"
domain="${CERTBOT_DOMAIN:?Missing CERTBOT_DOMAIN}"
value="${CERTBOT_VALIDATION:?Missing CERTBOT_VALIDATION}"
fqdn="_acme-challenge.${domain}"
fqdn="${fqdn%.}."
curl -fsS \
-H "Authorization: Bearer ${KRIKRIDNS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"fqdn\":\"${fqdn}\",\"value\":\"${value}\",\"ttl\":120}" \
"${KRIKRIDNS_API_BASE%/}/api/lego/present"
#!/usr/bin/env bash
set -euo pipefail
: "${KRIKRIDNS_API_BASE:?Missing KRIKRIDNS_API_BASE}"
: "${KRIKRIDNS_API_TOKEN:?Missing KRIKRIDNS_API_TOKEN}"
domain="${CERTBOT_DOMAIN:?Missing CERTBOT_DOMAIN}"
value="${CERTBOT_VALIDATION:?Missing CERTBOT_VALIDATION}"
fqdn="_acme-challenge.${domain}"
fqdn="${fqdn%.}."
curl -fsS \
-H "Authorization: Bearer ${KRIKRIDNS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"fqdn\":\"${fqdn}\",\"value\":\"${value}\"}" \
"${KRIKRIDNS_API_BASE%/}/api/lego/cleanup"
Mais tarde, pode ser criado um provider libdns.
Exemplo de configuração desejada no Caddy:
{
acme_dns krikridns {
api_base_url https://dns.krikri.zone/api/lego/
api_token {$KRIKRIDNS_API_TOKEN}
ttl 120
}
}
*.krikri.zone {
tls {
dns krikridns
}
reverse_proxy 127.0.0.1:8080
}
As receitas são o grande diferencial do produto.
Em vez de exigir que o usuário saiba exatamente quais registros criar, o sistema oferece ações prontas.
Objetivo: impedir abuso de spoofing em um domínio sem e-mail.
Registros:
@ MX 0 .
@ TXT "v=spf1 -all"
*._domainkey TXT "v=DKIM1; p="
_dmarc TXT "v=DMARC1; p=reject; adkim=s; aspf=s;"
Registros:
@ TXT "v=spf1 include:provedor.example -all"
_dmarc TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@krikri.zone"
DKIM dependeria do provedor.
Criar MX padrão do Google:
@ MX 1 ASPMX.L.GOOGLE.COM.
@ MX 5 ALT1.ASPMX.L.GOOGLE.COM.
@ MX 5 ALT2.ASPMX.L.GOOGLE.COM.
@ MX 10 ALT3.ASPMX.L.GOOGLE.COM.
@ MX 10 ALT4.ASPMX.L.GOOGLE.COM.
Também preparar SPF:
@ TXT "v=spf1 include:_spf.google.com -all"
Criar os registros necessários para Fastmail, incluindo MX, SPF, DKIM e DMARC, conforme valores fornecidos pela conta do usuário.
Criar registros de envio transacional:
SPF
DKIM
DMARC
CNAME de tracking, se aplicável
Os valores devem ser preenchidos com base no painel do Resend.
Criar registros comuns:
@ A IP_DO_SERVIDOR
www CNAME @
Opcionalmente, documentar uso de WebFinger, ActivityPub e proxies.
Criar registros:
@ A IP_DO_SERVIDOR
www CNAME @
Ou, se hospedagem externa exigir:
www CNAME host-do-provedor.example.
Criar TXT para handle do Bluesky:
_atproto TXT "did=did:plc:..."
Criar registros .well-known não é DNS puro, mas DNS pode ajudar com delegation via SRV, dependendo do modelo usado.
Possível receita:
_matrix._tcp.krikri.zone SRV 10 5 8448 matrix.krikri.zone.
@ CAA 0 issue "letsencrypt.org"
@ CAA 0 iodef "mailto:admin@krikri.zone"
Criar API token limitado a:
_acme-challenge.krikri.zone
Escopo:
acme:dns01
Permissões:
create TXT
delete own TXT
DNS tem regras chatas. O painel deve proteger o usuário de erros comuns.
Inválido:
blog A 203.0.113.10
blog CNAME krikri.zone.
Também inválido:
blog CNAME krikri.zone.
blog TXT "teste"
Se um hostname tem CNAME, ele não deve ter outros tipos de registro.
Inválido:
@ MX mail.krikri.zone.
Correto:
@ MX 10 mail.krikri.zone.
Formato:
_service._proto.name TTL IN SRV priority weight port target
Exemplo:
_matrix._tcp.krikri.zone. 3600 IN SRV 10 5 8448 matrix.krikri.zone.
Exemplo:
@ CAA 0 issue "letsencrypt.org"
TXT muito grande pode precisar ser dividido em múltiplas strings dentro do mesmo registro.
Se o usuário controla:
krikri.zone
A API não pode aceitar:
_acme-challenge.outrodominio.com
Definir limites:
TTL mínimo: 60 ou 120 segundos
TTL padrão: 3600 segundos
TTL máximo: 86400 ou 604800 segundos
O usuário comum não deve conseguir apagar acidentalmente:
SOA
NS principais
A edição desses registros precisa ser controlada.
Nunca usar token global para tudo.
Tipos de token:
read-only
zone-admin
record-editor
acme-dns01
recipe-runner
Token ACME deve ser extremamente limitado.
Exemplo:
{
"scope": "acme:dns01",
"zone": "krikri.zone",
"allowed_names": [
"_acme-challenge.krikri.zone."
],
"allowed_types": ["TXT"]
}
Nunca armazenar token puro.
Guardar apenas hash:
sha256/token hash com salt adequado
Mostrar o token ao usuário apenas uma vez.
Registrar:
Aplicar limite em:
Para qualquer serviço DNS com painel web, 2FA é recomendável.
Mínimo:
TOTP
Toda alteração de zona deve poder ser revertida.
Ideal:
histórico de versões da zona
botão “restaurar versão anterior”
exportação BIND zone file
DNSSEC é útil, mas adiciona complexidade.
Recomendação:
Erro em DNSSEC pode deixar o domínio aparentemente “fora do ar” para resolvers validadores.
DNSSEC mal operado é pior do que DNS sem DNSSEC.
Telas mínimas:
Dashboard
Zonas
Registros
Receitas
API Keys
Logs
Verificador DNS
Configurações
Ajuda
Mostrar:
Exemplo:
Zona: krikri.zone
Status: ativa
Nameservers esperados:
- ns1.krikri.zone
- ns2.krikri.zone
Delegação detectada:
- ns1.krikri.zone
- ns2.krikri.zone
SOA serial: 2026062701
Última alteração: 2026-06-27 14:32
Tabela:
Nome | Tipo | Valor | TTL | Prioridade | Ações
Exemplo de erro útil:
Você tentou criar um CNAME em blog.krikri.zone, mas esse nome já possui um registro A.
DNS não permite CNAME coexistindo com outros registros no mesmo hostname.
Escolha uma opção:
1. apagar o registro A e criar CNAME;
2. manter o A;
3. criar o CNAME em outro subdomínio.
Isso é muito melhor do que:
Invalid record
Antes de aplicar uma receita, mostrar exatamente o que será criado:
Esta receita criará:
@ MX 0 .
@ TXT "v=spf1 -all"
*._domainkey TXT "v=DKIM1; p="
_dmarc TXT "v=DMARC1; p=reject; adkim=s; aspf=s;"
Botões:
[Aplicar]
[Cancelar]
PowerDNS Authoritative
PostgreSQL
Boas opções:
Go
Python/FastAPI
Node.js/NestJS
PHP/Laravel
Escolha recomendada:
Python/FastAPI ou Go
Para produtividade rápida:
Python/FastAPI
Para binário simples e performance:
Go
Opções:
HTML server-side simples
SvelteKit
Next.js
Django templates
Laravel Blade
Recomendação pragmática:
SvelteKit ou templates server-side simples
Não precisa virar uma SPA monstruosa.
Caddy
ou:
Nginx
Uptime Kuma
Prometheus
Grafana
Opções:
Docker Compose
Systemd direto
Ansible
Para MVP:
Docker Compose
Para produção mais controlada:
Ansible + systemd + backups
krikri-dns/
├── README.md
├── docs/
│ ├── architecture.md
│ ├── api.md
│ ├── recipes.md
│ ├── security.md
│ └── operations.md
├── backend/
│ ├── app/
│ ├── migrations/
│ ├── tests/
│ └── pyproject.toml
├── frontend/
│ ├── src/
│ └── package.json
├── deploy/
│ ├── docker-compose.yml
│ ├── pdns/
│ ├── postgres/
│ └── caddy/
├── scripts/
│ ├── certbot-auth.sh
│ ├── certbot-cleanup.sh
│ ├── backup.sh
│ └── healthcheck.sh
└── recipes/
├── no-email-domain.yml
├── google-workspace.yml
├── resend.yml
├── gotosocial.yml
├── ghost.yml
└── letsencrypt-caa.yml
Exemplo em YAML:
id: no-email-domain
name: Domínio sem e-mail
version: "1.0"
description: Protege um domínio que não envia nem recebe e-mail.
records:
- name: "@"
type: "MX"
priority: 0
content: "."
ttl: 3600
- name: "@"
type: "TXT"
content: "v=spf1 -all"
ttl: 3600
- name: "*._domainkey"
type: "TXT"
content: "v=DKIM1; p="
ttl: 3600
- name: "_dmarc"
type: "TXT"
content: "v=DMARC1; p=reject; adkim=s; aspf=s;"
ttl: 3600
warnings:
- "Use esta receita apenas se o domínio realmente não envia nem recebe e-mail."
Receita com variáveis:
id: resend
name: Resend
version: "1.0"
description: Configura registros básicos para envio via Resend.
variables:
- id: dkim_name
label: Nome do DKIM
required: true
- id: dkim_value
label: Valor do DKIM
required: true
records:
- name: "@"
type: "TXT"
content: "v=spf1 include:amazonses.com -all"
ttl: 3600
- name: "{{ dkim_name }}"
type: "TXT"
content: "{{ dkim_value }}"
ttl: 3600
- name: "_dmarc"
type: "TXT"
content: "v=DMARC1; p=quarantine;"
ttl: 3600
Escolher domínio base para nameservers.
Sugestões:
krikri.zone
krikri.zone
runv.club
Evitar usar domínio crítico no começo.
Não começar com:
portalidea.com.br
krikri.zone
murad.social
Objetivo: rodar PowerDNS Authoritative em uma VPS.
Entregáveis:
dig funcionando.Exemplo de teste:
dig @IP_DA_VPS krikri.zone SOA
dig @IP_DA_VPS www.krikri.zone A
dig @IP_DA_VPS krikri.zone TXT
Objetivo: ter ns1 e ns2 reais.
Entregáveis:
Objetivo: CRUD básico de zonas e registros.
Entregáveis:
Objetivo: permitir DNS-01 automático.
Entregáveis:
/api/lego/present;/api/lego/cleanup;Objetivo: transformar DNS em ações prontas.
Entregáveis:
Objetivo: tratar DNS como infraestrutura crítica.
Entregáveis:
Objetivo: colocar domínio não crítico em produção.
Entregáveis:
Objetivo: avaliar abertura para terceiros.
Entregáveis:
dig @ns1.krikri.zone krikri.zone SOA +short
dig krikri.zone NS +short
dig @ns1.krikri.zone www.krikri.zone A
dig krikri.zone +trace
dig _acme-challenge.krikri.zone TXT +short
dig @ns1.krikri.zone krikri.zone SOA +short
dig @ns2.krikri.zone krikri.zone SOA +short
dig @ns1.krikri.zone krikri.zone SOA +tcp
Se nameservers falham, os domínios ficam inacessíveis.
Impacto:
Um registro errado pode quebrar serviço crítico.
Mitigação:
ns1 e ns2 podem responder dados diferentes.
Mitigação:
Token API vazado pode permitir alteração de DNS.
Mitigação:
DNSSEC quebrado pode fazer o domínio sumir para resolvers validadores.
Mitigação:
Não fazer:
usar uma VPS só para ns1 e ns2
colocar domínios críticos no primeiro teste
ativar DNSSEC cedo demais
não ter backup
não ter monitoramento
não ter rollback
não validar CNAME/MX/SRV/CAA
usar token global para ACME
armazenar API token puro
editar zona sem log
Não migrar inicialmente:
portalidea.com.br
krikri.zone
murad.social
serviços com e-mail crítico
Usar primeiro:
domínio laboratório
domínio descartável
subdomínio experimental
O MVP mais sensato:
PowerDNS Authoritative
PostgreSQL
2 VPS
ns1/ns2 reais
painel simples
API ACME
receitas básicas
monitoramento
backup
Escopo do MVP:
Não incluir no MVP:
Descrição curta:
Um serviço de DNS autoritativo simples e independente, com receitas prontas para e-mail, certificados, fediverse e projetos indie.
Descrição mais longa:
Um painel DNS autoritativo para pessoas que querem controlar seus próprios domínios sem depender totalmente de provedores grandes. Ele combina nameservers próprios, API, automação de certificados wildcard, receitas DNS prontas e explicações claras para evitar erros comuns.
Tom do produto:
simples
indie
técnico
humano
sem firula corporativa
com personalidade
Frase possível:
DNS sem drama para gente que hospeda coisas estranhas na internet.
Outra:
Um jardim de zonas DNS para projetos indie, fediverse, e-mail próprio e certificados wildcard.
A ideia é boa, mas deve ser tratada como infraestrutura crítica.
Construir um serviço desses é totalmente viável. A parte técnica não é absurda. O perigo está na operação: DNS é silencioso, mas quando falha, derruba tudo que depende dele.
A melhor estratégia é:
A arquitetura recomendada é:
PowerDNS Authoritative
PostgreSQL
API própria
Painel web simples
Receitas YAML
Tokens com escopo
Integração Certbot/Caddy
2 VPS reais para ns1/ns2
Monitoramento e backup
O erro seria tentar transformar isso imediatamente em SaaS público.
O caminho inteligente é fazer primeiro como ferramenta própria, usar em domínios secundários, endurecer a operação e só então decidir se vale oferecer para outras pessoas.
DNS próprio é bonito, elegante e poderoso. Mas também é uma maneira sofisticada de derrubar os próprios serviços se for feito com preguiça.
View the original Markdown file
Ideas | What changed | RSS | About | Text version
Pablo Murad <pablomurad@pm.me>