{"id":47762754,"url":"https://github.com/taskcluster/stateless-dns-go","last_synced_at":"2026-04-03T05:49:08.881Z","repository":{"id":2612270,"uuid":"46985186","full_name":"taskcluster/stateless-dns-go","owner":"taskcluster","description":"A go (golang) port of https://github.com/taskcluster/stateless-dns-server/blob/master/index.js","archived":false,"fork":false,"pushed_at":"2022-05-03T10:21:05.000Z","size":53,"stargazers_count":1,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-14T17:56:15.041Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/taskcluster.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-27T14:45:44.000Z","updated_at":"2022-05-28T22:45:42.000Z","dependencies_parsed_at":"2022-07-27T02:47:13.768Z","dependency_job_id":null,"html_url":"https://github.com/taskcluster/stateless-dns-go","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/taskcluster/stateless-dns-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taskcluster%2Fstateless-dns-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taskcluster%2Fstateless-dns-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taskcluster%2Fstateless-dns-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taskcluster%2Fstateless-dns-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/taskcluster","download_url":"https://codeload.github.com/taskcluster/stateless-dns-go/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taskcluster%2Fstateless-dns-go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31337184,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T04:42:29.251Z","status":"ssl_error","status_checked_at":"2026-04-03T04:42:12.667Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2026-04-03T05:49:08.171Z","updated_at":"2026-04-03T05:49:08.874Z","avatar_url":"https://github.com/taskcluster.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg align=\"right\" src=\"http://media.taskcluster.net/logo/logo-96x120.png\" /\u003e\n\nstateless-dns-go\n================\n\nA go (golang) port of https://github.com/taskcluster/stateless-dns-server/blob/master/index.js\n\n[![GoDoc](https://godoc.org/github.com/taskcluster/stateless-dns-go?status.svg)](https://godoc.org/github.com/taskcluster/stateless-dns-go)\n[![Build Status](https://travis-ci.org/taskcluster/stateless-dns-go.svg?branch=master)](http://travis-ci.org/taskcluster/stateless-dns-go)\n[![Coverage Status](https://coveralls.io/repos/taskcluster/stateless-dns-go/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/taskcluster/stateless-dns-go?branch=master)\n[![License](https://img.shields.io/badge/license-MPL%202.0-orange.svg)](https://github.com/taskcluster/stateless-dns-go/blob/master/LICENSE)\n\nstateless-dns-go provides:\n\n* A go (golang) package for generating client dns names that can be used in\n  conjunction with https://github.com/taskcluster/stateless-dns-server, that\n  can be directly imported in go applications\n* A command line utility to expose the features of the library, which can be\n  called from any language\n\nDomains generated by this library encode an IP-address, expiration date, a\nrandom salt and an HMAC-SHA256 signature truncated to 128 bits.\n\nThis provides a mechanism to assign temporary sub-domains names to nodes with a\npublic IP-address. The same problem can also be solved with dynamic DNS server,\nbut such entries often requires clean-up. The beauty of this approach is that\nthe DNS server is state-less, so there is no stale DNS records to discard.\n\nIn Taskcluster this is used to assign temporary sub-domain names to EC2 spot\nnodes, such that we can host HTTPS resources, such as live logs, without\nupdating and cleaning up the state of the DNS server.\n\nNotice, that with IP-address, expiration date, random salt and HMAC-SHA256\nsignature encoded in the sub-domain label, you cannot decide which sub-domain\nlabel you wish to have. Hence, this is only useful in cases were the hostname\nfor your node is transmitted to clients by other means, for example in a\nmessage over RabbitMQ or as temporary entry in a database. Further more, to\nserve HTTPS content you'll need a wild-card SSL certificate, for domain managed\nby this DNS server.\n\nNote, this obviously doesn't have many applications, as the sub-domain label is\nstateful. It's mostly for serving HTTPS content from nodes that come and go\nquickly with minimal setup, where the hostname is transmitted by other means.\nGenerally, any case where you might consider using the default EC2 hostname.\n\nSub-domain Label Generation\n---------------------------\nThe sub-domain label encodes the following parameters:\n * `ip`, address to which the `A` record returned should point,\n * `expires`, expiration of sub-domain as number of ms since epoch,\n * `salt`, random salt, allowing for generation of multiple sub-domain labels\n   for each IP-address, and,\n * `signature`, HMAC-SHA256 signature of `ip`, `expires` and `salt` truncated\n   to 128 bit.\n\nThe `expires` property is encoded as a big-endian 64 bit signed integer. The\n`salt` property is encoded as bit-endian 16 bit unsigned integer. All\nproperties are concatenated and base32 (RFC 3548) encoded to form the\nsub-domain label.\n\n\nGo library usage\n----------------\n\nHere is a trivial example:\n\n```go\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/taskcluster/stateless-dns-go/hostname\"\n)\n\nfunc PrintHostname() {\n\tip := net.IPv4(byte(203), byte(43), byte(55), byte(2))\n\tsubdomain := \"foo.com\"\n\texpires := time.Now().Add(15 * time.Minute)\n\tsecret := \"turnip-4tea-2nite\"\n\tname := hostname.New(ip, subdomain, expires, secret)\n\tfmt.Printf(\"Hostname: '%s'\\n\", name)\n}\n```\n\nInstalling command line tool\n----------------------------\n\n__Binary installation__\n\nDownload the create-hostname and/or decode-hostname command line tools for your\nplatform from [here](https://github.com/taskcluster/stateless-dns-go/releases).\nIf running on Mac or Linux, make sure to make the binary download executable:\n\n```\n$ chmod a+x '\u003cdownloaded file\u003e'\n```\n\n__Source installation__\n\nRequirements:\n\n  * go (golang) v1.17 or higher\n  * `$(go env GOPATH)/bin` is in your path\n\nRun:\n\n```\ngo install github.com/taskcluster/stateless-dns-go/...@latest\n```\n\nCommand line usage\n------------------\n\nCreating hostnames...\n\n```\nUsage:\n  create-hostname --ip IP --subdomain SUBDOMAIN --expires EXPIRES --secret SECRET\n  create-hostname -h|--help\n  create-hostname --version\n\nExit Codes:\n   0: Success\n   1: Unrecognised command line options\n  64: Invalid IP given\n  65: IP given was an IPv6 IP (IP should be an IPv4 IP)\n  66: Invalid SUBDOMAIN given\n  67: Invalid EXPIRES given\n  68: Invalid SECRET given\n\nExample:\n  $ create-hostname --ip 203.115.35.2 --subdomain foo.com --expires 2016-06-04T16:04:03.739Z --secret 'cheese monkey'\n  znzsgaqaaaavkhbigan6of6sjltgr47okqtriauwfs3agzkj.foo.com\n```\n\nDecoding hostnames...\n\n```\nUsage:\n  decode-hostname --fqdn FQDN --subdomain SUBDOMAIN [ --secret SECRET ]\n  decode-hostname --help|-h\n  decode-hostname --version\n\nExit Codes:\n   0: Success\n   1: Unrecognised command line options\n\nExamples:\n  $ decode-hostname --fqdn aebagbaaaaadqfbf6nanb2v3zyzdeq27biltfievlqaktog2.foo.com --subdomain foo.com --secret 'Happy Birthday Pete!'\n  2017/01/10 18:50:08 IP: 1.2.3.4\n  2017/01/10 18:50:08 Expires: 1977-08-19 16:30:00 +0000 UTC\n  2017/01/10 18:50:08 Salt: [2]uint8{0xd0, 0xea}\n  $ decode-hostname --fqdn aebagbaaaaadqfbf6nanb2v3zyzdeq27biltfievlqaktog2.foo.com --subdomain foo.com\n  2017/01/10 18:50:08 IP: 1.2.3.4\n  2017/01/10 18:50:08 Expires: 1977-08-19 16:30:00 +0000 UTC\n  2017/01/10 18:50:08 Salt: [2]uint8{0xd0, 0xea}\n  2017/01/10 18:50:08 NO SECRET GIVEN TO VERIFY SIGNATURE !!\n```\n\nLicense\n-------\nThe stateless-dns-go library is released on the MPL 2.0 license, see file\n`LICENSE` for the complete license.\n\nTesting\n-------\n\n```bash\ngo test ./...\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaskcluster%2Fstateless-dns-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftaskcluster%2Fstateless-dns-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaskcluster%2Fstateless-dns-go/lists"}