pkg/sshd/sshd.go (72 lines of code) (raw):

// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package sshd import ( "context" "fmt" "io/ioutil" "log" "os" "os/exec" "github.com/GoogleCloudPlatform/cloud-run-mesh/pkg/mesh" ) // Helpers around sshd, using exec. // Will be used if /usr/bin/sshd is added to the docker image. // WIP: the code is using a built-in sshd, but it may be easier to use the official sshd if present and reduce code size. // The 'special' thing about the built-in is that it's using SSH certificates - but they can also be created as // secrets or provisioned the same way as Istio certs, in files by the agent. var sshdConfig = ` Port 15022 AddressFamily any ListenAddress 0.0.0.0 ListenAddress :: Protocol 2 LogLevel INFO HostKey %s/id_ecdsa PermitRootLogin yes AuthorizedKeysFile %s/authorized_keys PasswordAuthentication no PermitUserEnvironment yes AcceptEnv LANG LC_* PrintMotd no Subsystem sftp /usr/lib/openssh/sftp-server PidFile %s/sshd.pid ` type SSHDConfig struct { Port int } var ( inprocessInit func(sshCM map[string][]byte, ns string) ) func InitDebug(kr *mesh.KRun) { sshCM, err := kr.Cfg.GetSecret(context.Background(), kr.Namespace, "sshdebug") if err != nil { log.Println("SSH debug disabled, missing sshdebug secret ", err) return } if _, err := os.Stat("/usr/sbin/sshd"); os.IsNotExist(err) { if inprocessInit != nil { inprocessInit(sshCM, kr.Namespace) return } log.Println("SSH debug disabled, sshd not installed") return } pwd, _ := os.Getwd() sshd := pwd + "/var/run/secrets/sshd" os.MkdirAll(sshd, 0700) for k, v := range sshCM { err = os.WriteFile(sshd + "/" + k, v, 0700) if err != nil { log.Println("Secret write error", k, err) return } } // /usr/sbin/sshd -p 15022 -e -D -h ~/.ssh/ec-key.pem // -f config // -c host_cert_file // -d debug - only one connection processed // -e debug to stderr // -h or -o HostKey // -p or -o Port // if _, err := os.Stat(sshd + "/sshd_config"); os.IsNotExist(err) { ioutil.WriteFile(sshd+"/sshd_config", []byte(fmt.Sprintf(sshdConfig, sshd, sshd, sshd)), 0700) } cmd := exec.Command("/usr/sbin/sshd", "-f", sshd + "/sshd_config", "-e", "-D") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr kr.Children = append(kr.Children, cmd) go func() { err := cmd.Start() log.Println("sshd exit", "err", err, "state", cmd.ProcessState) }() }