From 85e466698f6fc58d8e53b8c2ade58ee6a5f93270 Mon Sep 17 00:00:00 2001 From: Khanh Ngo Date: Mon, 20 Apr 2020 16:50:50 +0700 Subject: [PATCH] Get Endpoint Address for suggestion form --- go.mod | 1 + go.sum | 2 + handler/routes.go | 22 +++++++++++ main.go | 1 + model/misc.go | 7 ++++ templates/global_settings.html | 66 ++++++++++++++++++++++++++++++++- util/util.go | 67 ++++++++++++++++++++++++++++++++++ 7 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 model/misc.go diff --git a/go.mod b/go.mod index c2c9d91..b858250 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/ngoduykhanh/wireguard-ui go 1.14 require ( + github.com/glendc/go-external-ip v0.0.0-20170425150139-139229dcdddd github.com/go-playground/universal-translator v0.17.0 // indirect github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 // indirect github.com/labstack/echo/v4 v4.1.16 diff --git a/go.sum b/go.sum index 803f7a8..dddb22a 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/glendc/go-external-ip v0.0.0-20170425150139-139229dcdddd h1:1BzxHapafGJd/XlpMvocLeDBin2EKn90gXv2AQt5sfo= +github.com/glendc/go-external-ip v0.0.0-20170425150139-139229dcdddd/go.mod h1:o9OoDQyE1WHvYVUH1FdFapy1/rCZHHq3O5wS4VA83ig= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= diff --git a/handler/routes.go b/handler/routes.go index 817e24f..bca9c77 100644 --- a/handler/routes.go +++ b/handler/routes.go @@ -281,3 +281,25 @@ func GlobalSettingSubmit() echo.HandlerFunc { return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Updated global settings successfully"}) } } + +// MachineIPAddresses handler to get local interface ip addresses +func MachineIPAddresses() echo.HandlerFunc { + return func(c echo.Context) error { + // get private ip addresses + interfaceList, err := util.GetInterfaceIPs() + if err != nil { + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot get machine ip addresses"}) + } + + // get public ip address + // TODO: Remove the go-external-ip dependency + publicInterface, err := util.GetPublicIP() + if err != nil { + log.Warn("Cannot get machine public ip address: ", err) + } else { + interfaceList = append(interfaceList, publicInterface) + } + + return c.JSON(http.StatusOK, interfaceList) + } +} diff --git a/main.go b/main.go index aa85b5d..9553c7f 100644 --- a/main.go +++ b/main.go @@ -16,5 +16,6 @@ func main() { app.POST("wg-server/keypair", handler.WireGuardServerKeyPair()) app.GET("/global-settings", handler.GlobalSettings()) app.POST("/global-settings", handler.GlobalSettingSubmit()) + app.GET("/api/machine-ips", handler.MachineIPAddresses()) app.Logger.Fatal(app.Start("127.0.0.1:5000")) } diff --git a/model/misc.go b/model/misc.go new file mode 100644 index 0000000..249cb9f --- /dev/null +++ b/model/misc.go @@ -0,0 +1,7 @@ +package model + +// Interface model +type Interface struct { + Name string `json:"name"` + IPAddress string `json:"ip_address"` +} diff --git a/templates/global_settings.html b/templates/global_settings.html index ed52490..2c4448b 100644 --- a/templates/global_settings.html +++ b/templates/global_settings.html @@ -27,8 +27,15 @@ Global Settings
- +
+ + + + +
@@ -60,6 +67,31 @@ Global Settings
+ + {{end}} {{define "bottom_js"}} @@ -88,6 +120,20 @@ Global Settings } }); } + + function updateEndpointSuggestionIP() { + $.getJSON("/api/machine-ips", null, function(data) { + $("#ip_suggestion option").remove(); + $.each(data, function(index, item) { + $("#ip_suggestion").append( + $("") + .text(item.ip_address + ' on ' + item.name) + .val(item.ip_address) + ); + }); + document.getElementById("btn_use_ip").disabled = false; + }); + } {{end}} \ No newline at end of file diff --git a/util/util.go b/util/util.go index fa1c194..343fa10 100644 --- a/util/util.go +++ b/util/util.go @@ -4,7 +4,9 @@ import ( "fmt" "net" "strings" + "time" + externalip "github.com/glendc/go-external-ip" "github.com/ngoduykhanh/wireguard-ui/model" ) @@ -87,3 +89,68 @@ func ValidateIPAddressList(ips []string) bool { } return true } + +// GetInterfaceIPs to get local machine's interface ip addresses +func GetInterfaceIPs() ([]model.Interface, error) { + // get machine's interfaces + ifaces, err := net.Interfaces() + if err != nil { + return nil, err + } + + var interfaceList = []model.Interface{} + + // get interface's ip addresses + for _, i := range ifaces { + addrs, err := i.Addrs() + if err != nil { + return nil, err + } + 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() { + continue + } + ip = ip.To4() + if ip == nil { + continue + } + + iface := model.Interface{} + iface.Name = i.Name + iface.IPAddress = ip.String() + interfaceList = append(interfaceList, iface) + } + } + return interfaceList, err +} + +// GetPublicIP to get machine's public ip address +func GetPublicIP() (model.Interface, error) { + // set time out to 5 seconds + cfg := externalip.ConsensusConfig{} + cfg.Timeout = time.Second * 5 + consensus := externalip.NewConsensus(&cfg, nil) + + // add trusted voters + consensus.AddVoter(externalip.NewHTTPSource("http://checkip.amazonaws.com/"), 1) + consensus.AddVoter(externalip.NewHTTPSource("http://whatismyip.akamai.com"), 1) + consensus.AddVoter(externalip.NewHTTPSource("http://ifconfig.top"), 1) + + publicInterface := model.Interface{} + publicInterface.Name = "Public" + + ip, err := consensus.ExternalIP() + if err != nil { + publicInterface.IPAddress = "N/A" + } + publicInterface.IPAddress = ip.String() + + return publicInterface, err +}