mirror of
https://github.com/dcarrillo/whatismyip.git
synced 2026-07-23 22:45:46 +00:00
4.4 KiB
4.4 KiB
whatismyip
Single-binary Go service: HTTP/TLS/QUIC server that returns the client's IP, geolocation, ASN, headers, TCP port scan, and DNS discovery. Uses gin + httprouter. Requires Go >= 1.25.
Commands
make build # CGO_ENABLED=0 -> ./whatismyip (GOOS/GOARCH for cross-compile)
make build-all # cross-compile all 5 platforms into dist/
make unit-test # go test -count=1 -race -short -cover ./...
make integration-test # requires Docker; runs integration-tests/ module
make test # unit-test + integration-test
make lint # gofmt -l + golangci-lint + shadow (auto-installs tools)
make docker-build # local single-arch build (root Dockerfile)
make docker-run # builds dev image + runs with test DBs, ports :8080 :8081 :9100
Order and quirks: lint -> unit-test -> integration-test. Integration tests use testcontainers-go (needs Docker). They are a separate Go module with its own go.mod — run from the integration-tests/ directory. They use test/Dockerfile (distinct from the root Dockerfile).
Architecture
cmd/whatismyip.go # entrypoint: parses flags, wires servers, runs
├── server/server.go # Manager: Start/Stop/SIGHUP-reload for all server types
├── server/tcp.go # plain HTTP
├── server/tls.go # TLS/HTTP2
├── server/quic.go # HTTP/3 (requires TLS server)
├── server/dns.go # micro-DNS server for discovery
├── server/prometheus.go # separate metrics endpoint
├── router/setup.go # Gin route registration
│ ├── router/generic.go # /, /client-port, /all, /json
│ ├── router/geo.go # /geo/*, /asn/*
│ ├── router/headers.go # /headers, /:header
│ ├── router/dns.go # DNS discovery HTTP handler
│ ├── router/port_scanner.go # /scan/tcp/:port
│ └── router/templates.go # embedded HTML template
├── service/geo.go # GeoIP lookup service (MaxMind MMDB)
├── service/port_scanner.go
├── resolver/setup.go # authoritative micro-DNS server (miekg/dns)
├── internal/setting/ # flag parsing + resolver YAML config
├── internal/httputils/ # header filtering and formatting
├── internal/metrics/ # Prometheus counters/histograms (opt-in)
├── internal/validator/uuid/
├── internal/core/version.go
└── models/geo.go # GeoDB wrapper around oschwald/maxminddb-golang
Key facts
- DNS discovery: enabled via
-resolver test/resolver.yml. The resolver is an authoritative DNS server answering for a subdomain. Clients prove their DNS provider by resolving<uuid>.dns.<domain>. - Geo: both
-geoip2-cityand-geoip2-asnrequired together (or omitted). Uses test DBs intest/. - Trusted headers:
-trusted-header X-Real-IPfor proxy mode. When set without-trusted-port-header, client port shows "unknown". - SIGHUP: reloads GeoIP databases and restarts all servers without full stop.
- HTTP/3: requires
-tls-bind; reuses its port for UDP. - Prometheus: separate process/port via
-metrics-bind. Metrics prefixedwhatismyip_*. - Port scan: enabled by default; disable with
-disable-scan. - Embedded template:
router/templates.gohas the defaulthometemplate.-templateoverrides. - Version: injected at build via
-ldflags="-X 'github.com/dcarrillo/whatismyip/internal/core.Version=${VERSION}'".
Testing quirks
- Integration tests need Docker (testcontainers-go) and will take longer. They run against a real containerized build.
- Unit tests in
internal/setting/,internal/httputils/,internal/metrics/,internal/validator/uuid/,models/,router/, andservice/use test DBs fromtest/. - The router test reads
test/resources by relative path — run from repo root.
Lint
Uses golangci-lint v2 config (.golangci.yaml) with strict revive rules and goimports as formatter. One exception: internal/metrics/ gets a pass on var-naming (package name conflicts with stdlib metrics). Also runs shadow and gofmt -l -d.