mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-02 22:35:59 +00:00
safesocket, ipn/ipnserver: look up peer creds on Darwin
And open up socket permissions like Linux, now that we know who connections are from. This uses the new inet.af/peercred that supports Linux and Darwin at the moment. Fixes #1347 Fixes #1348 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
65815cc1ac
commit
d3efe8caf6
@ -63,6 +63,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
|
|||||||
gvisor.dev/gvisor/pkg/tcpip/transport/udp from gvisor.dev/gvisor/pkg/tcpip/adapters/gonet+
|
gvisor.dev/gvisor/pkg/tcpip/transport/udp from gvisor.dev/gvisor/pkg/tcpip/adapters/gonet+
|
||||||
gvisor.dev/gvisor/pkg/waiter from gvisor.dev/gvisor/pkg/tcpip+
|
gvisor.dev/gvisor/pkg/waiter from gvisor.dev/gvisor/pkg/tcpip+
|
||||||
inet.af/netaddr from tailscale.com/control/controlclient+
|
inet.af/netaddr from tailscale.com/control/controlclient+
|
||||||
|
inet.af/peercred from tailscale.com/ipn/ipnserver
|
||||||
rsc.io/goversion/version from tailscale.com/version
|
rsc.io/goversion/version from tailscale.com/version
|
||||||
tailscale.com/atomicfile from tailscale.com/ipn+
|
tailscale.com/atomicfile from tailscale.com/ipn+
|
||||||
tailscale.com/control/controlclient from tailscale.com/ipn/ipnlocal+
|
tailscale.com/control/controlclient from tailscale.com/ipn/ipnlocal+
|
||||||
|
3
go.mod
3
go.mod
@ -32,7 +32,7 @@ require (
|
|||||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
|
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
|
||||||
golang.org/x/sys v0.0.0-20210105210732-16f7687f5001
|
golang.org/x/sys v0.0.0-20210216224549-f992740a1bac
|
||||||
golang.org/x/term v0.0.0-20201207232118-ee85cb95a76b
|
golang.org/x/term v0.0.0-20201207232118-ee85cb95a76b
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
||||||
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58
|
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58
|
||||||
@ -40,5 +40,6 @@ require (
|
|||||||
gvisor.dev/gvisor v0.0.0-20210111185822-3ff3110fcdd6
|
gvisor.dev/gvisor v0.0.0-20210111185822-3ff3110fcdd6
|
||||||
honnef.co/go/tools v0.1.0
|
honnef.co/go/tools v0.1.0
|
||||||
inet.af/netaddr v0.0.0-20210105212526-648fbc18a69d
|
inet.af/netaddr v0.0.0-20210105212526-648fbc18a69d
|
||||||
|
inet.af/peercred v0.0.0-20210216231719-993aa01eacaa
|
||||||
rsc.io/goversion v1.2.0
|
rsc.io/goversion v1.2.0
|
||||||
)
|
)
|
||||||
|
4
go.sum
4
go.sum
@ -461,6 +461,8 @@ golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 h1:+CBz4km/0KPU3RGTwARGh/noP
|
|||||||
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210105210732-16f7687f5001 h1:/dSxr6gT0FNI1MO5WLJo8mTmItROeOKTkDn+7OwWBos=
|
golang.org/x/sys v0.0.0-20210105210732-16f7687f5001 h1:/dSxr6gT0FNI1MO5WLJo8mTmItROeOKTkDn+7OwWBos=
|
||||||
golang.org/x/sys v0.0.0-20210105210732-16f7687f5001/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210105210732-16f7687f5001/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210216224549-f992740a1bac h1:9glrpwtNjBYgRpb67AZJKHfzj1stG/8BL5H7In2oTC4=
|
||||||
|
golang.org/x/sys v0.0.0-20210216224549-f992740a1bac/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20201207232118-ee85cb95a76b h1:a0ErnNnPKmhDyIXQvdZr+Lq8dc8xpMeqkF8y5PgQU4Q=
|
golang.org/x/term v0.0.0-20201207232118-ee85cb95a76b h1:a0ErnNnPKmhDyIXQvdZr+Lq8dc8xpMeqkF8y5PgQU4Q=
|
||||||
@ -576,6 +578,8 @@ inet.af/netaddr v0.0.0-20201228234250-33d0a924ebbf h1:0eHZ8v6j5wIiOVyoYPd70ueZ/R
|
|||||||
inet.af/netaddr v0.0.0-20201228234250-33d0a924ebbf/go.mod h1:9NdhtHLglxJliAZB6aC5ws3mfnUArdAzHG/iJq7cB/o=
|
inet.af/netaddr v0.0.0-20201228234250-33d0a924ebbf/go.mod h1:9NdhtHLglxJliAZB6aC5ws3mfnUArdAzHG/iJq7cB/o=
|
||||||
inet.af/netaddr v0.0.0-20210105212526-648fbc18a69d h1:6f0242aW/6x2enQBOSKgDS8KQNw6Tp7IVR8eG3x0Jc8=
|
inet.af/netaddr v0.0.0-20210105212526-648fbc18a69d h1:6f0242aW/6x2enQBOSKgDS8KQNw6Tp7IVR8eG3x0Jc8=
|
||||||
inet.af/netaddr v0.0.0-20210105212526-648fbc18a69d/go.mod h1:jPZo7Jy4nke2cCgISa4fKJKa5T7+EO8k5fWwWghzneg=
|
inet.af/netaddr v0.0.0-20210105212526-648fbc18a69d/go.mod h1:jPZo7Jy4nke2cCgISa4fKJKa5T7+EO8k5fWwWghzneg=
|
||||||
|
inet.af/peercred v0.0.0-20210216231719-993aa01eacaa h1:6qseJO2iNDHl+MLL2BkO5oURJR4A9pLmRz11Yf7KdGM=
|
||||||
|
inet.af/peercred v0.0.0-20210216231719-993aa01eacaa/go.mod h1:VZeNdG7cRIUqKl9DWoFX86AHyfYwdb4RextAw1CAEO4=
|
||||||
k8s.io/api v0.16.13/go.mod h1:QWu8UWSTiuQZMMeYjwLs6ILu5O74qKSJ0c+4vrchDxs=
|
k8s.io/api v0.16.13/go.mod h1:QWu8UWSTiuQZMMeYjwLs6ILu5O74qKSJ0c+4vrchDxs=
|
||||||
k8s.io/apimachinery v0.16.13/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ=
|
k8s.io/apimachinery v0.16.13/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ=
|
||||||
k8s.io/apimachinery v0.16.14-rc.0/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ=
|
k8s.io/apimachinery v0.16.14-rc.0/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ=
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package ipnserver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
"tailscale.com/types/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
func isReadonlyConn(c net.Conn, logf logger.Logf) (ro bool) {
|
|
||||||
ro = true // conservative default for naked returns below
|
|
||||||
uc, ok := c.(*net.UnixConn)
|
|
||||||
if !ok {
|
|
||||||
logf("unexpected connection type %T", c)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
raw, err := uc.SyscallConn()
|
|
||||||
if err != nil {
|
|
||||||
logf("SyscallConn: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var cred *unix.Ucred
|
|
||||||
cerr := raw.Control(func(fd uintptr) {
|
|
||||||
cred, err = unix.GetsockoptUcred(int(fd),
|
|
||||||
unix.SOL_SOCKET,
|
|
||||||
unix.SO_PEERCRED)
|
|
||||||
})
|
|
||||||
if cerr != nil {
|
|
||||||
logf("raw.Control: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
logf("raw.Control: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cred.Uid == 0 {
|
|
||||||
// root is not read-only.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
logf("non-root connection from %v (read-only)", cred.Uid)
|
|
||||||
return true
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !linux
|
|
||||||
|
|
||||||
package ipnserver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
|
|
||||||
"tailscale.com/types/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
func isReadonlyConn(c net.Conn, logf logger.Logf) bool {
|
|
||||||
// Windows doesn't need/use this mechanism, at least yet. It
|
|
||||||
// has a different last-user-wins auth model.
|
|
||||||
|
|
||||||
// And on Darwin, we're not using it yet, as the Darwin
|
|
||||||
// tailscaled port isn't yet done, and unix.Ucred and
|
|
||||||
// unix.GetsockoptUcred aren't in x/sys/unix.
|
|
||||||
|
|
||||||
// TODO(bradfitz): OpenBSD and FreeBSD should implement this too.
|
|
||||||
// But their x/sys/unix package is different than Linux, so
|
|
||||||
// I didn't include it for now.
|
|
||||||
return false
|
|
||||||
}
|
|
@ -26,6 +26,7 @@ import (
|
|||||||
|
|
||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"inet.af/peercred"
|
||||||
"tailscale.com/control/controlclient"
|
"tailscale.com/control/controlclient"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/ipn/ipnlocal"
|
"tailscale.com/ipn/ipnlocal"
|
||||||
@ -309,6 +310,19 @@ func (s *server) serveConn(ctx context.Context, c net.Conn, logf logger.Logf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isReadonlyConn(c net.Conn, logf logger.Logf) bool {
|
||||||
|
creds, err := peercred.Get(c)
|
||||||
|
if err != nil {
|
||||||
|
return true // conservatively
|
||||||
|
}
|
||||||
|
uid, ok := creds.UserID()
|
||||||
|
if !ok {
|
||||||
|
return true // conservatively
|
||||||
|
}
|
||||||
|
logf("connection from userid %v", uid)
|
||||||
|
return uid != "0"
|
||||||
|
}
|
||||||
|
|
||||||
// inUseOtherUserError is the error type for when the server is in use
|
// inUseOtherUserError is the error type for when the server is in use
|
||||||
// by a different local user.
|
// by a different local user.
|
||||||
type inUseOtherUserError struct{ error }
|
type inUseOtherUserError struct{ error }
|
||||||
|
@ -103,8 +103,9 @@ func tailscaledRunningUnderLaunchd() bool {
|
|||||||
// socketPermissionsForOS returns the permissions to use for the
|
// socketPermissionsForOS returns the permissions to use for the
|
||||||
// tailscaled.sock.
|
// tailscaled.sock.
|
||||||
func socketPermissionsForOS() os.FileMode {
|
func socketPermissionsForOS() os.FileMode {
|
||||||
if runtime.GOOS == "linux" {
|
switch runtime.GOOS {
|
||||||
// On Linux, the ipn/ipnserver package looks at the Unix peer creds
|
case "linux", "darwin":
|
||||||
|
// On Linux and Darwin, the ipn/ipnserver package looks at the Unix peer creds
|
||||||
// and only permits read-only actions from non-root users, so we want
|
// and only permits read-only actions from non-root users, so we want
|
||||||
// this opened up wider.
|
// this opened up wider.
|
||||||
//
|
//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user