Add the shared packages for the sharks stack

model, tunnel, wg, authtoken, netguard, docker and dotenv, split out of the
original single repository so Hammerhead, Blacktip and Bamboo can live in
their own repos and import them. README extended; LICENSE unchanged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
VeillaxandClaude Sonnet 5.5 committed 2026-10-26 02:41:44 -06:00
1 parent c7c2ae8f8d
commit 2259580adf
16 files changed
+1359 -1

No files matched your search

+107
View File
@@ -0,0 +1,107 @@
// Package netguard decides which network destinations a server-side feature
// may be pointed at. Anything that makes outbound connections on a user's behalf
// (webhooks, mail delivery) must refuse internal addresses by default, or it can
// be used to probe the machine's own network and cloud metadata services.
package netguard
import (
"context"
"errors"
"net"
"net/http"
"strconv"
"time"
)
var internal = func() []*net.IPNet {
var out []*net.IPNet
for _, c := range []string{"0.0.0.0/8", "100.64.0.0/10", "192.0.0.0/24", "198.18.0.0/15", "240.0.0.0/4", "64:ff9b::/96", "2001:db8::/32"} {
_, n, _ := net.ParseCIDR(c)
out = append(out, n)
}
return out
}()
// Blocked reports whether ip is private, loopback, link-local, multicast,
// unspecified, or in a range reserved for carrier-grade NAT (which includes
// the WireGuard tunnel network) and similar.
func Blocked(ip net.IP) bool {
if v4 := ip.To4(); v4 != nil {
ip = v4
}
if ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsMulticast() || ip.IsUnspecified() {
return true
}
for _, n := range internal {
if n.Contains(ip) {
return true
}
}
return false
}
// ErrBlocked is returned when every address a name resolves to is internal.
var ErrBlocked = errors.New("not allowed: that address is on an internal network")
// DialContext resolves the host itself, checks every address, and connects to
// the one it checked, so a name that changes between the check and the
// connection (DNS rebinding) can't slip through.
func DialContext(allowPrivate bool) func(ctx context.Context, network, addr string) (net.Conn, error) {
return func(ctx context.Context, network, addr string) (net.Conn, error) {
host, port, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
var ips []net.IP
if ip := net.ParseIP(host); ip != nil {
ips = []net.IP{ip}
} else {
res, err := net.DefaultResolver.LookupIPAddr(ctx, host)
if err != nil {
return nil, err
}
for _, r := range res {
ips = append(ips, r.IP)
}
}
var last error = errors.New("no addresses")
blocked := false
d := net.Dialer{Timeout: 10 * time.Second}
for _, ip := range ips {
if !allowPrivate && Blocked(ip) {
blocked = true
continue
}
c, err := d.DialContext(ctx, network, net.JoinHostPort(ip.String(), port))
if err == nil {
return c, nil
}
last = err
}
if blocked && !allowPrivate {
return nil, ErrBlocked
}
return nil, last
}
}
// Client is an HTTP client for user-supplied URLs: guarded dialing, a short
// timeout, and no following of redirects (a redirect could point somewhere internal).
func Client(allowPrivate bool) *http.Client {
return &http.Client{
Timeout: 12 * time.Second,
Transport: &http.Transport{DialContext: DialContext(allowPrivate), TLSHandshakeTimeout: 10 * time.Second, DisableKeepAlives: true},
CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse },
}
}
// PortOf is a small helper for URLs without an explicit port.
func PortOf(scheme, port string) string {
if port != "" {
return port
}
if scheme == "https" {
return strconv.Itoa(443)
}
return strconv.Itoa(80)
}