Dog – A command-line DNS client written in Rust
github.com
github.com
I've been trying to force myself to use curl --resolve rather than using hosts file entries (where it's suitable) but for some reason I just can't seem to force myself to get into the habit of getent vs dig.
What would save me wasted time is an asterisk next to an entry or a reminder at the bottom of the output (or in stderr) which indicates that there is a hosts file entry which matches, but it was "ignored" (and even what it's value is).
I understand if it's not something you want to support, but it's definitely a pain point for myself and quite a few ops people I've shoulder surfed over the years.
I found this page which has some good examples for getent, if anyone is interested: https://www.commandlinefu.com/commands/using/getent
https://doc.powerdns.com/recursor/manpages/pdns_recursor.1.h...
Assuming for example, one had HOSTS entries
127.0.0.1 localhost
93.184.216.34 example.com
pdns_recursor is listening on 127.0.0.1 and /etc/resolv.conf contains namserver 127.0.0.1, then dig ns example.com
should return "localhost" as the NS RR for example.com so we know the A RR came from /etc/hosts not a.iana-servers.netAdditionally, adding the "--trace=on" option will output debugging info that will tell whether the answer came from "local auth storage", e.g., /etc/hosts
Over on the Rust forum I gave a brief overview of the crates and developer tools I used: https://users.rust-lang.org/t/dog-a-command-line-dns-client/...
Something that puzzles me while using dig(1) is that I don't really understand the +trace output. In my mind it should be rather easy to trace a DNS request, something like: dig A google.com → etc/resolv.conf says your nameserver is X.Y.Z.T → made a query to X.Y.Z.T, it recursed → domain google.com has nameserver ns.a.b. → ADDITIONAL section told us ns.a.b is at X.C.F.G IP → made dns query to X.C.F.G, it told us it was Authoritative and gave RRs [IP1, IP2].
I never quite can get this level of clarity from dig(1), instead, "dig A google.com +trace" gives an output like this: https://gist.github.com/ahmetb/28a3853bef72fbabf4f0d8ac0712a... which makes me think like: what the hell, am I actually hitting root nameservers every time?
If your tool can help developers here, I think it's a major value add.
Trace hits the roots because trace is for tracing the lookups from the root nameservers through the rest of the path. It's in the man page:
+[no]trace
Toggle tracing of the delegation path from the root name servers for the name being looked up. ...If it recursed, then X.Y.Z.T gave you the final response. It doesn't tell you how it arrived at that final response, and it might not even know (it only saves the final response in the cache). The output of dig +trace is the steps a recursive resolver would have to follow if it started from scratch (with a cold cache).
Some others: dust (like du), procs (like ps), zoxide (z), and sd (like sed)
On the downside it has no tabs and fewer typical GUI features like right click.
If you love your emulator I wouldn’t suggest switching.
I've never understood why anyone would want a higher-throughput terminal. Better latency I could see, but throughput? I'm not Commander Data. I can only read so fast. If my shell is dumping text at me faster than my terminal can render, it's because I catted something I shouldn't have.
Only qualm would be line number color contrast being mostly terrible, but I don't really need it as much.
What would be kind of interesting is if it would read vim colorschemes, so your cat output is syntax highlighted like if you were editing it.
This shows how much our old-school Unix tools need an update.
What if all the CLI tools had an option for JSON output and the shell natively supported a query language like `jq`. Then you could pipe commands together:
host -t A example.org --json-out | ping -c1 --json-in .arecords[0] --json-out | echo --json-in .[0].time > outputfile
This assumes the default output would still be the legacy text format. But if the default output changed to JSON then you could get rid of the ugly json-in/out syntax.Don't you know that the output of every tool and the format of every configuration file must have their own unique format?
Not even systemd is allowed to use JSON for config files.
/s
The thing that would make this really useful is a(t least one) global database of serialization formats to be a lingua franca between tools. Designing those formats to be useful cross-platform would be tough, but you could start with a format db that only promises linux compat, and later add bsd, and maybe windows even later.
edit: google had something like this internally, the "protodb", a versioned repository of protobuf definitions so that any other tool could consume your tool's output.
[0] https://elv.sh/
Having to manually specify "you, output JSON! And you, input JSON! and also filter based on this difficult to remember for most people syntax!" would be cumbersome; much easier to have "commandlets" built into the shell to handle this sort of thing in a sort of composable pipeline. For example:
host -t A example.org
| select arecords --limit 1
| ping -c1
| select pings.time --limit 1
| write --append outputfile
As others have said, Powershell supports this, and it's completely awesome to work with. The fact that (assuming proper metadata on the binaries) I can do queries like this is awesome: ~ > Get-Command java -All | Sort-Object Version -Descending
CommandType Name Version Source
----------- ---- ------- ------
Application java.exe 15.0.1.0 C:\Program Files\Java\jdk-15.0.1\bin\java.exe
Application java.exe 11.0.6.0 C:\Program Files\Java\jdk-11.0.6\bin\java.exe
Application java.exe 8.0.2610.… C:\Program Files (x86)\Common Files\Oracle\Java\javapath\java.exe
This lets you, for example, have multiple versions of something installed, and have a script easily and cleanly get a list of all of them and either choose which one to use, or run something on each (e.g. for testing scripts).There are also a lot of "that's weird but handy" features, like being able to interact with environment variables the same way you do local files:
if (Test-Path 'env:GIT_COMMIT') {
echo "GIT_COMMIT is $Env:GIT_COMMIT"
$commit_hash = $Env:GIT_COMMIT
}
Extremely impressed with Microsoft on this implementation. Also worth noting: you can install Powershell on your Linux or macOS systems and use it there as well. Semi-tempted to try implementing things in Powershell as the only cross-platform shell available.I suppose these two could mention each other.
It does look neat when comparing it to the classic output you have in some other tools; not always the easiest to spot the records in then a lot of debug information that looks the same as 'output' information is often stacked on top of each other making it less readable and even without the colouring this looks like a better fit if you simply want to look at some records.
dig github.com ns
; <<>> DiG 9.16.8 <<>> github.com ns
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8592
;; flags: qr rd ra; QUERY: 1, ANSWER: 8, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;github.com. IN NS
;; ANSWER SECTION:
github.com. 46 IN NS dns1.p08.nsone.net.
github.com. 46 IN NS dns2.p08.nsone.net.
github.com. 46 IN NS dns3.p08.nsone.net.
github.com. 46 IN NS dns4.p08.nsone.net.
github.com. 46 IN NS ns-1283.awsdns-32.org.
github.com. 46 IN NS ns-1707.awsdns-21.co.uk.
github.com. 46 IN NS ns-421.awsdns-52.com.
github.com. 46 IN NS ns-520.awsdns-01.net.
dog github.com ns Status: NXDomain
A github.com. 31s 140.82.121.3
SOA 23h58m44s A "a.root-servers.net." "nstld.verisign-grs.com." 2020110900 30m00s 15m00s 7d0h00m00s 1d0h00m00s dog example.com example.net AAAA A
AAAA example.com. 1d0h00m00s 2606:2800:220:1:248:1893:25c8:1946
A example.com. 1d0h00m00s 93.184.216.34
AAAA example.net. 23h45m04s 2606:2800:220:1:248:1893:25c8:1946
A example.net. 23h45m04s 93.184.216.34See also: mutt, tail, sleep, roff
$ dig +short -x 209.216.230.240
news.ycombinator.com.
$ dog PTR 240.230.216.209.in-addr.arpa.
PTR 240.230.216.209.in-addr.arpa. 23h59m44s "news.ycombinator.com."
And yes, I use dig -x quite often.As an example: I sometimes run 'curl ifconfig.me' to get my public IP from the command-line, but I wouldn't expect curl to add an '--ip' option to make this specific query easier to run. curl is a general tool, and the fact that you can use HTTP to get your public IP doesn't mean it needs a top-level option in an HTTP client. (I get that reverse lookup is an internet standard, and ifconfig.me is a third-party service, but still.)
dog 209.216.230.240
should directly perform a PTR lookup instead of requiring something like dog -x 209.216.230.240
Here's how host works when you give it an IP address as opposed to a domain name: $ host 209.216.230.240
240.230.216.209.in-addr.arpa domain name pointer news.ycombinator.com.
$ host news.ycombinator.com
news.ycombinator.com has address 209.216.230.240If it can see that an argument is an IP address and automatically do the PTR lookup for me, even better!
I just tried `cargo build --release --verbose --target x86_64-unknown-linux-musl` with Dog but it uses the `native-tls` Crate that wraps OpenSSL.
It would be great for tools like this to leverage Rustls [0] so one could compile without requiring OpenSSL and be able to compile statically with musl