chore: add docs

pull/2/head
Karan Sharma 2020-12-18 12:10:40 +05:30
parent 81a04b6d93
commit 05914cca9e
8 changed files with 228 additions and 34 deletions

189
README.md
View File

@ -1,6 +1,189 @@
# doggo <!-- PROJECT LOGO -->
<br />
<p align="center">
<h2 align="center">doggo</h2>
<p align="center">
🐶 <i>Command-line DNS client for humans</i>
</p>
<img src="www/static/usage.png" alt="doggo CLI usage">
</p>
_Command-line DNS client written in Golang_ ---
![](www/static/main.png) `doggo` is a modern command-line DNS client (like _dig_) written in Golang. It outputs information in a neat concise manner and supports protocols like DoH, DoT as well.
It's totally inspired from [dog](https://github.com/ogham/dog/) which is written in Rust. I wanted to add some features to it but since I don't know Rust, I found it as a nice oppurtunity
to experiment with writing a DNS Client from scratch in `Go` myself. Hence the name `dog` +`go` => `doggo`.
## Features
- Human readable output - Supports colors and tabular format.
- Supports JSON format - useful for writing scripts.
- Has support for multiple transport protocols:
- DNS over **HTTPS** (DoH)
- DNS over **TLS** (DoT)
- DNS over **TCP**
- DNS over **UDP**
- Supports **ndots** and **search** configurations from `resolv.conf` or command-line arguments.
- Supports multiple resolvers in one go.
- Supports IPv4 **and** IPv6 _both_.
## Installation
### Binary (Recommended)
### Docker
### Snap
## Usage Examples
**Do a simple DNS Lookup for `mrkaran.dev`**
```bash
$ doggo mrkaran.dev
NAME TYPE CLASS TTL ADDRESS NAMESERVER
mrkaran.dev. A IN 20s 13.250.205.9 127.0.0.1:53
mrkaran.dev. A IN 20s 206.189.89.118 127.0.0.1:53
```
**Query MX records for `github.com` using `9.9.9.9` resolver**
```
doggo MX github.com @9.9.9.9
NAME TYPE CLASS TTL ADDRESS NAMESERVER
github.com. MX IN 3600s 10 alt3.aspmx.l.google.com. 9.9.9.9:53
github.com. MX IN 3600s 5 alt1.aspmx.l.google.com. 9.9.9.9:53
github.com. MX IN 3600s 10 alt4.aspmx.l.google.com. 9.9.9.9:53
github.com. MX IN 3600s 5 alt2.aspmx.l.google.com. 9.9.9.9:53
github.com. MX IN 3600s 1 aspmx.l.google.com. 9.9.9.9:53
```
or using _named parameters_:
```bash
$ doggo -t MX -n 9.9.9.9 github.com
NAME TYPE CLASS TTL ADDRESS NAMESERVER
github.com. MX IN 3600s 10 alt3.aspmx.l.google.com. 9.9.9.9:53
github.com. MX IN 3600s 5 alt1.aspmx.l.google.com. 9.9.9.9:53
github.com. MX IN 3600s 10 alt4.aspmx.l.google.com. 9.9.9.9:53
github.com. MX IN 3600s 5 alt2.aspmx.l.google.com. 9.9.9.9:53
github.com. MX IN 3600s 1 aspmx.l.google.com. 9.9.9.9:53
```
**Query DNS records for archive.org using Cloudflare DoH resolver**
```bash
$ doggo archive.org @https://cloudflare-dns.com/dns-query
NAME TYPE CLASS TTL ADDRESS NAMESERVER
archive.org. A IN 41s 207.241.224.2 https://cloudflare-dns.com/dns-query
```
**Query DNS records for internetfreedom.in with JSON output**
```bash
$ doggo internetfreedom.in --json | jq
{
"responses": {
"answers": [
{
"name": "internetfreedom.in.",
"type": "A",
"class": "IN",
"ttl": "22s",
"address": "104.27.158.96",
"rtt": "37ms",
"nameserver": "127.0.0.1:53"
},
{
"name": "internetfreedom.in.",
"type": "A",
"class": "IN",
"ttl": "22s",
"address": "104.27.159.96",
"rtt": "37ms",
"nameserver": "127.0.0.1:53"
},
{
"name": "internetfreedom.in.",
"type": "A",
"class": "IN",
"ttl": "22s",
"address": "172.67.202.77",
"rtt": "37ms",
"nameserver": "127.0.0.1:53"
}
],
"queries": [
{
"name": "internetfreedom.in.",
"type": "A",
"class": "IN"
}
]
}
}
```
**Query DNS records for duckduckgo.com and show RTT (Round Trip Time)**
```bash
$ doggo duckduckgo.com --time
NAME TYPE CLASS TTL ADDRESS NAMESERVER TIME TAKEN
duckduckgo.com. A IN 30s 40.81.94.43 127.0.0.1:53 45ms
```
## Command-line Arguments
![](www/static/help.png)
### Transport Options
URL scheme of the server is used to identify which resolver to use for lookups. If no scheme is specified, defaults to `udp`.
```
@udp:// eg: @1.1.1.1 initiates a UDP resolver for 1.1.1.1:53.
@tcp:// eg: @1.1.1.1 initiates a TCP resolver for 1.1.1.1:53.
@https:// eg: @https://cloudflare-dns.com/dns-query initiates a DOH resolver for Cloudflare DoH server.
@tls:// eg: @1.1.1.1 initiates a DoT resolver for 1.1.1.1:853.
```
### Query Options
```
-q, --query=HOSTNAME Hostname to query the DNS records for (eg mrkaran.dev).
-t, --type=TYPE Type of the DNS Record (A, MX, NS etc).
-n, --nameserver=ADDR Address of a specific nameserver to send queries to (9.9.9.9, 8.8.8.8 etc).
-c, --class=CLASS Network class of the DNS record (IN, CH, HS etc).
```
### Resolver Options
```
--ndots=INT Specify ndots parameter. Takes value from /etc/resolv.conf if using the system namesever or 1 otherwise.
--search Use the search list defined in resolv.conf. Defaults to true. Set --search=false to disable search list.
--timeout Specify timeout (in seconds) for the resolver to return a response.
-4 --ipv4 Use IPv4 only.
-6 --ipv6 Use IPv6 only.
```
### Output Options
```
-J, --json Format the output as JSON.
--color Defaults to true. Set --color=false to disable colored output.
--debug Enable debug logging.
--time Shows how long the response took from the server.
```
---
## Contributing
I'm open to accept feature requests and/or issues. I understand `doggo` is a very new DNS Client in the town and there might be some edge cases I am not handling. Please feel free to open issues if you ever come across such a case.
For now I am focussing more on [planned features](TODO.md) for a **stable** v1.0 release _soon_.
## License
[LICENSE](LICENSE)

22
TODO.md
View File

@ -39,25 +39,18 @@
- [x] Remove urfave/cli in favour of `pflag + koanf` - [x] Remove urfave/cli in favour of `pflag + koanf`
- [x] Flags - Remove uneeded ones - [x] Flags - Remove uneeded ones
## Tests
- [ ] Add tests for Resolvers.
- [ ] Add tests for CLI Output.
## Documentation ## Documentation
- [ ] README - [x] README
- [ ] Usage - [x] Usage
- [ ] Installation - [x] Installation
- [ ] Features - [x] Features
- [ ] Mkdocs init project
- [ ] Custom Index (Landing Page)
## Release Checklist ## Release Checklist
- [ ] Goreleaser - [ ] Goreleaser
- [ ] Snap - [ ] Snap
- [ ] Homebrew - [ ] Homebrew
- [ ] ARM
- [ ] Docker - [ ] Docker
--- ---
# Future Release # Future Release
@ -70,4 +63,7 @@
- [ ] zsh - [ ] zsh
- [ ] fish - [ ] fish
- [ ] Support non RFC Compliant DOH Google response (_ugh_) - [ ] Support non RFC Compliant DOH Google response (_ugh_)
- [ ] Add tests for Resolvers.
- [ ] Add tests for CLI Output.
- [ ] Mkdocs init project
- [ ] Custom Index (Landing Page)

View File

@ -40,7 +40,7 @@ func main() {
// Resolver Options // Resolver Options
f.Int("timeout", 5, "Sets the timeout for a query to T seconds. The default timeout is 5 seconds.") f.Int("timeout", 5, "Sets the timeout for a query to T seconds. The default timeout is 5 seconds.")
f.Bool("search", true, "Use the search list provided in resolv.conf. It sets the `ndots` parameter as well unless overriden by `ndots` flag.") f.Bool("search", true, "Use the search list provided in resolv.conf. It sets the `ndots` parameter as well unless overriden by `ndots` flag.")
f.Int("ndots", 1, "Specify the ndots paramter. Default value is taken from resolv.conf and fallbacks to 1 if ndots statement is missing in resolv.conf") f.Int("ndots", 0, "Specify the ndots paramter. Default value is taken from resolv.conf and fallbacks to 1 if ndots statement is missing in resolv.conf")
f.BoolP("ipv4", "4", false, "Use IPv4 only") f.BoolP("ipv4", "4", false, "Use IPv4 only")
f.BoolP("ipv6", "6", false, "Use IPv6 only") f.BoolP("ipv6", "6", false, "Use IPv6 only")

View File

@ -13,32 +13,48 @@ var appHelpTextTemplate = `{{ "NAME" | color "" "heading" }}:
{{ .Name | color "green" "bold" }} 🐶 {{.Description}} {{ .Name | color "green" "bold" }} 🐶 {{.Description}}
{{ "USAGE" | color "" "heading" }}: {{ "USAGE" | color "" "heading" }}:
{{ .Name | color "green" "" }} [--] {{ "[query options]" | color "yellow" "" }} {{ "[arguments...]" | color "cyan" "" }} {{ .Name | color "green" "bold" }} [--] {{ "[query options]" | color "yellow" "" }} {{ "[arguments...]" | color "cyan" "" }}
{{ "VERSION" | color "" "heading" }}: {{ "VERSION" | color "" "heading" }}:
{{.Version | color "red" "" }} - {{.Date | color "red" ""}} {{.Version | color "red" "" }} - {{.Date | color "red" ""}}
{{ "EXAMPLES" | color "" "heading" }}: {{ "EXAMPLES" | color "" "heading" }}:
{{ .Name | color "green" "" }} {{ "mrkaran.dev" | color "cyan" "" }} Query a domain using defaults {{ .Name | color "green" "bold" }} {{ "mrkaran.dev" | color "cyan" "" }} Query a domain using defaults.
{{ .Name | color "green" "" }} {{ "mrkaran.dev CNAME" | color "cyan" "" }} Looks up for a CNAME record {{ .Name | color "green" "bold" }} {{ "mrkaran.dev CNAME" | color "cyan" "" }} Looks up for a CNAME record.
{{ .Name | color "green" "" }} {{ "mrkaran.dev MX @9.9.9.9" | color "cyan" "" }} Uses a custom DNS resolver {{ .Name | color "green" "bold" }} {{ "mrkaran.dev MX @9.9.9.9" | color "cyan" "" }} Uses a custom DNS resolver.
{{ .Name | color "green" "" }} {{"-q mrkaran.dev -t MX -n 1.1.1.1" | color "yellow" ""}} Using named arguments {{ .Name | color "green" "bold" }} {{"-q mrkaran.dev -t MX -n 1.1.1.1" | color "yellow" ""}} Using named arguments.
{{ "Free Form Arguments" | color "" "heading" }}: {{ "Free Form Arguments" | color "" "heading" }}:
Supply hostnames, query types, classes without any flag. For eg: Supply hostnames, query types, classes without any flag. For eg:
{{ .Name | color "green" "" }} {{"mrkaran.dev A @1.1.1.1" | color "cyan" "" }} {{ .Name | color "green" "bold" }} {{"mrkaran.dev A @1.1.1.1" | color "cyan" "" }}
{{ "Transport Options" | color "" "heading" }}:
Based on the URL scheme the correct resolver is chosen.
Fallbacks to UDP resolver if no scheme is present.
{{"@udp://" | color "yellow" ""}} eg: @1.1.1.1 initiates a {{"UDP" | color "cyan" ""}} resolver for 1.1.1.1:53.
{{"@tcp://" | color "yellow" ""}} eg: @1.1.1.1 initiates a {{"TCP" | color "cyan" ""}} resolver for 1.1.1.1:53.
{{"@https://" | color "yellow" ""}} eg: @https://cloudflare-dns.com/dns-query initiates a {{"DOH" | color "cyan" ""}} resolver for Cloudflare DoH server.
{{"@tls://" | color "yellow" ""}} eg: @1.1.1.1 initiates a {{"DoT" | color "cyan" ""}} resolver for 1.1.1.1:853.
{{ "Query Options" | color "" "heading" }}: {{ "Query Options" | color "" "heading" }}:
{{"-q, --query=HOSTNAME" | color "yellow" ""}} Hostname to query the DNS records for {{"-q, --query=HOSTNAME" | color "yellow" ""}} Hostname to query the DNS records for (eg {{"mrkaran.dev" | color "cyan" ""}}).
{{"-t, --type=TYPE" | color "yellow" ""}} Type of the DNS Record (A, MX, NS etc) {{"-t, --type=TYPE" | color "yellow" ""}} Type of the DNS Record ({{"A, MX, NS" | color "cyan" ""}} etc).
{{"-n, --nameserver=ADDR" | color "yellow" ""}} Address of a specific nameserver to send queries to (9.9.9.9, 1.1.1.1 etc) {{"-n, --nameserver=ADDR" | color "yellow" ""}} Address of a specific nameserver to send queries to ({{"9.9.9.9, 8.8.8.8" | color "cyan" ""}} etc).
{{"-c, --class=CLASS" | color "yellow" ""}} Network class of the DNS record (IN, CH, HS etc) {{"-c, --class=CLASS" | color "yellow" ""}} Network class of the DNS record ({{"IN, CH, HS" | color "cyan" ""}} etc).
{{ "Resolver Options" | color "" "heading" }}:
{{"--ndots=INT" | color "yellow" ""}} Specify ndots parameter. Takes value from /etc/resolv.conf if using the system namesever or 1 otherwise.
{{"--search" | color "yellow" ""}} Use the search list defined in resolv.conf. Defaults to true. Set --search=false to disable search list.
{{"--timeout" | color "yellow" ""}} Specify timeout (in seconds) for the resolver to return a response.
{{"-4 --ipv4" | color "yellow" ""}} Use IPv4 only.
{{"-6 --ipv6" | color "yellow" ""}} Use IPv6 only.
{{ "Output Options" | color "" "heading" }}: {{ "Output Options" | color "" "heading" }}:
{{"-J, --json " | color "yellow" ""}} Format the output as JSON {{"-J, --json " | color "yellow" ""}} Format the output as JSON.
{{"--color " | color "yellow" ""}} Defaults to true. Set --color=false to disable colored output {{"--color " | color "yellow" ""}} Defaults to true. Set --color=false to disable colored output.
{{"--debug " | color "yellow" ""}} Enable debug logging {{"--debug " | color "yellow" ""}} Enable debug logging.
{{"--time" | color "yellow" ""}} Shows how long the response took from the server {{"--time" | color "yellow" ""}} Shows how long the response took from the server.
` `
func renderCustomHelp() { func renderCustomHelp() {
@ -67,8 +83,7 @@ func renderCustomHelp() {
case "underline": case "underline":
formatter = formatter.Add(color.Underline) formatter = formatter.Add(color.Underline)
case "heading": case "heading":
formatter = formatter.Add(color.Bold) formatter = formatter.Add(color.Bold, color.Underline)
formatter = formatter.Add(color.Underline)
} }
return formatter.SprintFunc()(str) return formatter.SprintFunc()(str)
}, },

View File

@ -46,7 +46,7 @@ func (hub *Hub) loadNameservers() error {
if err != nil { if err != nil {
return fmt.Errorf("error fetching system default nameserver") return fmt.Errorf("error fetching system default nameserver")
} }
if !hub.QueryFlags.isNdotsSet { if hub.QueryFlags.Ndots == 0 {
hub.QueryFlags.Ndots = ndots hub.QueryFlags.Ndots = ndots
} }
hub.Nameservers = append(hub.Nameservers, ns...) hub.Nameservers = append(hub.Nameservers, ns...)

BIN
www/static/help.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB