|
|
|
@ -5,6 +5,7 @@
|
|
|
|
|
package ipnlocal
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"context"
|
|
|
|
|
"encoding/base64"
|
|
|
|
|
"encoding/json"
|
|
|
|
@ -17,6 +18,7 @@ import (
|
|
|
|
|
"net/netip"
|
|
|
|
|
"net/url"
|
|
|
|
|
"os"
|
|
|
|
|
"os/exec"
|
|
|
|
|
"os/user"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"runtime"
|
|
|
|
@ -2495,6 +2497,7 @@ func (b *LocalBackend) checkSSHPrefsLocked(p *ipn.Prefs) error {
|
|
|
|
|
if distro.Get() == distro.QNAP && !envknob.UseWIPCode() {
|
|
|
|
|
return errors.New("The Tailscale SSH server does not run on QNAP.")
|
|
|
|
|
}
|
|
|
|
|
checkSELinux()
|
|
|
|
|
// otherwise okay
|
|
|
|
|
case "darwin":
|
|
|
|
|
// okay only in tailscaled mode for now.
|
|
|
|
@ -4508,11 +4511,26 @@ func (b *LocalBackend) sshServerOrInit() (_ SSHServer, err error) {
|
|
|
|
|
return b.sshServer, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var warnSSHSELinux = health.NewWarnable()
|
|
|
|
|
|
|
|
|
|
func checkSELinux() {
|
|
|
|
|
if runtime.GOOS != "linux" {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
out, _ := exec.Command("getenforce").Output()
|
|
|
|
|
if string(bytes.TrimSpace(out)) == "Enforcing" {
|
|
|
|
|
warnSSHSELinux.Set(errors.New("SELinux is enabled; Tailscale SSH may not work. See https://tailscale.com/s/ssh-selinux"))
|
|
|
|
|
} else {
|
|
|
|
|
warnSSHSELinux.Set(nil)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *LocalBackend) HandleSSHConn(c net.Conn) (err error) {
|
|
|
|
|
s, err := b.sshServerOrInit()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
checkSELinux()
|
|
|
|
|
return s.HandleSSHConn(c)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|