dashboard,cmd/buildlet,cmd/coordinator: public key auth on windows Enable public key auth for windows buildlets. Previously the username/password was hardcoded. This change enables the `/connect-ssh` http endpoint on the buildlet to setup authorized_keys and uses the coordinator to proxy ssh traffic to the buildlet. Validation: - run local coordinator (with patches to dev env to act like GCE) with changes - build windows buildlet, post to own bucket - execute: gomote -localdev create windows-amd64-2012 ssh -p 2222 user-jrjohnson-windows-amd64-2012-0@127.0.0.1 Fixes golang/go#21247 Change-Id: If7adc7e6296a071d50412d9fa9d46ecd9e6cc3f3 Reviewed-on: https://go-review.googlesource.com/52350 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
diff --git a/cmd/buildlet/buildlet.go b/cmd/buildlet/buildlet.go index a1ed73c..03f5ddb 100644 --- a/cmd/buildlet/buildlet.go +++ b/cmd/buildlet/buildlet.go
@@ -1615,8 +1615,10 @@ switch runtime.GOOS { case "darwin": homeRoot = "/Users" - case "windows", "plan9": + case "plan9": return fmt.Errorf("ssh not supported on %v", runtime.GOOS) + case "windows": + homeRoot = `C:\Users` default: homeRoot = "/home" if runtime.GOOS == "freebsd" { @@ -1657,5 +1659,10 @@ if runtime.GOOS == "freebsd" { exec.Command("/usr/sbin/chown", "-R", sshUser, sshDir).Run() } + if runtime.GOOS == "windows" { + if res, err := exec.Command("icacls.exe", authFile, "/grant", `NT SERVICE\sshd:(R)`).CombinedOutput(); err != nil { + return fmt.Errorf("setting permissions on authorized_keys with: %v\n%s.", err, res) + } + } return nil }
diff --git a/cmd/coordinator/remote.go b/cmd/coordinator/remote.go index ff4ad37..d216b61 100644 --- a/cmd/coordinator/remote.go +++ b/cmd/coordinator/remote.go
@@ -491,8 +491,8 @@ go rb.renew(ctx) sshUser := hostConf.SSHUsername - needsSSHProxyPport := bconf.GOOS() != "plan9" && bconf.GOOS() != "windows" - if sshUser == "" && needsSSHProxyPport { + useLocalSSHProxy := bconf.GOOS() != "plan9" + if sshUser == "" && useLocalSSHProxy { fmt.Fprintf(s, "instance %q host type %q does not have SSH configured\n", inst, hostType) return } @@ -512,7 +512,7 @@ fmt.Fprintf(s, "#\n") var localProxyPort int - if needsSSHProxyPport { + if useLocalSSHProxy { sshConn, err := rb.buildlet.ConnectSSH(sshUser, pubKey) log.Printf("buildlet(%q).ConnectSSH = %T, %v", inst, sshConn, err) if err != nil { @@ -579,18 +579,6 @@ "-o", "StrictHostKeyChecking=no", "-i", sshPrivateKeyFile, sshUser+"@localhost") - case "windows": - // TODO(jrjohnson,bradfitz): figure out SSH public key auth on Windows (ACL issues?) - // and make this path more like the default case agbove. - fmt.Fprintf(s, "# Windows user/pass: gopher/gopher\n") - if ipErr != nil { - fmt.Fprintf(s, "# Failed to get IP out of %q: %v\n", rb.buildlet.IPPort(), err) - return - } - cmd = exec.Command("ssh", - "-o", "UserKnownHostsFile=/dev/null", - "-o", "StrictHostKeyChecking=no", - "gopher@"+ip) case "plan9": fmt.Fprintf(s, "# Plan9 user/pass: glenda/glenda123\n") if ipErr != nil {
diff --git a/dashboard/builders.go b/dashboard/builders.go index ba26b41..b10283e 100644 --- a/dashboard/builders.go +++ b/dashboard/builders.go
@@ -212,18 +212,21 @@ machineType: "n1-highcpu-4", buildletURLTmpl: "http://storage.googleapis.com/$BUCKET/buildlet.windows-amd64", goBootstrapURLTmpl: "https://storage.googleapis.com/$BUCKET/go1.4-windows-amd64.tar.gz", + SSHUsername: "gopher", }, "host-windows-amd64-2012": &HostConfig{ VMImage: "windows-amd64-server-2012r2-v4", machineType: "n1-highcpu-4", buildletURLTmpl: "http://storage.googleapis.com/$BUCKET/buildlet.windows-amd64", goBootstrapURLTmpl: "https://storage.googleapis.com/$BUCKET/go1.4-windows-amd64.tar.gz", + SSHUsername: "gopher", }, "host-windows-amd64-2016": &HostConfig{ VMImage: "windows-amd64-server-2016-v4", machineType: "n1-highcpu-4", buildletURLTmpl: "http://storage.googleapis.com/$BUCKET/buildlet.windows-amd64", goBootstrapURLTmpl: "https://storage.googleapis.com/$BUCKET/go1.4-windows-amd64.tar.gz", + SSHUsername: "gopher", }, "host-darwin-10_8": &HostConfig{ IsReverse: true,