1{
2 lib,
3 stdenv,
4
5 buildGoModule,
6 fetchFromGitHub,
7
8 makeWrapper,
9 installShellFiles,
10 # runtime tooling - linux
11 getent,
12 iproute2,
13 iptables,
14 shadow,
15 procps,
16 # runtime tooling - darwin
17 lsof,
18 # check phase tooling - darwin
19 unixtools,
20
21 nixosTests,
22 tailscale-nginx-auth,
23}:
24
25let
26 version = "1.86.2";
27in
28buildGoModule {
29 pname = "tailscale";
30 inherit version;
31
32 outputs = [
33 "out"
34 "derper"
35 ];
36
37 src = fetchFromGitHub {
38 owner = "tailscale";
39 repo = "tailscale";
40 tag = "v${version}";
41 hash = "sha256-hozfvKkvTeaabN1tYl0NlEpjfD4sZQe9Z+agdoXFHNE=";
42 };
43
44 vendorHash = "sha256-4QTSspHLYJfzlontQ7msXyOB5gzq7ZwSvWmKuYY5klA=";
45
46 nativeBuildInputs = [
47 makeWrapper
48 installShellFiles
49 ];
50
51 nativeCheckInputs = lib.optionals stdenv.hostPlatform.isDarwin [
52 unixtools.netstat
53 ];
54
55 env.CGO_ENABLED = 0;
56
57 subPackages = [
58 "cmd/derper"
59 "cmd/derpprobe"
60 "cmd/tailscaled"
61 "cmd/tsidp"
62 "cmd/get-authkey"
63 ];
64
65 excludedPackages = [
66 # Exclude integration tests which fail to work and require additional tooling
67 "tstest/integration"
68 ];
69
70 ldflags = [
71 "-w"
72 "-s"
73 "-X tailscale.com/version.longStamp=${version}"
74 "-X tailscale.com/version.shortStamp=${version}"
75 ];
76
77 tags = [
78 "ts_include_cli"
79 ];
80
81 # Remove vendored tooling to ensure it's not used; also avoids some unnecessary tests
82 preBuild = ''
83 rm -rf ./tool
84 '';
85
86 # Tests start http servers which need to bind to local addresses:
87 # panic: httptest: failed to listen on a port: listen tcp6 [::1]:0: bind: operation not permitted
88 __darwinAllowLocalNetworking = true;
89
90 preCheck = ''
91 # feed in all tests for testing
92 # subPackages above limits what is built to just what we
93 # want but also limits the tests
94 unset subPackages
95
96 # several tests hang, but keeping the file for tsnet/packet_filter_test.go
97 # packet_filter_test issue: https://github.com/tailscale/tailscale/issues/16051
98 substituteInPlace tsnet/tsnet_test.go \
99 --replace-fail 'func Test' 'func skippedTest'
100 '';
101
102 checkFlags =
103 let
104 skippedTests = [
105 # dislikes vendoring
106 "TestPackageDocs" # .
107 # tries to start tailscaled
108 "TestContainerBoot" # cmd/containerboot
109
110 # just part of a tool which generates yaml for k8s CRDs
111 # requires helm
112 "Test_generate" # cmd/k8s-operator/generate
113 # self reported potentially flakey test
114 "TestConnMemoryOverhead" # control/controlbase
115
116 # interacts with `/proc/net/route` and need a default route
117 "TestDefaultRouteInterface" # net/netmon
118 "TestRouteLinuxNetlink" # net/netmon
119 "TestGetRouteTable" # net/routetable
120
121 # remote udp call to 8.8.8.8
122 "TestDefaultInterfacePortable" # net/netutil
123
124 # launches an ssh server which works when provided openssh
125 # also requires executing commands but nixbld user has /noshell
126 "TestSSH" # ssh/tailssh
127 # wants users alice & ubuntu
128 "TestMultipleRecorders" # ssh/tailssh
129 "TestSSHAuthFlow" # ssh/tailssh
130 "TestSSHRecordingCancelsSessionsOnUploadFailure" # ssh/tailssh
131 "TestSSHRecordingNonInteractive" # ssh/tailssh
132
133 # test for a dev util which helps to fork golang.org/x/crypto/acme
134 # not necessary and fails to match
135 "TestSyncedToUpstream" # tempfork/acme
136
137 # flaky: https://github.com/tailscale/tailscale/issues/7030
138 "TestConcurrent"
139
140 # flaky: https://github.com/tailscale/tailscale/issues/11762
141 "TestTwoDevicePing"
142
143 # timeout 10m
144 "TestTaildropIntegration"
145 "TestTaildropIntegration_Fresh"
146
147 # context deadline exceeded
148 "TestPacketFilterFromNetmap"
149
150 # flaky: https://github.com/tailscale/tailscale/issues/15348
151 "TestSafeFuncHappyPath"
152
153 # Requires `go` to be installed with the `go tool` system which we don't use
154 "TestGoVersion"
155
156 # Fails because we vendor dependencies
157 "TestLicenseHeaders"
158 ]
159 ++ lib.optionals stdenv.hostPlatform.isDarwin [
160 # syscall default route interface en0 differs from netstat
161 "TestLikelyHomeRouterIPSyscallExec" # net/netmon
162
163 # Even with __darwinAllowLocalNetworking this doesn't work.
164 # panic: write udp [::]:59507->127.0.0.1:50830: sendto: operation not permitted
165 "TestUDP" # net/socks5
166
167 # portlist_test.go:81: didn't find ephemeral port in p2 53643
168 "TestPoller" # portlist
169
170 # Fails only on Darwin, succeeds on other tested platforms.
171 "TestOnTailnetDefaultAutoUpdate"
172
173 # Fails due to UNIX domain socket path limits in the Nix build environment.
174 # Likely we could do something to make the paths shorter.
175 "TestProtocolQEMU"
176 "TestProtocolUnixDgram"
177 ];
178 in
179 [ "-skip=^${builtins.concatStringsSep "$|^" skippedTests}$" ];
180
181 postInstall = ''
182 ln -s $out/bin/tailscaled $out/bin/tailscale
183 moveToOutput "bin/derper" "$derper"
184 moveToOutput "bin/derpprobe" "$derper"
185 ''
186 + lib.optionalString stdenv.hostPlatform.isDarwin ''
187 wrapProgram $out/bin/tailscaled \
188 --prefix PATH : ${
189 lib.makeBinPath [
190 # Uses lsof only on macOS to detect socket location
191 # See tailscale safesocket_darwin.go
192 lsof
193 ]
194 }
195 ''
196 + lib.optionalString stdenv.hostPlatform.isLinux ''
197 wrapProgram $out/bin/tailscaled \
198 --prefix PATH : ${
199 lib.makeBinPath [
200 getent
201 iproute2
202 iptables
203 shadow
204 ]
205 } \
206 --suffix PATH : ${lib.makeBinPath [ procps ]}
207 sed -i -e "s#/usr/sbin#$out/bin#" -e "/^EnvironmentFile/d" ./cmd/tailscaled/tailscaled.service
208 install -D -m0444 -t $out/lib/systemd/system ./cmd/tailscaled/tailscaled.service
209 ''
210 + lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
211 local INSTALL="$out/bin/tailscale"
212 installShellCompletion --cmd tailscale \
213 --bash <($out/bin/tailscale completion bash) \
214 --fish <($out/bin/tailscale completion fish) \
215 --zsh <($out/bin/tailscale completion zsh)
216 '';
217
218 passthru.tests = {
219 inherit (nixosTests) headscale;
220 inherit tailscale-nginx-auth;
221 };
222
223 meta = {
224 homepage = "https://tailscale.com";
225 description = "Node agent for Tailscale, a mesh VPN built on WireGuard";
226 changelog = "https://github.com/tailscale/tailscale/releases/tag/v${version}";
227 license = lib.licenses.bsd3;
228 mainProgram = "tailscale";
229 maintainers = with lib.maintainers; [
230 mbaillie
231 jk
232 mfrw
233 pyrox0
234 ryan4yin
235 ];
236 };
237}