-
Notifications
You must be signed in to change notification settings - Fork 75
/
Copy pathrun
executable file
·170 lines (151 loc) · 6.13 KB
/
run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/command/with-contenv bashio
# shellcheck shell=bash
# ==============================================================================
# Home Assistant Community Add-on: Tailscale
# Runs after the machine has been logged in into the Tailscale network
# ==============================================================================
declare default_route_device
declare -a options
declare -a routes=()
declare route
declare -a colliding_routes=()
declare login_server
declare tags
declare keyexpiry
# Linux optimizations for subnet routers and exit nodes
# Based on: https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
# Note: Changes made via ethtool are not persistent and will be lost after the machine shuts down.
# Note: Executing it before "tailscale up" to avoid warning messages
default_route_device=$(ip -4 route show 0/0 | cut -f5 -d' ')
if bashio::var.has_value "${default_route_device}"; then
ethtool -K "${default_route_device}" rx-udp-gro-forwarding on rx-gro-list off
fi
# Default options
options+=(--hostname "$(bashio::info.hostname)")
# Accept magicDNS by default when not set, or when explicitly enabled
if ! bashio::config.has_value "accept_dns" || \
bashio::config.true "accept_dns";
then
options+=(--accept-dns)
else
options+=(--accept-dns=false)
fi
# Accept routes by default when not set, or when explicitly enabled
if ! bashio::config.has_value "accept_routes" || \
bashio::config.true "accept_routes";
then
options+=(--accept-routes)
else
options+=(--accept-routes=false)
fi
# Advertise as exit node by default when not set, or when explicitly enabled
if ! bashio::config.has_value "advertise_exit_node" || \
bashio::config.true "advertise_exit_node";
then
options+=(--advertise-exit-node)
else
options+=(--advertise-exit-node=false)
fi
# Advertise app connector by default when not set, or when explicitly enabled
if ! bashio::config.has_value "advertise_connector" || \
bashio::config.true "advertise_connector";
then
options+=(--advertise-connector)
else
options+=(--advertise-connector=false)
fi
# Get configured control server
if bashio::config.has_value "login_server";
then
login_server=$(bashio::config "login_server")
options+=(--login-server="${login_server}")
fi
# Support basic site-to-site networking, disable stateful filtering
if ! bashio::config.has_value "stateful_filtering" || \
bashio::config.true "stateful_filtering";
then
options+=(--stateful-filtering)
else
options+=(--stateful-filtering=false)
fi
# Support advanced site-to-site networking, disable source addresses NAT
if ! bashio::config.has_value "snat_subnet_routes" || \
bashio::config.true "snat_subnet_routes";
then
options+=(--snat-subnet-routes)
else
options+=(--snat-subnet-routes=false)
fi
# Get configured tags
tags=$(bashio::config "tags//[] | join(\",\")" "")
options+=(--advertise-tags="${tags}")
# Advertise subnet routes
readarray -t routes < <(subnet-routes advertised)
IFS=","
options+=(--advertise-routes="${routes[*]}")
unset IFS
# Wait for the network to be available and logged in
while ! bashio::fs.socket_exists "/var/run/tailscale/tailscaled.sock" || \
! /opt/tailscale status --json --peers=false --self=false \
| jq --exit-status '.BackendState == "Running" or .BackendState == "NeedsLogin"' > /dev/null;
do
sleep 2
done
# Start Tailscale
if ! /opt/tailscale up "${options[@]}"; then
bashio::log.error "Unable to start up Tailscale"
bashio::exit.nok
fi
# Wait for the network to be available and logged in
while ! /opt/tailscale status --json --peers=false --self=false \
| jq --exit-status '.BackendState == "Running"' > /dev/null
do
sleep 2
done
bashio::log.info "Tailscale is running"
# Delete previously created persistent tailscale serve configuration ONCE
# After add-on's serve (proxy and funnel) service is a longrun service, we do not modify the serve state permanently
# This step can be removed in a later version with the file in the data folder also
if ! bashio::fs.file_exists "/data/final_serve_reset_is_done"; then
if ! /opt/tailscale serve reset; then
bashio::log.error "Unable to remove previous Tailscale Proxy and Funnel settings"
bashio::exit.nok
fi
touch "/data/final_serve_reset_is_done"
fi
# Warn about key expiration
if keyexpiry=$(/opt/tailscale status --self=true --peers=false --json | jq -rce '.Self.KeyExpiry'); then
bashio::log.warning "The connection's key will expire on: ${keyexpiry}"
bashio::log.warning "Consider disabling key expiry to avoid losing connection to your Home Assistant device."
bashio::log.warning "Please check your configuration based on the add-on's documentation under \"Configuration\""
fi
# Warn about colliding subnet routes if non-userspace networking and accepting routes are enabled
if bashio::config.false "userspace_networking" && \
(! bashio::config.has_value "accept_routes" || \
bashio::config.true "accept_routes");
then
readarray -t colliding_routes < <( \
comm -1 -2 \
<(subnet-routes local) \
<(/opt/tailscale status --json --peers=true --self=false \
| jq -rc '.Peer[] | select(has("PrimaryRoutes")) | .PrimaryRoutes[]' \
| sort -u))
if (( 0 < ${#colliding_routes[@]} )); then
bashio::log.warning "Currently the following subnets are both present as local subnets"
bashio::log.warning "and are also routed within your tailnet to other nodes!"
bashio::log.warning "Please reconfigure your subnet routing within your tailnet"
bashio::log.warning "to prevent current or future collisions."
fi
for route in "${colliding_routes[@]}"; do
bashio::log.warning " ${route}"
done
fi
# Notify about userspace networking
if ! bashio::config.has_value "userspace_networking" || \
bashio::config.true "userspace_networking";
then
bashio::log.notice "The add-on uses userspace networking mode."
bashio::log.notice "If you need to access other clients on your tailnet from your Home Assistant instance,"
bashio::log.notice "disable userspace networking mode, that will create a \"tailscale0\" network interface on your host."
bashio::log.notice "Please check your configuration based on the add-on's documentation under \"Option: userspace_networking\""
fi