зеркало из https://github.com/mozilla/mig.git
[medium] discover endpoint IP addresses, both local and public (via stun)
This commit is contained in:
Родитель
72a9676dcb
Коммит
9eadf2fe2e
1
Makefile
1
Makefile
|
@ -100,6 +100,7 @@ go_get_deps:
|
|||
$(GOGETTER) camlistore.org/pkg/misc/gpgagent
|
||||
$(GOGETTER) camlistore.org/pkg/misc/pinentry
|
||||
$(GOGETTER) github.com/bobappleyard/readline
|
||||
$(GOGETTER) github.com/ccding/go-stun/stun
|
||||
ifeq ($(OS),windows)
|
||||
$(GOGETTER) code.google.com/p/winsvc/eventlog
|
||||
endif
|
||||
|
|
|
@ -16,6 +16,9 @@ var ISIMMORTAL bool = true
|
|||
// request installing of a service to start the agent at boot
|
||||
var MUSTINSTALLSERVICE bool = true
|
||||
|
||||
// attempt to discover the public IP of the endpoint by querying a STUN server
|
||||
var DISCOVERPUBLICIP = false
|
||||
|
||||
var LOGGINGCONF = mig.Logging{
|
||||
Mode: "stdout", // stdout | file | syslog
|
||||
Level: "debug", // debug | info | ...
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
; Sample MIG Agent configuration file
|
||||
|
||||
[agent]
|
||||
isimmortal = on
|
||||
installservice = on
|
||||
relay = "amqp://guest:guest@localhost:5672/"
|
||||
socket = "127.0.0.1:51664"
|
||||
heartbeatfreq = "300s"
|
||||
moduletimeout = "300s"
|
||||
isimmortal = on
|
||||
installservice = on
|
||||
discoverpublicip = off
|
||||
relay = "amqp://guest:guest@localhost:5672/"
|
||||
socket = "127.0.0.1:51664"
|
||||
heartbeatfreq = "300s"
|
||||
moduletimeout = "300s"
|
||||
|
||||
[certs]
|
||||
ca = "/path/to/ca/cert"
|
||||
|
|
|
@ -23,11 +23,20 @@ type Agent struct {
|
|||
}
|
||||
|
||||
type AgentEnv struct {
|
||||
Init string `json:"init,omitempty"`
|
||||
Ident string `json:"ident,omitempty"`
|
||||
Arch string `json:"arch,omitempty"`
|
||||
IsProxied bool `json:"isproxied"`
|
||||
Proxy string `json:"proxy,omitempty"`
|
||||
Init string `json:"init,omitempty"`
|
||||
Ident string `json:"ident,omitempty"`
|
||||
Arch string `json:"arch,omitempty"`
|
||||
IsProxied bool `json:"isproxied"`
|
||||
Proxy string `json:"proxy,omitempty"`
|
||||
Addresses []string `json:"addresses,omitempty"`
|
||||
NAT NAT `json:"nat,omitempty"`
|
||||
}
|
||||
|
||||
// NAT stores Network Address Translation information of an endpoint
|
||||
type NAT struct {
|
||||
IP string `json:"ip,omitempty"`
|
||||
Result string `json:"result,omitempty"`
|
||||
StunServer string `json:"stunserver,omitempty"`
|
||||
}
|
||||
|
||||
// findHostname retrieves the hostname of the node
|
||||
|
|
|
@ -136,6 +136,18 @@ func Init(foreground, upgrade bool) (ctx Context, err error) {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ctx, err = findLocalIPs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Attempt to discover the public IP by querying a STUN server
|
||||
if DISCOVERPUBLICIP {
|
||||
ctx, err = findNATviaStun(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// find the run directory
|
||||
ctx.Agent.RunDir = getRunDir()
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Contributor:
|
||||
// - Julien Vehent jvehent@mozilla.com [:ulfr]
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"mig"
|
||||
"net"
|
||||
|
||||
"github.com/ccding/go-stun/stun"
|
||||
)
|
||||
|
||||
func findLocalIPs(orig_ctx Context) (ctx Context, err error) {
|
||||
ctx = orig_ctx
|
||||
// grab the local ip addresses
|
||||
addresses, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, addr := range addresses {
|
||||
if addr.String() == "127.0.0.1/8" || addr.String() == "::1/128" {
|
||||
continue
|
||||
}
|
||||
ctx.Agent.Env.Addresses = append(ctx.Agent.Env.Addresses, addr.String())
|
||||
ctx.Channels.Log <- mig.Log{Desc: fmt.Sprintf("Found local address %s", addr.String())}.Debug()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var stunHosts = map[string]int{
|
||||
"stun01.sipphone.com": 3478,
|
||||
"stun.ekiga.net": 3478,
|
||||
"stun.fwdnet.net": 3478,
|
||||
"stun.ideasip.com": 3478,
|
||||
"stun.iptel.org": 3478,
|
||||
"stun.rixtelecom.se": 3478,
|
||||
"stun.schlund.de": 3478,
|
||||
"stunserver.org": 3478,
|
||||
"stun.softjoys.com": 3478,
|
||||
"stun.voiparound.com": 3478,
|
||||
"stun.voipbuster.com": 3478,
|
||||
"stun.voipstunt.com": 3478,
|
||||
"stun.voxgratia.org": 3478,
|
||||
"stun.xten.com": 3478,
|
||||
}
|
||||
var maxStunLookups = 3
|
||||
|
||||
func findNATviaStun(orig_ctx Context) (ctx Context, err error) {
|
||||
ctx = orig_ctx
|
||||
ctr := 0
|
||||
for stunSrv, stunPort := range stunHosts {
|
||||
stun.SetServerHost(stunSrv, stunPort)
|
||||
nat, host, err := stun.Discover()
|
||||
if err != nil {
|
||||
ctx.Channels.Log <- mig.Log{Desc: fmt.Sprintf("STUN discovery failed against %s:%d with error '%v'", stunSrv, stunPort, err)}.Debug()
|
||||
}
|
||||
switch nat {
|
||||
case stun.NAT_ERROR:
|
||||
ctx.Agent.Env.NAT.Result = "Test failed"
|
||||
case stun.NAT_UNKNOWN:
|
||||
ctx.Agent.Env.NAT.Result = "Unexpected response from the STUN server"
|
||||
case stun.NAT_BLOCKED:
|
||||
ctx.Agent.Env.NAT.Result = "UDP is blocked"
|
||||
case stun.NAT_FULL:
|
||||
ctx.Agent.Env.NAT.Result = "Full cone NAT"
|
||||
case stun.NAT_SYMETRIC:
|
||||
ctx.Agent.Env.NAT.Result = "Symetric NAT"
|
||||
case stun.NAT_RESTRICTED:
|
||||
ctx.Agent.Env.NAT.Result = "Restricted NAT"
|
||||
case stun.NAT_PORT_RESTRICTED:
|
||||
ctx.Agent.Env.NAT.Result = "Port restricted NAT"
|
||||
case stun.NAT_NONE:
|
||||
ctx.Agent.Env.NAT.Result = "Not behind a NAT"
|
||||
case stun.NAT_SYMETRIC_UDP_FIREWALL:
|
||||
ctx.Agent.Env.NAT.Result = "Symetric UDP firewall"
|
||||
default:
|
||||
ctx.Agent.Env.NAT.Result = "Unknown"
|
||||
}
|
||||
if host != nil {
|
||||
ctx.Agent.Env.NAT.IP = host.Ip()
|
||||
ctx.Agent.Env.NAT.StunServer = fmt.Sprintf("%s:%d", stunSrv, stunPort)
|
||||
break
|
||||
}
|
||||
ctr++
|
||||
if ctr == 3 {
|
||||
ctx.Agent.Env.NAT.Result = "Max lookups reached without results"
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
|
@ -53,8 +53,10 @@ func findOSInfo(orig_ctx Context) (ctx Context, err error) {
|
|||
}()
|
||||
ctx.Agent.OS = runtime.GOOS
|
||||
ctx.Channels.Log <- mig.Log{Desc: fmt.Sprintf("OS is %s", ctx.Agent.OS)}.Debug()
|
||||
|
||||
ctx.Agent.Env.Arch = runtime.GOARCH
|
||||
ctx.Channels.Log <- mig.Log{Desc: fmt.Sprintf("Arch is %s", ctx.Agent.Env.Arch)}.Debug()
|
||||
|
||||
ctx.Agent.Env.Ident, err = getLSBRelease()
|
||||
if err != nil {
|
||||
ctx.Channels.Log <- mig.Log{Desc: fmt.Sprintf("getLSBRelease() failed: %v", err)}.Info()
|
||||
|
@ -64,11 +66,13 @@ func findOSInfo(orig_ctx Context) (ctx Context, err error) {
|
|||
}
|
||||
}
|
||||
ctx.Channels.Log <- mig.Log{Desc: fmt.Sprintf("Ident is %s", ctx.Agent.Env.Ident)}.Debug()
|
||||
|
||||
ctx.Agent.Env.Init, err = getInit()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ctx.Channels.Log <- mig.Log{Desc: fmt.Sprintf("Init is %s", ctx.Agent.Env.Init)}.Debug()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче