Преглед изворни кода

Added -interface flag. Uses network interface IP address in server entry dat file.
If no interface IP can be found, uses -ipaddress.

mfallone пре 9 година
родитељ
комит
9faaa50056
2 измењених фајлова са 48 додато и 1 уклоњено
  1. 8 0
      Server/main.go
  2. 40 1
      psiphon/server/config.go

+ 8 - 0
Server/main.go

@@ -32,6 +32,7 @@ import (
 func main() {
 
 	var generateServerIPaddress, newConfigFilename, newServerEntryFilename string
+	var networkInterface string
 	var generateWebServerPort, generateSSHServerPort, generateObfuscatedSSHServerPort int
 	var runConfigFilenames stringListFlag
 
@@ -47,6 +48,12 @@ func main() {
 		server.SERVER_ENTRY_FILENAME,
 		"generate new server entry with this `filename`")
 
+	flag.StringVar(
+		&networkInterface,
+		"interface",
+		"",
+		"generate server entry with this `network-interface`")
+
 	flag.StringVar(
 		&generateServerIPaddress,
 		"ipaddress",
@@ -97,6 +104,7 @@ func main() {
 		configFileContents, serverEntryFileContents, err := server.GenerateConfig(
 			&server.GenerateConfigParams{
 				ServerIPAddress:         generateServerIPaddress,
+				ServerNetworkInterface:  networkInterface,
 				WebServerPort:           generateWebServerPort,
 				SSHServerPort:           generateSSHServerPort,
 				ObfuscatedSSHServerPort: generateObfuscatedSSHServerPort,

+ 40 - 1
psiphon/server/config.go

@@ -62,6 +62,7 @@ const (
 	REDIS_POOL_MAX_IDLE                    = 50
 	REDIS_POOL_MAX_ACTIVE                  = 1000
 	REDIS_POOL_IDLE_TIMEOUT                = 5 * time.Minute
+	DEFAULT_NETWORK_INTERFACE              = "lo"
 )
 
 // TODO: break config into sections (sub-structs)
@@ -355,6 +356,10 @@ type GenerateConfigParams struct {
 	// ServerIPAddress is the public IP address of the server.
 	ServerIPAddress string
 
+	// ServerNetworkInterface is the (optional) nic to expose the server on
+	// when running in unprivileged mode but want to allow external clients to connect.
+	ServerNetworkInterface string
+
 	// WebServerPort is the listening port of the web server.
 	// When <= 0, no web server component is run.
 	WebServerPort int
@@ -453,6 +458,14 @@ func GenerateConfig(params *GenerateConfigParams) ([]byte, []byte, error) {
 		return nil, nil, psiphon.ContextError(err)
 	}
 
+	// Find IP address of the network interface (if not loopback)
+	serverNetworkInterface := params.ServerNetworkInterface
+	serverNetworkInterfaceIP, err := getNetworkInterfaceIP(serverNetworkInterface)
+	if err != nil {
+		serverNetworkInterfaceIP = serverIPaddress
+		fmt.Printf("Could not find IP address of nic.  Falling back to %s\n", serverIPaddress)
+	}
+
 	// Assemble config and server entry
 
 	config := &Config{
@@ -492,7 +505,7 @@ func GenerateConfig(params *GenerateConfigParams) ([]byte, []byte, error) {
 	}
 
 	serverEntry := &psiphon.ServerEntry{
-		IpAddress:            serverIPaddress,
+		IpAddress:            serverNetworkInterfaceIP,
 		WebServerPort:        fmt.Sprintf("%d", webServerPort),
 		WebServerSecret:      webServerSecret,
 		WebServerCertificate: strippedWebServerCertificate,
@@ -577,3 +590,29 @@ func generateWebServerCertificate() (string, string, error) {
 
 	return string(webServerCertificate), string(webServerPrivateKey), nil
 }
+
+func getNetworkInterfaceIP(networkInterface string) (string, error) {
+	iface, err := net.InterfaceByName(networkInterface)
+	if err != nil {
+		return "", psiphon.ContextError(err)
+	}
+
+	addrs, err := iface.Addrs()
+	if err != nil {
+		return "", psiphon.ContextError(err)
+	}
+	for _, addr := range addrs {
+		var ip net.IP
+		switch t := addr.(type) {
+		case *net.IPNet:
+			ip = t.IP
+		}
+		ip = ip.To4()
+		if ip == nil {
+			continue
+		}
+		return ip.String(), nil
+	}
+
+	return "", psiphon.ContextError(errors.New("Could not find IP address of specified interface"))
+}