Merge pull request #1460 from gravitl/feature_v0.14.7_ipchecker

move client public ip check to use server
This commit is contained in:
Matthew R Kasun 2022-08-18 15:45:16 -04:00 committed by GitHub
commit a529222bff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 85 additions and 10 deletions

View file

@ -1,2 +0,0 @@
10.0.0.1 testnode.skynet
10.0.0.2 myhost.skynet

View file

@ -24,6 +24,7 @@ var HttpHandlers = []interface{}{
fileHandlers,
serverHandlers,
extClientHandlers,
ipHandlers,
}
// HandleRESTRequests - handles the rest requests

72
controllers/ipservice.go Normal file
View file

@ -0,0 +1,72 @@
package controller
import (
"fmt"
"net"
"net/http"
"strings"
"github.com/gorilla/mux"
)
func ipHandlers(r *mux.Router) {
r.HandleFunc("/api/getip", http.HandlerFunc(getPublicIP)).Methods("GET")
}
func getPublicIP(w http.ResponseWriter, r *http.Request) {
r.Header.Set("Connection", "close")
ip, err := parseIP(r)
if err != nil {
w.WriteHeader(400)
if ip != "" {
w.Write([]byte("ip is invalid: " + ip))
return
} else {
w.Write([]byte("no ip found"))
return
}
} else {
if err != nil {
fmt.Println(err)
}
}
w.WriteHeader(200)
w.Write([]byte(ip))
}
func parseIP(r *http.Request) (string, error) {
// Get Public IP from header
ip := r.Header.Get("X-REAL-IP")
ipnet := net.ParseIP(ip)
if ipnet != nil && !ipIsPrivate(ipnet) {
return ip, nil
}
// If above fails, get Public IP from other header instead
forwardips := r.Header.Get("X-FORWARDED-FOR")
iplist := strings.Split(forwardips, ",")
for _, ip := range iplist {
ipnet := net.ParseIP(ip)
if ipnet != nil && !ipIsPrivate(ipnet) {
return ip, nil
}
}
// If above also fails, get Public IP from Remote Address of request
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return "", err
}
ipnet = net.ParseIP(ip)
if ipnet != nil {
if ipIsPrivate(ipnet) {
return ip, fmt.Errorf("ip is a private address")
}
return ip, nil
}
return "", fmt.Errorf("no ip found")
}
func ipIsPrivate(ipnet net.IP) bool {
return ipnet.IsPrivate() || ipnet.IsLoopback()
}

View file

@ -85,7 +85,7 @@ func JoinNetwork(cfg *config.ClientConfig, privateKey string) error {
if cfg.Node.IsLocal == "yes" && cfg.Node.LocalAddress != "" {
cfg.Node.Endpoint = cfg.Node.LocalAddress
} else {
cfg.Node.Endpoint, err = ncutils.GetPublicIP()
cfg.Node.Endpoint, err = ncutils.GetPublicIP(cfg.Server.API)
}
if err != nil || cfg.Node.Endpoint == "" {
logger.Log(0, "network:", cfg.Network, "error setting cfg.Node.Endpoint.")

View file

@ -56,7 +56,7 @@ func checkin() {
nodeCfg.Node.FirewallInUse = models.FIREWALL_IPTABLES
}
if nodeCfg.Node.IsStatic != "yes" {
extIP, err := ncutils.GetPublicIP()
extIP, err := ncutils.GetPublicIP(nodeCfg.Server.API)
if err != nil {
logger.Log(1, "error encountered checking public ip addresses: ", err.Error())
}

View file

@ -137,9 +137,9 @@ func IsEmptyRecord(err error) bool {
}
// GetPublicIP - gets public ip
func GetPublicIP() (string, error) {
func GetPublicIP(api string) (string, error) {
iplist := []string{"https://ip.server.gravitl.com", "https://ifconfig.me", "https://api.ipify.org", "https://ipinfo.io/ip"}
iplist := []string{"https://ip.client.gravitl.com", "https://ifconfig.me", "https://api.ipify.org", "https://ipinfo.io/ip"}
for network, ipService := range global_settings.PublicIPServices {
logger.Log(3, "User provided public IP service defined for network", network, "is", ipService)
@ -147,6 +147,10 @@ func GetPublicIP() (string, error) {
// prepend the user-specified service so it's checked first
iplist = append([]string{ipService}, iplist...)
}
if api != "" {
api = "https://" + api + "/api/getip"
iplist = append([]string{api}, iplist...)
}
endpoint := ""
var err error

View file

@ -430,20 +430,20 @@ func GetPublicIP() (string, error) {
iplist := []string{"https://ip.server.gravitl.com", "https://ifconfig.me", "https://api.ipify.org", "https://ipinfo.io/ip"}
publicIpService := os.Getenv("PUBLIC_IP_SERVICE")
if publicIpService != "" {
logger.Log(3, "User (environment variable) provided public IP service is", publicIpService)
logger.Log(4, "User (environment variable) provided public IP service is", publicIpService)
// prepend the user-specified service so it's checked first
iplist = append([]string{publicIpService}, iplist...)
} else if config.Config.Server.PublicIPService != "" {
publicIpService = config.Config.Server.PublicIPService
logger.Log(3, "User (config file) provided public IP service is", publicIpService)
logger.Log(4, "User (config file) provided public IP service is", publicIpService)
// prepend the user-specified service so it's checked first
iplist = append([]string{publicIpService}, iplist...)
}
for _, ipserver := range iplist {
logger.Log(3, "Running public IP check with service", ipserver)
logger.Log(4, "Running public IP check with service", ipserver)
client := &http.Client{
Timeout: time.Second * 10,
}
@ -458,7 +458,7 @@ func GetPublicIP() (string, error) {
continue
}
endpoint = string(bodyBytes)
logger.Log(3, "Public IP address is", endpoint)
logger.Log(4, "Public IP address is", endpoint)
break
}
}