diff --git a/prog/weaveproxy/main.go b/prog/weaveproxy/main.go index 36d1db9d5f..5c2431066c 100644 --- a/prog/weaveproxy/main.go +++ b/prog/weaveproxy/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "log" "os" "strings" @@ -11,8 +12,7 @@ import ( ) var ( - version = "(unreleased version)" - defaultListenAddrs = []string{"tcp://0.0.0.0:12375", "unix:///var/run/weave.sock"} + version = "(unreleased version)" ) type listOpts struct { @@ -50,7 +50,7 @@ func main() { mflag.BoolVar(&justVersion, []string{"#version", "-version"}, false, "print version and exit") mflag.StringVar(&logLevel, []string{"-log-level"}, "info", "logging level (debug, info, warning, error)") - ListVar(&c.ListenAddrs, []string{"H"}, defaultListenAddrs, "addresses on which to listen") + ListVar(&c.ListenAddrs, []string{"H"}, nil, "addresses on which to listen") mflag.StringVar(&c.HostnameMatch, []string{"-hostname-match"}, "(.*)", "Regexp pattern to apply on container names (e.g. '^aws-[0-9]+-(.*)$')") mflag.StringVar(&c.HostnameReplacement, []string{"-hostname-replacement"}, "$1", "Expression to generate hostnames based on matches from --hostname-match (e.g. 'my-app-$1')") mflag.BoolVar(&c.NoDefaultIPAM, []string{"#-no-default-ipam", "-no-default-ipalloc"}, false, "do not automatically allocate addresses for containers without a WEAVE_CIDR") @@ -69,12 +69,14 @@ func main() { os.Exit(0) } + SetLogLevel(logLevel) + + loadDefaultListenAddr(&c) + if c.WithDNS && c.WithoutDNS { Log.Fatalf("Cannot use both '--with-dns' and '--without-dns' flags") } - SetLogLevel(logLevel) - Log.Infoln("weave proxy", version) Log.Infoln("Command line arguments:", strings.Join(os.Args[1:], " ")) @@ -85,3 +87,44 @@ func main() { p.ListenAndServe() } + +func loadDefaultListenAddr(c *proxy.Config) { + if len(c.ListenAddrs) > 0 { + return + } + + tlsEnabled := (os.Getenv("DOCKER_CLIENT_TLS_VERIFY") != "") + + clientArgs := strings.Fields(os.Getenv("DOCKER_CLIENT_ARGS")) + filteredArgs := []string{} + for i := 0; i < len(clientArgs); i++ { + arg := strings.SplitN(clientArgs[i], "=", 2) + switch arg[0] { + case "-tls", "--tls", "-tlsverify", "--tlsverify": + tlsEnabled = true + case "-H", "--host": + filteredArgs = append(filteredArgs, clientArgs[i]) + if !strings.Contains(clientArgs[i], "=") { + if i++; i < len(clientArgs) { + filteredArgs = append(filteredArgs, clientArgs[i]) + } + } + } + } + + if tlsEnabled { + log.Fatalln("Cannot autoconfigure the proxy when using TLS. Please specify -H") + } + + host := os.Getenv("DOCKER_CLIENT_HOST") + f := &mflag.FlagSet{} + f.StringVar(&host, []string{"H", "-host"}, host, "") + if err := f.Parse(filteredArgs); err != nil { + log.Fatalf("Error configuring proxy: %s", err) + } + + c.ListenAddrs = []string{"tcp://0.0.0.0:12375"} + if host == "" || strings.HasPrefix(host, "unix://") { + c.ListenAddrs = []string{"unix:///var/run/weave.sock"} + } +} diff --git a/site/proxy.md b/site/proxy.md index 8e55b99acf..92fbf4ac64 100644 --- a/site/proxy.md +++ b/site/proxy.md @@ -36,13 +36,18 @@ The first form is more convenient, however you can only pass proxy related configuration arguments to `launch-proxy` so if you need to modify the default behaviour you will have to use the latter. -By default, the proxy listens on /var/run/weave.sock and port 12375, on -all network interfaces. This can be adjusted with the `-H` argument, e.g. +By default, the proxy decides where to listen based on how the +launching client connects to docker. If the launching client connected +over a unix socket, the proxy will listen on /var/run/weave.sock. If +the launching client connected over TCP, the proxy will listen on port +12375, on all network interfaces. This can be adjusted with the `-H` +argument, e.g. host1$ weave launch-proxy -H tcp://127.0.0.1:9999 -Multiple -H arguments can be specified. If you are working with a remote -docker daemon, then any firewalls inbetween need to be configured to permit +If you are connecting via TLS, you will need to specify `-H`. Multiple +-H arguments can be specified. If you are working with a remote docker +daemon, then any firewalls inbetween need to be configured to permit access to the proxy port. All docker commands can be run via the proxy, so it is safe to adjust diff --git a/test/690_proxy_autoconfig_test.sh b/test/690_proxy_autoconfig_test.sh new file mode 100755 index 0000000000..4cd36890fd --- /dev/null +++ b/test/690_proxy_autoconfig_test.sh @@ -0,0 +1,29 @@ +#! /bin/bash + +. ./config.sh + +start_suite "Boot the proxy should only listen on client's interface" + +# Booting it over unix socket listens on unix socket +run_on $HOST1 sudo weave launch-proxy +assert_raises "run_on $HOST1 sudo docker -H unix:///var/run/weave.sock ps" +assert_raises "proxy docker_on $HOST1 ps" 1 +weave_on $HOST1 stop-proxy + +# Booting it over tcp listens on tcp +weave_on $HOST1 launch-proxy +assert_raises "run_on $HOST1 sudo docker -H unix:///var/run/weave.sock ps" 1 +assert_raises "proxy docker_on $HOST1 ps" +weave_on $HOST1 stop-proxy + +# Booting it over tls errors +assert_raises "DOCKER_CLIENT_ARGS='--tls' weave_on $HOST1 launch-proxy" 1 +assert_raises "DOCKER_CERT_PATH='./tls' DOCKER_TLS_VERIFY=1 weave_on $HOST1 launch-proxy" 1 + +# Booting it with a specific -H overrides defaults +weave_on $HOST1 launch-proxy -H unix:///var/run/weave2.sock +assert_raises "run_on $HOST1 sudo docker -H unix:///var/run/weave2.sock ps" +assert_raises "proxy docker_on $HOST1 ps" 1 +weave_on $HOST1 stop-proxy + +end_suite diff --git a/weave b/weave index 8c35df1ee8..992066a025 100755 --- a/weave +++ b/weave @@ -84,6 +84,9 @@ exec_remote() { -e WEAVE_PORT \ -e WEAVE_CONTAINER_NAME \ -e DOCKER_BRIDGE \ + -e DOCKER_CLIENT_ARGS \ + -e DOCKER_CLIENT_TLS_VERIFY="$DOCKER_TLS_VERIFY" \ + -e DOCKER_CLIENT_HOST="$DOCKER_HOST" \ -e PROXY_HOST="$PROXY_HOST" \ -e WEAVE_CIDR=none \ -e COVERAGE \ @@ -1065,6 +1068,9 @@ launch_proxy() { -e PROCFS=/hostproc \ -e WEAVE_CIDR=none \ -e DOCKER_BRIDGE \ + -e DOCKER_CLIENT_ARGS \ + -e DOCKER_CLIENT_TLS_VERIFY="${DOCKER_CLIENT_TLS_VERIFY:-$DOCKER_TLS_VERIFY}" \ + -e DOCKER_CLIENT_HOST="${DOCKER_CLIENT_HOST:-$DOCKER_HOST}" \ --entrypoint=/home/weave/weaveproxy \ $WEAVEPROXY_DOCKER_ARGS $EXEC_IMAGE $PROXY_ARGS) wait_for_log $PROXY_CONTAINER_NAME "proxy listening"