mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-15 21:00:27 +00:00
Update tailscale to v1.102.1
This commit is contained in:
@@ -24,7 +24,7 @@ import (
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/go-chi/render"
|
||||
"golang.org/x/net/http2"
|
||||
"golang.org/x/net/http2/h2c"
|
||||
"golang.org/x/net/http2/h2c" //nolint:staticcheck
|
||||
)
|
||||
|
||||
func RegisterRealmService(registry *boxService.Registry) {
|
||||
@@ -98,6 +98,7 @@ func NewRealmService(ctx context.Context, logger log.ContextLogger, tag string,
|
||||
Listen: options.ListenOptions,
|
||||
}),
|
||||
httpServer: &http.Server{
|
||||
//nolint:staticcheck
|
||||
Handler: h2c.NewHandler(chiRouter, &http2.Server{
|
||||
IdleTimeout: time.Duration(options.IdleTimeout),
|
||||
ReadIdleTimeout: time.Duration(options.KeepAlivePeriod),
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
sHttp "github.com/sagernet/sing/protocol/http"
|
||||
|
||||
"golang.org/x/net/http2"
|
||||
"golang.org/x/net/http2/h2c"
|
||||
"golang.org/x/net/http2/h2c" //nolint:staticcheck
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -102,6 +102,7 @@ func (n *Inbound) Start(stage adapter.StartStage) error {
|
||||
return err
|
||||
}
|
||||
n.httpServer = &http.Server{
|
||||
//nolint:staticcheck
|
||||
Handler: h2c.NewHandler(n, &http2.Server{}),
|
||||
BaseContext: func(listener net.Listener) context.Context {
|
||||
return n.ctx
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/service"
|
||||
nDNS "github.com/sagernet/tailscale/net/dns"
|
||||
nDNSResolver "github.com/sagernet/tailscale/net/dns/resolver"
|
||||
"github.com/sagernet/tailscale/types/dnstype"
|
||||
"github.com/sagernet/tailscale/util/dnsname"
|
||||
"github.com/sagernet/tailscale/wgengine/router"
|
||||
@@ -55,6 +56,7 @@ type DNSTransport struct {
|
||||
routePrefixes []netip.Prefix
|
||||
routes map[string][]adapter.DNSTransport
|
||||
hosts map[string][]netip.Addr
|
||||
magicHosts nDNSResolver.MagicDNSHosts
|
||||
searchDomains []string
|
||||
defaultResolvers []adapter.DNSTransport
|
||||
}
|
||||
@@ -150,6 +152,7 @@ func (t *DNSTransport) updateDNSServers(routeConfig *router.Config, dnsConfig *n
|
||||
t.routePrefixes = routePrefixes
|
||||
t.routes = routes
|
||||
t.hosts = hosts
|
||||
t.magicHosts = t.endpoint.server.ExportLocalBackend().ExportMagicDNSHosts()
|
||||
t.searchDomains = searchDomains
|
||||
t.defaultResolvers = defaultResolvers
|
||||
t.access.Unlock()
|
||||
@@ -241,6 +244,7 @@ func (t *DNSTransport) Close() error {
|
||||
t.routePrefixes = nil
|
||||
t.routes = nil
|
||||
t.hosts = nil
|
||||
t.magicHosts = nil
|
||||
t.defaultResolvers = nil
|
||||
t.access.Unlock()
|
||||
|
||||
@@ -261,9 +265,14 @@ func (t *DNSTransport) Raw() bool {
|
||||
func (t *DNSTransport) PreferredDomain(domain string) bool {
|
||||
t.access.RLock()
|
||||
hosts := t.hosts
|
||||
magicHosts := t.magicHosts
|
||||
routes := t.routes
|
||||
searchDomains := t.searchDomains
|
||||
t.access.RUnlock()
|
||||
if _, loaded := hosts[domain]; loaded {
|
||||
if _, loaded := lookupHosts(hosts, magicHosts, domain); loaded {
|
||||
return true
|
||||
}
|
||||
if t.acceptSearchDomain && len(searchDomains) > 0 && mDNS.CountLabel(domain) == 1 {
|
||||
return true
|
||||
}
|
||||
for suffix := range routes {
|
||||
@@ -351,30 +360,20 @@ func (t *DNSTransport) exchangeOnce(ctx context.Context, message *mDNS.Msg, allo
|
||||
|
||||
t.access.RLock()
|
||||
hosts := t.hosts
|
||||
magicHosts := t.magicHosts
|
||||
routes := t.routes
|
||||
defaultResolvers := t.defaultResolvers
|
||||
t.access.RUnlock()
|
||||
|
||||
addresses, hostsLoaded := hosts[question.Name]
|
||||
addresses, hostsLoaded := lookupHosts(hosts, magicHosts, question.Name)
|
||||
if hostsLoaded {
|
||||
switch question.Qtype {
|
||||
case mDNS.TypeA:
|
||||
addresses4 := common.Filter(addresses, func(addr netip.Addr) bool {
|
||||
return addr.Is4()
|
||||
})
|
||||
if len(addresses4) > 0 {
|
||||
callback(dns.FixedResponse(message.Id, question, addresses4, C.DefaultDNSTTL), nil)
|
||||
return
|
||||
}
|
||||
case mDNS.TypeAAAA:
|
||||
addresses6 := common.Filter(addresses, func(addr netip.Addr) bool {
|
||||
return addr.Is6()
|
||||
})
|
||||
if len(addresses6) > 0 {
|
||||
callback(dns.FixedResponse(message.Id, question, addresses6, C.DefaultDNSTTL), nil)
|
||||
return
|
||||
}
|
||||
case mDNS.TypeA, mDNS.TypeAAAA:
|
||||
callback(dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil)
|
||||
default:
|
||||
callback(dns.FixedResponseStatus(message, mDNS.RcodeSuccess), nil)
|
||||
}
|
||||
return
|
||||
}
|
||||
for domainSuffix, transports := range routes {
|
||||
if mDNS.IsSubDomain(domainSuffix, question.Name) {
|
||||
@@ -404,6 +403,30 @@ func (t *DNSTransport) exchangeOnce(ctx context.Context, message *mDNS.Msg, allo
|
||||
callback(nil, dns.RcodeNameError)
|
||||
}
|
||||
|
||||
func lookupHosts(hosts map[string][]netip.Addr, magicHosts nDNSResolver.MagicDNSHosts, name string) ([]netip.Addr, bool) {
|
||||
addresses, loaded := hosts[name]
|
||||
if loaded {
|
||||
return addresses, true
|
||||
}
|
||||
if magicHosts == nil {
|
||||
return nil, false
|
||||
}
|
||||
fqdn, err := dnsname.ToFQDN(name)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
addresses, loaded = magicHosts.LookupHost(fqdn)
|
||||
if loaded {
|
||||
return addresses, true
|
||||
}
|
||||
for parent := fqdn.Parent(); parent != ""; parent = parent.Parent() {
|
||||
if magicHosts.SubdomainHost(parent) {
|
||||
return magicHosts.LookupHost(parent)
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func resolverExchangers(resolvers []adapter.DNSTransport, message *mDNS.Msg) []transport.AsyncExchanger {
|
||||
return common.Map(resolvers, func(resolver adapter.DNSTransport) transport.AsyncExchanger {
|
||||
return func(ctx context.Context, callback func(response *mDNS.Msg, err error)) {
|
||||
|
||||
@@ -57,12 +57,10 @@ import (
|
||||
"github.com/sagernet/tailscale/types/nettype"
|
||||
"github.com/sagernet/tailscale/version"
|
||||
"github.com/sagernet/tailscale/wgengine"
|
||||
"github.com/sagernet/tailscale/wgengine/filter"
|
||||
"github.com/sagernet/tailscale/wgengine/router"
|
||||
"github.com/sagernet/tailscale/wgengine/wgcfg"
|
||||
|
||||
mDNS "github.com/miekg/dns"
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -92,7 +90,6 @@ type Endpoint struct {
|
||||
server *tsnet.Server
|
||||
stack *stack.Stack
|
||||
icmpForwarder *tun.ICMPForwarder
|
||||
filter *atomic.Pointer[filter.Filter]
|
||||
returnAccess sync.Mutex
|
||||
returnPath tun.Return
|
||||
wgEngine wgengine.ExportedUserspaceEngine
|
||||
@@ -105,7 +102,6 @@ type Endpoint struct {
|
||||
routeDomains common.TypedValue[map[string]bool]
|
||||
routeSuffixes common.TypedValue[[]string]
|
||||
searchDomains atomic.Bool
|
||||
routePrefixes atomic.Pointer[netipx.IPSet]
|
||||
|
||||
acceptRoutes bool
|
||||
exitNode string
|
||||
@@ -330,7 +326,7 @@ func (t *Endpoint) start() error {
|
||||
}
|
||||
t.systemTun = systemTun
|
||||
t.systemDialer = systemDialer
|
||||
t.server.TunDevice = wgTunDevice
|
||||
t.server.Tun = wgTunDevice
|
||||
}
|
||||
if t.network.AutoRedirectOutputMark() != 0 {
|
||||
netns.SetControlFunc(t.network.AutoRedirectOutputMarkFunc())
|
||||
@@ -467,12 +463,10 @@ func (t *Endpoint) postStart() error {
|
||||
t.logger.Warn("SSH server degraded: ", degraded)
|
||||
}
|
||||
}
|
||||
localBackend := t.server.ExportLocalBackend()
|
||||
err = t.editPrefs(sshEnabled)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.filter = localBackend.ExportFilter()
|
||||
if sshEnabled {
|
||||
sshServer, err := tailssh.New(t.ctx, t.server, t.platformInterface, t.sshServerOptions, t.logger)
|
||||
if err != nil {
|
||||
@@ -494,48 +488,76 @@ func (t *Endpoint) watchState() {
|
||||
localBackend := t.server.ExportLocalBackend()
|
||||
var reportedAuthURL string
|
||||
exitNodePending := t.exitNode != ""
|
||||
localBackend.WatchNotifications(t.ctx, ipn.NotifyInitialState, nil, func(roNotify *ipn.Notify) (keepGoing bool) {
|
||||
if roNotify.State == nil && roNotify.BrowseToURL == nil {
|
||||
return true
|
||||
running := false
|
||||
tryApplyExitNode := func() {
|
||||
err := t.applyExitNode()
|
||||
if err != nil {
|
||||
t.logger.Error("set exit node: ", err)
|
||||
} else {
|
||||
exitNodePending = false
|
||||
}
|
||||
status := localBackend.StatusWithoutPeers()
|
||||
switch status.BackendState {
|
||||
case ipn.NoState.String(), ipn.NeedsLogin.String():
|
||||
if t.exitNode != "" {
|
||||
exitNodePending = true
|
||||
}
|
||||
for {
|
||||
var busError string
|
||||
localBackend.WatchNotifications(t.ctx, ipn.NotifyInitialState|ipn.NotifyPeerPatches, nil, func(roNotify *ipn.Notify) (keepGoing bool) {
|
||||
if roNotify.ErrMessage != nil {
|
||||
busError = *roNotify.ErrMessage
|
||||
return false
|
||||
}
|
||||
authURL := status.AuthURL
|
||||
if authURL == "" || authURL == reportedAuthURL {
|
||||
if running && exitNodePending && len(roNotify.PeersChanged) > 0 {
|
||||
tryApplyExitNode()
|
||||
}
|
||||
if roNotify.State == nil && roNotify.BrowseToURL == nil {
|
||||
return true
|
||||
}
|
||||
reportedAuthURL = authURL
|
||||
t.logger.Info("Waiting for authentication: ", authURL)
|
||||
if t.platformInterface != nil && t.platformInterface.UsePlatformNotification() {
|
||||
err := t.platformInterface.SendNotification(&adapter.Notification{
|
||||
Identifier: "tailscale-authentication",
|
||||
TypeName: "Tailscale Authentication Notifications",
|
||||
TypeID: 10,
|
||||
Title: "Tailscale Authentication",
|
||||
Body: F.ToString("Tailscale outbound[", t.Tag(), "] is waiting for authentication."),
|
||||
OpenURL: authURL,
|
||||
})
|
||||
if err != nil {
|
||||
t.logger.Error("send authentication notification: ", err)
|
||||
}
|
||||
}
|
||||
case ipn.Running.String():
|
||||
reportedAuthURL = ""
|
||||
if exitNodePending {
|
||||
err := t.applyExitNode()
|
||||
if err != nil {
|
||||
t.logger.Error("set exit node: ", err)
|
||||
} else {
|
||||
exitNodePending = false
|
||||
status := localBackend.StatusWithoutPeers()
|
||||
running = status.BackendState == ipn.Running.String()
|
||||
switch status.BackendState {
|
||||
case ipn.NoState.String(), ipn.NeedsLogin.String():
|
||||
if t.exitNode != "" {
|
||||
exitNodePending = true
|
||||
}
|
||||
authURL := status.AuthURL
|
||||
if authURL == "" || authURL == reportedAuthURL {
|
||||
return true
|
||||
}
|
||||
reportedAuthURL = authURL
|
||||
t.logger.Info("Waiting for authentication: ", authURL)
|
||||
if t.platformInterface != nil && t.platformInterface.UsePlatformNotification() {
|
||||
err := t.platformInterface.SendNotification(&adapter.Notification{
|
||||
Identifier: "tailscale-authentication",
|
||||
TypeName: "Tailscale Authentication Notifications",
|
||||
TypeID: 10,
|
||||
Title: "Tailscale Authentication",
|
||||
Body: F.ToString("Tailscale outbound[", t.Tag(), "] is waiting for authentication."),
|
||||
OpenURL: authURL,
|
||||
})
|
||||
if err != nil {
|
||||
t.logger.Error("send authentication notification: ", err)
|
||||
}
|
||||
}
|
||||
case ipn.Running.String():
|
||||
reportedAuthURL = ""
|
||||
if exitNodePending {
|
||||
tryApplyExitNode()
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
if t.ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
return true
|
||||
})
|
||||
if busError != "" {
|
||||
t.logger.Warn("restarting state watcher: ", busError)
|
||||
} else {
|
||||
t.logger.Warn("state watcher stopped unexpectedly, restarting")
|
||||
}
|
||||
select {
|
||||
case <-t.ctx.Done():
|
||||
return
|
||||
case <-time.After(time.Second):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Endpoint) editPrefs(sshEnabled bool) error {
|
||||
@@ -895,6 +917,12 @@ func (t *Endpoint) PreferredDomain(metadata *adapter.InboundContext, domain stri
|
||||
if routeDomains[domain] {
|
||||
return true
|
||||
}
|
||||
if t.started.Load() {
|
||||
magicHosts := t.server.ExportLocalBackend().ExportMagicDNSHosts()
|
||||
if _, found := lookupHosts(nil, magicHosts, domain); found {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, suffix := range t.routeSuffixes.Load() {
|
||||
if mDNS.IsSubDomain(suffix, domain) {
|
||||
return true
|
||||
@@ -904,11 +932,11 @@ func (t *Endpoint) PreferredDomain(metadata *adapter.InboundContext, domain stri
|
||||
}
|
||||
|
||||
func (t *Endpoint) PreferredAddress(metadata *adapter.InboundContext, address netip.Addr) bool {
|
||||
routePrefixes := t.routePrefixes.Load()
|
||||
if routePrefixes == nil {
|
||||
if !t.started.Load() {
|
||||
return false
|
||||
}
|
||||
return routePrefixes.Contains(address)
|
||||
peer, found := t.server.ExportLocalBackend().PeerForIP(address)
|
||||
return found && !peer.IsSelf && peer.Route.Bits() > 0
|
||||
}
|
||||
|
||||
func (t *Endpoint) Server() *tsnet.Server {
|
||||
@@ -919,6 +947,12 @@ func (t *Endpoint) onReconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCf
|
||||
if cfg == nil || dnsCfg == nil {
|
||||
return
|
||||
}
|
||||
// The engine invokes the listener on every Reconfig call, including
|
||||
// unchanged ones: SSH policy lives only in the netmap, outside the
|
||||
// three configs, so the SSH hook must run before the change check.
|
||||
if t.sshReconfigHook != nil {
|
||||
t.sshReconfigHook(cfg, routerCfg, dnsCfg)
|
||||
}
|
||||
if t.cfg != nil && reflect.DeepEqual(t.cfg, cfg) &&
|
||||
t.routerCfg != nil && reflect.DeepEqual(t.routerCfg, routerCfg) &&
|
||||
t.dnsCfg != nil && reflect.DeepEqual(t.dnsCfg, dnsCfg) {
|
||||
@@ -943,23 +977,9 @@ func (t *Endpoint) onReconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCf
|
||||
t.routeSuffixes.Store(routeSuffixes)
|
||||
t.searchDomains.Store(len(dnsCfg.SearchDomains) > 0)
|
||||
|
||||
var builder netipx.IPSetBuilder
|
||||
for _, peer := range cfg.Peers {
|
||||
for _, allowedIP := range peer.AllowedIPs {
|
||||
if allowedIP.Bits() == 0 {
|
||||
continue
|
||||
}
|
||||
builder.AddPrefix(allowedIP)
|
||||
}
|
||||
}
|
||||
t.routePrefixes.Store(common.Must1(builder.IPSet()))
|
||||
|
||||
if t.onReconfigHook != nil {
|
||||
t.onReconfigHook(cfg, routerCfg, dnsCfg)
|
||||
}
|
||||
if t.sshReconfigHook != nil {
|
||||
t.sshReconfigHook(cfg, routerCfg, dnsCfg)
|
||||
}
|
||||
}
|
||||
|
||||
func addressFromAddr(destination netip.Addr) tcpip.Address {
|
||||
|
||||
@@ -41,8 +41,8 @@ func (t *Endpoint) JudgeFlow(network uint8, source netip.AddrPort, destination n
|
||||
if destination.Addr() == inet4Address || destination.Addr() == inet6Address {
|
||||
return tun.FlowVerdict{Action: tun.ActionAccept}
|
||||
}
|
||||
if t.filter != nil {
|
||||
tsFilter := t.filter.Load()
|
||||
if t.started.Load() {
|
||||
tsFilter := t.wgEngine.GetFilter()
|
||||
if tsFilter != nil {
|
||||
var (
|
||||
ipProto ipproto.Proto
|
||||
|
||||
@@ -5,6 +5,7 @@ package tailscale
|
||||
import (
|
||||
"context"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/tailscale/ipn"
|
||||
@@ -15,25 +16,60 @@ var _ adapter.TailscaleEndpoint = (*Endpoint)(nil)
|
||||
|
||||
func (t *Endpoint) SubscribeTailscaleStatus(ctx context.Context, fn func(*adapter.TailscaleEndpointStatus)) error {
|
||||
localBackend := t.server.ExportLocalBackend()
|
||||
sendStatus := func() {
|
||||
status := localBackend.Status()
|
||||
result := convertTailscaleStatus(status)
|
||||
result.KeyAuth = t.keyAuth
|
||||
fn(result)
|
||||
}
|
||||
sendStatus()
|
||||
localBackend.WatchNotifications(ctx, ipn.NotifyInitialState|ipn.NotifyInitialNetMap|ipn.NotifyRateLimit, nil, func(roNotify *ipn.Notify) (keepGoing bool) {
|
||||
// The notification callback must stay cheap and non-blocking: a
|
||||
// watcher whose queue fills is disconnected by the IPN bus, so
|
||||
// status collection and delivery (which blocks on the subscriber)
|
||||
// run on a separate coalescing goroutine.
|
||||
updateSignal := make(chan struct{}, 1)
|
||||
scheduleUpdate := func() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return false
|
||||
case updateSignal <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
if roNotify.State != nil || roNotify.NetMap != nil || roNotify.BrowseToURL != nil || roNotify.Prefs != nil {
|
||||
sendStatus()
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-updateSignal:
|
||||
}
|
||||
status := localBackend.Status()
|
||||
result := convertTailscaleStatus(status)
|
||||
result.KeyAuth = t.keyAuth
|
||||
fn(result)
|
||||
}
|
||||
return true
|
||||
})
|
||||
return ctx.Err()
|
||||
}()
|
||||
scheduleUpdate()
|
||||
for {
|
||||
var busError string
|
||||
localBackend.WatchNotifications(ctx, ipn.NotifyInitialState|ipn.NotifyPeerPatches, nil, func(roNotify *ipn.Notify) (keepGoing bool) {
|
||||
if roNotify.ErrMessage != nil {
|
||||
busError = *roNotify.ErrMessage
|
||||
return false
|
||||
}
|
||||
if roNotify.State != nil || roNotify.SelfChange != nil ||
|
||||
len(roNotify.PeersChanged) > 0 || len(roNotify.PeersRemoved) > 0 || len(roNotify.PeerChangedPatch) > 0 ||
|
||||
roNotify.BrowseToURL != nil || roNotify.Prefs != nil {
|
||||
scheduleUpdate()
|
||||
}
|
||||
return true
|
||||
})
|
||||
if ctx.Err() != nil {
|
||||
return ctx.Err()
|
||||
}
|
||||
if busError != "" {
|
||||
t.logger.Warn("restarting status watcher: ", busError)
|
||||
} else {
|
||||
t.logger.Warn("status watcher stopped unexpectedly, restarting")
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-time.After(time.Second):
|
||||
}
|
||||
scheduleUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
func convertTailscaleStatus(status *ipnstate.Status) *adapter.TailscaleEndpointStatus {
|
||||
@@ -78,25 +114,27 @@ func convertTailscaleStatus(status *ipnstate.Status) *adapter.TailscaleEndpointS
|
||||
return 0
|
||||
})
|
||||
}
|
||||
if status.ExitNodeStatus != nil {
|
||||
for _, peerKey := range status.Peers() {
|
||||
peer := status.Peer[peerKey]
|
||||
if peer.ID == status.ExitNodeStatus.ID {
|
||||
result.ExitNode = convertTailscalePeer(peer)
|
||||
break
|
||||
}
|
||||
// status.ExitNodeStatus is populated from the cached netmap Peers
|
||||
// slice, which incremental deltas do not update; the live peer map
|
||||
// behind status.Peer sets PeerStatus.ExitNode delta-correctly, so it
|
||||
// is the primary source.
|
||||
for _, peerKey := range status.Peers() {
|
||||
peer := status.Peer[peerKey]
|
||||
if peer.ExitNode {
|
||||
result.ExitNode = convertTailscalePeer(peer)
|
||||
break
|
||||
}
|
||||
if result.ExitNode == nil {
|
||||
ips := make([]string, 0, len(status.ExitNodeStatus.TailscaleIPs))
|
||||
for _, prefix := range status.ExitNodeStatus.TailscaleIPs {
|
||||
ips = append(ips, prefix.Addr().String())
|
||||
}
|
||||
result.ExitNode = &adapter.TailscalePeer{
|
||||
StableID: string(status.ExitNodeStatus.ID),
|
||||
TailscaleIPs: ips,
|
||||
Online: status.ExitNodeStatus.Online,
|
||||
ExitNode: true,
|
||||
}
|
||||
}
|
||||
if result.ExitNode == nil && status.ExitNodeStatus != nil {
|
||||
ips := make([]string, 0, len(status.ExitNodeStatus.TailscaleIPs))
|
||||
for _, prefix := range status.ExitNodeStatus.TailscaleIPs {
|
||||
ips = append(ips, prefix.Addr().String())
|
||||
}
|
||||
result.ExitNode = &adapter.TailscalePeer{
|
||||
StableID: string(status.ExitNodeStatus.ID),
|
||||
TailscaleIPs: ips,
|
||||
Online: status.ExitNodeStatus.Online,
|
||||
ExitNode: true,
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
||||
@@ -287,7 +287,7 @@ func (s *Server) authenticate(ctx gliderssh.Context, conn gossh.ConnMetadata) (*
|
||||
s.logger.Warn("SSH auth: unknown peer ", remoteAddrPort)
|
||||
return nil, &gossh.PartialSuccessError{}
|
||||
}
|
||||
netMap := localBackend.NetMap()
|
||||
netMap := localBackend.NetMapNoPeers()
|
||||
if netMap == nil || netMap.SSHPolicy == nil {
|
||||
s.logger.Warn("SSH auth: no SSH policy")
|
||||
return nil, &gossh.PartialSuccessError{}
|
||||
@@ -419,7 +419,7 @@ func (s *Server) holdAndDelegate(ctx context.Context, action *tailcfg.SSHAction,
|
||||
srcNodeIP = node.Addresses().At(0).Addr()
|
||||
}
|
||||
var dstNodeID string
|
||||
netMap := lb.NetMap()
|
||||
netMap := lb.NetMapNoPeers()
|
||||
if netMap != nil && netMap.SelfNode.Valid() {
|
||||
dstNodeID = fmt.Sprint(int64(netMap.SelfNode.ID()))
|
||||
}
|
||||
@@ -831,7 +831,7 @@ func (s *Server) buildEnvironment(session gliderssh.Session, connInfo *sshConnIn
|
||||
// capability, matching upstream's capability gate.
|
||||
acceptEnv := connInfo.acceptEnv
|
||||
if len(acceptEnv) > 0 {
|
||||
netMap := s.tsnetServer.ExportLocalBackend().NetMap()
|
||||
netMap := s.tsnetServer.ExportLocalBackend().NetMapNoPeers()
|
||||
if netMap == nil || !netMap.HasCap(tailcfg.NodeAttrSSHEnvironmentVariables) {
|
||||
acceptEnv = nil
|
||||
}
|
||||
@@ -957,7 +957,7 @@ func (s *Server) allowReverseUnixForward(ctx gliderssh.Context, socketPath strin
|
||||
|
||||
func (s *Server) OnReconfig(cfg *wgcfg.Config, routerCfg *router.Config, dnsCfg *tsDNS.Config) {
|
||||
localBackend := s.tsnetServer.ExportLocalBackend()
|
||||
netMap := localBackend.NetMap()
|
||||
netMap := localBackend.NetMapNoPeers()
|
||||
if netMap == nil || netMap.SSHPolicy == nil {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user