Something went wrong. Try again.
sloproxy
Something went wrong. Try again.
4.4 kB · 135 lines
Go
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136// Package util provides helper functions for SSH tunnel instructions and network-related tasks.// This includes detecting the appropriate IP address and printing commands// to help users connect to the local server from a remote machine.package util
import ( "context" "fmt" "io" "net" "net/http" "strings" "time"
log "github.com/sirupsen/logrus")
var ipServices = []string{ "https://api.ipify.org", "https://ifconfig.me/ip", "https://icanhazip.com", "https://ipinfo.io/ip",}
// getPublicIP attempts to retrieve the public IP address from a list of external services.// It iterates through the ipServices and returns the first successful response.//// Returns:// - string: The public IP address as a string// - error: An error if all services fail, nil otherwisefunc getPublicIP() (string, error) { for _, service := range ipServices { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() req, err := http.NewRequestWithContext(ctx, "GET", service, nil) if err != nil { log.Debugf("Failed to create request to %s: %v", service, err) continue }
resp, err := http.DefaultClient.Do(req) if err != nil { log.Debugf("Failed to get public IP from %s: %v", service, err) continue } defer func() { if closeErr := resp.Body.Close(); closeErr != nil { log.Warnf("Failed to close response body from %s: %v", service, closeErr) } }()
if resp.StatusCode != http.StatusOK { log.Debugf("bad status code from %s: %d", service, resp.StatusCode) continue }
ip, err := io.ReadAll(resp.Body) if err != nil { log.Debugf("Failed to read response body from %s: %v", service, err) continue } return strings.TrimSpace(string(ip)), nil } return "", fmt.Errorf("all IP services failed")}
// getOutboundIP retrieves the preferred outbound IP address of this machine.// It uses a UDP connection to a public DNS server to determine the local IP// address that would be used for outbound traffic.//// Returns:// - string: The outbound IP address as a string// - error: An error if the IP address cannot be determined, nil otherwisefunc getOutboundIP() (string, error) { conn, err := net.Dial("udp", "8.8.8.8:80") if err != nil { return "", err } defer func() { if closeErr := conn.Close(); closeErr != nil { log.Warnf("Failed to close UDP connection: %v", closeErr) } }()
localAddr, ok := conn.LocalAddr().(*net.UDPAddr) if !ok { return "", fmt.Errorf("could not assert UDP address type") }
return localAddr.IP.String(), nil}
// GetIPAddress attempts to find the best-available IP address.// It first tries to get the public IP address, and if that fails,// it falls back to getting the local outbound IP address.//// Returns:// - string: The determined IP address (preferring public IPv4)func GetIPAddress() string { publicIP, err := getPublicIP() if err == nil { log.Debugf("Public IP detected: %s", publicIP) return publicIP } log.Warnf("Failed to get public IP, falling back to outbound IP: %v", err) outboundIP, err := getOutboundIP() if err == nil { log.Debugf("Outbound IP detected: %s", outboundIP) return outboundIP } log.Errorf("Failed to get any IP address: %v", err) return "127.0.0.1" // Fallback}
// PrintSSHTunnelInstructions detects the IP address and prints SSH tunnel instructions// for the user to connect to the local OAuth callback server from a remote machine.//// Parameters:// - port: The local port number for the SSH tunnelfunc PrintSSHTunnelInstructions(port int) { ipAddress := GetIPAddress() border := "================================================================================" fmt.Println("To authenticate from a remote machine, an SSH tunnel may be required.") fmt.Println(border) fmt.Println(" Run one of the following commands on your local machine (NOT the server):") fmt.Println() fmt.Printf(" # Standard SSH command (assumes SSH port 22):\n") fmt.Printf(" ssh -L %d:127.0.0.1:%d root@%s -p 22\n", port, port, ipAddress) fmt.Println() fmt.Printf(" # If using an SSH key (assumes SSH port 22):\n") fmt.Printf(" ssh -i <path_to_your_key> -L %d:127.0.0.1:%d root@%s -p 22\n", port, port, ipAddress) fmt.Println() fmt.Println(" NOTE: If your server's SSH port is not 22, please modify the '-p 22' part accordingly.") fmt.Println(border)}