installer.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. #!/bin/sh
  2. # Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
  3. # Use of this source code is governed by a BSD-style
  4. # license that can be found in the LICENSE file.
  5. #
  6. # This script detects the current operating system, and installs
  7. # Tailscale according to that OS's conventions.
  8. set -eu
  9. # All the code is wrapped in a main function that gets called at the
  10. # bottom of the file, so that a truncated partial download doesn't end
  11. # up executing half a script.
  12. main() {
  13. # Step 1: detect the current linux distro, version, and packaging system.
  14. #
  15. # We rely on a combination of 'uname' and /etc/os-release to find
  16. # an OS name and version, and from there work out what
  17. # installation method we should be using.
  18. #
  19. # The end result of this step is that the following three
  20. # variables are populated, if detection was successful.
  21. OS=""
  22. VERSION=""
  23. PACKAGETYPE=""
  24. APT_KEY_TYPE="" # Only for apt-based distros
  25. APT_SYSTEMCTL_START=false # Only needs to be true for Kali
  26. TRACK="${TRACK:-stable}"
  27. case "$TRACK" in
  28. stable|unstable)
  29. ;;
  30. *)
  31. echo "unsupported track $TRACK"
  32. exit 1
  33. ;;
  34. esac
  35. if [ -f /etc/os-release ]; then
  36. # /etc/os-release populates a number of shell variables. We care about the following:
  37. # - ID: the short name of the OS (e.g. "debian", "freebsd")
  38. # - VERSION_ID: the numeric release version for the OS, if any (e.g. "18.04")
  39. # - VERSION_CODENAME: the codename of the OS release, if any (e.g. "buster")
  40. # - UBUNTU_CODENAME: if it exists, use instead of VERSION_CODENAME
  41. . /etc/os-release
  42. case "$ID" in
  43. ubuntu|pop|neon|zorin)
  44. OS="ubuntu"
  45. if [ "${UBUNTU_CODENAME:-}" != "" ]; then
  46. VERSION="$UBUNTU_CODENAME"
  47. else
  48. VERSION="$VERSION_CODENAME"
  49. fi
  50. PACKAGETYPE="apt"
  51. # Third-party keyrings became the preferred method of
  52. # installation in Ubuntu 20.04.
  53. if expr "$VERSION_ID" : "2.*" >/dev/null; then
  54. APT_KEY_TYPE="keyring"
  55. else
  56. APT_KEY_TYPE="legacy"
  57. fi
  58. ;;
  59. debian)
  60. OS="$ID"
  61. VERSION="$VERSION_CODENAME"
  62. PACKAGETYPE="apt"
  63. # Third-party keyrings became the preferred method of
  64. # installation in Debian 11 (Bullseye).
  65. if [ "$VERSION_ID" -lt 11 ]; then
  66. APT_KEY_TYPE="legacy"
  67. else
  68. APT_KEY_TYPE="keyring"
  69. fi
  70. ;;
  71. linuxmint)
  72. if [ "${UBUNTU_CODENAME:-}" != "" ]; then
  73. OS="ubuntu"
  74. VERSION="$UBUNTU_CODENAME"
  75. elif [ "${DEBIAN_CODENAME:-}" != "" ]; then
  76. OS="debian"
  77. VERSION="$DEBIAN_CODENAME"
  78. else
  79. OS="ubuntu"
  80. VERSION="$VERSION_CODENAME"
  81. fi
  82. PACKAGETYPE="apt"
  83. if [ "$VERSION_ID" -lt 5 ]; then
  84. APT_KEY_TYPE="legacy"
  85. else
  86. APT_KEY_TYPE="keyring"
  87. fi
  88. ;;
  89. elementary)
  90. OS="ubuntu"
  91. VERSION="$UBUNTU_CODENAME"
  92. PACKAGETYPE="apt"
  93. if [ "$VERSION_ID" -lt 6 ]; then
  94. APT_KEY_TYPE="legacy"
  95. else
  96. APT_KEY_TYPE="keyring"
  97. fi
  98. ;;
  99. parrot)
  100. OS="debian"
  101. PACKAGETYPE="apt"
  102. if [ "$VERSION_ID" -lt 5 ]; then
  103. VERSION="buster"
  104. APT_KEY_TYPE="legacy"
  105. else
  106. VERSION="bullseye"
  107. APT_KEY_TYPE="keyring"
  108. fi
  109. ;;
  110. raspbian)
  111. OS="$ID"
  112. VERSION="$VERSION_CODENAME"
  113. PACKAGETYPE="apt"
  114. # Third-party keyrings became the preferred method of
  115. # installation in Raspbian 11 (Bullseye).
  116. if [ "$VERSION_ID" -lt 11 ]; then
  117. APT_KEY_TYPE="legacy"
  118. else
  119. APT_KEY_TYPE="keyring"
  120. fi
  121. ;;
  122. kali)
  123. OS="debian"
  124. PACKAGETYPE="apt"
  125. YEAR="$(echo "$VERSION_ID" | cut -f1 -d.)"
  126. APT_SYSTEMCTL_START=true
  127. # Third-party keyrings became the preferred method of
  128. # installation in Debian 11 (Bullseye), which Kali switched
  129. # to in roughly 2021.x releases
  130. if [ "$YEAR" -lt 2021 ]; then
  131. # Kali VERSION_ID is "kali-rolling", which isn't distinguishing
  132. VERSION="buster"
  133. APT_KEY_TYPE="legacy"
  134. else
  135. VERSION="bullseye"
  136. APT_KEY_TYPE="keyring"
  137. fi
  138. ;;
  139. centos)
  140. OS="$ID"
  141. VERSION="$VERSION_ID"
  142. PACKAGETYPE="dnf"
  143. if [ "$VERSION" = "7" ]; then
  144. PACKAGETYPE="yum"
  145. fi
  146. ;;
  147. ol)
  148. OS="oracle"
  149. VERSION="$(echo "$VERSION_ID" | cut -f1 -d.)"
  150. PACKAGETYPE="dnf"
  151. if [ "$VERSION" = "7" ]; then
  152. PACKAGETYPE="yum"
  153. fi
  154. ;;
  155. rhel)
  156. OS="$ID"
  157. VERSION="$(echo "$VERSION_ID" | cut -f1 -d.)"
  158. PACKAGETYPE="dnf"
  159. ;;
  160. fedora)
  161. OS="$ID"
  162. VERSION=""
  163. PACKAGETYPE="dnf"
  164. ;;
  165. rocky|almalinux)
  166. OS="fedora"
  167. VERSION=""
  168. PACKAGETYPE="dnf"
  169. ;;
  170. amzn)
  171. OS="amazon-linux"
  172. VERSION="$VERSION_ID"
  173. PACKAGETYPE="yum"
  174. ;;
  175. xenenterprise)
  176. OS="centos"
  177. VERSION="$(echo "$VERSION_ID" | cut -f1 -d.)"
  178. PACKAGETYPE="yum"
  179. ;;
  180. opensuse-leap)
  181. OS="opensuse"
  182. VERSION="leap/$VERSION_ID"
  183. PACKAGETYPE="zypper"
  184. ;;
  185. opensuse-tumbleweed)
  186. OS="opensuse"
  187. VERSION="tumbleweed"
  188. PACKAGETYPE="zypper"
  189. ;;
  190. arch|archarm|endeavouros)
  191. OS="arch"
  192. VERSION="" # rolling release
  193. PACKAGETYPE="pacman"
  194. ;;
  195. manjaro|manjaro-arm)
  196. OS="manjaro"
  197. VERSION="" # rolling release
  198. PACKAGETYPE="pacman"
  199. ;;
  200. alpine)
  201. OS="$ID"
  202. VERSION="$VERSION_ID"
  203. PACKAGETYPE="apk"
  204. ;;
  205. nixos)
  206. echo "Please add Tailscale to your NixOS configuration directly:"
  207. echo
  208. echo "services.tailscale.enable = true;"
  209. exit 1
  210. ;;
  211. void)
  212. OS="$ID"
  213. VERSION="" # rolling release
  214. PACKAGETYPE="xbps"
  215. ;;
  216. gentoo)
  217. OS="$ID"
  218. VERSION="" # rolling release
  219. PACKAGETYPE="emerge"
  220. ;;
  221. freebsd)
  222. OS="$ID"
  223. VERSION="$(echo "$VERSION_ID" | cut -f1 -d.)"
  224. PACKAGETYPE="pkg"
  225. ;;
  226. # TODO: wsl?
  227. # TODO: synology? qnap?
  228. esac
  229. fi
  230. # If we failed to detect something through os-release, consult
  231. # uname and try to infer things from that.
  232. if [ -z "$OS" ]; then
  233. if type uname >/dev/null 2>&1; then
  234. case "$(uname)" in
  235. FreeBSD)
  236. # FreeBSD before 12.2 doesn't have
  237. # /etc/os-release, so we wouldn't have found it in
  238. # the os-release probing above.
  239. OS="freebsd"
  240. VERSION="$(freebsd-version | cut -f1 -d.)"
  241. PACKAGETYPE="pkg"
  242. ;;
  243. OpenBSD)
  244. OS="openbsd"
  245. VERSION="$(uname -r)"
  246. PACKAGETYPE=""
  247. ;;
  248. Darwin)
  249. OS="macos"
  250. VERSION="$(sw_vers -productVersion | cut -f1-2 -d.)"
  251. PACKAGETYPE="appstore"
  252. ;;
  253. Linux)
  254. OS="other-linux"
  255. VERSION=""
  256. PACKAGETYPE=""
  257. ;;
  258. esac
  259. fi
  260. fi
  261. # Step 2: having detected an OS we support, is it one of the
  262. # versions we support?
  263. OS_UNSUPPORTED=
  264. case "$OS" in
  265. ubuntu)
  266. if [ "$VERSION" != "xenial" ] && \
  267. [ "$VERSION" != "bionic" ] && \
  268. [ "$VERSION" != "eoan" ] && \
  269. [ "$VERSION" != "focal" ] && \
  270. [ "$VERSION" != "groovy" ] && \
  271. [ "$VERSION" != "hirsute" ] && \
  272. [ "$VERSION" != "impish" ] && \
  273. [ "$VERSION" != "jammy" ]
  274. then
  275. OS_UNSUPPORTED=1
  276. fi
  277. ;;
  278. debian)
  279. if [ "$VERSION" != "stretch" ] && \
  280. [ "$VERSION" != "buster" ] && \
  281. [ "$VERSION" != "bullseye" ] && \
  282. [ "$VERSION" != "bookworm" ] && \
  283. [ "$VERSION" != "sid" ]
  284. then
  285. OS_UNSUPPORTED=1
  286. fi
  287. ;;
  288. raspbian)
  289. if [ "$VERSION" != "stretch" ] && \
  290. [ "$VERSION" != "buster" ] && \
  291. [ "$VERSION" != "bullseye" ]
  292. then
  293. OS_UNSUPPORTED=1
  294. fi
  295. ;;
  296. centos)
  297. if [ "$VERSION" != "7" ] && \
  298. [ "$VERSION" != "8" ] && \
  299. [ "$VERSION" != "9" ]
  300. then
  301. OS_UNSUPPORTED=1
  302. fi
  303. ;;
  304. oracle)
  305. if [ "$VERSION" != "7" ] && \
  306. [ "$VERSION" != "8" ]
  307. then
  308. OS_UNSUPPORTED=1
  309. fi
  310. ;;
  311. rhel)
  312. if [ "$VERSION" != "8" ] && \
  313. [ "$VERSION" != "9" ]
  314. then
  315. OS_UNSUPPORTED=1
  316. fi
  317. ;;
  318. amazon-linux)
  319. if [ "$VERSION" != "2" ]
  320. then
  321. OS_UNSUPPORTED=1
  322. fi
  323. ;;
  324. opensuse)
  325. if [ "$VERSION" != "leap/15.1" ] && \
  326. [ "$VERSION" != "leap/15.2" ] && \
  327. [ "$VERSION" != "leap/15.3" ] && \
  328. [ "$VERSION" != "tumbleweed" ]
  329. then
  330. OS_UNSUPPORTED=1
  331. fi
  332. ;;
  333. fedora)
  334. # All versions supported, no version checking required.
  335. ;;
  336. arch)
  337. # Rolling release, no version checking needed.
  338. ;;
  339. manjaro)
  340. # Rolling release, no version checking needed.
  341. ;;
  342. alpine)
  343. # All versions supported, no version checking needed.
  344. # TODO: is that true? When was tailscale packaged?
  345. ;;
  346. void)
  347. # Rolling release, no version checking needed.
  348. ;;
  349. gentoo)
  350. # Rolling release, no version checking needed.
  351. ;;
  352. freebsd)
  353. if [ "$VERSION" != "12" ] && \
  354. [ "$VERSION" != "13" ]
  355. then
  356. OS_UNSUPPORTED=1
  357. fi
  358. ;;
  359. openbsd)
  360. OS_UNSUPPORTED=1
  361. ;;
  362. macos)
  363. # We delegate macOS installation to the app store, it will
  364. # perform version checks for us.
  365. ;;
  366. other-linux)
  367. OS_UNSUPPORTED=1
  368. ;;
  369. *)
  370. OS_UNSUPPORTED=1
  371. ;;
  372. esac
  373. if [ "$OS_UNSUPPORTED" = "1" ]; then
  374. case "$OS" in
  375. other-linux)
  376. echo "Couldn't determine what kind of Linux is running."
  377. echo "You could try the static binaries at:"
  378. echo "https://pkgs.tailscale.com/$TRACK/#static"
  379. ;;
  380. "")
  381. echo "Couldn't determine what operating system you're running."
  382. ;;
  383. *)
  384. echo "$OS $VERSION isn't supported by this script yet."
  385. ;;
  386. esac
  387. echo
  388. echo "If you'd like us to support your system better, please email [email protected]"
  389. echo "and tell us what OS you're running."
  390. echo
  391. echo "Please include the following information we gathered from your system:"
  392. echo
  393. echo "OS=$OS"
  394. echo "VERSION=$VERSION"
  395. echo "PACKAGETYPE=$PACKAGETYPE"
  396. if type uname >/dev/null 2>&1; then
  397. echo "UNAME=$(uname -a)"
  398. else
  399. echo "UNAME="
  400. fi
  401. echo
  402. if [ -f /etc/os-release ]; then
  403. cat /etc/os-release
  404. else
  405. echo "No /etc/os-release"
  406. fi
  407. exit 1
  408. fi
  409. # Step 3: work out if we can run privileged commands, and if so,
  410. # how.
  411. CAN_ROOT=
  412. SUDO=
  413. if [ "$(id -u)" = 0 ]; then
  414. CAN_ROOT=1
  415. SUDO=""
  416. elif type sudo >/dev/null; then
  417. CAN_ROOT=1
  418. SUDO="sudo"
  419. elif type doas >/dev/null; then
  420. CAN_ROOT=1
  421. SUDO="doas"
  422. fi
  423. if [ "$CAN_ROOT" != "1" ]; then
  424. echo "This installer needs to run commands as root."
  425. echo "We tried looking for 'sudo' and 'doas', but couldn't find them."
  426. echo "Either re-run this script as root, or set up sudo/doas."
  427. exit 1
  428. fi
  429. # Step 4: run the installation.
  430. echo "Installing Tailscale for $OS $VERSION, using method $PACKAGETYPE"
  431. case "$PACKAGETYPE" in
  432. apt)
  433. # Ideally we want to use curl, but on some installs we
  434. # only have wget. Detect and use what's available.
  435. CURL=
  436. if type curl >/dev/null; then
  437. CURL="curl -fsSL"
  438. elif type wget >/dev/null; then
  439. CURL="wget -q -O-"
  440. fi
  441. if [ -z "$CURL" ]; then
  442. echo "The installer needs either curl or wget to download files."
  443. echo "Please install either curl or wget to proceed."
  444. exit 1
  445. fi
  446. export DEBIAN_FRONTEND=noninteractive
  447. if [ "$APT_KEY_TYPE" = "legacy" ] && ! type gpg >/dev/null; then
  448. $SUDO apt-get update
  449. $SUDO apt-get install -y gnupg
  450. fi
  451. set -x
  452. $SUDO mkdir -p --mode=0755 /usr/share/keyrings
  453. case "$APT_KEY_TYPE" in
  454. legacy)
  455. $CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.asc" | $SUDO apt-key add -
  456. $CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.list" | $SUDO tee /etc/apt/sources.list.d/tailscale.list
  457. ;;
  458. keyring)
  459. $CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.noarmor.gpg" | $SUDO tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
  460. $CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.tailscale-keyring.list" | $SUDO tee /etc/apt/sources.list.d/tailscale.list
  461. ;;
  462. esac
  463. $SUDO apt-get update
  464. $SUDO apt-get install -y tailscale
  465. if [ "$APT_SYSTEMCTL_START" = "true" ]; then
  466. $SUDO systemctl enable --now tailscaled
  467. $SUDO systemctl start tailscaled
  468. fi
  469. set +x
  470. ;;
  471. yum)
  472. set -x
  473. $SUDO yum install yum-utils
  474. $SUDO yum-config-manager -y --add-repo "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION/tailscale.repo"
  475. $SUDO yum install tailscale -y
  476. $SUDO systemctl enable --now tailscaled
  477. set +x
  478. ;;
  479. dnf)
  480. set -x
  481. $SUDO dnf config-manager --add-repo "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION/tailscale.repo"
  482. $SUDO dnf install -y tailscale
  483. $SUDO systemctl enable --now tailscaled
  484. set +x
  485. ;;
  486. zypper)
  487. set -x
  488. $SUDO zypper ar -g -r "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION/tailscale.repo"
  489. $SUDO zypper ref
  490. $SUDO zypper in tailscale
  491. $SUDO systemctl enable --now tailscaled
  492. set +x
  493. ;;
  494. pacman)
  495. set -x
  496. $SUDO pacman -S tailscale --noconfirm
  497. $SUDO systemctl enable --now tailscaled
  498. set +x
  499. ;;
  500. pkg)
  501. set -x
  502. $SUDO pkg install tailscale
  503. $SUDO service tailscaled enable
  504. $SUDO service tailscaled start
  505. set +x
  506. ;;
  507. apk)
  508. set -x
  509. $SUDO apk add tailscale
  510. $SUDO rc-update add tailscale
  511. set +x
  512. ;;
  513. xbps)
  514. set -x
  515. $SUDO xbps-install tailscale -y
  516. set +x
  517. ;;
  518. emerge)
  519. set -x
  520. $SUDO emerge --ask=n net-vpn/tailscale
  521. set +x
  522. ;;
  523. appstore)
  524. set -x
  525. open "https://apps.apple.com/us/app/tailscale/id1475387142"
  526. set +x
  527. ;;
  528. *)
  529. echo "unexpected: unknown package type $PACKAGETYPE"
  530. exit 1
  531. ;;
  532. esac
  533. echo "Installation complete! Log in to start using Tailscale by running:"
  534. echo
  535. if [ -z "$SUDO" ]; then
  536. echo "tailscale up"
  537. else
  538. echo "$SUDO tailscale up"
  539. fi
  540. }
  541. main