support for commonly used Tailscale param settings
This commit is contained in:
@@ -19,7 +19,7 @@ var callServiceList = rpc.declare({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function getServiceStatus() {
|
function getServiceStatus() {
|
||||||
return L.resolveDefault(callServiceList('tailscale'), {}).then(function (res) {
|
return Promise.resolve(callServiceList('tailscale')).then(function (res) {
|
||||||
var isRunning = false;
|
var isRunning = false;
|
||||||
try {
|
try {
|
||||||
isRunning = res['tailscale']['instances']['instance1']['running'];
|
isRunning = res['tailscale']['instances']['instance1']['running'];
|
||||||
@@ -83,8 +83,9 @@ return view.extend({
|
|||||||
var m, s, o;
|
var m, s, o;
|
||||||
var isRunning = data[1];
|
var isRunning = data[1];
|
||||||
|
|
||||||
m = new form.Map('tailscale', _('Tailscale'),
|
var tailscaleLink = E('a', { href: 'https://login.tailscale.com/admin/machines', target: '_blank' }, _('Tailscale'));
|
||||||
_('Tailscale is a cross-platform and easy to use virtual LAN.'));
|
var description = E('span', {}, _(' is a cross-platform and easy to use virtual LAN.'));
|
||||||
|
m = new form.Map('tailscale', _('Tailscale'), [tailscaleLink, description]);
|
||||||
|
|
||||||
s = m.section(form.TypedSection);
|
s = m.section(form.TypedSection);
|
||||||
s.anonymous = true;
|
s.anonymous = true;
|
||||||
@@ -95,23 +96,84 @@ return view.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
s = m.section(form.NamedSection, 'settings', 'config');
|
s = m.section(form.NamedSection, 'settings', 'config');
|
||||||
|
s.title = _('Basic Settings');
|
||||||
|
|
||||||
o = s.option(form.Flag, 'enabled', _('Enable'));
|
o = s.option(form.Flag, 'enabled', _('Enable'));
|
||||||
o.default = o.disabled;
|
o.default = o.disabled;
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
|
|
||||||
o = s.option(form.DummyValue, 'login_status', _('Login Status'));
|
o = s.option(form.DummyValue, 'login_status', _('Login Status'));
|
||||||
o.depends('enabled', '1');
|
o.depends('enabled', '1');
|
||||||
o.renderWidget = function(section_id, option_id) {
|
o.renderWidget = function(section_id, option_id) {
|
||||||
poll.add(function() {
|
poll.add(function() {
|
||||||
return L.resolveDefault(getLoginStatus()).then(function(res) {
|
return Promise.resolve(getLoginStatus()).then(function(res) {
|
||||||
document.getElementById('login_status_div').innerHTML = renderLogin(res.backendState, res.authURL);
|
document.getElementById('login_status_div').innerHTML = renderLogin(res.backendState, res.authURL);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return E('div', { 'id': 'login_status_div' }, _('Collecting data ...'));
|
return E('div', { 'id': 'login_status_div' }, _('Collecting data ...'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'port', _('Port'), _('Set the Tailscale port number.'));
|
||||||
|
o.datatype = 'port';
|
||||||
|
o.default = '41641';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'config_path', _('Workdir'), _('The working directory contains config files, audit logs, and runtime info.'));
|
||||||
|
o.default = '/etc/tailscale';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.ListValue, 'fw_mode', _('Firewall Mode'));
|
||||||
|
o.value('nftables', 'nftables');
|
||||||
|
o.value('iptables', 'iptables');
|
||||||
|
o.default = 'nftables';
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Flag, 'log_stdout', _('Output Log'), _('Logging program activities.'));
|
||||||
|
o.default = o.enabled;
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Flag, 'log_stderr', _('Error Log'), _('Logging program errors and exceptions.'));
|
||||||
|
o.default = o.enabled;
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
s = m.section(form.NamedSection, 'settings', 'config');
|
||||||
|
s.title = _('Advanced Settings');
|
||||||
|
|
||||||
|
o = s.option(form.Flag, 'acceptRoutes', _('Auto NAT clients'), _('Expose physical network routes onto Tailscale.'));
|
||||||
|
o.default = o.disabled;
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'hostname', _('Hostname'),
|
||||||
|
_("Leave blank to use the device's hostname."));
|
||||||
|
o.default = '';
|
||||||
|
o.rmempty = true;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'advertiseRoutes', _('Expose Subnets'), _('e.g. 10.0.0.0/24'));
|
||||||
|
o.datatype = 'cidr4';
|
||||||
|
o.default = '';
|
||||||
|
o.rmempty = true;
|
||||||
|
|
||||||
|
o = s.option(form.MultiValue, 'access', _('Access Control'));
|
||||||
|
o.value('tsfwlan', _('Tailscale access LAN'));
|
||||||
|
o.value('tsfwwan', _('Tailscale access WAN'));
|
||||||
|
o.value('lanfwts', _('LAN access Tailscale'));
|
||||||
|
o.value('wanfwts', _('WAN access Tailscale'));
|
||||||
|
o.default = "tsfwlan tsfwwan lanfwts";
|
||||||
|
o.depends('acceptRoutes', '1');
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
|
s = m.section(form.NamedSection, 'settings', 'config');
|
||||||
|
s.title = _('Custom Server Settings');
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'loginServer', _('Server address'));
|
||||||
|
o.default = '';
|
||||||
|
o.rmempty = true;
|
||||||
|
|
||||||
|
o = s.option(form.Value, 'authKey', _('Auth Key'));
|
||||||
|
o.default = '';
|
||||||
|
o.rmempty = true;
|
||||||
|
|
||||||
return m.render();
|
return m.render();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ START=90
|
|||||||
|
|
||||||
USE_PROCD=1
|
USE_PROCD=1
|
||||||
|
|
||||||
PROG=/usr/sbin/tailscaled
|
PROG=/usr/sbin/tailscale
|
||||||
|
PROGD=/usr/sbin/tailscaled
|
||||||
CONFIG_PATH=/var/lib/tailscale
|
CONFIG_PATH=/var/lib/tailscale
|
||||||
|
|
||||||
service_triggers() {
|
service_triggers() {
|
||||||
@@ -17,9 +18,115 @@ section_enabled() {
|
|||||||
[ $enabled -gt 0 ]
|
[ $enabled -gt 0 ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
custom_instance() {
|
||||||
|
local cfg="$1"
|
||||||
|
local port config_path fw_mode std_out std_err state_file
|
||||||
|
local ARGS=" up --reset"
|
||||||
|
|
||||||
|
if ! section_enabled "$cfg"; then
|
||||||
|
echo "disabled in config"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
config_get_bool acceptRoutes $cfg 'acceptRoutes'
|
||||||
|
config_get hostname $cfg 'hostname'
|
||||||
|
config_get advertiseRoutes $cfg 'advertiseRoutes'
|
||||||
|
config_get loginServer $cfg 'loginServer'
|
||||||
|
config_get authkey $cfg 'authkey'
|
||||||
|
config_get_bool std_out $cfg 'log_stdout'
|
||||||
|
config_get_bool std_err $cfg 'log_stderr'
|
||||||
|
|
||||||
|
[ -n "$acceptRoutes" ] && ARGS="$ARGS --accept-routes true"
|
||||||
|
[ -n "$hostname" ] && ARGS="$ARGS --hostname $hostname"
|
||||||
|
[ -n "$advertiseRoutes" ] && ARGS="$ARGS --advertise-routes $advertiseRoutes"
|
||||||
|
[ -n "$loginServer" ] && ARGS="$ARGS --login-server $loginServer"
|
||||||
|
[ -n "$authkey" ] && ARGS="$ARGS --authkey $authkey"
|
||||||
|
|
||||||
|
procd_open_instance
|
||||||
|
procd_set_param command $PROG $ARGS
|
||||||
|
procd_set_param stdout "$std_out"
|
||||||
|
procd_set_param stderr "$std_err"
|
||||||
|
procd_close_instance
|
||||||
|
(
|
||||||
|
[ -f "/var/run/tailscale.wait.pid" ] && return
|
||||||
|
touch /var/run/tailscale.wait.pid
|
||||||
|
count=0
|
||||||
|
while [ -z "$(ifconfig | grep 'tailscale' | awk '{print $1}')" ]
|
||||||
|
do
|
||||||
|
sleep 2
|
||||||
|
let count++
|
||||||
|
[ "${count}" -ge 5 ] && { rm /var/run/tailscale.wait.pid; exit 19; }
|
||||||
|
done
|
||||||
|
ts0=$(ifconfig | grep 'tailscale' | awk '{print $1}')
|
||||||
|
for i in ${ts0}
|
||||||
|
do
|
||||||
|
echo "tailscale interface $i is started!"
|
||||||
|
if [ -z "$(uci -q get network.$i)" ]; then
|
||||||
|
uci set network.$i=interface
|
||||||
|
uci set network.$i.proto='static'
|
||||||
|
uci set network.$i.device=$i
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
config_get_bool acceptRoutes $cfg 'acceptRoutes'
|
||||||
|
if [ "$acceptRoutes" == "1" ]; then
|
||||||
|
if [ -z "$(uci -q get firewall.tszone)" ]; then
|
||||||
|
uci set firewall.tszone=zone
|
||||||
|
uci set firewall.tszone.input='ACCEPT'
|
||||||
|
uci set firewall.tszone.output='ACCEPT'
|
||||||
|
uci set firewall.tszone.forward='REJECT'
|
||||||
|
uci set firewall.tszone.masq='1'
|
||||||
|
uci set firewall.tszone.name='tailscale'
|
||||||
|
if [ "$ts0" = *$'\n'* ]; then
|
||||||
|
printf '%s\n' "$ts0" | IFS=$'\n' read -ra ts0_array
|
||||||
|
uci add_list firewall.tszone.network ${ts0_array[@]}
|
||||||
|
else
|
||||||
|
uci set firewall.tszone.network=$ts0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
uci -q delete firewall.tszone
|
||||||
|
fi
|
||||||
|
|
||||||
|
config_get access $cfg 'access'
|
||||||
|
if [ "${access//tsfwlan/}" != "$access" ]; then
|
||||||
|
uci set firewall.tsfwlan=forwarding
|
||||||
|
uci set firewall.tsfwlan.dest='lan'
|
||||||
|
uci set firewall.tsfwlan.src='tailscale'
|
||||||
|
else
|
||||||
|
uci -q delete firewall.tsfwlan
|
||||||
|
fi
|
||||||
|
if [ "${access//tsfwwan/}" != "$access" ]; then
|
||||||
|
uci set firewall.tsfwwan=forwarding
|
||||||
|
uci set firewall.tsfwwan.dest='wan'
|
||||||
|
uci set firewall.tsfwwan.src='tailscale'
|
||||||
|
else
|
||||||
|
uci -q delete firewall.tsfwwan
|
||||||
|
fi
|
||||||
|
if [ "${access//lanfwts/}" != "$access" ]; then
|
||||||
|
uci set firewall.lanfwts=forwarding
|
||||||
|
uci set firewall.lanfwts.dest='tailscale'
|
||||||
|
uci set firewall.lanfwts.src='lan'
|
||||||
|
else
|
||||||
|
uci -q delete firewall.lanfwts
|
||||||
|
fi
|
||||||
|
if [ "${access//wanfwts/}" != "$access" ]; then
|
||||||
|
uci set firewall.wanfwts=forwarding
|
||||||
|
uci set firewall.wanfwts.dest='tailscale'
|
||||||
|
uci set firewall.wanfwts.src='wan'
|
||||||
|
else
|
||||||
|
uci -q delete firewall.wanfwts
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -n "$(uci changes network)" ] && uci commit network && /etc/init.d/network reload
|
||||||
|
[ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload
|
||||||
|
rm /var/run/tailscale.wait.pid
|
||||||
|
) &
|
||||||
|
}
|
||||||
|
|
||||||
start_instance() {
|
start_instance() {
|
||||||
local cfg="$1"
|
local cfg="$1"
|
||||||
local port std_err std_out config_path
|
local port config_path fw_mode std_out std_err state_file
|
||||||
local ARGS=""
|
local ARGS=""
|
||||||
|
|
||||||
if ! section_enabled "$cfg"; then
|
if ! section_enabled "$cfg"; then
|
||||||
@@ -27,34 +134,23 @@ start_instance() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ -d /etc/tailscale ] || mkdir -p /etc/tailscale
|
config_get port $cfg 'port'
|
||||||
config_path=/etc/tailscale
|
config_get config_path $cfg 'config_path'
|
||||||
|
config_get fw_mode $cfg 'fw_mode'
|
||||||
|
config_get_bool std_out $cfg 'log_stdout'
|
||||||
|
config_get_bool std_err $cfg 'log_stderr'
|
||||||
|
|
||||||
config_get_bool std_out $cfg log_stdout 1
|
[ -d $config_path ] || mkdir -p $config_path
|
||||||
config_get_bool std_err $cfg log_stderr 1
|
[ -d $CONFIG_PATH ] || mkdir -p $CONFIG_PATH
|
||||||
config_get port $cfg port 41641
|
state_file=$config_path/tailscaled.state
|
||||||
config_get state_file $cfg state_file /etc/tailscale/tailscaled.state
|
|
||||||
config_get fw_mode $cfg fw_mode nftables
|
|
||||||
|
|
||||||
/usr/sbin/tailscaled --cleanup
|
/usr/sbin/tailscaled --cleanup
|
||||||
|
|
||||||
# Remove existing link or folder
|
[ -n "$port" ] && ARGS="$ARGS --port $port"
|
||||||
rm -rf $CONFIG_PATH
|
|
||||||
|
|
||||||
# Create link from CONFIG_PATH to config_path
|
|
||||||
if [ -n "$config_path" -a "$config_path" != $CONFIG_PATH ]; then
|
|
||||||
if [ ! -d "$config_path" ]; then
|
|
||||||
echo "Tailscale config_path does not exist: $config_path"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
ln -s $config_path $CONFIG_PATH
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ -n "$port" ] && ARGS="$ARGS --port $port"
|
|
||||||
[ -n "$state_file" ] && ARGS="$ARGS --state $state_file"
|
[ -n "$state_file" ] && ARGS="$ARGS --state $state_file"
|
||||||
|
|
||||||
procd_open_instance
|
procd_open_instance
|
||||||
procd_set_param command $PROG $ARGS
|
procd_set_param command $PROGD $ARGS
|
||||||
|
|
||||||
procd_set_param env TS_DEBUG_FIREWALL_MODE="$fw_mode"
|
procd_set_param env TS_DEBUG_FIREWALL_MODE="$fw_mode"
|
||||||
|
|
||||||
@@ -67,14 +163,30 @@ start_instance() {
|
|||||||
start_service() {
|
start_service() {
|
||||||
config_load 'tailscale'
|
config_load 'tailscale'
|
||||||
config_foreach start_instance 'tailscale'
|
config_foreach start_instance 'tailscale'
|
||||||
|
config_foreach custom_instance 'tailscale'
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_instance() {
|
stop_instance() {
|
||||||
local cfg="$1"
|
local cfg="$1"
|
||||||
/usr/sbin/tailscaled --cleanup
|
/usr/sbin/tailscaled --cleanup
|
||||||
|
|
||||||
|
# Remove network interfaces
|
||||||
|
ts0="$(ifconfig | grep 'tailscale' | awk '{print $1}')"
|
||||||
|
for i in ${ts0}
|
||||||
|
do
|
||||||
|
uci -q delete network.$i
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove firewall settings
|
||||||
|
uci -q delete firewall.tszone
|
||||||
|
uci -q delete firewall.tsfwlan
|
||||||
|
uci -q delete firewall.tsfwwan
|
||||||
|
uci -q delete firewall.lanfwts
|
||||||
|
uci -q delete firewall.wanfwts
|
||||||
|
[ -n "$(uci changes network)" ] && uci commit network && /etc/init.d/network reload
|
||||||
|
[ -n "$(uci changes firewall)" ] && uci commit firewall && /etc/init.d/firewall reload
|
||||||
|
|
||||||
# Remove existing link or folder
|
# Remove existing link or folder
|
||||||
rm -rf $CONFIG_PATH/*.log*
|
|
||||||
rm -rf $CONFIG_PATH
|
rm -rf $CONFIG_PATH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user