45f75a916c
Bug fixes: - Add applyEnvOverrides to LoadFromBytes (M05) - Set state=failed on compose-up failure in selfupdate (M16) - Clamp usableMB to min 0 in memory check (M22) - Remove "manual" schedule from triggerAllCrossBackups (M23) - Add mmcblk device handling for partition paths (M21) - Fix stripPartition for mmcblk devices (L25) - Fix TruncateStr for UTF-8 and negative maxLen (L05/L06) - Fix AllDone to return false for empty restore plans (L14) - Fix PushOnce to return actual errors (L39) - Restore pending events on save failure in DrainPendingEvents (M03) - Add duplicate check in AddStoragePath (M04) - Call CleanupTempMounts after drive scan (H13) - Log SetStep save errors (M25) Hardening: - Guard scheduler Start() against double-start (M14) - Acquire mutex in scheduler Stop() before reading cancel (L24) - Cap log lines parameter to 10000 (L31) - Require POST for logout (L32) - Use sync.Once for Server.Close() (L49) - Panic on crypto/rand.Read failure in setup CSRF (L40) - Validate Bearer token against Hub API key in CSRF (H16 fix) - Replace custom hasPrefix with strings.HasPrefix (L13) - Replace simpleHash with crc32.ChecksumIEEE (L48) Cleanup: - Remove dead imageName function (L02) - Remove dead detectHostIPViaRoute function (L03) - Rename shadowed copy variable to cp (L07) - Copy DefaultEnabledEvents in GetNotificationPrefs early return (L09) - Update BUGHUNT.md with comprehensive audit results Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
63 lines
1.5 KiB
Go
63 lines
1.5 KiB
Go
package setup
|
|
|
|
import (
|
|
"net"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// DetectLocalIPs returns the host's LAN IP addresses.
|
|
// Inside a Docker container, the network interfaces only show the bridge IP
|
|
// (e.g. 172.18.0.4), which is useless for users. Instead, we:
|
|
// 1. Check HOST_IP env var (set by docker-compose.yml)
|
|
// 2. Fall back to interface enumeration as last resort
|
|
func DetectLocalIPs() []string {
|
|
// Option 1: explicit HOST_IP from environment
|
|
if hostIP := os.Getenv("HOST_IP"); hostIP != "" {
|
|
return []string{hostIP}
|
|
}
|
|
|
|
// Option 2: fallback to interface enumeration (works on bare metal)
|
|
return detectInterfaceIPs()
|
|
}
|
|
|
|
func detectInterfaceIPs() []string {
|
|
ifaces, err := net.Interfaces()
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
var ips []string
|
|
for _, iface := range ifaces {
|
|
// Skip down, loopback, and Docker/container interfaces
|
|
if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
|
|
continue
|
|
}
|
|
name := strings.ToLower(iface.Name)
|
|
if strings.HasPrefix(name, "docker") || strings.HasPrefix(name, "br-") ||
|
|
strings.HasPrefix(name, "veth") || strings.HasPrefix(name, "lo") {
|
|
continue
|
|
}
|
|
|
|
addrs, err := iface.Addrs()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
for _, addr := range addrs {
|
|
var ip net.IP
|
|
switch v := addr.(type) {
|
|
case *net.IPNet:
|
|
ip = v.IP
|
|
case *net.IPAddr:
|
|
ip = v.IP
|
|
}
|
|
if ip == nil || ip.IsLoopback() || ip.To4() == nil {
|
|
continue // skip non-IPv4
|
|
}
|
|
ips = append(ips, ip.String())
|
|
}
|
|
}
|
|
|
|
return ips
|
|
}
|