{"id":25829390,"url":"https://github.com/majst01/metal-dns","last_synced_at":"2026-05-11T08:51:28.843Z","repository":{"id":45092515,"uuid":"330925065","full_name":"majst01/metal-dns","owner":"majst01","description":"dns as a service","archived":false,"fork":false,"pushed_at":"2023-08-04T11:10:26.000Z","size":243,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-06-21T03:15:39.514Z","etag":null,"topics":["dns","external-dns","grpc","powerdns-api"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/majst01.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-19T09:18:30.000Z","updated_at":"2022-09-14T07:13:12.000Z","dependencies_parsed_at":"2024-06-21T02:08:07.340Z","dependency_job_id":"79c5f7eb-3286-4536-b3ce-32e4469048b4","html_url":"https://github.com/majst01/metal-dns","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majst01%2Fmetal-dns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majst01%2Fmetal-dns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majst01%2Fmetal-dns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majst01%2Fmetal-dns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/majst01","download_url":"https://codeload.github.com/majst01/metal-dns/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241205843,"owners_count":19927164,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dns","external-dns","grpc","powerdns-api"],"created_at":"2025-02-28T18:58:28.072Z","updated_at":"2026-05-11T08:51:23.823Z","avatar_url":"https://github.com/majst01.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# metal-dns\n\n[![Actions](https://github.com/majst01/metal-dns/workflows/build/badge.svg)](https://github.com/majst01/metal-dns/actions)\n[![Go Reference](https://pkg.go.dev/badge/github.com/majst01/metal-dns.svg)](https://pkg.go.dev/github.com/majst01/metal-dns)\n[![Go Report Card](https://goreportcard.com/badge/github.com/majst01/metal-dns)](https://goreportcard.com/report/github.com/majst01/metal-dns)\n[![codecov](https://codecov.io/gh/majst01/metal-dns/branch/master/graph/badge.svg)](https://codecov.io/gh/majst01/metal-dns)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/majst01/metal-dns/blob/master/LICENSE)\n\nActs as a authorization proxy in front of a powerdns resolver. Metal-DNS will restrict access to specific domains and subdomains.\nAccess to certain api actions can also be restricted.\n\nA POC external-dns implementation is also available \u003chttps://github.com/majst01/external-dns/tree/metal-dns-support\u003e .\n\nOpen Topics:\n\n- Management of authorization tokens and who is able to modify certain domains.\n- actually there is a Token create endpoint which can be used to create tokens with domains and permissions specified.\n\n## Authorization\n\nStandard JWT token authorization is implemented.\n\n- get/list/create/update domains if not already present\n- add/delete/update records\n\nExample JWT Payload:\n\n```json\n{\n  \"sub\": \"1234567890\",\n  \"name\": \"John Doe\",\n  \"iat\": 1516239022,\n  \"domains\": [\n     \"a.example.com\",\n     \"b.example.com\"\n  ],\n  \"permissions\": [\n    \"/api.v1.DomainService/Get\",\n    \"/api.v1.DomainService/List\",\n    \"/api.v1.DomainService/Create\",\n    \"/api.v1.DomainService/Update\",\n    \"/api.v1.DomainService/Delete\",\n    \"/api.v1.RecordService/Create\",\n    \"/api.v1.RecordService/List\",\n    \"/api.v1.RecordService/Update\",\n    \"/api.v1.RecordService/Delete\"\n  ]\n}\n```\n\n## Usage\n\n### Server\n\n1.) start Powerdns:\n\n```bash\ndocker run -d --rm \\\n  --name powerdns \\\n  -p 8081:80 \\\n  -p 5533:53 powerdns/pdns-auth-47 \\\n    --api=yes \\\n    --api-key=apipw \\\n    --webserver=yes \\\n    --webserver-address=0.0.0.0 \\\n    --webserver-port=80 \\\n    --webserver-allow-from=0.0.0.0/0 \\\n    --disable-syslog=yes \\\n    --loglevel=9 \\\n    --log-dns-queries=yes \\\n    --log-dns-details=yes \\\n    --query-logging=yes\n```\n\n2.) start metal-dns api server pointing to the powerdns api endpoint\n\n```bash\nmake certs\ndocker run -d --rm \\\n  --name metal-dns \\\n  -p 50051:50051 \\\n  -v $PWD/certs:/certs ghcr.io/majst01/metal-dns \\\n    --pdns-api-password=apipw \\\n    --pdns-api-url=http://localhost:8081 \\\n    --pdns-api-vhost=localhost \\\n    --secret=YOUR-JWT-TOKEN-SECRET\n```\n\n### Client\n\n`go get github.com/majst01/metal-dns`\n\n```go\nimport (\n  \"context\"\n  \"os\"\n\n  v1 \"github.com/majst01/metal-dns/api/v1\"\n  \"github.com/majst01/metal-dns/pkg/client\"\n)\n\nfunc main() {\n  ctx := context.Background()\n  addr := \"localhost:50051\"\n  dialConfig := client.DialConfig{\n    Address: \u0026addr,\n    Token: os.Getenv(\"JWT_TOKEN\"),\n  }\n  c, err = client.NewClient(ctx, dialConfig)\n  if err != nil {\n    panic(err)\n  }\n\n  dcr := \u0026v1.DomainCreateRequest{\n    Name:        \"a.example.com.\",\n    Nameservers: []string{\"ns1.example.com.\"},\n  }\n  d, err := c.Domain().Create(ctx, dcr)\n  if err != nil {\n    panic(err)\n  }\n  fmt.Println(\"Domain created:\" + d)\n\n  rcr := \u0026v1.RecordCreateRequest{\n    Type: v1.RecordType_A,\n    Name: \"www.a.example.com.\",\n    Data: \"1.2.3.4\",\n    Ttl: uint32(600),\n  }\n\n  r, err := c.Record().Create(ctx, rcr)\n  if err != nil {\n    panic(err)\n  }\n  fmt.Println(\"Record created:\" + r)\n}\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmajst01%2Fmetal-dns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmajst01%2Fmetal-dns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmajst01%2Fmetal-dns/lists"}