blob: f117385d6ec8f9dcb584fad87486bef0c024c6aa (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
package config
import (
"fmt"
"net"
)
// ValidateBindAddr enforces loopback-by-default binding. It returns an error
// when addr resolves to a non-loopback interface and externalAllowed is false,
// so the server fails loud rather than silently exposing itself. Loopback
// addresses (127.0.0.1, ::1, localhost) always pass.
func ValidateBindAddr(addr string, externalAllowed bool) error {
host, _, err := net.SplitHostPort(addr)
if err != nil {
// No port (or malformed): treat the whole string as the host.
host = addr
}
if isLoopbackHost(host) {
return nil
}
if externalAllowed {
return nil
}
return fmt.Errorf(
"refusing to bind non-loopback address %q: set external_bind_allowed = true to override, "+
"but prefer fronting external access with a reverse proxy (Tailscale / Cloudflare Access / Caddy)",
addr,
)
}
// isLoopbackHost reports whether host is a loopback target. An empty host
// (e.g. ":8484") or 0.0.0.0/:: binds all interfaces and is NOT loopback.
func isLoopbackHost(host string) bool {
switch host {
case "localhost":
return true
case "":
return false
}
if ip := net.ParseIP(host); ip != nil {
return ip.IsLoopback()
}
return false
}
|