Add Tailscale Application

This commit is contained in:
Taylor Helsper 2022-09-03 23:35:02 -05:00
parent d188139cdb
commit 6771a11543
16 changed files with 784 additions and 0 deletions

View File

@ -0,0 +1,553 @@
#!/bin/sh
# Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
#
# This script detects the current operating system, and installs
# Tailscale according to that OS's conventions.
set -eu
# All the code is wrapped in a main function that gets called at the
# bottom of the file, so that a truncated partial download doesn't end
# up executing half a script.
main() {
# Step 1: detect the current linux distro, version, and packaging system.
#
# We rely on a combination of 'uname' and /etc/os-release to find
# an OS name and version, and from there work out what
# installation method we should be using.
#
# The end result of this step is that the following three
# variables are populated, if detection was successful.
OS=""
VERSION=""
PACKAGETYPE=""
APT_KEY_TYPE="" # Only for apt-based distros
APT_SYSTEMCTL_START=false # Only needs to be true for Kali
TRACK="${TRACK:-stable}"
case "$TRACK" in
stable|unstable)
;;
*)
echo "unsupported track $TRACK"
exit 1
;;
esac
if [ -f /etc/os-release ]; then
# /etc/os-release populates a number of shell variables. We care about the following:
# - ID: the short name of the OS (e.g. "debian", "freebsd")
# - VERSION_ID: the numeric release version for the OS, if any (e.g. "18.04")
# - VERSION_CODENAME: the codename of the OS release, if any (e.g. "buster")
# - UBUNTU_CODENAME: if it exists, use instead of VERSION_CODENAME
. /etc/os-release
case "$ID" in
ubuntu|pop|neon|zorin)
OS="ubuntu"
if [ "${UBUNTU_CODENAME:-}" != "" ]; then
VERSION="$UBUNTU_CODENAME"
else
VERSION="$VERSION_CODENAME"
fi
PACKAGETYPE="apt"
# Third-party keyrings became the preferred method of
# installation in Ubuntu 20.04.
if expr "$VERSION_ID" : "2.*" >/dev/null; then
APT_KEY_TYPE="keyring"
else
APT_KEY_TYPE="legacy"
fi
;;
debian)
OS="$ID"
VERSION="$VERSION_CODENAME"
PACKAGETYPE="apt"
# Third-party keyrings became the preferred method of
# installation in Debian 11 (Bullseye).
if [ "$VERSION_ID" -lt 11 ]; then
APT_KEY_TYPE="legacy"
else
APT_KEY_TYPE="keyring"
fi
;;
linuxmint)
if [ "${UBUNTU_CODENAME:-}" != "" ]; then
OS="ubuntu"
VERSION="$UBUNTU_CODENAME"
elif [ "${DEBIAN_CODENAME:-}" != "" ]; then
OS="debian"
VERSION="$DEBIAN_CODENAME"
else
OS="ubuntu"
VERSION="$VERSION_CODENAME"
fi
PACKAGETYPE="apt"
if [ "$VERSION_ID" -lt 5 ]; then
APT_KEY_TYPE="legacy"
else
APT_KEY_TYPE="keyring"
fi
;;
elementary)
OS="ubuntu"
VERSION="$UBUNTU_CODENAME"
PACKAGETYPE="apt"
if [ "$VERSION_ID" -lt 6 ]; then
APT_KEY_TYPE="legacy"
else
APT_KEY_TYPE="keyring"
fi
;;
parrot)
OS="debian"
PACKAGETYPE="apt"
if [ "$VERSION_ID" -lt 5 ]; then
VERSION="buster"
APT_KEY_TYPE="legacy"
else
VERSION="bullseye"
APT_KEY_TYPE="keyring"
fi
;;
raspbian)
OS="$ID"
VERSION="$VERSION_CODENAME"
PACKAGETYPE="apt"
# Third-party keyrings became the preferred method of
# installation in Raspbian 11 (Bullseye).
if [ "$VERSION_ID" -lt 11 ]; then
APT_KEY_TYPE="legacy"
else
APT_KEY_TYPE="keyring"
fi
;;
kali)
OS="debian"
PACKAGETYPE="apt"
YEAR="$(echo "$VERSION_ID" | cut -f1 -d.)"
APT_SYSTEMCTL_START=true
# Third-party keyrings became the preferred method of
# installation in Debian 11 (Bullseye), which Kali switched
# to in roughly 2021.x releases
if [ "$YEAR" -lt 2021 ]; then
# Kali VERSION_ID is "kali-rolling", which isn't distinguishing
VERSION="buster"
APT_KEY_TYPE="legacy"
else
VERSION="bullseye"
APT_KEY_TYPE="keyring"
fi
;;
centos)
OS="$ID"
VERSION="$VERSION_ID"
PACKAGETYPE="dnf"
if [ "$VERSION" = "7" ]; then
PACKAGETYPE="yum"
fi
;;
ol)
OS="oracle"
VERSION="$(echo "$VERSION_ID" | cut -f1 -d.)"
PACKAGETYPE="dnf"
if [ "$VERSION" = "7" ]; then
PACKAGETYPE="yum"
fi
;;
rhel)
OS="$ID"
VERSION="$(echo "$VERSION_ID" | cut -f1 -d.)"
PACKAGETYPE="dnf"
;;
fedora)
OS="$ID"
VERSION=""
PACKAGETYPE="dnf"
;;
rocky|almalinux)
OS="fedora"
VERSION=""
PACKAGETYPE="dnf"
;;
amzn)
OS="amazon-linux"
VERSION="$VERSION_ID"
PACKAGETYPE="yum"
;;
xenenterprise)
OS="centos"
VERSION="$(echo "$VERSION_ID" | cut -f1 -d.)"
PACKAGETYPE="yum"
;;
opensuse-leap)
OS="opensuse"
VERSION="leap/$VERSION_ID"
PACKAGETYPE="zypper"
;;
opensuse-tumbleweed)
OS="opensuse"
VERSION="tumbleweed"
PACKAGETYPE="zypper"
;;
arch|archarm|endeavouros)
OS="arch"
VERSION="" # rolling release
PACKAGETYPE="pacman"
;;
manjaro|manjaro-arm)
OS="manjaro"
VERSION="" # rolling release
PACKAGETYPE="pacman"
;;
alpine)
OS="$ID"
VERSION="$VERSION_ID"
PACKAGETYPE="apk"
;;
nixos)
echo "Please add Tailscale to your NixOS configuration directly:"
echo
echo "services.tailscale.enable = true;"
exit 1
;;
void)
OS="$ID"
VERSION="" # rolling release
PACKAGETYPE="xbps"
;;
gentoo)
OS="$ID"
VERSION="" # rolling release
PACKAGETYPE="emerge"
;;
freebsd)
OS="$ID"
VERSION="$(echo "$VERSION_ID" | cut -f1 -d.)"
PACKAGETYPE="pkg"
;;
# TODO: wsl?
# TODO: synology? qnap?
esac
fi
# If we failed to detect something through os-release, consult
# uname and try to infer things from that.
if [ -z "$OS" ]; then
if type uname >/dev/null 2>&1; then
case "$(uname)" in
FreeBSD)
# FreeBSD before 12.2 doesn't have
# /etc/os-release, so we wouldn't have found it in
# the os-release probing above.
OS="freebsd"
VERSION="$(freebsd-version | cut -f1 -d.)"
PACKAGETYPE="pkg"
;;
OpenBSD)
OS="openbsd"
VERSION="$(uname -r)"
PACKAGETYPE=""
;;
Darwin)
OS="macos"
VERSION="$(sw_vers -productVersion | cut -f1-2 -d.)"
PACKAGETYPE="appstore"
;;
Linux)
OS="other-linux"
VERSION=""
PACKAGETYPE=""
;;
esac
fi
fi
# Step 2: having detected an OS we support, is it one of the
# versions we support?
OS_UNSUPPORTED=
case "$OS" in
ubuntu)
if [ "$VERSION" != "xenial" ] && \
[ "$VERSION" != "bionic" ] && \
[ "$VERSION" != "eoan" ] && \
[ "$VERSION" != "focal" ] && \
[ "$VERSION" != "groovy" ] && \
[ "$VERSION" != "hirsute" ] && \
[ "$VERSION" != "impish" ] && \
[ "$VERSION" != "jammy" ]
then
OS_UNSUPPORTED=1
fi
;;
debian)
if [ "$VERSION" != "stretch" ] && \
[ "$VERSION" != "buster" ] && \
[ "$VERSION" != "bullseye" ] && \
[ "$VERSION" != "bookworm" ] && \
[ "$VERSION" != "sid" ]
then
OS_UNSUPPORTED=1
fi
;;
raspbian)
if [ "$VERSION" != "stretch" ] && \
[ "$VERSION" != "buster" ] && \
[ "$VERSION" != "bullseye" ]
then
OS_UNSUPPORTED=1
fi
;;
centos)
if [ "$VERSION" != "7" ] && \
[ "$VERSION" != "8" ] && \
[ "$VERSION" != "9" ]
then
OS_UNSUPPORTED=1
fi
;;
oracle)
if [ "$VERSION" != "7" ] && \
[ "$VERSION" != "8" ]
then
OS_UNSUPPORTED=1
fi
;;
rhel)
if [ "$VERSION" != "8" ] && \
[ "$VERSION" != "9" ]
then
OS_UNSUPPORTED=1
fi
;;
amazon-linux)
if [ "$VERSION" != "2" ]
then
OS_UNSUPPORTED=1
fi
;;
opensuse)
if [ "$VERSION" != "leap/15.1" ] && \
[ "$VERSION" != "leap/15.2" ] && \
[ "$VERSION" != "leap/15.3" ] && \
[ "$VERSION" != "tumbleweed" ]
then
OS_UNSUPPORTED=1
fi
;;
fedora)
# All versions supported, no version checking required.
;;
arch)
# Rolling release, no version checking needed.
;;
manjaro)
# Rolling release, no version checking needed.
;;
alpine)
# All versions supported, no version checking needed.
# TODO: is that true? When was tailscale packaged?
;;
void)
# Rolling release, no version checking needed.
;;
gentoo)
# Rolling release, no version checking needed.
;;
freebsd)
if [ "$VERSION" != "12" ] && \
[ "$VERSION" != "13" ]
then
OS_UNSUPPORTED=1
fi
;;
openbsd)
OS_UNSUPPORTED=1
;;
macos)
# We delegate macOS installation to the app store, it will
# perform version checks for us.
;;
other-linux)
OS_UNSUPPORTED=1
;;
*)
OS_UNSUPPORTED=1
;;
esac
if [ "$OS_UNSUPPORTED" = "1" ]; then
case "$OS" in
other-linux)
echo "Couldn't determine what kind of Linux is running."
echo "You could try the static binaries at:"
echo "https://pkgs.tailscale.com/$TRACK/#static"
;;
"")
echo "Couldn't determine what operating system you're running."
;;
*)
echo "$OS $VERSION isn't supported by this script yet."
;;
esac
echo
echo "If you'd like us to support your system better, please email support@tailscale.com"
echo "and tell us what OS you're running."
echo
echo "Please include the following information we gathered from your system:"
echo
echo "OS=$OS"
echo "VERSION=$VERSION"
echo "PACKAGETYPE=$PACKAGETYPE"
if type uname >/dev/null 2>&1; then
echo "UNAME=$(uname -a)"
else
echo "UNAME="
fi
echo
if [ -f /etc/os-release ]; then
cat /etc/os-release
else
echo "No /etc/os-release"
fi
exit 1
fi
# Step 3: work out if we can run privileged commands, and if so,
# how.
CAN_ROOT=
SUDO=
if [ "$(id -u)" = 0 ]; then
CAN_ROOT=1
SUDO=""
elif type sudo >/dev/null; then
CAN_ROOT=1
SUDO="sudo"
elif type doas >/dev/null; then
CAN_ROOT=1
SUDO="doas"
fi
if [ "$CAN_ROOT" != "1" ]; then
echo "This installer needs to run commands as root."
echo "We tried looking for 'sudo' and 'doas', but couldn't find them."
echo "Either re-run this script as root, or set up sudo/doas."
exit 1
fi
# Step 4: run the installation.
echo "Installing Tailscale for $OS $VERSION, using method $PACKAGETYPE"
case "$PACKAGETYPE" in
apt)
# Ideally we want to use curl, but on some installs we
# only have wget. Detect and use what's available.
CURL=
if type curl >/dev/null; then
CURL="curl -fsSL"
elif type wget >/dev/null; then
CURL="wget -q -O-"
fi
if [ -z "$CURL" ]; then
echo "The installer needs either curl or wget to download files."
echo "Please install either curl or wget to proceed."
exit 1
fi
export DEBIAN_FRONTEND=noninteractive
if [ "$APT_KEY_TYPE" = "legacy" ] && ! type gpg >/dev/null; then
$SUDO apt-get update
$SUDO apt-get install -y gnupg
fi
set -x
$SUDO mkdir -p --mode=0755 /usr/share/keyrings
case "$APT_KEY_TYPE" in
legacy)
$CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.asc" | $SUDO apt-key add -
$CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.list" | $SUDO tee /etc/apt/sources.list.d/tailscale.list
;;
keyring)
$CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.noarmor.gpg" | $SUDO tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
$CURL "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION.tailscale-keyring.list" | $SUDO tee /etc/apt/sources.list.d/tailscale.list
;;
esac
$SUDO apt-get update
$SUDO apt-get install -y tailscale
if [ "$APT_SYSTEMCTL_START" = "true" ]; then
$SUDO systemctl enable --now tailscaled
$SUDO systemctl start tailscaled
fi
set +x
;;
yum)
set -x
$SUDO yum install yum-utils -y
$SUDO yum-config-manager -y --add-repo "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION/tailscale.repo"
$SUDO yum install tailscale -y
$SUDO systemctl enable --now tailscaled
set +x
;;
dnf)
set -x
$SUDO dnf config-manager --add-repo "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION/tailscale.repo"
$SUDO dnf install -y tailscale
$SUDO systemctl enable --now tailscaled
set +x
;;
zypper)
set -x
$SUDO zypper ar -g -r "https://pkgs.tailscale.com/$TRACK/$OS/$VERSION/tailscale.repo"
$SUDO zypper ref
$SUDO zypper in tailscale
$SUDO systemctl enable --now tailscaled
set +x
;;
pacman)
set -x
$SUDO pacman -S tailscale --noconfirm
$SUDO systemctl enable --now tailscaled
set +x
;;
pkg)
set -x
$SUDO pkg install tailscale
$SUDO service tailscaled enable
$SUDO service tailscaled start
set +x
;;
apk)
set -x
$SUDO apk add tailscale
$SUDO rc-update add tailscale
set +x
;;
xbps)
set -x
$SUDO xbps-install tailscale -y
set +x
;;
emerge)
set -x
$SUDO emerge --ask=n net-vpn/tailscale
set +x
;;
appstore)
set -x
open "https://apps.apple.com/us/app/tailscale/id1475387142"
set +x
;;
*)
echo "unexpected: unknown package type $PACKAGETYPE"
exit 1
;;
esac
echo "Installation complete! Log in to start using Tailscale by running:"
echo
if [ -z "$SUDO" ]; then
echo "tailscale up"
else
echo "$SUDO tailscale up"
fi
}
main

View File

@ -0,0 +1,17 @@
server {
listen 8089 ssl;
server_name tailscale;
include /etc/nginx/mynode/mynode_ssl_params.conf;
include /etc/nginx/mynode/mynode_ssl_cert_key.conf;
access_log /var/log/nginx/access_tailscale.log;
error_log /var/log/nginx/error_tailscale.log;
location / {
proxy_pass http://127.0.0.1:8088;
include /etc/nginx/mynode/mynode_ssl_proxy_params.conf;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

View File

@ -0,0 +1,20 @@
#!/bin/bash
source /usr/share/mynode/mynode_device_info.sh
source /usr/share/mynode/mynode_app_versions.sh
set -x
set -e
echo "==================== INSTALLING APP ===================="
# The current directory is the app install folder and the app tarball from GitHub
# has already been downloaded and extracted. Any additional env variables specified
# in the JSON file are also present.
# Load repos (it's OK if this is run multiple times)
# This file comes from https://tailscale.com/install.sh on 9/3/22
bash /usr/share/mynode_apps/tailscale/app_data/install_tailscale.sh
echo "================== DONE INSTALLING APP ================="

View File

@ -0,0 +1,3 @@
#!/bin/bash
# This will run after launching the application

View File

@ -0,0 +1,3 @@
#!/bin/bash
# This will run prior to launching the application

View File

@ -0,0 +1,12 @@
#!/bin/bash
source /usr/share/mynode/mynode_device_info.sh
source /usr/share/mynode/mynode_app_versions.sh
echo "==================== UNINSTALLING APP ===================="
# The app folder will be removed automatically after this script runs. You may not need to do anything here.
/usr/bin/tailscale logout
echo "================== DONE UNINSTALLING APP ================="

View File

@ -0,0 +1,58 @@
{
"name": "Tailscale",
"short_name": "tailscale",
"author": {
"name": "Tailscale",
"link": "https://tailscale.com/"
},
"website": {
"name": "GitHub",
"link": "https://github.com/tailscale/tailscale"
},
"category": "networking",
"short_description": "Simple VPN",
"description": [
"Tailscale is a VPN service that makes the devices and applications you own accessible anywhere in the world, securely and effortlessly. It enables encrypted point-to-point connections using the open source WireGuard protocol, which means only devices on your private network can communicate with each other."
],
"latest_version": "v1.30.0",
"linux_user": "root",
"targz_download_url": "https://github.com/FILL_IN_GITHUB_USER/FILL_IN_GITHUB_PROJECT/archive/refs/tags/{VERSION}.tar.gz",
"skip_targz_download": true,
"install_env_vars": {},
"supports_app_page": true,
"supports_testnet": true,
"http_port": 8088,
"https_port": 8089,
"requires_bitcoin": false,
"requires_docker_image_installation": false,
"requires_electrs": false,
"requires_lightning": false,
"show_on_application_page": true,
"show_on_homepage": true,
"show_on_status_page": true,
"hide_status_icon": false,
"app_tile_name": "Tailscale",
"app_tile_running_status_text": "Running",
"app_tile_button_text": "Info",
"app_tile_button_href": "/app/tailscale/info",
"app_page_show_open_button": true,
"app_page_content": [
{
"heading": "Instructions",
"content": [
"Setting up Tailscale is simple! First, once Tailscale is enabled it will run a web interface that allows you to login to your Tailscale account.",
"After logging in, Tailscale will start running on your device and if you re-open the Tailscale web app, you will see a an IP address. This IP address can be used on any device you have running Tailscale to access the myNode interface!",
"Enjoy!"
]
}
],
"can_uninstall": true,
"can_reinstall": true,
"can_enable_disable": true,
"is_beta": false,
"is_premium": true,
"homepage_section": "remote_services",
"homepage_order": 4,
"app_type": "custom",
"sdk_version": 1
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,29 @@
# tailscale service
# /etc/systemd/system/tailscale.service
[Unit]
Description=tailscale
Wants=www.service
After=www.service
[Service]
WorkingDirectory=/opt/mynode/tailscale
ExecStartPre=/usr/bin/is_not_shutting_down.sh
ExecStartPre=/bin/bash -c 'if [ -f /usr/bin/service_scripts/pre_tailscale.sh ]; then /bin/bash /usr/bin/service_scripts/pre_tailscale.sh; fi'
ExecStart=/usr/bin/tailscale web --listen 0.0.0.0:8088
ExecStartPost=/bin/bash -c 'if [ -f /usr/bin/service_scripts/post_tailscale.sh ]; then /bin/bash /usr/bin/service_scripts/post_tailscale.sh; fi'
ExecStop=/bin/bash -c '/usr/bin/tailscale down || true'
User=root
Group=root
Type=simple
TimeoutSec=120
Restart=always
RestartSec=60
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=tailscale
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,32 @@
from flask import Blueprint, render_template, redirect
from user_management import check_logged_in
from enable_disable_functions import *
from device_info import *
from application_info import *
from systemctl_info import *
import subprocess
import os
mynode_tailscale = Blueprint('mynode_tailscale',__name__)
### Page functions (have prefix /app/<app name/)
@mynode_tailscale.route("/info")
def tailscale_page():
check_logged_in()
app = get_application("tailscale")
app_status = get_application_status("tailscale")
app_status_color = get_application_status_color("tailscale")
# Load page
templateData = {
"title": "myNode - " + app["name"],
"ui_settings": read_ui_settings(),
"app_status": app_status,
"app_status_color": app_status_color,
"app": app
}
return render_template('/app/generic_app.html', **templateData)

View File

@ -0,0 +1,3 @@
Custom Jinja templates (HTML files) can be added here for unique application pages
Templates will be available under applications/<short_name>/xyz.html

View File

@ -0,0 +1,54 @@
<!DOCTYPE html lang="en">
<head>
<title>{{ title }}</title>
{% include 'includes/head.html' %}
</head>
<body>
{% include 'includes/logo_header.html' %}
<div class="mynode_top_left_div">
<a href="/"><img class="mynode_nav_icon" src="{{ url_for('static', filename="images/home.png")}}"/></a>
</div>
<div class="main_header">{{app.name}} (custom page - remove)</div>
<br/>
<div class="app_tile_row">
<div class="info_tile">
<div class="info_tile_header">Status</div>
<div class="info_tile_contents">
<table class="info_table">
<tr>
<th>Status</th>
<td>{{app_status}}</td>
</tr>
<tr>
<th>Actions</th>
<td>
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="#">Open</a>
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="#">Button A</a>
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="#">Button B</a>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="instructions">
<div class="instructions-header">Instructions</div>
<ol class="instructions-steps">
<li>Custom instructions?</li>
</ol>
</div>
<div id="confirm-dialog"></div>
<div id="loading_spinner_overlay" class="loading_spinner_overlay" style="display:none;">
<img id="loading_spinner" class="loading_image" src="{{ url_for('static', filename="images/loading.gif")}}"/>
<br/>
<span id="loading_spinner_message">Loading...</span>
</div>
</body>
</html>