diff --git a/CHANGELOG.md b/CHANGELOG.md
index dfbc51a..367f87b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+
+## [v0.2.0] - 2023-03-03
+### Features
+- now has the option to use a custom [extip server](https://github.com/hrbrmstr/extip-svr)
+
+
## [v0.1.0] - 2023-02-28
### Features
diff --git a/README.md b/README.md
index c467e06..437e376 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,9 @@
Small Golang package/cli that uses special DNS resolvers to return your external IP address.
-Presently it uses Google, OpenDNS, and Akamai. If there is a conflict between the resolver answers a message will be delivered on stderr with the conflicting values.
+By default it uses Google, OpenDNS, and Akamai. If there is a conflict between the resolver answers a message will be delivered on stderr with the conflicting values.
+
+Alternatively, you can specify an [extip server](https://github.com/hrbrmstr/extip-svr) to use. See below for how to do that.
## References
@@ -21,7 +23,40 @@ just build # requires https://github.com/casey/just
go install -ldflags "-s -w" github.com/hrbrmstr/extip@latest
```
-## TODO
+## Options
+
+```
+Lookup external IP address via DNS.
+
+Defaults to using Akamai, OpenDNS, and Google services.
+You can specify an extip server via the following command line options.
+NOTE: Both server and domain should be specified to override default behavior.
+More info about running an extip server can be found at .
+
+extip 0.2.0
+Usage: extip [--server EXTIP_SERVER] [--domain DOMAIN] [--record-type RECORD_TYPE] [--port PORT]
+
+Options:
+ --server EXTIP_SERVER, -s EXTIP_SERVER
+ extip-svr IP/FQDN. e.g., ip.rudis.net [env: EXTIP_SERVER]
+ --domain DOMAIN, -d DOMAIN
+ Domain to use for IP Lookup. e.g., myip.is [env: EXTIP_DOMAIN]
+ --record-type RECORD_TYPE, -r RECORD_TYPE
+ DNS record type to lookup. One of TXT or A. [default: TXT, env: EXTIP_RECORD_TYPE]
+ --port PORT, -p PORT Port extip resolver is listening on. [default: 53, env: EXTIP_PORT]
+ --help, -h display this help and exit
+```
+
+## Usage
+
+Default:
-- [ ] Spruce up the CLI to allow folks to choose from the existing list vs use all of them
-- [ ] Allow folks to specify an endpoint and record type so it can be used with the companion server
+```
+extipsvr
+```
+
+Use an extip server:
+
+```
+extip -s ip.rudis.net -d ip.is
+```
\ No newline at end of file
diff --git a/go.mod b/go.mod
index f405b10..3806e82 100644
--- a/go.mod
+++ b/go.mod
@@ -3,4 +3,6 @@ module github.com/hrbrmstr/extip
go 1.19
require (
+ github.com/alexflint/go-arg v1.4.3 // indirect
+ github.com/alexflint/go-scalar v1.1.0 // indirect
)
diff --git a/go.sum b/go.sum
index e69de29..5dd0ea8 100644
--- a/go.sum
+++ b/go.sum
@@ -0,0 +1,12 @@
+github.com/alexflint/go-arg v1.4.3 h1:9rwwEBpMXfKQKceuZfYcwuc/7YY7tWJbFsgG5cAU/uo=
+github.com/alexflint/go-arg v1.4.3/go.mod h1:3PZ/wp/8HuqRZMUUgu7I+e1qcpUbvmS258mRXkFH4IA=
+github.com/alexflint/go-scalar v1.1.0 h1:aaAouLLzI9TChcPXotr6gUhq+Scr8rl0P9P4PnltbhM=
+github.com/alexflint/go-scalar v1.1.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/justfile b/justfile
index f45bb2c..9413790 100755
--- a/justfile
+++ b/justfile
@@ -11,7 +11,7 @@ set shell := ["zsh", "-cu"]
go build -ldflags "-s -w" -o bin/extip
@run: build
- ./extip
+ ./bin/extip
# Be a good citizen
@fmt:
@@ -25,12 +25,9 @@ set shell := ["zsh", "-cu"]
GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w" -o bin/extip-darwin-amd64 main.go && cd bin && gzip extip-darwin-amd64
GOOS=darwin GOARCH=arm64 go build -ldflags "-s -w" -o bin/extip-darwin-arm64 main.go && cd bin && gzip extip-darwin-arm64
-# release binaries
-@release:
- gh workflow run release-binaries.yml
-
# Check results against dig. Requires dig.
@test: build
[ "$(dig myip.opendns.com @resolver1.opendns.com +short)" = "$(./bin/extip)" ] && echo "Passed OpenDNS test"
[ "$(dig o-o.myaddr.1.google.com @ns1.google.com TXT +short | tr -d '"')" = "$(./bin/extip)" ] && echo "Passed Google test"
- [ "$(dig +short TXT whoami.ds.akahelp.net @$(dig +short +answer NS akamai.com | head -1) | grep ns | sed -e 's/[^0-9\.\:]//g')" = "$(./bin/extip)" ] && echo "Passed Akamai test"
\ No newline at end of file
+ [ "$(dig +short TXT whoami.ds.akahelp.net @$(dig +short +answer NS akamai.com | head -1) | grep ns | sed -e 's/[^0-9\.\:]//g')" = "$(./bin/extip)" ] && echo "Passed Akamai test"
+ [ "$(dig +short TXT myip.is @ip.rudis.net | tr -d '"')" = "$(./bin/extip)" ] && echo "Passed custom extip server test"
\ No newline at end of file
diff --git a/main.go b/main.go
index 7aa0554..29903ec 100644
--- a/main.go
+++ b/main.go
@@ -7,13 +7,17 @@ import (
"net"
"os"
"regexp"
+ "strconv"
"strings"
"time"
+
+ "github.com/alexflint/go-arg"
)
const(
+ version = "0.2.0"
resolverTimeout = 10000
- defaultPort = "53"
+ defaultPort = 53
googleResolver = "ns1.google.com"
openDNSResolver = "resolver1.opendns.com"
@@ -44,13 +48,13 @@ func TrimSuffix(s, suffix string) string {
}
// Setup a specific resovler to use for DNS lookups
-func UseResolver(resolver string) *net.Resolver {
+func UseResolver(resolver string, port int) *net.Resolver {
return &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{Timeout: time.Millisecond * time.Duration(resolverTimeout)}
- return d.DialContext(ctx, network, resolver + ":" + defaultPort)
+ return d.DialContext(ctx, network, resolver + ":" + strconv.Itoa(port))
},
}
@@ -82,7 +86,7 @@ func AkamaiExtIP() ([]string, error) {
return []string{""}, err
}
- r := UseResolver(akamaiResolver)
+ r := UseResolver(akamaiResolver, defaultPort)
txts, err := r.LookupTXT(context.Background(), akamaiHost)
if (err != nil) {
@@ -98,7 +102,7 @@ func AkamaiExtIP() ([]string, error) {
// Get our local, external IP via Google's hack
func GoogleExtIP() ([]string, error) {
- r := UseResolver(googleResolver)
+ r := UseResolver(googleResolver, defaultPort)
txts, err := r.LookupTXT(context.Background(), googleHost)
if (err != nil) {
@@ -112,7 +116,7 @@ func GoogleExtIP() ([]string, error) {
// Get our local, external IP via OpenDNS's hack
func OpenDNSExtIP() ([]string, error) {
- r := UseResolver(openDNSResolver)
+ r := UseResolver(openDNSResolver, defaultPort)
ips, err := r.LookupHost(context.Background(), openDNSHost)
if (err != nil) {
@@ -123,10 +127,63 @@ func OpenDNSExtIP() ([]string, error) {
}
+// Get our local, external IP via custom extip resolver
+func CustomExtIP(resolver string, host string, rectype string, port int) ([]string, error) {
+
+ r := UseResolver(resolver, port)
+
+ var res [](string)
+ var err error
+
+ if (rectype == "A") {
+ res, err = r.LookupHost(context.Background(), host)
+ } else {
+ res, err = r.LookupTXT(context.Background(), host)
+ }
+
+ if (err != nil) {
+ res = []string{""}
+ }
+
+ return res, err
+
+}
+
+type args struct {
+ Server string `arg:"-s,--server,env:EXTIP_SERVER" help:"extip-svr IP/FQDN. e.g., ip.rudis.net" placeholder:"EXTIP_SERVER"`
+ Domain string `arg:"-d,--domain,env:EXTIP_DOMAIN" help:"Domain to use for IP Lookup. e.g., myip.is" placeholder:"DOMAIN"`
+ RecordType string `arg:"-r,--record-type,env:EXTIP_RECORD_TYPE" help:"DNS record type to lookup. One of TXT or A." placeholder:"RECORD_TYPE" default:"TXT"`
+ Port int `arg:"-p,--port,env:EXTIP_PORT" help:"Port extip resolver is listening on." placeholder:"PORT" default:"53"`
+}
+
+func (args) Description() string {
+ return "Lookup external IP address via DNS.\n\nDefaults to using Akamai, OpenDNS, and Google services.\nYou can specify an extip server via the following command line options.\nNOTE: Both server and domain should be specified to override default behavior.\nMore info about running an extip server can be found at .\n"
+}
+
+func (args) Version() string {
+ return "extip " + version
+}
+
// TODO: Make this a proper CLI with cmdline options since we have 3 services
func main() {
-
+
l := log.New(os.Stderr, "", 1)
+
+ var args args
+
+ arg.MustParse(&args)
+
+ if args.Server != "" && args.Domain != "" {
+ custom, cerr := CustomExtIP(args.Server, args.Domain, args.RecordType, args.Port)
+ if (cerr != nil) {
+ l.Println("No DNS resolutions worked.")
+ os.Exit(3)
+ } else {
+ fmt.Println(custom[0])
+ os.Exit(0)
+ }
+
+ }
opendns, oerr := OpenDNSExtIP()
google, gerr := GoogleExtIP()