integration_test.go 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package integration
  4. //go:generate go run gen_deps.go
  5. import (
  6. "bytes"
  7. "context"
  8. "encoding/json"
  9. "errors"
  10. "flag"
  11. "fmt"
  12. "io"
  13. "net"
  14. "net/http"
  15. "net/http/httptest"
  16. "net/netip"
  17. "os"
  18. "os/exec"
  19. "path/filepath"
  20. "regexp"
  21. "runtime"
  22. "slices"
  23. "strconv"
  24. "strings"
  25. "sync"
  26. "sync/atomic"
  27. "testing"
  28. "time"
  29. "github.com/google/go-cmp/cmp"
  30. "github.com/miekg/dns"
  31. "go4.org/mem"
  32. "tailscale.com/client/local"
  33. "tailscale.com/client/tailscale"
  34. "tailscale.com/cmd/testwrapper/flakytest"
  35. "tailscale.com/feature"
  36. _ "tailscale.com/feature/clientupdate"
  37. "tailscale.com/health"
  38. "tailscale.com/hostinfo"
  39. "tailscale.com/ipn"
  40. "tailscale.com/net/tsaddr"
  41. "tailscale.com/net/tstun"
  42. "tailscale.com/net/udprelay/status"
  43. "tailscale.com/tailcfg"
  44. "tailscale.com/tstest"
  45. "tailscale.com/tstest/integration/testcontrol"
  46. "tailscale.com/types/key"
  47. "tailscale.com/types/netmap"
  48. "tailscale.com/types/opt"
  49. "tailscale.com/types/ptr"
  50. "tailscale.com/util/must"
  51. "tailscale.com/util/set"
  52. )
  53. func TestMain(m *testing.M) {
  54. // Have to disable UPnP which hits the network, otherwise it fails due to HTTP proxy.
  55. os.Setenv("TS_DISABLE_UPNP", "true")
  56. flag.Parse()
  57. v := m.Run()
  58. if v != 0 {
  59. os.Exit(v)
  60. }
  61. if err := MainError.Load(); err != nil {
  62. fmt.Fprintf(os.Stderr, "FAIL: %v\n", err)
  63. os.Exit(1)
  64. }
  65. os.Exit(0)
  66. }
  67. // Tests that tailscaled starts up in TUN mode, and also without data races:
  68. // https://github.com/tailscale/tailscale/issues/7894
  69. func TestTUNMode(t *testing.T) {
  70. tstest.Shard(t)
  71. if os.Getuid() != 0 {
  72. t.Skip("skipping when not root")
  73. }
  74. tstest.Parallel(t)
  75. env := NewTestEnv(t)
  76. env.tunMode = true
  77. n1 := NewTestNode(t, env)
  78. d1 := n1.StartDaemon()
  79. n1.AwaitResponding()
  80. n1.MustUp()
  81. t.Logf("Got IP: %v", n1.AwaitIP4())
  82. n1.AwaitRunning()
  83. d1.MustCleanShutdown(t)
  84. }
  85. func TestOneNodeUpNoAuth(t *testing.T) {
  86. tstest.Shard(t)
  87. tstest.Parallel(t)
  88. env := NewTestEnv(t)
  89. n1 := NewTestNode(t, env)
  90. d1 := n1.StartDaemon()
  91. n1.AwaitResponding()
  92. n1.MustUp()
  93. t.Logf("Got IP: %v", n1.AwaitIP4())
  94. n1.AwaitRunning()
  95. d1.MustCleanShutdown(t)
  96. t.Logf("number of HTTP logcatcher requests: %v", env.LogCatcher.numRequests())
  97. }
  98. func TestOneNodeExpiredKey(t *testing.T) {
  99. tstest.Shard(t)
  100. tstest.Parallel(t)
  101. env := NewTestEnv(t)
  102. n1 := NewTestNode(t, env)
  103. d1 := n1.StartDaemon()
  104. n1.AwaitResponding()
  105. n1.MustUp()
  106. n1.AwaitRunning()
  107. nodes := env.Control.AllNodes()
  108. if len(nodes) != 1 {
  109. t.Fatalf("expected 1 node, got %d nodes", len(nodes))
  110. }
  111. nodeKey := nodes[0].Key
  112. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  113. if err := env.Control.AwaitNodeInMapRequest(ctx, nodeKey); err != nil {
  114. t.Fatal(err)
  115. }
  116. cancel()
  117. env.Control.SetExpireAllNodes(true)
  118. n1.AwaitNeedsLogin()
  119. ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
  120. if err := env.Control.AwaitNodeInMapRequest(ctx, nodeKey); err != nil {
  121. t.Fatal(err)
  122. }
  123. cancel()
  124. env.Control.SetExpireAllNodes(false)
  125. n1.AwaitRunning()
  126. d1.MustCleanShutdown(t)
  127. }
  128. func TestControlKnobs(t *testing.T) {
  129. tstest.Shard(t)
  130. tstest.Parallel(t)
  131. env := NewTestEnv(t)
  132. n1 := NewTestNode(t, env)
  133. d1 := n1.StartDaemon()
  134. defer d1.MustCleanShutdown(t)
  135. n1.AwaitResponding()
  136. n1.MustUp()
  137. t.Logf("Got IP: %v", n1.AwaitIP4())
  138. n1.AwaitRunning()
  139. cmd := n1.Tailscale("debug", "control-knobs")
  140. cmd.Stdout = nil // in case --verbose-tailscale was set
  141. cmd.Stderr = nil // in case --verbose-tailscale was set
  142. out, err := cmd.CombinedOutput()
  143. if err != nil {
  144. t.Fatal(err)
  145. }
  146. t.Logf("control-knobs output:\n%s", out)
  147. var m map[string]any
  148. if err := json.Unmarshal(out, &m); err != nil {
  149. t.Fatal(err)
  150. }
  151. if got, want := m["DisableUPnP"], true; got != want {
  152. t.Errorf("control-knobs DisableUPnP = %v; want %v", got, want)
  153. }
  154. }
  155. func TestExpectedFeaturesLinked(t *testing.T) {
  156. tstest.Shard(t)
  157. tstest.Parallel(t)
  158. env := NewTestEnv(t)
  159. n1 := NewTestNode(t, env)
  160. d1 := n1.StartDaemon()
  161. n1.AwaitResponding()
  162. lc := n1.LocalClient()
  163. got, err := lc.QueryOptionalFeatures(t.Context())
  164. if err != nil {
  165. t.Fatal(err)
  166. }
  167. if !got.Features["portmapper"] {
  168. t.Errorf("optional feature portmapper unexpectedly not found: got %v", got.Features)
  169. }
  170. d1.MustCleanShutdown(t)
  171. t.Logf("number of HTTP logcatcher requests: %v", env.LogCatcher.numRequests())
  172. }
  173. func TestCollectPanic(t *testing.T) {
  174. flakytest.Mark(t, "https://github.com/tailscale/tailscale/issues/15865")
  175. tstest.Shard(t)
  176. tstest.Parallel(t)
  177. env := NewTestEnv(t)
  178. n := NewTestNode(t, env)
  179. cmd := exec.Command(env.daemon, "--cleanup")
  180. cmd.Env = append(os.Environ(),
  181. "TS_PLEASE_PANIC=1",
  182. "TS_LOG_TARGET="+n.env.LogCatcherServer.URL,
  183. )
  184. got, _ := cmd.CombinedOutput() // we expect it to fail, ignore err
  185. t.Logf("initial run: %s", got)
  186. // Now we run it again, and on start, it will upload the logs to logcatcher.
  187. cmd = exec.Command(env.daemon, "--cleanup")
  188. cmd.Env = append(os.Environ(), "TS_LOG_TARGET="+n.env.LogCatcherServer.URL)
  189. if out, err := cmd.CombinedOutput(); err != nil {
  190. t.Fatalf("cleanup failed: %v: %q", err, out)
  191. }
  192. if err := tstest.WaitFor(20*time.Second, func() error {
  193. const sub = `panic`
  194. if !n.env.LogCatcher.logsContains(mem.S(sub)) {
  195. return fmt.Errorf("log catcher didn't see %#q; got %s", sub, n.env.LogCatcher.logsString())
  196. }
  197. return nil
  198. }); err != nil {
  199. t.Fatal(err)
  200. }
  201. }
  202. func TestControlTimeLogLine(t *testing.T) {
  203. tstest.Shard(t)
  204. tstest.Parallel(t)
  205. env := NewTestEnv(t)
  206. env.LogCatcher.StoreRawJSON()
  207. n := NewTestNode(t, env)
  208. n.StartDaemon()
  209. n.AwaitResponding()
  210. n.MustUp()
  211. n.AwaitRunning()
  212. if err := tstest.WaitFor(20*time.Second, func() error {
  213. const sub = `"controltime":"2020-08-03T00:00:00.000000001Z"`
  214. if !n.env.LogCatcher.logsContains(mem.S(sub)) {
  215. return fmt.Errorf("log catcher didn't see %#q; got %s", sub, n.env.LogCatcher.logsString())
  216. }
  217. return nil
  218. }); err != nil {
  219. t.Fatal(err)
  220. }
  221. }
  222. // test Issue 2321: Start with UpdatePrefs should save prefs to disk
  223. func TestStateSavedOnStart(t *testing.T) {
  224. tstest.Shard(t)
  225. tstest.Parallel(t)
  226. env := NewTestEnv(t)
  227. n1 := NewTestNode(t, env)
  228. d1 := n1.StartDaemon()
  229. n1.AwaitResponding()
  230. n1.MustUp()
  231. t.Logf("Got IP: %v", n1.AwaitIP4())
  232. n1.AwaitRunning()
  233. p1 := n1.diskPrefs()
  234. t.Logf("Prefs1: %v", p1.Pretty())
  235. // Bring it down, to prevent an EditPrefs call in the
  236. // subsequent "up", as we want to test the bug when
  237. // cmd/tailscale implements "up" via LocalBackend.Start.
  238. n1.MustDown()
  239. // And change the hostname to something:
  240. if err := n1.Tailscale("up", "--login-server="+n1.env.ControlURL(), "--hostname=foo").Run(); err != nil {
  241. t.Fatalf("up: %v", err)
  242. }
  243. p2 := n1.diskPrefs()
  244. if pretty := p1.Pretty(); pretty == p2.Pretty() {
  245. t.Errorf("Prefs didn't change on disk after 'up', still: %s", pretty)
  246. }
  247. if p2.Hostname != "foo" {
  248. t.Errorf("Prefs.Hostname = %q; want foo", p2.Hostname)
  249. }
  250. d1.MustCleanShutdown(t)
  251. }
  252. // This handler receives auth URLs, and logs into control.
  253. //
  254. // It counts how many URLs it sees, and will fail the test if it
  255. // sees multiple login URLs.
  256. func completeLogin(t *testing.T, control *testcontrol.Server, counter *atomic.Int32) func(string) error {
  257. return func(urlStr string) error {
  258. t.Logf("saw auth URL %q", urlStr)
  259. if control.CompleteAuth(urlStr) {
  260. if counter.Add(1) > 1 {
  261. err := errors.New("completed multiple auth URLs")
  262. t.Error(err)
  263. return err
  264. }
  265. t.Logf("completed login to %s", urlStr)
  266. return nil
  267. } else {
  268. err := fmt.Errorf("failed to complete initial login to %q", urlStr)
  269. t.Fatal(err)
  270. return err
  271. }
  272. }
  273. }
  274. // This handler receives device approval URLs, and approves the device.
  275. //
  276. // It counts how many URLs it sees, and will fail the test if it
  277. // sees multiple device approval URLs, or if you try to approve a device
  278. // with the wrong control server.
  279. func completeDeviceApproval(t *testing.T, node *TestNode, counter *atomic.Int32) func(string) error {
  280. return func(urlStr string) error {
  281. control := node.env.Control
  282. nodeKey := node.MustStatus().Self.PublicKey
  283. t.Logf("saw device approval URL %q", urlStr)
  284. if control.CompleteDeviceApproval(node.env.ControlURL(), urlStr, &nodeKey) {
  285. if counter.Add(1) > 1 {
  286. err := errors.New("completed multiple device approval URLs")
  287. t.Error(err)
  288. return err
  289. }
  290. t.Log("completed device approval")
  291. return nil
  292. } else {
  293. err := errors.New("failed to complete device approval")
  294. t.Fatal(err)
  295. return err
  296. }
  297. }
  298. }
  299. func TestOneNodeUpAuth(t *testing.T) {
  300. type step struct {
  301. args []string
  302. //
  303. // Do we expect to log in again with a new /auth/ URL?
  304. wantAuthURL bool
  305. //
  306. // Do we expect to need a device approval URL?
  307. wantDeviceApprovalURL bool
  308. }
  309. for _, tt := range []struct {
  310. name string
  311. args []string
  312. //
  313. // What auth key should we use for control?
  314. authKey string
  315. //
  316. // Do we require device approval in the tailnet?
  317. requireDeviceApproval bool
  318. //
  319. // What CLI commands should we run in this test?
  320. steps []step
  321. }{
  322. {
  323. name: "up",
  324. steps: []step{
  325. {args: []string{"up"}, wantAuthURL: true},
  326. },
  327. },
  328. {
  329. name: "up-with-machine-auth",
  330. steps: []step{
  331. {args: []string{"up"}, wantAuthURL: true, wantDeviceApprovalURL: true},
  332. },
  333. requireDeviceApproval: true,
  334. },
  335. {
  336. name: "up-with-force-reauth",
  337. steps: []step{
  338. {args: []string{"up", "--force-reauth"}, wantAuthURL: true},
  339. },
  340. },
  341. {
  342. name: "up-with-auth-key",
  343. authKey: "opensesame",
  344. steps: []step{
  345. {args: []string{"up", "--auth-key=opensesame"}},
  346. },
  347. },
  348. {
  349. name: "up-with-auth-key-with-machine-auth",
  350. authKey: "opensesame",
  351. steps: []step{
  352. {
  353. args: []string{"up", "--auth-key=opensesame"},
  354. wantAuthURL: false,
  355. wantDeviceApprovalURL: true,
  356. },
  357. },
  358. requireDeviceApproval: true,
  359. },
  360. {
  361. name: "up-with-force-reauth-and-auth-key",
  362. authKey: "opensesame",
  363. steps: []step{
  364. {args: []string{"up", "--force-reauth", "--auth-key=opensesame"}},
  365. },
  366. },
  367. {
  368. name: "up-after-login",
  369. steps: []step{
  370. {args: []string{"up"}, wantAuthURL: true},
  371. {args: []string{"up"}, wantAuthURL: false},
  372. },
  373. },
  374. {
  375. name: "up-after-login-with-machine-approval",
  376. steps: []step{
  377. {args: []string{"up"}, wantAuthURL: true, wantDeviceApprovalURL: true},
  378. {args: []string{"up"}, wantAuthURL: false, wantDeviceApprovalURL: false},
  379. },
  380. requireDeviceApproval: true,
  381. },
  382. {
  383. name: "up-with-force-reauth-after-login",
  384. steps: []step{
  385. {args: []string{"up"}, wantAuthURL: true},
  386. {args: []string{"up", "--force-reauth"}, wantAuthURL: true},
  387. },
  388. },
  389. {
  390. name: "up-with-force-reauth-after-login-with-machine-approval",
  391. steps: []step{
  392. {args: []string{"up"}, wantAuthURL: true, wantDeviceApprovalURL: true},
  393. {args: []string{"up", "--force-reauth"}, wantAuthURL: true, wantDeviceApprovalURL: false},
  394. },
  395. requireDeviceApproval: true,
  396. },
  397. {
  398. name: "up-with-auth-key-after-login",
  399. authKey: "opensesame",
  400. steps: []step{
  401. {args: []string{"up", "--auth-key=opensesame"}},
  402. {args: []string{"up", "--auth-key=opensesame"}},
  403. },
  404. },
  405. {
  406. name: "up-with-force-reauth-and-auth-key-after-login",
  407. authKey: "opensesame",
  408. steps: []step{
  409. {args: []string{"up", "--auth-key=opensesame"}},
  410. {args: []string{"up", "--force-reauth", "--auth-key=opensesame"}},
  411. },
  412. },
  413. } {
  414. tstest.Shard(t)
  415. for _, useSeamlessKeyRenewal := range []bool{true, false} {
  416. name := tt.name
  417. if useSeamlessKeyRenewal {
  418. name += "-with-seamless"
  419. }
  420. t.Run(name, func(t *testing.T) {
  421. tstest.Parallel(t)
  422. env := NewTestEnv(t, ConfigureControl(
  423. func(control *testcontrol.Server) {
  424. if tt.authKey != "" {
  425. control.RequireAuthKey = tt.authKey
  426. } else {
  427. control.RequireAuth = true
  428. }
  429. if tt.requireDeviceApproval {
  430. control.RequireMachineAuth = true
  431. }
  432. control.AllNodesSameUser = true
  433. if useSeamlessKeyRenewal {
  434. control.DefaultNodeCapabilities = &tailcfg.NodeCapMap{
  435. tailcfg.NodeAttrSeamlessKeyRenewal: []tailcfg.RawMessage{},
  436. }
  437. }
  438. },
  439. ))
  440. n1 := NewTestNode(t, env)
  441. d1 := n1.StartDaemon()
  442. defer d1.MustCleanShutdown(t)
  443. for i, step := range tt.steps {
  444. t.Logf("Running step %d", i)
  445. cmdArgs := append(step.args, "--login-server="+env.ControlURL())
  446. t.Logf("Running command: %s", strings.Join(cmdArgs, " "))
  447. var authURLCount atomic.Int32
  448. var deviceApprovalURLCount atomic.Int32
  449. handler := &authURLParserWriter{t: t,
  450. authURLFn: completeLogin(t, env.Control, &authURLCount),
  451. deviceApprovalURLFn: completeDeviceApproval(t, n1, &deviceApprovalURLCount),
  452. }
  453. cmd := n1.Tailscale(cmdArgs...)
  454. cmd.Stdout = handler
  455. cmd.Stdout = handler
  456. cmd.Stderr = cmd.Stdout
  457. if err := cmd.Run(); err != nil {
  458. t.Fatalf("up: %v", err)
  459. }
  460. n1.AwaitRunning()
  461. var wantAuthURLCount int32
  462. if step.wantAuthURL {
  463. wantAuthURLCount = 1
  464. }
  465. if n := authURLCount.Load(); n != wantAuthURLCount {
  466. t.Errorf("Auth URLs completed = %d; want %d", n, wantAuthURLCount)
  467. }
  468. var wantDeviceApprovalURLCount int32
  469. if step.wantDeviceApprovalURL {
  470. wantDeviceApprovalURLCount = 1
  471. }
  472. if n := deviceApprovalURLCount.Load(); n != wantDeviceApprovalURLCount {
  473. t.Errorf("Device approval URLs completed = %d; want %d", n, wantDeviceApprovalURLCount)
  474. }
  475. }
  476. })
  477. }
  478. }
  479. }
  480. // Returns true if the error returned by [exec.Run] fails with a non-zero
  481. // exit code, false otherwise.
  482. func isNonZeroExitCode(err error) bool {
  483. if err == nil {
  484. return false
  485. }
  486. exitError, ok := err.(*exec.ExitError)
  487. if !ok {
  488. return false
  489. }
  490. return exitError.ExitCode() != 0
  491. }
  492. // If we interrupt `tailscale up` and then run it again, we should only
  493. // print a single auth URL.
  494. func TestOneNodeUpInterruptedAuth(t *testing.T) {
  495. tstest.Shard(t)
  496. tstest.Parallel(t)
  497. env := NewTestEnv(t, ConfigureControl(
  498. func(control *testcontrol.Server) {
  499. control.RequireAuth = true
  500. control.AllNodesSameUser = true
  501. },
  502. ))
  503. n := NewTestNode(t, env)
  504. d := n.StartDaemon()
  505. defer d.MustCleanShutdown(t)
  506. cmdArgs := []string{"up", "--login-server=" + env.ControlURL()}
  507. // The first time we run the command, we wait for an auth URL to be
  508. // printed, and then we cancel the command -- equivalent to ^C.
  509. //
  510. // At this point, we've connected to control to get an auth URL,
  511. // and printed it in the CLI, but not clicked it.
  512. t.Logf("Running command for the first time: %s", strings.Join(cmdArgs, " "))
  513. cmd1 := n.Tailscale(cmdArgs...)
  514. // This handler watches for auth URLs in stdout, then cancels the
  515. // running `tailscale up` CLI command.
  516. cmd1.Stdout = &authURLParserWriter{t: t, authURLFn: func(urlStr string) error {
  517. t.Logf("saw auth URL %q", urlStr)
  518. cmd1.Process.Kill()
  519. return nil
  520. }}
  521. cmd1.Stderr = cmd1.Stdout
  522. if err := cmd1.Run(); !isNonZeroExitCode(err) {
  523. t.Fatalf("Command did not fail with non-zero exit code: %q", err)
  524. }
  525. // Because we didn't click the auth URL, we should still be in NeedsLogin.
  526. n.AwaitBackendState("NeedsLogin")
  527. // The second time we run the command, we click the first auth URL we see
  528. // and check that we log in correctly.
  529. //
  530. // In #17361, there was a bug where we'd print two auth URLs, and you could
  531. // click either auth URL and log in to control, but logging in through the
  532. // first URL would leave `tailscale up` hanging.
  533. //
  534. // Using `authURLHandler` ensures we only print the new, correct auth URL.
  535. //
  536. // If we print both URLs, it will throw an error because it only expects
  537. // to log in with one auth URL.
  538. //
  539. // If we only print the stale auth URL, the test will timeout because
  540. // `tailscale up` will never return.
  541. t.Logf("Running command for the second time: %s", strings.Join(cmdArgs, " "))
  542. var authURLCount atomic.Int32
  543. cmd2 := n.Tailscale(cmdArgs...)
  544. cmd2.Stdout = &authURLParserWriter{
  545. t: t, authURLFn: completeLogin(t, env.Control, &authURLCount),
  546. }
  547. cmd2.Stderr = cmd2.Stdout
  548. if err := cmd2.Run(); err != nil {
  549. t.Fatalf("up: %v", err)
  550. }
  551. if urls := authURLCount.Load(); urls != 1 {
  552. t.Errorf("Auth URLs completed = %d; want %d", urls, 1)
  553. }
  554. n.AwaitRunning()
  555. }
  556. // If we interrupt `tailscale up` and login successfully, but don't
  557. // complete the device approval, we should see the device approval URL
  558. // when we run `tailscale up` a second time.
  559. func TestOneNodeUpInterruptedDeviceApproval(t *testing.T) {
  560. tstest.Shard(t)
  561. tstest.Parallel(t)
  562. env := NewTestEnv(t, ConfigureControl(
  563. func(control *testcontrol.Server) {
  564. control.RequireAuth = true
  565. control.RequireMachineAuth = true
  566. control.AllNodesSameUser = true
  567. },
  568. ))
  569. n := NewTestNode(t, env)
  570. d := n.StartDaemon()
  571. defer d.MustCleanShutdown(t)
  572. // The first time we run the command, we:
  573. //
  574. // * set a custom login URL
  575. // * wait for an auth URL to be printed
  576. // * click it to complete the login process
  577. // * wait for a device approval URL to be printed
  578. // * cancel the command, equivalent to ^C
  579. //
  580. // At this point, we've logged in to control, but our node isn't
  581. // approved to connect to the tailnet.
  582. cmd1Args := []string{"up", "--login-server=" + env.ControlURL()}
  583. t.Logf("Running command: %s", strings.Join(cmd1Args, " "))
  584. cmd1 := n.Tailscale(cmd1Args...)
  585. handler1 := &authURLParserWriter{t: t,
  586. authURLFn: completeLogin(t, env.Control, &atomic.Int32{}),
  587. deviceApprovalURLFn: func(urlStr string) error {
  588. t.Logf("saw device approval URL %q", urlStr)
  589. cmd1.Process.Kill()
  590. return nil
  591. },
  592. }
  593. cmd1.Stdout = handler1
  594. cmd1.Stderr = cmd1.Stdout
  595. if err := cmd1.Run(); !isNonZeroExitCode(err) {
  596. t.Fatalf("Command did not fail with non-zero exit code: %q", err)
  597. }
  598. // Because we logged in but we didn't complete the device approval, we
  599. // should be in state NeedsMachineAuth.
  600. n.AwaitBackendState("NeedsMachineAuth")
  601. // The second time we run the command, we expect not to get an auth URL
  602. // and go straight to the device approval URL. We don't need to pass the
  603. // login server, because `tailscale up` should remember our control URL.
  604. cmd2Args := []string{"up"}
  605. t.Logf("Running command: %s", strings.Join(cmd2Args, " "))
  606. var deviceApprovalURLCount atomic.Int32
  607. cmd2 := n.Tailscale(cmd2Args...)
  608. cmd2.Stdout = &authURLParserWriter{t: t,
  609. authURLFn: func(urlStr string) error {
  610. t.Fatalf("got unexpected auth URL: %q", urlStr)
  611. cmd2.Process.Kill()
  612. return nil
  613. },
  614. deviceApprovalURLFn: completeDeviceApproval(t, n, &deviceApprovalURLCount),
  615. }
  616. cmd2.Stderr = cmd2.Stdout
  617. if err := cmd2.Run(); err != nil {
  618. t.Fatalf("up: %v", err)
  619. }
  620. wantDeviceApprovalURLCount := int32(1)
  621. if n := deviceApprovalURLCount.Load(); n != wantDeviceApprovalURLCount {
  622. t.Errorf("Device approval URLs completed = %d; want %d", n, wantDeviceApprovalURLCount)
  623. }
  624. n.AwaitRunning()
  625. }
  626. func TestConfigFileAuthKey(t *testing.T) {
  627. tstest.SkipOnUnshardedCI(t)
  628. tstest.Shard(t)
  629. t.Parallel()
  630. const authKey = "opensesame"
  631. env := NewTestEnv(t, ConfigureControl(func(control *testcontrol.Server) {
  632. control.RequireAuthKey = authKey
  633. }))
  634. n1 := NewTestNode(t, env)
  635. n1.configFile = filepath.Join(n1.dir, "config.json")
  636. authKeyFile := filepath.Join(n1.dir, "my-auth-key")
  637. must.Do(os.WriteFile(authKeyFile, fmt.Appendf(nil, "%s\n", authKey), 0666))
  638. must.Do(os.WriteFile(n1.configFile, must.Get(json.Marshal(ipn.ConfigVAlpha{
  639. Version: "alpha0",
  640. AuthKey: ptr.To("file:" + authKeyFile),
  641. ServerURL: ptr.To(n1.env.ControlServer.URL),
  642. })), 0644))
  643. d1 := n1.StartDaemon()
  644. n1.AwaitListening()
  645. t.Logf("Got IP: %v", n1.AwaitIP4())
  646. n1.AwaitRunning()
  647. d1.MustCleanShutdown(t)
  648. }
  649. func TestTwoNodes(t *testing.T) {
  650. tstest.Shard(t)
  651. tstest.Parallel(t)
  652. env := NewTestEnv(t)
  653. // Create two nodes:
  654. n1 := NewTestNode(t, env)
  655. n1SocksAddrCh := n1.socks5AddrChan()
  656. d1 := n1.StartDaemon()
  657. n2 := NewTestNode(t, env)
  658. n2SocksAddrCh := n2.socks5AddrChan()
  659. d2 := n2.StartDaemon()
  660. // Drop some logs to disk on test failure.
  661. //
  662. // TODO(bradfitz): make all nodes for all tests do this? give each node a
  663. // unique integer within the test? But for now only do this test because
  664. // this is what we often saw flaking.
  665. t.Cleanup(func() {
  666. if !t.Failed() {
  667. return
  668. }
  669. n1.mu.Lock()
  670. n2.mu.Lock()
  671. defer n1.mu.Unlock()
  672. defer n2.mu.Unlock()
  673. rxNoDates := regexp.MustCompile(`(?m)^\d{4}.\d{2}.\d{2}.\d{2}:\d{2}:\d{2}`)
  674. cleanLog := func(n *TestNode) []byte {
  675. b := n.tailscaledParser.allBuf.Bytes()
  676. b = rxNoDates.ReplaceAll(b, nil)
  677. return b
  678. }
  679. t.Logf("writing tailscaled logs to n1.log and n2.log")
  680. os.WriteFile("n1.log", cleanLog(n1), 0666)
  681. os.WriteFile("n2.log", cleanLog(n2), 0666)
  682. })
  683. n1Socks := n1.AwaitSocksAddr(n1SocksAddrCh)
  684. n2Socks := n1.AwaitSocksAddr(n2SocksAddrCh)
  685. t.Logf("node1 SOCKS5 addr: %v", n1Socks)
  686. t.Logf("node2 SOCKS5 addr: %v", n2Socks)
  687. n1.AwaitListening()
  688. t.Logf("n1 is listening")
  689. n2.AwaitListening()
  690. t.Logf("n2 is listening")
  691. n1.MustUp()
  692. t.Logf("n1 is up")
  693. n2.MustUp()
  694. t.Logf("n2 is up")
  695. n1.AwaitRunning()
  696. t.Logf("n1 is running")
  697. n2.AwaitRunning()
  698. t.Logf("n2 is running")
  699. if err := tstest.WaitFor(2*time.Second, func() error {
  700. st := n1.MustStatus()
  701. if len(st.Peer) == 0 {
  702. return errors.New("no peers")
  703. }
  704. if len(st.Peer) > 1 {
  705. return fmt.Errorf("got %d peers; want 1", len(st.Peer))
  706. }
  707. peer := st.Peer[st.Peers()[0]]
  708. if peer.ID == st.Self.ID {
  709. return errors.New("peer is self")
  710. }
  711. if len(st.TailscaleIPs) == 0 {
  712. return errors.New("no Tailscale IPs")
  713. }
  714. return nil
  715. }); err != nil {
  716. t.Error(err)
  717. }
  718. d1.MustCleanShutdown(t)
  719. d2.MustCleanShutdown(t)
  720. }
  721. // tests two nodes where the first gets a incremental MapResponse (with only
  722. // PeersRemoved set) saying that the second node disappeared.
  723. func TestIncrementalMapUpdatePeersRemoved(t *testing.T) {
  724. tstest.Shard(t)
  725. tstest.Parallel(t)
  726. env := NewTestEnv(t)
  727. // Create one node:
  728. n1 := NewTestNode(t, env)
  729. d1 := n1.StartDaemon()
  730. n1.AwaitListening()
  731. n1.MustUp()
  732. n1.AwaitRunning()
  733. all := env.Control.AllNodes()
  734. if len(all) != 1 {
  735. t.Fatalf("expected 1 node, got %d nodes", len(all))
  736. }
  737. tnode1 := all[0]
  738. n2 := NewTestNode(t, env)
  739. d2 := n2.StartDaemon()
  740. n2.AwaitListening()
  741. n2.MustUp()
  742. n2.AwaitRunning()
  743. all = env.Control.AllNodes()
  744. if len(all) != 2 {
  745. t.Fatalf("expected 2 node, got %d nodes", len(all))
  746. }
  747. var tnode2 *tailcfg.Node
  748. for _, n := range all {
  749. if n.ID != tnode1.ID {
  750. tnode2 = n
  751. break
  752. }
  753. }
  754. if tnode2 == nil {
  755. t.Fatalf("failed to find second node ID (two dups?)")
  756. }
  757. t.Logf("node1=%v, node2=%v", tnode1.ID, tnode2.ID)
  758. if err := tstest.WaitFor(2*time.Second, func() error {
  759. st := n1.MustStatus()
  760. if len(st.Peer) == 0 {
  761. return errors.New("no peers")
  762. }
  763. if len(st.Peer) > 1 {
  764. return fmt.Errorf("got %d peers; want 1", len(st.Peer))
  765. }
  766. peer := st.Peer[st.Peers()[0]]
  767. if peer.ID == st.Self.ID {
  768. return errors.New("peer is self")
  769. }
  770. return nil
  771. }); err != nil {
  772. t.Fatal(err)
  773. }
  774. t.Logf("node1 saw node2")
  775. // Now tell node1 that node2 is removed.
  776. if !env.Control.AddRawMapResponse(tnode1.Key, &tailcfg.MapResponse{
  777. PeersRemoved: []tailcfg.NodeID{tnode2.ID},
  778. }) {
  779. t.Fatalf("failed to add map response")
  780. }
  781. // And see that node1 saw that.
  782. if err := tstest.WaitFor(2*time.Second, func() error {
  783. st := n1.MustStatus()
  784. if len(st.Peer) == 0 {
  785. return nil
  786. }
  787. return fmt.Errorf("got %d peers; want 0", len(st.Peer))
  788. }); err != nil {
  789. t.Fatal(err)
  790. }
  791. t.Logf("node1 saw node2 disappear")
  792. d1.MustCleanShutdown(t)
  793. d2.MustCleanShutdown(t)
  794. }
  795. func TestNodeAddressIPFields(t *testing.T) {
  796. tstest.Shard(t)
  797. flakytest.Mark(t, "https://github.com/tailscale/tailscale/issues/7008")
  798. tstest.Parallel(t)
  799. env := NewTestEnv(t)
  800. n1 := NewTestNode(t, env)
  801. d1 := n1.StartDaemon()
  802. n1.AwaitListening()
  803. n1.MustUp()
  804. n1.AwaitRunning()
  805. testNodes := env.Control.AllNodes()
  806. if len(testNodes) != 1 {
  807. t.Errorf("Expected %d nodes, got %d", 1, len(testNodes))
  808. }
  809. node := testNodes[0]
  810. if len(node.Addresses) == 0 {
  811. t.Errorf("Empty Addresses field in node")
  812. }
  813. if len(node.AllowedIPs) == 0 {
  814. t.Errorf("Empty AllowedIPs field in node")
  815. }
  816. d1.MustCleanShutdown(t)
  817. }
  818. func TestAddPingRequest(t *testing.T) {
  819. tstest.Shard(t)
  820. tstest.Parallel(t)
  821. env := NewTestEnv(t)
  822. n1 := NewTestNode(t, env)
  823. n1.StartDaemon()
  824. n1.AwaitListening()
  825. n1.MustUp()
  826. n1.AwaitRunning()
  827. gotPing := make(chan bool, 1)
  828. waitPing := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  829. gotPing <- true
  830. }))
  831. defer waitPing.Close()
  832. nodes := env.Control.AllNodes()
  833. if len(nodes) != 1 {
  834. t.Fatalf("expected 1 node, got %d nodes", len(nodes))
  835. }
  836. nodeKey := nodes[0].Key
  837. // Check that we get at least one ping reply after 10 tries.
  838. for try := 1; try <= 10; try++ {
  839. t.Logf("ping %v ...", try)
  840. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  841. if err := env.Control.AwaitNodeInMapRequest(ctx, nodeKey); err != nil {
  842. t.Fatal(err)
  843. }
  844. cancel()
  845. pr := &tailcfg.PingRequest{URL: fmt.Sprintf("%s/ping-%d", waitPing.URL, try), Log: true}
  846. if !env.Control.AddPingRequest(nodeKey, pr) {
  847. t.Logf("failed to AddPingRequest")
  848. continue
  849. }
  850. // Wait for PingRequest to come back
  851. pingTimeout := time.NewTimer(2 * time.Second)
  852. defer pingTimeout.Stop()
  853. select {
  854. case <-gotPing:
  855. t.Logf("got ping; success")
  856. return
  857. case <-pingTimeout.C:
  858. // Try again.
  859. }
  860. }
  861. t.Error("all ping attempts failed")
  862. }
  863. func TestC2NPingRequest(t *testing.T) {
  864. tstest.Shard(t)
  865. tstest.Parallel(t)
  866. env := NewTestEnv(t)
  867. n1 := NewTestNode(t, env)
  868. n1.StartDaemon()
  869. n1.AwaitListening()
  870. n1.MustUp()
  871. n1.AwaitRunning()
  872. nodes := env.Control.AllNodes()
  873. if len(nodes) != 1 {
  874. t.Fatalf("expected 1 node, got %d nodes", len(nodes))
  875. }
  876. nodeKey := nodes[0].Key
  877. // Check that we get at least one ping reply after 10 tries.
  878. for try := 1; try <= 10; try++ {
  879. t.Logf("ping %v ...", try)
  880. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  881. if err := env.Control.AwaitNodeInMapRequest(ctx, nodeKey); err != nil {
  882. t.Fatal(err)
  883. }
  884. cancel()
  885. ctx, cancel = context.WithTimeout(t.Context(), 2*time.Second)
  886. defer cancel()
  887. req, err := http.NewRequestWithContext(ctx, "POST", "/echo", bytes.NewReader([]byte("abc")))
  888. if err != nil {
  889. t.Errorf("failed to create request: %v", err)
  890. continue
  891. }
  892. r, err := env.Control.NodeRoundTripper(nodeKey).RoundTrip(req)
  893. if err != nil {
  894. t.Errorf("RoundTrip failed: %v", err)
  895. continue
  896. }
  897. if r.StatusCode != 200 {
  898. t.Errorf("unexpected status code: %d", r.StatusCode)
  899. continue
  900. }
  901. b, err := io.ReadAll(r.Body)
  902. if err != nil {
  903. t.Errorf("error reading body: %v", err)
  904. continue
  905. }
  906. if string(b) != "abc" {
  907. t.Errorf("body = %q; want %q", b, "abc")
  908. continue
  909. }
  910. return
  911. }
  912. t.Error("all ping attempts failed")
  913. }
  914. // Issue 2434: when "down" (WantRunning false), tailscaled shouldn't
  915. // be connected to control.
  916. func TestNoControlConnWhenDown(t *testing.T) {
  917. tstest.Shard(t)
  918. tstest.Parallel(t)
  919. env := NewTestEnv(t)
  920. n1 := NewTestNode(t, env)
  921. d1 := n1.StartDaemon()
  922. n1.AwaitResponding()
  923. // Come up the first time.
  924. n1.MustUp()
  925. ip1 := n1.AwaitIP4()
  926. n1.AwaitRunning()
  927. // Then bring it down and stop the daemon.
  928. n1.MustDown()
  929. d1.MustCleanShutdown(t)
  930. env.LogCatcher.Reset()
  931. d2 := n1.StartDaemon()
  932. n1.AwaitResponding()
  933. n1.AwaitBackendState("Stopped")
  934. ip2 := n1.AwaitIP4()
  935. if ip1 != ip2 {
  936. t.Errorf("IPs different: %q vs %q", ip1, ip2)
  937. }
  938. // The real test: verify our daemon doesn't have an HTTP request open.
  939. if n := env.Control.InServeMap(); n != 0 {
  940. t.Errorf("in serve map = %d; want 0", n)
  941. }
  942. d2.MustCleanShutdown(t)
  943. }
  944. // Issue 2137: make sure Windows tailscaled works with the CLI alone,
  945. // without the GUI to kick off a Start.
  946. func TestOneNodeUpWindowsStyle(t *testing.T) {
  947. tstest.Shard(t)
  948. tstest.Parallel(t)
  949. env := NewTestEnv(t)
  950. n1 := NewTestNode(t, env)
  951. n1.upFlagGOOS = "windows"
  952. d1 := n1.StartDaemonAsIPNGOOS("windows")
  953. n1.AwaitResponding()
  954. n1.MustUp("--unattended")
  955. t.Logf("Got IP: %v", n1.AwaitIP4())
  956. n1.AwaitRunning()
  957. d1.MustCleanShutdown(t)
  958. }
  959. // TestClientSideJailing tests that when one node is jailed for another, the
  960. // jailed node cannot initiate connections to the other node however the other
  961. // node can initiate connections to the jailed node.
  962. func TestClientSideJailing(t *testing.T) {
  963. flakytest.Mark(t, "https://github.com/tailscale/tailscale/issues/17419")
  964. tstest.Shard(t)
  965. tstest.Parallel(t)
  966. env := NewTestEnv(t)
  967. registerNode := func() (*TestNode, key.NodePublic) {
  968. n := NewTestNode(t, env)
  969. n.StartDaemon()
  970. n.AwaitListening()
  971. n.MustUp()
  972. n.AwaitRunning()
  973. k := n.MustStatus().Self.PublicKey
  974. return n, k
  975. }
  976. n1, k1 := registerNode()
  977. n2, k2 := registerNode()
  978. ln, err := net.Listen("tcp", "localhost:0")
  979. if err != nil {
  980. t.Fatal(err)
  981. }
  982. defer ln.Close()
  983. port := uint16(ln.Addr().(*net.TCPAddr).Port)
  984. lc1 := &local.Client{
  985. Socket: n1.sockFile,
  986. UseSocketOnly: true,
  987. }
  988. lc2 := &local.Client{
  989. Socket: n2.sockFile,
  990. UseSocketOnly: true,
  991. }
  992. ip1 := n1.AwaitIP4()
  993. ip2 := n2.AwaitIP4()
  994. tests := []struct {
  995. name string
  996. n1JailedForN2 bool
  997. n2JailedForN1 bool
  998. }{
  999. {
  1000. name: "not_jailed",
  1001. n1JailedForN2: false,
  1002. n2JailedForN1: false,
  1003. },
  1004. {
  1005. name: "uni_jailed",
  1006. n1JailedForN2: true,
  1007. n2JailedForN1: false,
  1008. },
  1009. {
  1010. name: "bi_jailed", // useless config?
  1011. n1JailedForN2: true,
  1012. n2JailedForN1: true,
  1013. },
  1014. }
  1015. testDial := func(t *testing.T, lc *local.Client, ip netip.Addr, port uint16, shouldFail bool) {
  1016. t.Helper()
  1017. ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1018. defer cancel()
  1019. c, err := lc.DialTCP(ctx, ip.String(), port)
  1020. failed := err != nil
  1021. if failed != shouldFail {
  1022. t.Errorf("failed = %v; want %v", failed, shouldFail)
  1023. }
  1024. if c != nil {
  1025. c.Close()
  1026. }
  1027. }
  1028. b1, err := lc1.WatchIPNBus(context.Background(), 0)
  1029. if err != nil {
  1030. t.Fatal(err)
  1031. }
  1032. b2, err := lc2.WatchIPNBus(context.Background(), 0)
  1033. if err != nil {
  1034. t.Fatal(err)
  1035. }
  1036. waitPeerIsJailed := func(t *testing.T, b *tailscale.IPNBusWatcher, jailed bool) {
  1037. t.Helper()
  1038. for {
  1039. n, err := b.Next()
  1040. if err != nil {
  1041. t.Fatal(err)
  1042. }
  1043. if n.NetMap == nil {
  1044. continue
  1045. }
  1046. if len(n.NetMap.Peers) == 0 {
  1047. continue
  1048. }
  1049. if j := n.NetMap.Peers[0].IsJailed(); j == jailed {
  1050. break
  1051. }
  1052. }
  1053. }
  1054. for _, tc := range tests {
  1055. t.Run(tc.name, func(t *testing.T) {
  1056. env.Control.SetJailed(k1, k2, tc.n2JailedForN1)
  1057. env.Control.SetJailed(k2, k1, tc.n1JailedForN2)
  1058. // Wait for the jailed status to propagate.
  1059. waitPeerIsJailed(t, b1, tc.n2JailedForN1)
  1060. waitPeerIsJailed(t, b2, tc.n1JailedForN2)
  1061. testDial(t, lc1, ip2, port, tc.n1JailedForN2)
  1062. testDial(t, lc2, ip1, port, tc.n2JailedForN1)
  1063. })
  1064. }
  1065. }
  1066. // TestNATPing creates two nodes, n1 and n2, sets up masquerades for both and
  1067. // tries to do bi-directional pings between them.
  1068. func TestNATPing(t *testing.T) {
  1069. flakytest.Mark(t, "https://github.com/tailscale/tailscale/issues/12169")
  1070. tstest.Shard(t)
  1071. tstest.Parallel(t)
  1072. for _, v6 := range []bool{false, true} {
  1073. env := NewTestEnv(t)
  1074. registerNode := func() (*TestNode, key.NodePublic) {
  1075. n := NewTestNode(t, env)
  1076. n.StartDaemon()
  1077. n.AwaitListening()
  1078. n.MustUp()
  1079. n.AwaitRunning()
  1080. k := n.MustStatus().Self.PublicKey
  1081. return n, k
  1082. }
  1083. n1, k1 := registerNode()
  1084. n2, k2 := registerNode()
  1085. var n1IP, n2IP netip.Addr
  1086. if v6 {
  1087. n1IP = n1.AwaitIP6()
  1088. n2IP = n2.AwaitIP6()
  1089. } else {
  1090. n1IP = n1.AwaitIP4()
  1091. n2IP = n2.AwaitIP4()
  1092. }
  1093. n1ExternalIP := netip.MustParseAddr("100.64.1.1")
  1094. n2ExternalIP := netip.MustParseAddr("100.64.2.1")
  1095. if v6 {
  1096. n1ExternalIP = netip.MustParseAddr("fd7a:115c:a1e0::1a")
  1097. n2ExternalIP = netip.MustParseAddr("fd7a:115c:a1e0::1b")
  1098. }
  1099. tests := []struct {
  1100. name string
  1101. pairs []testcontrol.MasqueradePair
  1102. n1SeesN2IP netip.Addr
  1103. n2SeesN1IP netip.Addr
  1104. }{
  1105. {
  1106. name: "no_nat",
  1107. n1SeesN2IP: n2IP,
  1108. n2SeesN1IP: n1IP,
  1109. },
  1110. {
  1111. name: "n1_has_external_ip",
  1112. pairs: []testcontrol.MasqueradePair{
  1113. {
  1114. Node: k1,
  1115. Peer: k2,
  1116. NodeMasqueradesAs: n1ExternalIP,
  1117. },
  1118. },
  1119. n1SeesN2IP: n2IP,
  1120. n2SeesN1IP: n1ExternalIP,
  1121. },
  1122. {
  1123. name: "n2_has_external_ip",
  1124. pairs: []testcontrol.MasqueradePair{
  1125. {
  1126. Node: k2,
  1127. Peer: k1,
  1128. NodeMasqueradesAs: n2ExternalIP,
  1129. },
  1130. },
  1131. n1SeesN2IP: n2ExternalIP,
  1132. n2SeesN1IP: n1IP,
  1133. },
  1134. {
  1135. name: "both_have_external_ips",
  1136. pairs: []testcontrol.MasqueradePair{
  1137. {
  1138. Node: k1,
  1139. Peer: k2,
  1140. NodeMasqueradesAs: n1ExternalIP,
  1141. },
  1142. {
  1143. Node: k2,
  1144. Peer: k1,
  1145. NodeMasqueradesAs: n2ExternalIP,
  1146. },
  1147. },
  1148. n1SeesN2IP: n2ExternalIP,
  1149. n2SeesN1IP: n1ExternalIP,
  1150. },
  1151. }
  1152. for _, tc := range tests {
  1153. t.Run(fmt.Sprintf("v6=%t/%v", v6, tc.name), func(t *testing.T) {
  1154. env.Control.SetMasqueradeAddresses(tc.pairs)
  1155. ipIdx := 0
  1156. if v6 {
  1157. ipIdx = 1
  1158. }
  1159. s1 := n1.MustStatus()
  1160. n2AsN1Peer := s1.Peer[k2]
  1161. if got := n2AsN1Peer.TailscaleIPs[ipIdx]; got != tc.n1SeesN2IP {
  1162. t.Fatalf("n1 sees n2 as %v; want %v", got, tc.n1SeesN2IP)
  1163. }
  1164. s2 := n2.MustStatus()
  1165. n1AsN2Peer := s2.Peer[k1]
  1166. if got := n1AsN2Peer.TailscaleIPs[ipIdx]; got != tc.n2SeesN1IP {
  1167. t.Fatalf("n2 sees n1 as %v; want %v", got, tc.n2SeesN1IP)
  1168. }
  1169. if err := n1.Tailscale("ping", tc.n1SeesN2IP.String()).Run(); err != nil {
  1170. t.Fatal(err)
  1171. }
  1172. if err := n1.Tailscale("ping", "-peerapi", tc.n1SeesN2IP.String()).Run(); err != nil {
  1173. t.Fatal(err)
  1174. }
  1175. if err := n2.Tailscale("ping", tc.n2SeesN1IP.String()).Run(); err != nil {
  1176. t.Fatal(err)
  1177. }
  1178. if err := n2.Tailscale("ping", "-peerapi", tc.n2SeesN1IP.String()).Run(); err != nil {
  1179. t.Fatal(err)
  1180. }
  1181. })
  1182. }
  1183. }
  1184. }
  1185. func TestLogoutRemovesAllPeers(t *testing.T) {
  1186. tstest.Shard(t)
  1187. tstest.Parallel(t)
  1188. env := NewTestEnv(t)
  1189. // Spin up some nodes.
  1190. nodes := make([]*TestNode, 2)
  1191. for i := range nodes {
  1192. nodes[i] = NewTestNode(t, env)
  1193. nodes[i].StartDaemon()
  1194. nodes[i].AwaitResponding()
  1195. nodes[i].MustUp()
  1196. nodes[i].AwaitIP4()
  1197. nodes[i].AwaitRunning()
  1198. }
  1199. expectedPeers := len(nodes) - 1
  1200. // Make every node ping every other node.
  1201. // This makes sure magicsock is fully populated.
  1202. for i := range nodes {
  1203. for j := range nodes {
  1204. if i <= j {
  1205. continue
  1206. }
  1207. if err := tstest.WaitFor(20*time.Second, func() error {
  1208. return nodes[i].Ping(nodes[j])
  1209. }); err != nil {
  1210. t.Fatalf("ping %v -> %v: %v", nodes[i].AwaitIP4(), nodes[j].AwaitIP4(), err)
  1211. }
  1212. }
  1213. }
  1214. // wantNode0PeerCount waits until node[0] status includes exactly want peers.
  1215. wantNode0PeerCount := func(want int) {
  1216. if err := tstest.WaitFor(20*time.Second, func() error {
  1217. s := nodes[0].MustStatus()
  1218. if peers := s.Peers(); len(peers) != want {
  1219. return fmt.Errorf("want %d peer(s) in status, got %v", want, peers)
  1220. }
  1221. return nil
  1222. }); err != nil {
  1223. t.Fatal(err)
  1224. }
  1225. }
  1226. wantNode0PeerCount(expectedPeers) // all other nodes are peers
  1227. nodes[0].MustLogOut()
  1228. wantNode0PeerCount(0) // node[0] is logged out, so it should not have any peers
  1229. nodes[0].MustUp() // This will create a new node
  1230. expectedPeers++
  1231. nodes[0].AwaitIP4()
  1232. wantNode0PeerCount(expectedPeers) // all existing peers and the new node
  1233. }
  1234. func TestAutoUpdateDefaults(t *testing.T) { testAutoUpdateDefaults(t, false) }
  1235. func TestAutoUpdateDefaults_cap(t *testing.T) { testAutoUpdateDefaults(t, true) }
  1236. // useCap is whether to use NodeAttrDefaultAutoUpdate (as opposed to the old
  1237. // DeprecatedDefaultAutoUpdate top-level MapResponse field).
  1238. func testAutoUpdateDefaults(t *testing.T, useCap bool) {
  1239. t.Cleanup(feature.HookCanAutoUpdate.SetForTest(func() bool { return true }))
  1240. tstest.Shard(t)
  1241. env := NewTestEnv(t)
  1242. var (
  1243. modifyMu sync.Mutex
  1244. modifyFirstMapResponse = func(*tailcfg.MapResponse, *tailcfg.MapRequest) {}
  1245. )
  1246. env.Control.ModifyFirstMapResponse = func(mr *tailcfg.MapResponse, req *tailcfg.MapRequest) {
  1247. modifyMu.Lock()
  1248. defer modifyMu.Unlock()
  1249. modifyFirstMapResponse(mr, req)
  1250. }
  1251. checkDefault := func(n *TestNode, want bool) error {
  1252. enabled, ok := n.diskPrefs().AutoUpdate.Apply.Get()
  1253. if !ok {
  1254. return fmt.Errorf("auto-update for node is unset, should be set as %v", want)
  1255. }
  1256. if enabled != want {
  1257. return fmt.Errorf("auto-update for node is %v, should be set as %v", enabled, want)
  1258. }
  1259. return nil
  1260. }
  1261. setDefaultAutoUpdate := func(send bool) {
  1262. modifyMu.Lock()
  1263. defer modifyMu.Unlock()
  1264. modifyFirstMapResponse = func(mr *tailcfg.MapResponse, req *tailcfg.MapRequest) {
  1265. if mr.Node == nil {
  1266. mr.Node = &tailcfg.Node{}
  1267. }
  1268. if useCap {
  1269. if mr.Node.CapMap == nil {
  1270. mr.Node.CapMap = make(tailcfg.NodeCapMap)
  1271. }
  1272. mr.Node.CapMap[tailcfg.NodeAttrDefaultAutoUpdate] = []tailcfg.RawMessage{
  1273. tailcfg.RawMessage(fmt.Sprintf("%t", send)),
  1274. }
  1275. } else {
  1276. mr.DeprecatedDefaultAutoUpdate = opt.NewBool(send)
  1277. }
  1278. }
  1279. }
  1280. tests := []struct {
  1281. desc string
  1282. run func(t *testing.T, n *TestNode)
  1283. }{
  1284. {
  1285. desc: "tailnet-default-false",
  1286. run: func(t *testing.T, n *TestNode) {
  1287. // First the server sends "false", and client should remember that.
  1288. setDefaultAutoUpdate(false)
  1289. n.MustUp()
  1290. n.AwaitRunning()
  1291. checkDefault(n, false)
  1292. // Now we disconnect and change the server to send "true", which
  1293. // the client should ignore, having previously remembered
  1294. // "false".
  1295. n.MustDown()
  1296. setDefaultAutoUpdate(true) // control sends default "true"
  1297. n.MustUp()
  1298. n.AwaitRunning()
  1299. checkDefault(n, false) // still false
  1300. // But can be changed explicitly by the user.
  1301. if out, err := n.TailscaleForOutput("set", "--auto-update").CombinedOutput(); err != nil {
  1302. t.Fatalf("failed to enable auto-update on node: %v\noutput: %s", err, out)
  1303. }
  1304. checkDefault(n, true)
  1305. },
  1306. },
  1307. {
  1308. desc: "tailnet-default-true",
  1309. run: func(t *testing.T, n *TestNode) {
  1310. // Same as above but starting with default "true".
  1311. // First the server sends "true", and client should remember that.
  1312. setDefaultAutoUpdate(true)
  1313. n.MustUp()
  1314. n.AwaitRunning()
  1315. checkDefault(n, true)
  1316. // Now we disconnect and change the server to send "false", which
  1317. // the client should ignore, having previously remembered
  1318. // "true".
  1319. n.MustDown()
  1320. setDefaultAutoUpdate(false) // control sends default "false"
  1321. n.MustUp()
  1322. n.AwaitRunning()
  1323. checkDefault(n, true) // still true
  1324. // But can be changed explicitly by the user.
  1325. if out, err := n.TailscaleForOutput("set", "--auto-update=false").CombinedOutput(); err != nil {
  1326. t.Fatalf("failed to enable auto-update on node: %v\noutput: %s", err, out)
  1327. }
  1328. checkDefault(n, false)
  1329. },
  1330. },
  1331. {
  1332. desc: "user-sets-first",
  1333. run: func(t *testing.T, n *TestNode) {
  1334. // User sets auto-update first, before receiving defaults.
  1335. if out, err := n.TailscaleForOutput("set", "--auto-update=false").CombinedOutput(); err != nil {
  1336. t.Fatalf("failed to disable auto-update on node: %v\noutput: %s", err, out)
  1337. }
  1338. setDefaultAutoUpdate(true)
  1339. n.MustUp()
  1340. n.AwaitRunning()
  1341. checkDefault(n, false)
  1342. },
  1343. },
  1344. }
  1345. for _, tt := range tests {
  1346. t.Run(tt.desc, func(t *testing.T) {
  1347. n := NewTestNode(t, env)
  1348. n.allowUpdates = true
  1349. d := n.StartDaemon()
  1350. defer d.MustCleanShutdown(t)
  1351. n.AwaitResponding()
  1352. tt.run(t, n)
  1353. })
  1354. }
  1355. }
  1356. // TestDNSOverTCPIntervalResolver tests that the quad-100 resolver successfully
  1357. // serves TCP queries. It exercises the host's TCP stack, a TUN device, and
  1358. // gVisor/netstack.
  1359. // https://github.com/tailscale/corp/issues/22511
  1360. func TestDNSOverTCPIntervalResolver(t *testing.T) {
  1361. tstest.Shard(t)
  1362. if os.Getuid() != 0 {
  1363. t.Skip("skipping when not root")
  1364. }
  1365. env := NewTestEnv(t)
  1366. env.tunMode = true
  1367. n1 := NewTestNode(t, env)
  1368. d1 := n1.StartDaemon()
  1369. n1.AwaitResponding()
  1370. n1.MustUp()
  1371. n1.AwaitRunning()
  1372. const dnsSymbolicFQDN = "magicdns.localhost-tailscale-daemon."
  1373. cases := []struct {
  1374. network string
  1375. serviceAddr netip.Addr
  1376. }{
  1377. {
  1378. "tcp4",
  1379. tsaddr.TailscaleServiceIP(),
  1380. },
  1381. {
  1382. "tcp6",
  1383. tsaddr.TailscaleServiceIPv6(),
  1384. },
  1385. }
  1386. for _, c := range cases {
  1387. err := tstest.WaitFor(time.Second*5, func() error {
  1388. m := new(dns.Msg)
  1389. m.SetQuestion(dnsSymbolicFQDN, dns.TypeA)
  1390. conn, err := net.DialTimeout(c.network, net.JoinHostPort(c.serviceAddr.String(), "53"), time.Second*1)
  1391. if err != nil {
  1392. return err
  1393. }
  1394. defer conn.Close()
  1395. dnsConn := &dns.Conn{
  1396. Conn: conn,
  1397. }
  1398. dnsClient := &dns.Client{}
  1399. ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1400. defer cancel()
  1401. resp, _, err := dnsClient.ExchangeWithConnContext(ctx, m, dnsConn)
  1402. if err != nil {
  1403. return err
  1404. }
  1405. if len(resp.Answer) != 1 {
  1406. return fmt.Errorf("unexpected DNS resp: %s", resp)
  1407. }
  1408. var gotAddr net.IP
  1409. answer, ok := resp.Answer[0].(*dns.A)
  1410. if !ok {
  1411. return fmt.Errorf("unexpected answer type: %s", resp.Answer[0])
  1412. }
  1413. gotAddr = answer.A
  1414. if !bytes.Equal(gotAddr, tsaddr.TailscaleServiceIP().AsSlice()) {
  1415. return fmt.Errorf("got (%s) != want (%s)", gotAddr, tsaddr.TailscaleServiceIP())
  1416. }
  1417. return nil
  1418. })
  1419. if err != nil {
  1420. t.Fatal(err)
  1421. }
  1422. }
  1423. d1.MustCleanShutdown(t)
  1424. }
  1425. // TestNetstackTCPLoopback tests netstack loopback of a TCP stream, in both
  1426. // directions.
  1427. func TestNetstackTCPLoopback(t *testing.T) {
  1428. tstest.Shard(t)
  1429. if os.Getuid() != 0 {
  1430. t.Skip("skipping when not root")
  1431. }
  1432. env := NewTestEnv(t)
  1433. env.tunMode = true
  1434. loopbackPort := 5201
  1435. env.loopbackPort = &loopbackPort
  1436. loopbackPortStr := strconv.Itoa(loopbackPort)
  1437. n1 := NewTestNode(t, env)
  1438. d1 := n1.StartDaemon()
  1439. n1.AwaitResponding()
  1440. n1.MustUp()
  1441. n1.AwaitIP4()
  1442. n1.AwaitRunning()
  1443. cases := []struct {
  1444. lisAddr string
  1445. network string
  1446. dialAddr string
  1447. }{
  1448. {
  1449. lisAddr: net.JoinHostPort("127.0.0.1", loopbackPortStr),
  1450. network: "tcp4",
  1451. dialAddr: net.JoinHostPort(tsaddr.TailscaleServiceIPString, loopbackPortStr),
  1452. },
  1453. {
  1454. lisAddr: net.JoinHostPort("::1", loopbackPortStr),
  1455. network: "tcp6",
  1456. dialAddr: net.JoinHostPort(tsaddr.TailscaleServiceIPv6String, loopbackPortStr),
  1457. },
  1458. }
  1459. writeBufSize := 128 << 10 // 128KiB, exercise GSO if enabled
  1460. writeBufIterations := 100 // allow TCP send window to open up
  1461. wantTotal := writeBufSize * writeBufIterations
  1462. for _, c := range cases {
  1463. lis, err := net.Listen(c.network, c.lisAddr)
  1464. if err != nil {
  1465. t.Fatal(err)
  1466. }
  1467. defer lis.Close()
  1468. writeFn := func(conn net.Conn) error {
  1469. for i := 0; i < writeBufIterations; i++ {
  1470. toWrite := make([]byte, writeBufSize)
  1471. var wrote int
  1472. for {
  1473. n, err := conn.Write(toWrite)
  1474. if err != nil {
  1475. return err
  1476. }
  1477. wrote += n
  1478. if wrote == len(toWrite) {
  1479. break
  1480. }
  1481. }
  1482. }
  1483. return nil
  1484. }
  1485. readFn := func(conn net.Conn) error {
  1486. var read int
  1487. for {
  1488. b := make([]byte, writeBufSize)
  1489. n, err := conn.Read(b)
  1490. if err != nil {
  1491. return err
  1492. }
  1493. read += n
  1494. if read == wantTotal {
  1495. return nil
  1496. }
  1497. }
  1498. }
  1499. lisStepCh := make(chan error)
  1500. go func() {
  1501. conn, err := lis.Accept()
  1502. if err != nil {
  1503. lisStepCh <- err
  1504. return
  1505. }
  1506. lisStepCh <- readFn(conn)
  1507. lisStepCh <- writeFn(conn)
  1508. }()
  1509. var conn net.Conn
  1510. err = tstest.WaitFor(time.Second*5, func() error {
  1511. conn, err = net.DialTimeout(c.network, c.dialAddr, time.Second*1)
  1512. if err != nil {
  1513. return err
  1514. }
  1515. return nil
  1516. })
  1517. if err != nil {
  1518. t.Fatal(err)
  1519. }
  1520. defer conn.Close()
  1521. dialerStepCh := make(chan error)
  1522. go func() {
  1523. dialerStepCh <- writeFn(conn)
  1524. dialerStepCh <- readFn(conn)
  1525. }()
  1526. var (
  1527. dialerSteps int
  1528. lisSteps int
  1529. )
  1530. for {
  1531. select {
  1532. case lisErr := <-lisStepCh:
  1533. if lisErr != nil {
  1534. t.Fatal(err)
  1535. }
  1536. lisSteps++
  1537. if dialerSteps == 2 && lisSteps == 2 {
  1538. return
  1539. }
  1540. case dialerErr := <-dialerStepCh:
  1541. if dialerErr != nil {
  1542. t.Fatal(err)
  1543. }
  1544. dialerSteps++
  1545. if dialerSteps == 2 && lisSteps == 2 {
  1546. return
  1547. }
  1548. }
  1549. }
  1550. }
  1551. d1.MustCleanShutdown(t)
  1552. }
  1553. // TestNetstackUDPLoopback tests netstack loopback of UDP packets, in both
  1554. // directions.
  1555. func TestNetstackUDPLoopback(t *testing.T) {
  1556. tstest.Shard(t)
  1557. if os.Getuid() != 0 {
  1558. t.Skip("skipping when not root")
  1559. }
  1560. env := NewTestEnv(t)
  1561. env.tunMode = true
  1562. loopbackPort := 5201
  1563. env.loopbackPort = &loopbackPort
  1564. n1 := NewTestNode(t, env)
  1565. d1 := n1.StartDaemon()
  1566. n1.AwaitResponding()
  1567. n1.MustUp()
  1568. ip4 := n1.AwaitIP4()
  1569. ip6 := n1.AwaitIP6()
  1570. n1.AwaitRunning()
  1571. cases := []struct {
  1572. pingerLAddr *net.UDPAddr
  1573. pongerLAddr *net.UDPAddr
  1574. network string
  1575. dialAddr *net.UDPAddr
  1576. }{
  1577. {
  1578. pingerLAddr: &net.UDPAddr{IP: ip4.AsSlice(), Port: loopbackPort + 1},
  1579. pongerLAddr: &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: loopbackPort},
  1580. network: "udp4",
  1581. dialAddr: &net.UDPAddr{IP: tsaddr.TailscaleServiceIP().AsSlice(), Port: loopbackPort},
  1582. },
  1583. {
  1584. pingerLAddr: &net.UDPAddr{IP: ip6.AsSlice(), Port: loopbackPort + 1},
  1585. pongerLAddr: &net.UDPAddr{IP: net.ParseIP("::1"), Port: loopbackPort},
  1586. network: "udp6",
  1587. dialAddr: &net.UDPAddr{IP: tsaddr.TailscaleServiceIPv6().AsSlice(), Port: loopbackPort},
  1588. },
  1589. }
  1590. writeBufSize := int(tstun.DefaultTUNMTU()) - 40 - 8 // mtu - ipv6 header - udp header
  1591. wantPongs := 100
  1592. for _, c := range cases {
  1593. pongerConn, err := net.ListenUDP(c.network, c.pongerLAddr)
  1594. if err != nil {
  1595. t.Fatal(err)
  1596. }
  1597. defer pongerConn.Close()
  1598. var pingerConn *net.UDPConn
  1599. err = tstest.WaitFor(time.Second*5, func() error {
  1600. pingerConn, err = net.DialUDP(c.network, c.pingerLAddr, c.dialAddr)
  1601. return err
  1602. })
  1603. if err != nil {
  1604. t.Fatal(err)
  1605. }
  1606. defer pingerConn.Close()
  1607. pingerFn := func(conn *net.UDPConn) error {
  1608. b := make([]byte, writeBufSize)
  1609. n, err := conn.Write(b)
  1610. if err != nil {
  1611. return err
  1612. }
  1613. if n != len(b) {
  1614. return fmt.Errorf("bad write size: %d", n)
  1615. }
  1616. err = conn.SetReadDeadline(time.Now().Add(time.Millisecond * 500))
  1617. if err != nil {
  1618. return err
  1619. }
  1620. n, err = conn.Read(b)
  1621. if err != nil {
  1622. return err
  1623. }
  1624. if n != len(b) {
  1625. return fmt.Errorf("bad read size: %d", n)
  1626. }
  1627. return nil
  1628. }
  1629. pongerFn := func(conn *net.UDPConn) error {
  1630. for {
  1631. b := make([]byte, writeBufSize)
  1632. n, from, err := conn.ReadFromUDP(b)
  1633. if err != nil {
  1634. return err
  1635. }
  1636. if n != len(b) {
  1637. return fmt.Errorf("bad read size: %d", n)
  1638. }
  1639. n, err = conn.WriteToUDP(b, from)
  1640. if err != nil {
  1641. return err
  1642. }
  1643. if n != len(b) {
  1644. return fmt.Errorf("bad write size: %d", n)
  1645. }
  1646. }
  1647. }
  1648. pongerErrCh := make(chan error, 1)
  1649. go func() {
  1650. pongerErrCh <- pongerFn(pongerConn)
  1651. }()
  1652. err = tstest.WaitFor(time.Second*5, func() error {
  1653. err = pingerFn(pingerConn)
  1654. if err != nil {
  1655. return err
  1656. }
  1657. return nil
  1658. })
  1659. if err != nil {
  1660. t.Fatal(err)
  1661. }
  1662. var pongsRX int
  1663. for {
  1664. pingerErrCh := make(chan error)
  1665. go func() {
  1666. pingerErrCh <- pingerFn(pingerConn)
  1667. }()
  1668. select {
  1669. case err := <-pongerErrCh:
  1670. t.Fatal(err)
  1671. case err := <-pingerErrCh:
  1672. if err != nil {
  1673. t.Fatal(err)
  1674. }
  1675. }
  1676. pongsRX++
  1677. if pongsRX == wantPongs {
  1678. break
  1679. }
  1680. }
  1681. }
  1682. d1.MustCleanShutdown(t)
  1683. }
  1684. func TestEncryptStateMigration(t *testing.T) {
  1685. if !hostinfo.New().TPM.Present() {
  1686. t.Skip("TPM not available")
  1687. }
  1688. if runtime.GOOS != "linux" && runtime.GOOS != "windows" {
  1689. t.Skip("--encrypt-state for tailscaled state not supported on this platform")
  1690. }
  1691. tstest.Shard(t)
  1692. tstest.Parallel(t)
  1693. env := NewTestEnv(t)
  1694. n := NewTestNode(t, env)
  1695. runNode := func(t *testing.T, wantStateKeys []string) {
  1696. t.Helper()
  1697. // Run the node.
  1698. d := n.StartDaemon()
  1699. n.AwaitResponding()
  1700. n.MustUp()
  1701. n.AwaitRunning()
  1702. // Check the contents of the state file.
  1703. buf, err := os.ReadFile(n.stateFile)
  1704. if err != nil {
  1705. t.Fatalf("reading %q: %v", n.stateFile, err)
  1706. }
  1707. t.Logf("state file content:\n%s", buf)
  1708. var content map[string]any
  1709. if err := json.Unmarshal(buf, &content); err != nil {
  1710. t.Fatalf("parsing %q: %v", n.stateFile, err)
  1711. }
  1712. for _, k := range wantStateKeys {
  1713. if _, ok := content[k]; !ok {
  1714. t.Errorf("state file is missing key %q", k)
  1715. }
  1716. }
  1717. // Stop the node.
  1718. d.MustCleanShutdown(t)
  1719. }
  1720. wantPlaintextStateKeys := []string{"_machinekey", "_current-profile", "_profiles"}
  1721. wantEncryptedStateKeys := []string{"key", "nonce", "data"}
  1722. t.Run("regular-state", func(t *testing.T) {
  1723. n.encryptState = false
  1724. runNode(t, wantPlaintextStateKeys)
  1725. })
  1726. t.Run("migrate-to-encrypted", func(t *testing.T) {
  1727. n.encryptState = true
  1728. runNode(t, wantEncryptedStateKeys)
  1729. })
  1730. t.Run("migrate-to-plaintext", func(t *testing.T) {
  1731. n.encryptState = false
  1732. runNode(t, wantPlaintextStateKeys)
  1733. })
  1734. }
  1735. // TestPeerRelayPing creates three nodes with one acting as a peer relay.
  1736. // The test succeeds when "tailscale ping" flows through the peer
  1737. // relay between all 3 nodes, and "tailscale debug peer-relay-sessions" returns
  1738. // expected values.
  1739. func TestPeerRelayPing(t *testing.T) {
  1740. flakytest.Mark(t, "https://github.com/tailscale/tailscale/issues/17251")
  1741. tstest.Shard(t)
  1742. tstest.Parallel(t)
  1743. env := NewTestEnv(t, ConfigureControl(func(server *testcontrol.Server) {
  1744. server.PeerRelayGrants = true
  1745. }))
  1746. env.neverDirectUDP = true
  1747. env.relayServerUseLoopback = true
  1748. n1 := NewTestNode(t, env)
  1749. n2 := NewTestNode(t, env)
  1750. peerRelay := NewTestNode(t, env)
  1751. allNodes := []*TestNode{n1, n2, peerRelay}
  1752. wantPeerRelayServers := make(set.Set[string])
  1753. for _, n := range allNodes {
  1754. n.StartDaemon()
  1755. n.AwaitResponding()
  1756. n.MustUp()
  1757. wantPeerRelayServers.Add(n.AwaitIP4().String())
  1758. n.AwaitRunning()
  1759. }
  1760. if err := peerRelay.Tailscale("set", "--relay-server-port=0").Run(); err != nil {
  1761. t.Fatal(err)
  1762. }
  1763. errCh := make(chan error)
  1764. for _, a := range allNodes {
  1765. go func() {
  1766. err := tstest.WaitFor(time.Second*5, func() error {
  1767. out, err := a.Tailscale("debug", "peer-relay-servers").CombinedOutput()
  1768. if err != nil {
  1769. return fmt.Errorf("debug peer-relay-servers failed: %v", err)
  1770. }
  1771. servers := make([]string, 0)
  1772. err = json.Unmarshal(out, &servers)
  1773. if err != nil {
  1774. return fmt.Errorf("failed to unmarshal debug peer-relay-servers: %v", err)
  1775. }
  1776. gotPeerRelayServers := make(set.Set[string])
  1777. for _, server := range servers {
  1778. gotPeerRelayServers.Add(server)
  1779. }
  1780. if !gotPeerRelayServers.Equal(wantPeerRelayServers) {
  1781. return fmt.Errorf("got peer relay servers: %v want: %v", gotPeerRelayServers, wantPeerRelayServers)
  1782. }
  1783. return nil
  1784. })
  1785. errCh <- err
  1786. }()
  1787. }
  1788. for range allNodes {
  1789. err := <-errCh
  1790. if err != nil {
  1791. t.Fatal(err)
  1792. }
  1793. }
  1794. pingPairs := make([][2]*TestNode, 0)
  1795. for _, a := range allNodes {
  1796. for _, z := range allNodes {
  1797. if a == z {
  1798. continue
  1799. }
  1800. pingPairs = append(pingPairs, [2]*TestNode{a, z})
  1801. }
  1802. }
  1803. for _, pair := range pingPairs {
  1804. go func() {
  1805. a := pair[0]
  1806. z := pair[1]
  1807. err := tstest.WaitFor(time.Second*10, func() error {
  1808. remoteKey := z.MustStatus().Self.PublicKey
  1809. if err := a.Tailscale("ping", "--until-direct=false", "--c=1", "--timeout=1s", z.AwaitIP4().String()).Run(); err != nil {
  1810. return err
  1811. }
  1812. remotePeer, ok := a.MustStatus().Peer[remoteKey]
  1813. if !ok {
  1814. return fmt.Errorf("%v->%v remote peer not found", a.MustStatus().Self.ID, z.MustStatus().Self.ID)
  1815. }
  1816. if len(remotePeer.PeerRelay) == 0 {
  1817. return fmt.Errorf("%v->%v not using peer relay, curAddr=%v relay=%v", a.MustStatus().Self.ID, z.MustStatus().Self.ID, remotePeer.CurAddr, remotePeer.Relay)
  1818. }
  1819. t.Logf("%v->%v using peer relay addr: %v", a.MustStatus().Self.ID, z.MustStatus().Self.ID, remotePeer.PeerRelay)
  1820. return nil
  1821. })
  1822. errCh <- err
  1823. }()
  1824. }
  1825. for range pingPairs {
  1826. err := <-errCh
  1827. if err != nil {
  1828. t.Fatal(err)
  1829. }
  1830. }
  1831. allControlNodes := env.Control.AllNodes()
  1832. wantSessionsForDiscoShorts := make(set.Set[[2]string])
  1833. for i, a := range allControlNodes {
  1834. if i == len(allControlNodes)-1 {
  1835. break
  1836. }
  1837. for _, z := range allControlNodes[i+1:] {
  1838. wantSessionsForDiscoShorts.Add([2]string{a.DiscoKey.ShortString(), z.DiscoKey.ShortString()})
  1839. }
  1840. }
  1841. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  1842. debugSessions, err := peerRelay.LocalClient().DebugPeerRelaySessions(ctx)
  1843. cancel()
  1844. if err != nil {
  1845. t.Fatalf("debug peer-relay-sessions failed: %v", err)
  1846. }
  1847. if len(debugSessions.Sessions) != len(wantSessionsForDiscoShorts) {
  1848. t.Errorf("got %d peer relay sessions, want %d", len(debugSessions.Sessions), len(wantSessionsForDiscoShorts))
  1849. }
  1850. for _, session := range debugSessions.Sessions {
  1851. if !wantSessionsForDiscoShorts.Contains([2]string{session.Client1.ShortDisco, session.Client2.ShortDisco}) &&
  1852. !wantSessionsForDiscoShorts.Contains([2]string{session.Client2.ShortDisco, session.Client1.ShortDisco}) {
  1853. t.Errorf("peer relay session for disco keys %s<->%s not found in debug peer-relay-sessions: %+v", session.Client1.ShortDisco, session.Client2.ShortDisco, debugSessions.Sessions)
  1854. }
  1855. for _, client := range []status.ClientInfo{session.Client1, session.Client2} {
  1856. if client.BytesTx == 0 {
  1857. t.Errorf("unexpected 0 bytes TX counter in peer relay session: %+v", session)
  1858. }
  1859. if client.PacketsTx == 0 {
  1860. t.Errorf("unexpected 0 packets TX counter in peer relay session: %+v", session)
  1861. }
  1862. if !client.Endpoint.IsValid() {
  1863. t.Errorf("unexpected endpoint zero value in peer relay session: %+v", session)
  1864. }
  1865. if len(client.ShortDisco) == 0 {
  1866. t.Errorf("unexpected zero len short disco in peer relay session: %+v", session)
  1867. }
  1868. }
  1869. }
  1870. }
  1871. func TestC2NDebugNetmap(t *testing.T) {
  1872. tstest.Shard(t)
  1873. tstest.Parallel(t)
  1874. env := NewTestEnv(t, ConfigureControl(func(s *testcontrol.Server) {
  1875. s.CollectServices = opt.False
  1876. }))
  1877. var testNodes []*TestNode
  1878. var nodes []*tailcfg.Node
  1879. for i := range 2 {
  1880. n := NewTestNode(t, env)
  1881. d := n.StartDaemon()
  1882. defer d.MustCleanShutdown(t)
  1883. n.AwaitResponding()
  1884. n.MustUp()
  1885. n.AwaitRunning()
  1886. testNodes = append(testNodes, n)
  1887. controlNodes := env.Control.AllNodes()
  1888. if len(controlNodes) != i+1 {
  1889. t.Fatalf("expected %d nodes, got %d nodes", i+1, len(controlNodes))
  1890. }
  1891. for _, cn := range controlNodes {
  1892. if n.MustStatus().Self.PublicKey == cn.Key {
  1893. nodes = append(nodes, cn)
  1894. break
  1895. }
  1896. }
  1897. }
  1898. // getC2NNetmap fetches the current netmap. If a candidate map response is provided,
  1899. // a candidate netmap is also fetched and compared to the current netmap.
  1900. getC2NNetmap := func(node key.NodePublic, cand *tailcfg.MapResponse) *netmap.NetworkMap {
  1901. t.Helper()
  1902. ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second)
  1903. defer cancel()
  1904. var req *http.Request
  1905. if cand != nil {
  1906. body := must.Get(json.Marshal(&tailcfg.C2NDebugNetmapRequest{Candidate: cand}))
  1907. req = must.Get(http.NewRequestWithContext(ctx, "POST", "/debug/netmap", bytes.NewReader(body)))
  1908. } else {
  1909. req = must.Get(http.NewRequestWithContext(ctx, "GET", "/debug/netmap", nil))
  1910. }
  1911. httpResp := must.Get(env.Control.NodeRoundTripper(node).RoundTrip(req))
  1912. defer httpResp.Body.Close()
  1913. if httpResp.StatusCode != 200 {
  1914. t.Errorf("unexpected status code: %d", httpResp.StatusCode)
  1915. return nil
  1916. }
  1917. respBody := must.Get(io.ReadAll(httpResp.Body))
  1918. var resp tailcfg.C2NDebugNetmapResponse
  1919. must.Do(json.Unmarshal(respBody, &resp))
  1920. var current netmap.NetworkMap
  1921. must.Do(json.Unmarshal(resp.Current, &current))
  1922. // Check candidate netmap if we sent a map response.
  1923. if cand != nil {
  1924. var candidate netmap.NetworkMap
  1925. must.Do(json.Unmarshal(resp.Candidate, &candidate))
  1926. if diff := cmp.Diff(current.SelfNode, candidate.SelfNode); diff != "" {
  1927. t.Errorf("SelfNode differs (-current +candidate):\n%s", diff)
  1928. }
  1929. if diff := cmp.Diff(current.Peers, candidate.Peers); diff != "" {
  1930. t.Errorf("Peers differ (-current +candidate):\n%s", diff)
  1931. }
  1932. }
  1933. return &current
  1934. }
  1935. for _, n := range nodes {
  1936. mr := must.Get(env.Control.MapResponse(&tailcfg.MapRequest{NodeKey: n.Key}))
  1937. nm := getC2NNetmap(n.Key, mr)
  1938. // Make sure peers do not have "testcap" initially (we'll change this later).
  1939. if len(nm.Peers) != 1 || nm.Peers[0].CapMap().Contains("testcap") {
  1940. t.Fatalf("expected 1 peer without testcap, got: %v", nm.Peers)
  1941. }
  1942. // Make sure nodes think each other are offline initially.
  1943. if nm.Peers[0].Online().Get() {
  1944. t.Fatalf("expected 1 peer to be offline, got: %v", nm.Peers)
  1945. }
  1946. }
  1947. // Send a delta update to n0, setting "testcap" on node 1.
  1948. env.Control.AddRawMapResponse(nodes[0].Key, &tailcfg.MapResponse{
  1949. PeersChangedPatch: []*tailcfg.PeerChange{{
  1950. NodeID: nodes[1].ID, CapMap: tailcfg.NodeCapMap{"testcap": []tailcfg.RawMessage{}},
  1951. }},
  1952. })
  1953. // node 0 should see node 1 with "testcap".
  1954. must.Do(tstest.WaitFor(5*time.Second, func() error {
  1955. st := testNodes[0].MustStatus()
  1956. p, ok := st.Peer[nodes[1].Key]
  1957. if !ok {
  1958. return fmt.Errorf("node 0 (%s) doesn't see node 1 (%s) as peer\n%v", nodes[0].Key, nodes[1].Key, st)
  1959. }
  1960. if _, ok := p.CapMap["testcap"]; !ok {
  1961. return fmt.Errorf("node 0 (%s) sees node 1 (%s) as peer but without testcap\n%v", nodes[0].Key, nodes[1].Key, p)
  1962. }
  1963. return nil
  1964. }))
  1965. // Check that node 0's current netmap has "testcap" for node 1.
  1966. nm := getC2NNetmap(nodes[0].Key, nil)
  1967. if len(nm.Peers) != 1 || !nm.Peers[0].CapMap().Contains("testcap") {
  1968. t.Errorf("current netmap missing testcap: %v", nm.Peers[0].CapMap())
  1969. }
  1970. // Send a delta update to n1, marking node 0 as online.
  1971. env.Control.AddRawMapResponse(nodes[1].Key, &tailcfg.MapResponse{
  1972. PeersChangedPatch: []*tailcfg.PeerChange{{
  1973. NodeID: nodes[0].ID, Online: ptr.To(true),
  1974. }},
  1975. })
  1976. // node 1 should see node 0 as online.
  1977. must.Do(tstest.WaitFor(5*time.Second, func() error {
  1978. st := testNodes[1].MustStatus()
  1979. p, ok := st.Peer[nodes[0].Key]
  1980. if !ok || !p.Online {
  1981. return fmt.Errorf("node 0 (%s) doesn't see node 1 (%s) as an online peer\n%v", nodes[0].Key, nodes[1].Key, st)
  1982. }
  1983. return nil
  1984. }))
  1985. // The netmap from node 1 should show node 0 as online.
  1986. nm = getC2NNetmap(nodes[1].Key, nil)
  1987. if len(nm.Peers) != 1 || !nm.Peers[0].Online().Get() {
  1988. t.Errorf("expected peer to be online; got %+v", nm.Peers[0].AsStruct())
  1989. }
  1990. }
  1991. func TestTailnetLock(t *testing.T) {
  1992. // If you run `tailscale lock log` on a node where Tailnet Lock isn't
  1993. // enabled, you get an error explaining that.
  1994. t.Run("log-when-not-enabled", func(t *testing.T) {
  1995. tstest.Shard(t)
  1996. t.Parallel()
  1997. env := NewTestEnv(t)
  1998. n1 := NewTestNode(t, env)
  1999. d1 := n1.StartDaemon()
  2000. defer d1.MustCleanShutdown(t)
  2001. n1.MustUp()
  2002. n1.AwaitRunning()
  2003. cmdArgs := []string{"lock", "log"}
  2004. t.Logf("Running command: %s", strings.Join(cmdArgs, " "))
  2005. var outBuf, errBuf bytes.Buffer
  2006. cmd := n1.Tailscale(cmdArgs...)
  2007. cmd.Stdout = &outBuf
  2008. cmd.Stderr = &errBuf
  2009. if err := cmd.Run(); !isNonZeroExitCode(err) {
  2010. t.Fatalf("command did not fail with non-zero exit code: %q", err)
  2011. }
  2012. if outBuf.String() != "" {
  2013. t.Fatalf("stdout: want '', got %q", outBuf.String())
  2014. }
  2015. wantErr := "Tailnet Lock is not enabled\n"
  2016. if errBuf.String() != wantErr {
  2017. t.Fatalf("stderr: want %q, got %q", wantErr, errBuf.String())
  2018. }
  2019. })
  2020. // If you create a tailnet with two signed nodes and one unsigned,
  2021. // the signed nodes can talk to each other but the unsigned node cannot
  2022. // talk to anybody.
  2023. t.Run("node-connectivity", func(t *testing.T) {
  2024. tstest.Shard(t)
  2025. t.Parallel()
  2026. env := NewTestEnv(t)
  2027. env.Control.DefaultNodeCapabilities = &tailcfg.NodeCapMap{
  2028. tailcfg.CapabilityTailnetLock: []tailcfg.RawMessage{},
  2029. }
  2030. // Start two nodes which will be our signing nodes.
  2031. signing1 := NewTestNode(t, env)
  2032. signing2 := NewTestNode(t, env)
  2033. nodes := []*TestNode{signing1, signing2}
  2034. for _, n := range nodes {
  2035. d := n.StartDaemon()
  2036. defer d.MustCleanShutdown(t)
  2037. n.MustUp()
  2038. n.AwaitRunning()
  2039. }
  2040. // Initiate Tailnet Lock with the two signing nodes.
  2041. initCmd := signing1.Tailscale("lock", "init",
  2042. "--gen-disablements", "10",
  2043. "--confirm",
  2044. signing1.NLPublicKey(), signing2.NLPublicKey(),
  2045. )
  2046. out, err := initCmd.CombinedOutput()
  2047. if err != nil {
  2048. t.Fatalf("init command failed: %q\noutput=%v", err, string(out))
  2049. }
  2050. // Check that the two signing nodes can ping each other
  2051. if err := signing1.Ping(signing2); err != nil {
  2052. t.Fatalf("ping signing1 -> signing2: %v", err)
  2053. }
  2054. if err := signing2.Ping(signing1); err != nil {
  2055. t.Fatalf("ping signing2 -> signing1: %v", err)
  2056. }
  2057. // Create and start a third node
  2058. node3 := NewTestNode(t, env)
  2059. d3 := node3.StartDaemon()
  2060. defer d3.MustCleanShutdown(t)
  2061. node3.MustUp()
  2062. node3.AwaitRunning()
  2063. if err := signing1.Ping(node3); err == nil {
  2064. t.Fatal("ping signing1 -> node3: expected err, but succeeded")
  2065. }
  2066. if err := node3.Ping(signing1); err == nil {
  2067. t.Fatal("ping node3 -> signing1: expected err, but succeeded")
  2068. }
  2069. // Sign node3, and check the nodes can now talk to each other
  2070. signCmd := signing1.Tailscale("lock", "sign", node3.PublicKey())
  2071. out, err = signCmd.CombinedOutput()
  2072. if err != nil {
  2073. t.Fatalf("sign command failed: %q\noutput = %v", err, string(out))
  2074. }
  2075. if err := signing1.Ping(node3); err != nil {
  2076. t.Fatalf("ping signing1 -> node3: expected success, got err: %v", err)
  2077. }
  2078. if err := node3.Ping(signing1); err != nil {
  2079. t.Fatalf("ping node3 -> signing1: expected success, got err: %v", err)
  2080. }
  2081. })
  2082. }
  2083. func TestNodeWithBadStateFile(t *testing.T) {
  2084. tstest.Shard(t)
  2085. tstest.Parallel(t)
  2086. env := NewTestEnv(t)
  2087. n1 := NewTestNode(t, env)
  2088. if err := os.WriteFile(n1.stateFile, []byte("bad json"), 0644); err != nil {
  2089. t.Fatal(err)
  2090. }
  2091. d1 := n1.StartDaemon()
  2092. n1.AwaitResponding()
  2093. // Make sure the health message shows up in status output.
  2094. n1.AwaitBackendState("NoState")
  2095. st := n1.MustStatus()
  2096. wantHealth := ipn.StateStoreHealth.Text(health.Args{health.ArgError: ""})
  2097. if !slices.ContainsFunc(st.Health, func(m string) bool { return strings.HasPrefix(m, wantHealth) }) {
  2098. t.Errorf("Status does not contain expected health message %q\ngot health messages: %q", wantHealth, st.Health)
  2099. }
  2100. // Make sure login attempts are rejected.
  2101. cmd := n1.Tailscale("up", "--login-server="+n1.env.ControlURL())
  2102. t.Logf("Running %v ...", cmd)
  2103. out, err := cmd.CombinedOutput()
  2104. if err == nil {
  2105. t.Fatalf("up succeeded with output %q", out)
  2106. }
  2107. wantOut := "cannot start backend when state store is unhealthy"
  2108. if !strings.Contains(string(out), wantOut) {
  2109. t.Fatalf("got up output:\n%s\nwant:\n%s", string(out), wantOut)
  2110. }
  2111. d1.MustCleanShutdown(t)
  2112. }