diff --git a/hack/test-templates.sh b/hack/test-templates.sh index aebbc3957e3..e67b459462f 100755 --- a/hack/test-templates.sh +++ b/hack/test-templates.sh @@ -339,7 +339,7 @@ if [[ -n ${CHECKS["ssh-over-vsock"]} ]]; then INFO "Testing .ssh.overVsock=true configuration" limactl stop "${NAME}" # Detection of the SSH server on VSOCK may fail; however, a failing log indicates that controlling detection via the environment variable works as expected. - if ! limactl start --set '.ssh.overVsock=true' "${NAME}" 2>&1 | grep -i -E "(started vsock forwarder|Failed to detect SSH server on vsock)"; then + if ! limactl start --set '.ssh.overVsock=true' "${NAME}" 2>&1 | grep -i -E "(started vsock forwarder|SSH server does not seem running on vsock port)"; then set +x diagnose "${NAME}" ERROR ".ssh.overVsock=true did not enable vsock forwarder" @@ -348,7 +348,7 @@ if [[ -n ${CHECKS["ssh-over-vsock"]} ]]; then INFO 'Testing .ssh.overVsock=null configuration' limactl stop "${NAME}" # Detection of the SSH server on VSOCK may fail; however, a failing log indicates that controlling detection via the environment variable works as expected. - if ! limactl start --set '.ssh.overVsock=null' "${NAME}" 2>&1 | grep -i -E "(started vsock forwarder|Failed to detect SSH server on vsock)"; then + if ! limactl start --set '.ssh.overVsock=null' "${NAME}" 2>&1 | grep -i -E "(started vsock forwarder|SSH server does not seem running on vsock port)"; then set +x diagnose "${NAME}" ERROR ".ssh.overVsock=null did not enable vsock forwarder" diff --git a/pkg/driver/vz/vm_darwin.go b/pkg/driver/vz/vm_darwin.go index c0014ad5c5a..bfe745ef88c 100644 --- a/pkg/driver/vz/vm_darwin.go +++ b/pkg/driver/vz/vm_darwin.go @@ -116,7 +116,9 @@ func startVM(ctx context.Context, inst *limatype.Instance, sshLocalPort int) (vm logrus.Infof("Detected SSH server is listening on the vsock port; changed %s to proxy for the vsock port", hostAddress) usernetSSHLocalPort = 0 // disable gvisor ssh port forwarding } else { - logrus.WithError(err).Warn("Failed to detect SSH server on vsock port, falling back to usernet forwarder") + logrus.WithError(err).WithField("hostAddress", hostAddress). + Debugf("Failed to start vsock forwarder (systemd is older than v256?)") + logrus.Info("SSH server does not seem running on vsock port, using usernet forwarder") } } else { logrus.WithError(err).Warn("Failed to wait for the guest SSH server to become available, falling back to usernet forwarder") diff --git a/pkg/osutil/osutil_unix.go b/pkg/osutil/osutil_unix.go index cf00ff69237..1aac658567b 100644 --- a/pkg/osutil/osutil_unix.go +++ b/pkg/osutil/osutil_unix.go @@ -8,6 +8,7 @@ package osutil import ( "bytes" "context" + "errors" "fmt" "os" "os/exec" @@ -36,3 +37,7 @@ func Sysctl(ctx context.Context, name string) (string, error) { } return strings.TrimSuffix(string(stdout), "\n"), nil } + +func IsEACCES(err error) bool { + return errors.Is(err, unix.EACCES) +} diff --git a/pkg/osutil/osutil_windows.go b/pkg/osutil/osutil_windows.go index a5ed533d988..c49b23b4ba1 100644 --- a/pkg/osutil/osutil_windows.go +++ b/pkg/osutil/osutil_windows.go @@ -57,3 +57,7 @@ func SignalName(sig os.Signal) string { func Sysctl(_ context.Context, _ string) (string, error) { return "", errors.New("sysctl: unimplemented on Windows") } + +func IsEACCES(err error) bool { + return errors.Is(err, syscall.ERROR_ACCESS_DENIED) || errors.Is(err, syscall.WSAEACCES) +} diff --git a/pkg/portfwd/listener.go b/pkg/portfwd/listener.go index 190a3bd06e0..c4d08794a1e 100644 --- a/pkg/portfwd/listener.go +++ b/pkg/portfwd/listener.go @@ -14,6 +14,8 @@ import ( "sync" "github.com/sirupsen/logrus" + + "github.com/lima-vm/lima/v2/pkg/osutil" ) type ClosableListeners struct { @@ -102,7 +104,7 @@ func (p *ClosableListeners) forwardTCP(ctx context.Context, dialContext func(ctx } tcpLis, err := Listen(ctx, p.listenConfig, hostAddress) if err != nil { - logrus.Errorf("failed to listen to TCP connection: %v", err) + logListenError(err, "tcp", hostAddress) p.listenersRW.Unlock() return } @@ -139,7 +141,7 @@ func (p *ClosableListeners) forwardUDP(ctx context.Context, dialContext func(ctx udpConn, err := ListenPacket(ctx, p.listenConfig, hostAddress) if err != nil { - logrus.Errorf("failed to listen udp: %v", err) + logListenError(err, "udp", hostAddress) p.udpListenersRW.Unlock() return } @@ -162,3 +164,41 @@ func prepareUnixSocket(hostSocket string) error { } return nil } + +func logListenError(err error, proto, hostAddress string) { + var negligibleReason string + if proto != "unix" { + if _, portStr, err := net.SplitHostPort(hostAddress); err == nil { + switch proto { + case "tcp": + //nolint:gocritic // singleCaseSwitch: should rewrite switch statement to if statement + switch portStr { + case "53": + negligibleReason = "DNS port (often conflicts with the system resolver)" + } + case "udp": + switch portStr { + case "53": + negligibleReason = "DNS port (often conflicts with the system resolver)" + case "323": + negligibleReason = "NTP port (often conflicts with the system NTP server)" + case "5353": + negligibleReason = "mDNS port (often conflicts with the system mDNS responder)" + case "5355": + negligibleReason = "LLMNR port (often conflicts with the system LLMNR responder)" + } + } + } + if osutil.IsEACCES(err) { + negligibleReason = "privileged port" + } + } + + if negligibleReason != "" { + logrus.WithError(err).WithField("negligible-reason", negligibleReason).Debugf("failed to listen %s: %s", proto, hostAddress) + logrus.Infof("Not forwarding %s %s", strings.ToUpper(proto), hostAddress) + return + } + + logrus.WithError(err).Warnf("failed to listen %s: %s", proto, hostAddress) +} diff --git a/pkg/portfwd/listener_darwin.go b/pkg/portfwd/listener_darwin.go index ea826f5ad79..b47e1f8f20f 100644 --- a/pkg/portfwd/listener_darwin.go +++ b/pkg/portfwd/listener_darwin.go @@ -22,7 +22,7 @@ func Listen(ctx context.Context, listenConfig net.ListenConfig, hostAddress stri var lc net.ListenConfig unixLis, err := lc.Listen(ctx, "unix", hostAddress) if err != nil { - logrus.WithError(err).Errorf("failed to listen unix: %v", hostAddress) + logListenError(err, "unix", hostAddress) return nil, err } return unixLis, nil @@ -34,14 +34,15 @@ func Listen(ctx context.Context, listenConfig net.ListenConfig, hostAddress stri if !localIP.Equal(IPv4loopback1) || localPort >= 1024 { tcpLis, err := listenConfig.Listen(ctx, "tcp", hostAddress) if err != nil { - logrus.Errorf("failed to listen tcp: %v", err) + logListenError(err, "tcp", hostAddress) return nil, err } return tcpLis, nil } - tcpLis, err := listenConfig.Listen(ctx, "tcp", fmt.Sprintf("0.0.0.0:%d", localPort)) + hostAddressPseudo := net.JoinHostPort("0.0.0.0", localPortStr) + tcpLis, err := listenConfig.Listen(ctx, "tcp", hostAddressPseudo) if err != nil { - logrus.Errorf("failed to listen tcp: %v", err) + logListenError(err, "tcp", hostAddressPseudo) return nil, err } return &pseudoLoopbackListener{tcpLis}, nil @@ -55,14 +56,15 @@ func ListenPacket(ctx context.Context, listenConfig net.ListenConfig, hostAddres if !localIP.Equal(IPv4loopback1) || localPort >= 1024 { udpConn, err := listenConfig.ListenPacket(ctx, "udp", hostAddress) if err != nil { - logrus.Errorf("failed to listen udp: %v", err) + logListenError(err, "udp", hostAddress) return nil, err } return udpConn, nil } - udpConn, err := listenConfig.ListenPacket(ctx, "udp", fmt.Sprintf("0.0.0.0:%d", localPort)) + hostAddressPseudo := net.JoinHostPort("0.0.0.0", localPortStr) + udpConn, err := listenConfig.ListenPacket(ctx, "udp", hostAddressPseudo) if err != nil { - logrus.Errorf("failed to listen udp: %v", err) + logListenError(err, "udp", hostAddressPseudo) return nil, err } return &pseudoLoopbackPacketConn{udpConn}, nil diff --git a/pkg/portfwd/listener_others.go b/pkg/portfwd/listener_others.go index d86619b4c94..9458f1005da 100644 --- a/pkg/portfwd/listener_others.go +++ b/pkg/portfwd/listener_others.go @@ -9,8 +9,6 @@ import ( "context" "net" "path/filepath" - - "github.com/sirupsen/logrus" ) func Listen(ctx context.Context, listenConfig net.ListenConfig, hostAddress string) (net.Listener, error) { @@ -22,7 +20,7 @@ func Listen(ctx context.Context, listenConfig net.ListenConfig, hostAddress stri var lc net.ListenConfig unixLis, err := lc.Listen(ctx, "unix", hostAddress) if err != nil { - logrus.WithError(err).Errorf("failed to listen unix: %v", hostAddress) + logListenError(err, "unix", hostAddress) return nil, err } return unixLis, nil