GithubHelp home page GithubHelp logo

yaleman / goatns Goto Github PK

View Code? Open in Web Editor NEW
7.0 4.0 0.0 14.53 MB

🐐-powered authoritative DNS server

Home Page: https://goatns.dotgoat.net

License: MIT License

Rust 94.12% Shell 1.65% Dockerfile 0.25% Makefile 0.65% HTML 3.20% CSS 0.02% JavaScript 0.02% Jinja 0.07%
dns goats nameserver regret rust server tokio api oauth2-client oauth2-resource-server

goatns's Introduction

GoatNS

GoatNS Logo

Yet another authoritative DNS name server. But with goat references.

Features

  • DNS over HTTPS (RFC8484) on /dns-query
  • Web API/UI for management
    • OIDC Authentication to the Web UI
    • Token auth for API endpoints

Configuration

Look at zones.json and goatns.example.json for examples.

The configuration file's fields are best found here: https://goatns.dotgoat.net/rustdoc/goatns/config/struct.ConfigFile.html. Note that the ip_allow_list field is a nested map.

Running in Docker

There's a docker container at ghcr.io/yaleman/goatns:latest and a docker-compose.yml file in the repository if that's your thing.

Help?

Found a bug, want to change something, the sky is falling? Create an issue!.

Wondering how something works, need a chat, or are curious there's so many goat references? Discussions are great for that.

Built in Rust

Thanks to some great packages:

Rust Crate Documentation

Auto-generated and available here: https://yaleman.github.io/goatns/rustdoc/goatns

Testing

Rust tests are run using cargo.

cargo test

A handy load testing tool is dnsblast. This'll run 50,000 "valid" queries, 1500 packets per second, to port 15353:

./dnsblast 127.0.0.1 50000 1500 15353

Or if you want to fuzz the server and test that it doesn't blow up:

./dnsblast fuzz 127.0.0.1 50000 1500 15353

Supported request/record types

This list is now in the book.

Additional thanks

goatns's People

Contributors

dependabot[bot] avatar imgbot[bot] avatar yaleman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

goatns's Issues

system stats/metrics

  • a broadcast channel?
  • a stats thread for handling it - maybe multiples
  • in-process storage
    • an in-memory sqlite db for holding them?
    • maybe just a weird struct?
    • maybe allow for periodic persistence?
    • prom stats? otel?
  • stats record maybe
    • clientip
    • zone
    • rrtype
    • rclass
    • a counter for repeats
    • a timestamp - set to 1 second resolution for now, but allow for configuration later?

query for un-owned domains

need to be able to look for these because if ownership-delete works but zone delete or record delete fails, whoops?

axum-csp incompatible http version of axum 0.7.x

With axum 0.7.x they switched to a newer version of http 1.0.0. The HeaderValue are incompatible.

In #405 you try to update the http crate. By why don't you use the http from axum::http. This way you are always compatible with the axum version.

turn the API.gov.au recommendations into tests

https://api.gov.au/sections/api-security.html

Transport Security

  • ALL transport MUST occur over HTTPS using at least TLS 1.2.
  • ALL certificates MUST be from SHA-2 (Secure Hash Algorithm 2) cryptographic hash functions with minimum key length of 2048.
  • ALL publicly accessible endpoints MUST use a Digital Certificate that has been signed by an approved Certificate Authority.
  • Internal facing endpoints MAY use self-signed Digital Certificates.
  • Do not redirect HTTP traffic to HTTPS - reject these requests
  • Unused HTTP methods SHOULD be disabled and return HTTP 405.
  • ALL requests must be validated.

Depending on the security classification you may be required to establish the following controls above and beyond the standard controls:

  • Mutual authentication between the consumer and the API Gateway
  • Mutual authentication between the API Gateway and the back-end API
  • PKI Mutual TLS OAuth Client Authentication Method
  • IP Whitelisting of API Consumers using either API Gateway Policy or Firewall configurations
  • IP Whitelisting of API Publishers using either API Gateway Policy or Firewall configurations
  • Payload encryption while in transit
  • Payload signing for integrity and verification

Abstraction

  • use JSON as an abstraction layer

Rate Limiting

Apply rate limiting and throttling policies to prevent abuse of your API. Ensure appropriate alerts are implemented and respond with informative errors when thresholds are nearing or have been exceeded.

The following headers will be returned when rate limits are in place:

Header Description
X-Rate-Limit-Limit Rate limit ceiling for the given request (for example, 100 messages).
X-Rate-Limit-Remaining Number of requests left for the time window (for example, 45 messages).
X-Rate-Limit-Reset Remaining time window before the rate limit resets in UTC epoch seconds (for example, 1353517297).

Error Handling

When your application displays error messages, it should not expose information that could be used to attack your system. You should establish the following controls when providing error messages:

  • Your API MUST mask any system related errors behind standard HTTP status responses and error messages e.g. do not expose system level information in your error response
  • Your API MUST NOT pass technical details (e.g. call stacks or other internal hints) to the client

Input Validation

  • Input validation is performed to ensure only properly formed data is received by your system, this helps to prevent malicious attacks
  • Input validation should happen as early as possible, preferably as soon as the data is received from the external party
  • Define an appropriate request size limit and reject requests exceeding the limit
  • Validate input: e.g. length / range / format and type
  • Consider logging input validation failures. Assume that someone who is performing hundreds of failed input validations per second has a malicious intent.
  • Constrain string inputs with regular expression where appropriate

Content Type Validation

  • Honour the specified content-type.
  • Reject requests containing unexpected or missing content type headers with HTTP response status 415 Unsupported Media Type.

replace InternalResourceRecord with a struct

struct ResourceRecord {
	ttl: u32
	rclass: RecordClass
	rdata: InternalResourceRecord
}

This lets access to TTL be a lot easier for things like setting them all to minimum etc.

requests that have an empty response, use the SOA minimum as TTL

... if we have, or can find the root zone. otherwise ... some kind of minimum like 60?

DoH and Standard responses probably need this checked, but if/when the data paths for resolution requests are normalized, it can be one clean path... right? right? 😄

login scopes for api tokens

when logging in via the UI or the API, the session should note it and refuse to work for the other thing... because yeah.

session cookies could specify a path? but that might take multiple layers/initializers.

automagically update user details on login

mostly for accounts which are manually created, but it'd be handy to pick up the details on login, or some user-initiated action

currently when manually creating an admin account, the displayname is set to anonymous kid

Support DNS over HTTPS - RFC8484

Methods / Routes

Requirements

  • handle the Accept request header
    • standard response is application/dns-message
    • also respond to application/dns-json?
  • all valid DNS responses get a HTTP/200, even with a DNS message whose DNS rcode indicates failure, such as SERVFAIL or NXDOMAIN.
  • HTTP 406 should come back if the "Accept" type doesn't match a supported one.
  • HTTP 401 is to be used for REFUSED responses.
  • The TTL shall be returned in the cache-control header - eg cache-control = max-age=3709
    • and should be the lowest in an RRSET (but I'm pretty sure that's handled by the datastore responder)
    • and should respect the SOA minimum if it's an empty response
  • maximum size of the DNS message is 65535 bytes.

References

Examples

JSON response

curl -s -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=example.com&type=A' | jq .

{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": true,
  "CD": false,
  "Question": [
    {
      "name": "example.com",
      "type": 1
    }
  ],
  "Answer": [
    {
      "name": "example.com",
      "type": 1,
      "TTL": 74831,
      "data": "93.184.216.34"
    }
  ]
}

"traditional one"

curl -sH 'accept: application/dns-message' 'https://dns.google/dns-query?dns=q80BAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB'  | hexdump -c

0000000   �   � 201 200  \0 001  \0 001  \0  \0  \0  \0 003   w   w   w
0000010  \a   e   x   a   m   p   l   e 003   c   o   m  \0  \0 001  \0
0000020 001   �  \f  \0 001  \0 001  \0  \0   Q   �  \0 004   ]   �   �
0000030   "
0000031

example config creator clap option

It'd be super handy to have a goatns --write-default-config that dumps a bare config file out to stdout or something.

Basically just println!("{}", serde_json::to_string_pretty(ConfigFile::default()))

ZONEMD records - RFC8976

https://www.rfc-editor.org/rfc/rfc8976

Type Value:

The Type value for the ZONEMD RR is 63.

Runs on any class:

The ZONEMD RR is class independent.

Internal repr:

The RDATA of the resource record consists of four fields: Serial, Scheme, Hash Algorithm, and Digest.

Fields:

  • The Serial field is a 32-bit unsigned integer in network byte order. It is the serial number from the zone's SOA record ([RFC1035], Section 3.3.13) for
    which the zone digest was generated.
  • The Scheme field is an 8-bit unsigned integer that identifies the methods by which data is collated and presented as input to the hashing function.
    • Herein, SIMPLE, with Scheme value 1, is the only standardized Scheme defined for ZONEMD records and it MUST be supported by implementations.
    • Scheme values 240-254 are allocated for Private Use.
    • (ie, 1 or 240-254 = ok, else fail)
  • The Hash Algorithm field is an 8-bit unsigned integer that identifies the cryptographic hash algorithm used to construct the digest.
    (ref)
    • Sha384 == 1
      • When SHA384 is used, the size of the Digest field is 48 octets.
    • Sha512 == 2
      • When SHA512 is used, the size of the Digest field is 64 octets.
    • Hash Algorithm values 240-254 are allocated for Private Use.
  • The Digest field MUST NOT be shorter than 12 octets. Digests for the SHA384 and SHA512 hash algorithms specified herein are never truncated. Digests for
    future hash algorithms MAY be truncated but MUST NOT be truncated to a length that results in less than 96 bits (12 octets) of equivalent strength.
    • Min-length check of 12 bytes
  • Display of the ZONEMD field
    • The Serial field is represented as an unsigned decimal integer.
    • The Scheme field is represented as an unsigned decimal integer.
    • The Hash Algorithm field is represented as an unsigned decimal integer.
    • The Digest is represented as a sequence of case-insensitive hexadecimal digits. Whitespace is allowed within the hexadecimal text.
  • Examples

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.