initramfs hook for tailscale
This is intended to be used with an ephemeral auth key with an ACL tag, and ACL rules that restrict the ephemeral node to inbound-only traffic. It does not share instance state with tailscale running in Linux. Reference: - https://tailscale.com/kb/1111/ephemeral-nodes/ - https://tailscale.com/kb/1068/acl-tags/#generate-an-auth-key-with-an-acl-tag - https://tailscale.com/kb/1068/acl-tags/#using-tags-in-acls-for-access-control
This commit is contained in:
3
conf-hooks.d/tailscale
Normal file
3
conf-hooks.d/tailscale
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Set the umask for the generated initramfs since it may contain a tailscale
|
||||||
|
# authkey
|
||||||
|
UMASK=0077
|
||||||
51
config/config
Normal file
51
config/config
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#
|
||||||
|
# Configuration options for the tailscale-initramfs boot scripts.
|
||||||
|
# You must run update-initramfs(8) to effect changes to this file (like
|
||||||
|
# for other files in the '/etc/tailscale/initramfs' directory).
|
||||||
|
|
||||||
|
#
|
||||||
|
# Authkey to be used to authenticate to tailscale. Passed to "tailscale up"
|
||||||
|
# --authkey, so can also be file:/path/to/secret (the file will be copied into
|
||||||
|
# the initramfs).
|
||||||
|
#
|
||||||
|
# Note that the config (and any key) is stored in the initramfs, which is
|
||||||
|
# often outside of a cryptroot.
|
||||||
|
# - https://tailscale.com/kb/1068/acl-tags/#generate-an-auth-key-with-an-acl-tag
|
||||||
|
# - https://tailscale.com/kb/1111/ephemeral-nodes/
|
||||||
|
#
|
||||||
|
TAILSCALE_AUTHKEY=
|
||||||
|
|
||||||
|
#
|
||||||
|
# Hostname to pass to "tailscale up".
|
||||||
|
# Default: ${HOSTNAME}-initramfs.
|
||||||
|
#
|
||||||
|
#TAILSCALE_HOSTNAME=
|
||||||
|
|
||||||
|
#
|
||||||
|
# Command-line options to pass to tailscale, in addition to
|
||||||
|
# --authkey"${TAILSCALE_AUTHKEY}"
|
||||||
|
# Default: none
|
||||||
|
#
|
||||||
|
#TAILSCALE_OPTIONS=
|
||||||
|
|
||||||
|
#
|
||||||
|
# Command-line options to pass to tailscaled
|
||||||
|
# Default: none
|
||||||
|
#
|
||||||
|
#TAILSCALED_OPTIONS=
|
||||||
|
|
||||||
|
#
|
||||||
|
# Set to any non-empty string to log out of tailscale before passing out of
|
||||||
|
# the initramfs. This is ineffective if some other package in the initramfs
|
||||||
|
# (dropbear-initramfs) brings down the external interfaces. See IFDOWN in
|
||||||
|
# dropbear-initramfs's config.
|
||||||
|
# Default: none
|
||||||
|
#
|
||||||
|
#TAILSCALE_LOGOUT=
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bring down interfaces matching this pattern before passing out of the
|
||||||
|
# initramfs. (Same behavior as dropbear-initramfs)
|
||||||
|
# Default: *
|
||||||
|
#
|
||||||
|
#IFDOWN=*
|
||||||
5
debian/changelog
vendored
Normal file
5
debian/changelog
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
tailscale-initramfs (0.1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Initial Release.
|
||||||
|
|
||||||
|
-- Paul Aurich <paul@darkrain42.org> Fri, 14 Jan 2022 21:03:16 -0800
|
||||||
20
debian/control
vendored
Normal file
20
debian/control
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Source: tailscale-initramfs
|
||||||
|
Section: net
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Paul Aurich <paul@darkrain42.org>
|
||||||
|
Build-Depends: debhelper-compat (= 13)
|
||||||
|
Standards-Version: 4.5.1
|
||||||
|
Homepage: https://github.com/darkrain42/tailscale-initramfs
|
||||||
|
Vcs-Browser: https://github.com/darkrain42/tailscale-initramfs
|
||||||
|
Vcs-Git: https://github.com/darkrain42/tailscale-initramfs.git
|
||||||
|
Rules-Requires-Root: no
|
||||||
|
|
||||||
|
Package: tailscale-initramfs
|
||||||
|
Architecture: all
|
||||||
|
Depends: initramfs-tools, tailscale, ${misc:Depends}
|
||||||
|
Recommends: ca-certificates
|
||||||
|
Suggests: dropbear-initramfs
|
||||||
|
Description: tailscale VPN - third-party initramfs integration
|
||||||
|
tailscale is a WireGuard VPN. This package provides initramfs integration,
|
||||||
|
intended to allow connectivity to/from a tailnet, e.g. to to allow remote
|
||||||
|
unlocking of a cryptroot.
|
||||||
24
debian/copyright
vendored
Normal file
24
debian/copyright
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: tailscale-initramfs
|
||||||
|
Upstream-Contact: Paul Aurich <paul@darkrain42.org>
|
||||||
|
Source: https://github.com/darkrain42/tailscale-initramfs
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: 2022 Paul Aurich <paul@darkrain42.org>
|
||||||
|
License: GPL-2+
|
||||||
|
|
||||||
|
# Started from dropbear-initramfs scripts.
|
||||||
|
Files: scripts/*
|
||||||
|
Copyright: 2009 <debian@x.ray.net>
|
||||||
|
2015 Guilhem Moulin <guilhem@debian.org>
|
||||||
|
2022 Paul Aurich <paul@darkrain42.org>
|
||||||
|
License: GPL-2+
|
||||||
|
|
||||||
|
License: GPL-2+
|
||||||
|
This package is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
.
|
||||||
|
The full text of version 2 of the GPL is distributed in
|
||||||
|
/usr/share/common-licenses/GPL-2 on Debian systems.
|
||||||
5
debian/install
vendored
Normal file
5
debian/install
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
conf-hooks.d/tailscale usr/share/initramfs-tools/conf-hooks.d
|
||||||
|
config/config etc/tailscale/initramfs
|
||||||
|
hooks/tailscale usr/share/initramfs-tools/hooks
|
||||||
|
scripts/init-bottom/tailscale usr/share/initramfs-tools/scripts/init-bottom
|
||||||
|
scripts/init-premount/tailscale usr/share/initramfs-tools/scripts/init-premount
|
||||||
14
debian/rules
vendored
Executable file
14
debian/rules
vendored
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
|
||||||
|
#export DH_VERBOSE = 1
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@
|
||||||
|
|
||||||
|
execute_after_dh_fixperms:
|
||||||
|
chmod 600 debian/tailscale-initramfs/etc/tailscale/initramfs/config
|
||||||
|
|
||||||
|
override_dh_builddeb:
|
||||||
|
# Workaround for building on Ubuntu and installing on Debian (Ubuntu uses
|
||||||
|
# zstd). https://bugs.debian.org/892664
|
||||||
|
dh_builddeb -- -Zxz
|
||||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
3.0 (native)
|
||||||
1
debian/tailscale-initramfs.lintian-overrides
vendored
Normal file
1
debian/tailscale-initramfs.lintian-overrides
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
tailscale-initramfs: non-standard-file-perm etc/tailscale/initramfs/config 0600 != 0644
|
||||||
65
hooks/tailscale
Executable file
65
hooks/tailscale
Executable file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
PREREQ=""
|
||||||
|
|
||||||
|
prereqs()
|
||||||
|
{
|
||||||
|
echo "$PREREQ"
|
||||||
|
}
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
prereqs)
|
||||||
|
prereqs
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
. /usr/share/initramfs-tools/hook-functions
|
||||||
|
|
||||||
|
tailscale_warn() {
|
||||||
|
echo >&2 "tailscale: WARNING: $*"
|
||||||
|
}
|
||||||
|
tailscale_error() {
|
||||||
|
echo >&2 "tailscale: ERROR: $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
RV=0
|
||||||
|
|
||||||
|
copy_exec /usr/bin/tailscale bin
|
||||||
|
copy_exec /usr/sbin/tailscaled sbin
|
||||||
|
|
||||||
|
copy_exec /bin/ip bin
|
||||||
|
copy_exec /usr/sbin/iptables sbin
|
||||||
|
copy_exec /usr/sbin/ip6tables sbin
|
||||||
|
|
||||||
|
copy_modules_dir kernel/net/ipv4/netfilter
|
||||||
|
copy_modules_dir kernel/net/ipv6/netfilter
|
||||||
|
copy_modules_dir kernel/net/netfilter
|
||||||
|
manual_add_modules tun
|
||||||
|
|
||||||
|
copy_file config /etc/ssl/certs/ca-certificates.crt
|
||||||
|
copy_file config /etc/hostname /etc/tailscale/initramfs/hostname
|
||||||
|
|
||||||
|
if [ -e /etc/tailscale/initramfs/config ]; then
|
||||||
|
cp -pt "$DESTDIR/etc/tailscale/initramfs" /etc/tailscale/initramfs/config
|
||||||
|
. /etc/tailscale/initramfs/config
|
||||||
|
|
||||||
|
case "${TAILSCALE_AUTHKEY-}" in
|
||||||
|
file:*)
|
||||||
|
AUTHKEY_FILE=${TAILSCALE_AUTHKEY#file:}
|
||||||
|
if [ -s "$AUTHKEY_FILE" ]; then
|
||||||
|
copy_file keyfile "$AUTHKEY_FILE"
|
||||||
|
else
|
||||||
|
tailscale_error "Auth key file '$AUTHKEY_FILE' does not exist or is empty."
|
||||||
|
RV=1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"")
|
||||||
|
tailscale_warn "\$TAILSCALE_AUTHKEY not set; logging into tailscale won't work!"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
tailscale_warn "Missing tailscale initramfs config; logging into tailscale won't work!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $RV
|
||||||
77
scripts/init-bottom/tailscale
Executable file
77
scripts/init-bottom/tailscale
Executable file
@@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#set -e
|
||||||
|
|
||||||
|
PREREQ=""
|
||||||
|
prereqs()
|
||||||
|
{
|
||||||
|
echo "$PREREQ"
|
||||||
|
}
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
prereqs)
|
||||||
|
prereqs
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
. /scripts/functions
|
||||||
|
|
||||||
|
EXE="$(readlink -f /sbin/tailscaled)" && [ -f "$EXE" ] || exit 1
|
||||||
|
PIDFILE="/run/tailscale.pid"
|
||||||
|
TAILSCALE_SHUTDOWN_TIMEOUT=60
|
||||||
|
TAILSCALE_LOGOUT=
|
||||||
|
IFDOWN="*"
|
||||||
|
|
||||||
|
if [ -e /etc/tailscale/initramfs/config ]; then
|
||||||
|
. /etc/tailscale/initramfs/config
|
||||||
|
fi
|
||||||
|
|
||||||
|
wait_for_tailscaled()
|
||||||
|
{
|
||||||
|
# shellcheck disable=SC2039
|
||||||
|
# SC2039: In POSIX sh, 'local' is undefined.
|
||||||
|
local pid exe timer="$TAILSCALE_SHUTDOWN_TIMEOUT"
|
||||||
|
pid="$(cat "$PIDFILE" 2>/dev/null)" || return 1
|
||||||
|
|
||||||
|
while [ $timer -gt 0 ] && exe="$(readlink -f "/proc/$pid/exe" 2>/dev/null)"; do
|
||||||
|
if [ "$exe" = "$EXE" ]; then
|
||||||
|
echo "$pid"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
timer=$(( timer - 1 ))
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if PID="$(wait_for_tailscaled)"; then
|
||||||
|
if [ -n "$TAILSCALE_LOGOUT" ]; then
|
||||||
|
log_begin_msg "Logging out of tailscale"
|
||||||
|
/bin/tailscale --socket=/run/tailscale/tailscaled.sock logout 2>>/run/initramfs/tailscale.log || true
|
||||||
|
log_end_msg
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_begin_msg "Stopping tailscale"
|
||||||
|
kill -TERM "$PID"
|
||||||
|
wait "$PID" || true
|
||||||
|
/sbin/tailscaled -cleanup 2>>/run/initramfs/tailscale.log
|
||||||
|
log_end_msg
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$PIDFILE"
|
||||||
|
|
||||||
|
if [ "$BOOT" != nfs ] && [ "$IFDOWN" != none ]; then
|
||||||
|
for IFACE in /sys/class/net/$IFDOWN; do
|
||||||
|
[ -e "$IFACE" ] || continue
|
||||||
|
IFACE="${IFACE#/sys/class/net/}"
|
||||||
|
log_begin_msg "Bringing down $IFACE"
|
||||||
|
ip link set dev "$IFACE" down
|
||||||
|
ip address flush dev "$IFACE"
|
||||||
|
ip route flush dev "$IFACE"
|
||||||
|
log_end_msg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
64
scripts/init-premount/tailscale
Executable file
64
scripts/init-premount/tailscale
Executable file
@@ -0,0 +1,64 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#set -e
|
||||||
|
|
||||||
|
PREREQ="udev"
|
||||||
|
prereqs()
|
||||||
|
{
|
||||||
|
echo "$PREREQ"
|
||||||
|
}
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
prereqs)
|
||||||
|
prereqs
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ -x /bin/tailscale ] || exit 0
|
||||||
|
|
||||||
|
. /scripts/functions
|
||||||
|
|
||||||
|
if [ -e /etc/tailscale/initramfs/config ]; then
|
||||||
|
. /etc/tailscale/initramfs/config
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${TAILSCALE_HOSTNAME-}" ]; then
|
||||||
|
if [ -f /etc/tailscale/initramfs/hostname ]; then
|
||||||
|
HOSTNAME=$(cat /etc/tailscale/initramfs/hostname)
|
||||||
|
else
|
||||||
|
HOSTNAME=$(hostname -s)
|
||||||
|
fi
|
||||||
|
|
||||||
|
TAILSCALE_HOSTNAME=${HOSTNAME}-initramfs
|
||||||
|
fi
|
||||||
|
|
||||||
|
# shellcheck disable=SC2039,SC2086
|
||||||
|
run_tailscale()
|
||||||
|
{
|
||||||
|
log_begin_msg "Starting tailscale"
|
||||||
|
|
||||||
|
local options="--state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock"
|
||||||
|
|
||||||
|
# FIXME: This races with dropbear-initramfs bringing up the network
|
||||||
|
# asynchronously
|
||||||
|
[ "$BOOT" = nfs ] || configure_networking
|
||||||
|
|
||||||
|
# A little race-y to start the client before the daemon, but the client
|
||||||
|
# will attempt to connect to the socket for a while.
|
||||||
|
# https://github.com/tailscale/tailscale/blob/8cf1af8a0703c36256fc58e98ddb63b8907848f1/safesocket/safesocket.go#L119-L122
|
||||||
|
/bin/tailscale --socket=/run/tailscale/tailscaled.sock up --authkey="${TAILSCALE_AUTHKEY}" --hostname="${TAILSCALE_HOSTNAME}" $TAILSCALE_OPTIONS &
|
||||||
|
|
||||||
|
if [ "${debug:-}" != y ]; then
|
||||||
|
exec 2>/run/initramfs/tailscale.log
|
||||||
|
fi
|
||||||
|
exec /sbin/tailscaled $options $TAILSCALED_OPTIONS
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "$BOOT" = nfs ] && configure_networking
|
||||||
|
|
||||||
|
modprobe tun
|
||||||
|
run_tailscale &
|
||||||
|
echo $! > /run/tailscale.pid
|
||||||
|
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user