installer.sh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  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, as in linuxmint, use instead of VERSION_CODENAME
  41. . /etc/os-release
  42. case "$ID" in
  43. ubuntu|pop|neon|zorin|elementary|linuxmint)
  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. raspbian)
  72. OS="$ID"
  73. VERSION="$VERSION_CODENAME"
  74. PACKAGETYPE="apt"
  75. # Third-party keyrings became the preferred method of
  76. # installation in Raspbian 11 (Bullseye).
  77. if [ "$VERSION_ID" -lt 11 ]; then
  78. APT_KEY_TYPE="legacy"
  79. else
  80. APT_KEY_TYPE="keyring"
  81. fi
  82. ;;
  83. kali)
  84. OS="debian"
  85. PACKAGETYPE="apt"
  86. YEAR="$(echo "$VERSION_ID" | cut -f1 -d.)"
  87. APT_SYSTEMCTL_START=true
  88. # Third-party keyrings became the preferred method of
  89. # installation in Debian 11 (Bullseye), which Kali switched
  90. # to in roughly 2021.x releases
  91. if [ "$YEAR" -lt 2021 ]; then
  92. # Kali VERSION_ID is "kali-rolling", which isn't distinguishing
  93. VERSION="buster"
  94. APT_KEY_TYPE="legacy"
  95. else
  96. VERSION="bullseye"
  97. APT_KEY_TYPE="keyring"
  98. fi
  99. ;;
  100. centos)
  101. OS="$ID"
  102. VERSION="$VERSION_ID"
  103. PACKAGETYPE="dnf"
  104. if [ "$VERSION" = "7" ]; then
  105. PACKAGETYPE="yum"
  106. fi
  107. ;;
  108. ol)
  109. OS="oracle"
  110. VERSION="$(echo "$VERSION_ID" | cut -f1 -d.)"
  111. PACKAGETYPE="dnf"
  112. if [ "$VERSION" = "7" ]; then
  113. PACKAGETYPE="yum"
  114. fi
  115. ;;
  116. rhel)
  117. OS="$ID"
  118. VERSION="$(echo "$VERSION_ID" | cut -f1 -d.)"
  119. PACKAGETYPE="dnf"
  120. ;;
  121. fedora)
  122. OS="$ID"
  123. VERSION=""
  124. PACKAGETYPE="dnf"
  125. ;;
  126. rocky)
  127. OS="fedora"
  128. VERSION=""
  129. PACKAGETYPE="dnf"
  130. ;;
  131. amzn)
  132. OS="amazon-linux"
  133. VERSION="$VERSION_ID"
  134. PACKAGETYPE="yum"
  135. ;;
  136. opensuse-leap)
  137. OS="opensuse"
  138. VERSION="leap/$VERSION_ID"
  139. PACKAGETYPE="zypper"
  140. ;;
  141. opensuse-tumbleweed)
  142. OS="opensuse"
  143. VERSION="tumbleweed"
  144. PACKAGETYPE="zypper"
  145. ;;
  146. arch)
  147. OS="$ID"
  148. VERSION="" # rolling release
  149. PACKAGETYPE="pacman"
  150. ;;
  151. manjaro)
  152. OS="$ID"
  153. VERSION="" # rolling release
  154. PACKAGETYPE="pacman"
  155. ;;
  156. alpine)
  157. OS="$ID"
  158. VERSION="$VERSION_ID"
  159. PACKAGETYPE="apk"
  160. ;;
  161. nixos)
  162. echo "Please add Tailscale to your NixOS configuration directly:"
  163. echo
  164. echo "services.tailscale.enable = true;"
  165. exit 1
  166. ;;
  167. void)
  168. OS="$ID"
  169. VERSION="" # rolling release
  170. PACKAGETYPE="xbps"
  171. ;;
  172. gentoo)
  173. OS="$ID"
  174. VERSION="" # rolling release
  175. PACKAGETYPE="emerge"
  176. ;;
  177. freebsd)
  178. OS="$ID"
  179. VERSION="$(echo "$VERSION_ID" | cut -f1 -d.)"
  180. PACKAGETYPE="pkg"
  181. ;;
  182. # TODO: wsl?
  183. # TODO: synology? qnap?
  184. esac
  185. fi
  186. # If we failed to detect something through os-release, consult
  187. # uname and try to infer things from that.
  188. if [ -z "$OS" ]; then
  189. if type uname >/dev/null 2>&1; then
  190. case "$(uname)" in
  191. FreeBSD)
  192. # FreeBSD before 12.2 doesn't have
  193. # /etc/os-release, so we wouldn't have found it in
  194. # the os-release probing above.
  195. OS="freebsd"
  196. VERSION="$(freebsd-version | cut -f1 -d.)"
  197. PACKAGETYPE="pkg"
  198. ;;
  199. OpenBSD)
  200. OS="openbsd"
  201. VERSION="$(uname -r)"
  202. PACKAGETYPE=""
  203. ;;
  204. Darwin)
  205. OS="macos"
  206. VERSION="$(sw_vers -productVersion | cut -f1-2 -d.)"
  207. PACKAGETYPE="appstore"
  208. ;;
  209. Linux)
  210. OS="other-linux"
  211. VERSION=""
  212. PACKAGETYPE=""
  213. ;;
  214. esac
  215. fi
  216. fi
  217. # Step 2: having detected an OS we support, is it one of the
  218. # versions we support?
  219. OS_UNSUPPORTED=
  220. case "$OS" in
  221. ubuntu)
  222. if [ "$VERSION" != "xenial" ] && \
  223. [ "$VERSION" != "bionic" ] && \
  224. [ "$VERSION" != "eoan" ] && \
  225. [ "$VERSION" != "focal" ] && \
  226. [ "$VERSION" != "groovy" ] && \
  227. [ "$VERSION" != "hirsute" ] && \
  228. [ "$VERSION" != "impish" ] && \
  229. [ "$VERSION" != "jammy" ]
  230. then
  231. OS_UNSUPPORTED=1
  232. fi
  233. ;;
  234. debian)
  235. if [ "$VERSION" != "stretch" ] && \
  236. [ "$VERSION" != "buster" ] && \
  237. [ "$VERSION" != "bullseye" ] && \
  238. [ "$VERSION" != "bookworm" ] && \
  239. [ "$VERSION" != "sid" ]
  240. then
  241. OS_UNSUPPORTED=1
  242. fi
  243. ;;
  244. raspbian)
  245. if [ "$VERSION" != "buster" ] && \
  246. [ "$VERSION" != "bullseye" ]
  247. then
  248. OS_UNSUPPORTED=1
  249. fi
  250. ;;
  251. centos)
  252. if [ "$VERSION" != "7" ] && \
  253. [ "$VERSION" != "8" ] && \
  254. [ "$VERSION" != "9" ]
  255. then
  256. OS_UNSUPPORTED=1
  257. fi
  258. ;;
  259. oracle)
  260. if [ "$VERSION" != "7" ] && \
  261. [ "$VERSION" != "8" ]
  262. then
  263. OS_UNSUPPORTED=1
  264. fi
  265. ;;
  266. rhel)
  267. if [ "$VERSION" != "8" ]
  268. then
  269. OS_UNSUPPORTED=1
  270. fi
  271. ;;
  272. amazon-linux)
  273. if [ "$VERSION" != "2" ]
  274. then
  275. OS_UNSUPPORTED=1
  276. fi
  277. ;;
  278. opensuse)
  279. if [ "$VERSION" != "leap/15.1" ] && \
  280. [ "$VERSION" != "leap/15.2" ] && \
  281. [ "$VERSION" != "leap/15.3" ] && \
  282. [ "$VERSION" != "tumbleweed" ]
  283. then
  284. OS_UNSUPPORTED=1
  285. fi
  286. ;;
  287. fedora)
  288. # All versions supported, no version checking required.
  289. ;;
  290. arch)
  291. # Rolling release, no version checking needed.
  292. ;;
  293. manjaro)
  294. # Rolling release, no version checking needed.
  295. ;;
  296. alpine)
  297. # All versions supported, no version checking needed.
  298. # TODO: is that true? When was tailscale packaged?
  299. ;;
  300. void)
  301. # Rolling release, no version checking needed.
  302. ;;
  303. gentoo)
  304. # Rolling release, no version checking needed.
  305. ;;
  306. freebsd)
  307. if [ "$VERSION" != "12" ] && \
  308. [ "$VERSION" != "13" ]
  309. then
  310. OS_UNSUPPORTED=1
  311. fi
  312. ;;
  313. openbsd)
  314. OS_UNSUPPORTED=1
  315. ;;
  316. macos)
  317. # We delegate macOS installation to the app store, it will
  318. # perform version checks for us.
  319. ;;
  320. other-linux)
  321. OS_UNSUPPORTED=1
  322. ;;
  323. *)
  324. OS_UNSUPPORTED=1
  325. ;;
  326. esac
  327. if [ "$OS_UNSUPPORTED" = "1" ]; then
  328. case "$OS" in
  329. other-linux)
  330. echo "Couldn't determine what kind of Linux is running."
  331. echo "You could try the static binaries at:"
  332. echo "https://pkgs.tailscale.com/$TRACK/#static"
  333. ;;
  334. "")
  335. echo "Couldn't determine what operating system you're running."
  336. ;;
  337. *)
  338. echo "$OS $VERSION isn't supported by this script yet."
  339. ;;
  340. esac
  341. echo
  342. echo "If you'd like us to support your system better, please email [email protected]"
  343. echo "and tell us what OS you're running."
  344. echo
  345. echo "Please include the following information we gathered from your system:"
  346. echo
  347. echo "OS=$OS"
  348. echo "VERSION=$VERSION"
  349. echo "PACKAGETYPE=$PACKAGETYPE"
  350. if type uname >/dev/null 2>&1; then
  351. echo "UNAME=$(uname -a)"
  352. else
  353. echo "UNAME="
  354. fi
  355. echo
  356. if [ -f /etc/os-release ]; then
  357. cat /etc/os-release
  358. else
  359. echo "No /etc/os-release"
  360. fi
  361. exit 1
  362. fi
  363. # Step 3: work out if we can run privileged commands, and if so,
  364. # how.
  365. CAN_ROOT=
  366. SUDO=
  367. if [ "$(id -u)" = 0 ]; then
  368. CAN_ROOT=1
  369. SUDO=""
  370. elif type sudo >/dev/null; then
  371. CAN_ROOT=1
  372. SUDO="sudo"
  373. elif type doas >/dev/null; then
  374. CAN_ROOT=1
  375. SUDO="doas"
  376. fi
  377. if [ "$CAN_ROOT" != "1" ]; then
  378. echo "This installer needs to run commands as root."
  379. echo "We tried looking for 'sudo' and 'doas', but couldn't find them."
  380. echo "Either re-run this script as root, or set up sudo/doas."
  381. exit 1
  382. fi
  383. # Step 4: run the installation.
  384. echo "Installing Tailscale for $OS $VERSION, using method $PACKAGETYPE"
  385. case "$PACKAGETYPE" in
  386. apt)
  387. # Ideally we want to use curl, but on some installs we
  388. # only have wget. Detect and use what's available.
  389. CURL=
  390. if type curl >/dev/null; then
  391. CURL="curl -fsSL"
  392. elif type wget >/dev/null; then
  393. CURL="wget -q -O-"
  394. fi
  395. if [ -z "$CURL" ]; then
  396. echo "The installer needs either curl or wget to download files."
  397. echo "Please install either curl or wget to proceed."
  398. exit 1
  399. fi
  400. export DEBIAN_FRONTEND=noninteractive
  401. if ! type gpg >/dev/null; then
  402. $SUDO apt-get update
  403. $SUDO apt-get install -y gnupg
  404. fi
  405. set -x
  406. $SUDO mkdir -p --mode=0755 /usr/share/keyrings
  407. case "$APT_KEY_TYPE" in
  408. legacy)
  409. $CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.asc" | $SUDO apt-key add -
  410. $CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.list" | $SUDO tee /etc/apt/sources.list.d/tailscale.list
  411. ;;
  412. keyring)
  413. $CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.noarmor.gpg" | $SUDO tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
  414. $CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.tailscale-keyring.list" | $SUDO tee /etc/apt/sources.list.d/tailscale.list
  415. ;;
  416. esac
  417. $SUDO apt-get update
  418. $SUDO apt-get install -y tailscale
  419. if [ "$APT_SYSTEMCTL_START" = "true" ]; then
  420. $SUDO systemctl enable --now tailscaled
  421. $SUDO systemctl start tailscaled
  422. fi
  423. set +x
  424. ;;
  425. yum)
  426. set -x
  427. $SUDO yum install yum-utils
  428. $SUDO yum-config-manager -y --add-repo "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION/tailscale.repo"
  429. $SUDO yum install tailscale -y
  430. $SUDO systemctl enable --now tailscaled
  431. set +x
  432. ;;
  433. dnf)
  434. set -x
  435. $SUDO dnf config-manager --add-repo "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION/tailscale.repo"
  436. $SUDO dnf install -y tailscale
  437. $SUDO systemctl enable --now tailscaled
  438. set +x
  439. ;;
  440. zypper)
  441. set -x
  442. $SUDO zypper ar -g -r "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION/tailscale.repo"
  443. $SUDO zypper ref
  444. $SUDO zypper in tailscale
  445. $SUDO systemctl enable --now tailscaled
  446. set +x
  447. ;;
  448. pacman)
  449. set -x
  450. $SUDO pacman -S tailscale
  451. $SUDO systemctl enable --now tailscaled
  452. set +x
  453. ;;
  454. apk)
  455. set -x
  456. $SUDO apk add tailscale
  457. $SUDO rc-update add tailscale
  458. set +x
  459. ;;
  460. xbps)
  461. set -x
  462. $SUDO xbps-install tailscale -y
  463. set +x
  464. ;;
  465. emerge)
  466. set -x
  467. $SUDO emerge net-vpn/tailscale
  468. set +x
  469. ;;
  470. appstore)
  471. set -x
  472. open "https://apps.apple.com/us/app/tailscale/id1475387142"
  473. set +x
  474. ;;
  475. *)
  476. echo "unexpected: unknown package type $PACKAGETYPE"
  477. exit 1
  478. ;;
  479. esac
  480. echo "Installation complete! Log in to start using Tailscale by running:"
  481. echo
  482. if [ -z "$SUDO" ]; then
  483. echo "tailscale up"
  484. else
  485. echo "$SUDO tailscale up"
  486. fi
  487. }
  488. main