diff --git a/lib/config/configuration.go b/lib/config/configuration.go index 4a9563a94cfdc..da8b3b9a985fb 100644 --- a/lib/config/configuration.go +++ b/lib/config/configuration.go @@ -2907,6 +2907,11 @@ func ConfigureOpenSSH(clf *CommandLineFlags, cfg *servicecfg.Config) error { cfg.SetTokenSecret(clf.TokenSecret) } + // apply --skip-version-check flag. + if clf.SkipVersionCheck { + cfg.SkipVersionCheck = clf.SkipVersionCheck + } + slog.DebugContext(context.Background(), "Disabling all services, only the Teleport OpenSSH service can run during the `teleport join openssh` command") servicecfg.DisableLongRunningServices(cfg) diff --git a/lib/openssh/sshd.go b/lib/openssh/sshd.go index 59bfe990b9efe..4f40760e425d3 100644 --- a/lib/openssh/sshd.go +++ b/lib/openssh/sshd.go @@ -20,7 +20,9 @@ package openssh import ( "bytes" + "context" "fmt" + "log/slog" "os" "os/exec" "path/filepath" @@ -44,8 +46,6 @@ func sshdConfigInclude(dataDir string) string { return fmt.Sprintf("Include %s", filepath.Join(dataDir, sshdConfigFile)) } -const DefaultRestartCommand = "systemctl restart sshd" - const ( // TeleportKey is the name the OpenSSH private key TeleportKey = "ssh_host_teleport_key" @@ -202,10 +202,17 @@ func (b *sshdBackend) restart() error { return trace.Wrap(err) } - cmd := exec.Command("/bin/sh", "-c", b.restartCmd) - if err := cmd.Run(); err != nil { - return trace.Wrap(err, "failed to restart the sshd service") + if b.restartCmd == "" { + if err := defaultRestart(); err != nil { + return trace.Wrap(err, "failed to restart OpenSSH") + } + } else { + cmd := exec.Command("/bin/sh", "-c", b.restartCmd) + if err := cmd.Run(); err != nil { + return trace.Wrap(err, "failed to restart OpenSSH") + } } + return nil } @@ -263,3 +270,31 @@ func checkSSHDConfigAlreadyUpdated(sshdConfigPath, fileContains string) (bool, e } return !strings.Contains(string(contents), fileContains), nil } + +// defaultRestart invokes systemctl to restart the OpenSSH service. Due to varying names +// of OpenSSH services on different distributions both ssh and the sshd service are attempted +// to be restarted if they are active. An error is returned if any of the enabled services fail to be restarted. +func defaultRestart() error { + var restartErrors []error + for _, service := range []string{"ssh", "sshd"} { + sshShowCommand := exec.Command("/bin/sh", "-c", "systemctl show --property=ActiveState "+service+".service") + out, err := sshShowCommand.CombinedOutput() + if err != nil { + return trace.Wrap(err, "listing OpenSSH services") + } + + const activeService = "ActiveState=active" + if !bytes.Equal([]byte(activeService), out) { + slog.DebugContext(context.Background(), "skipping inactive OpenSSH service", "service", service) + continue + } + + slog.DebugContext(context.Background(), "restarting active OpenSSH service", "service", service) + restartCommand := exec.Command("/bin/sh", "-c", "systemctl restart "+service) + if err := restartCommand.Run(); err != nil { + restartErrors = append(restartErrors, err) + } + } + + return trace.NewAggregate(restartErrors...) +} diff --git a/tool/teleport/common/teleport.go b/tool/teleport/common/teleport.go index 39e6007d5bf15..7bcf52e6939b0 100644 --- a/tool/teleport/common/teleport.go +++ b/tool/teleport/common/teleport.go @@ -50,7 +50,6 @@ import ( "github.com/gravitational/teleport/lib/defaults" dtconfig "github.com/gravitational/teleport/lib/devicetrust/config" "github.com/gravitational/teleport/lib/modules" - "github.com/gravitational/teleport/lib/openssh" "github.com/gravitational/teleport/lib/selinux" "github.com/gravitational/teleport/lib/service" "github.com/gravitational/teleport/lib/service/servicecfg" @@ -492,12 +491,15 @@ func Run(options Options) (app *kingpin.Application, executedCommand string, con joinOpenSSH.Flag("data-dir", fmt.Sprintf("Path to directory to store teleport data [%v].", defaults.DataDir)).Default(defaults.DataDir).StringVar(&ccf.DataDir) joinOpenSSH.Flag("restart-sshd", "Restart OpenSSH.").Default("true").BoolVar(&ccf.RestartOpenSSH) joinOpenSSH.Flag("sshd-check-command", "Command to use when checking OpenSSH config for validity. (sshd -t -f )").Default("sshd -t -f").StringVar(&ccf.CheckCommand) - joinOpenSSH.Flag("sshd-restart-command", "Command to use when restarting openssh.").Default(openssh.DefaultRestartCommand).StringVar(&ccf.RestartCommand) + joinOpenSSH.Flag("sshd-restart-command", "Command to use when restarting openssh.").StringVar(&ccf.RestartCommand) joinOpenSSH.Flag("labels", "Comma-separated list of labels for this OpenSSH node, for example env=dev,app=web.").StringVar(&ccf.Labels) joinOpenSSH.Flag("address", "Hostname or IP address of this OpenSSH node.").StringVar(&ccf.Address) joinOpenSSH.Flag("additional-principals", "Additional principal to include, can be specified multiple times.").StringVar(&ccf.AdditionalPrincipals) joinOpenSSH.Flag("insecure", "Insecure mode disables certificate validation.").BoolVar(&ccf.InsecureMode) - + joinOpenSSH.Flag("skip-version-check", + "Skip version checking between server and client."). + Default("false"). + BoolVar(&ccf.SkipVersionCheck) joinOpenSSH.Flag("debug", "Enable verbose logging to stderr.").Short('d').BoolVar(&ccf.Debug) integrationCmd := app.Command("integration", "Integration commands")