Skip to content

Instantly share code, notes, and snippets.

@Underknowledge
Created May 2, 2026 13:24
Show Gist options
  • Select an option

  • Save Underknowledge/002cb11cc693f1b59b1cadae000976b6 to your computer and use it in GitHub Desktop.

Select an option

Save Underknowledge/002cb11cc693f1b59b1cadae000976b6 to your computer and use it in GitHub Desktop.
Tailscale installer for X1Plus (Bambu Lab X1 Carbon)
#!/bin/sh
# Tailscale installer for a X1 Carbon running X1Plus
# re-run to update and restart manually
set -e
BIN=/usr/sbin
STATE=/mnt/sdcard/tailscale
CACHE_DIR=/mnt/sdcard/tailscale_cache
CACHE=$CACHE_DIR/tailscale_latest_arm.tgz
URL=https://pkgs.tailscale.com/stable/tailscale_latest_arm.tgz
err() { echo "$*" >&2; exit 1; }
[ "$(id -u)" = 0 ] || err "must be root"
[ -d /mnt/sdcard ] || err "no /mnt/sdcard"
command -v start-stop-daemon >/dev/null || err "no start-stop-daemon applet - youre on the right device?"
mkdir -p "$STATE" "$CACHE_DIR"
# Download unless cache is younger than 24h
if [ ! -f "$CACHE" ] || [ $(( $(date +%s) - $(stat -c %Y "$CACHE") )) -gt 86400 ]; then
echo "downloading $URL"
wget -q -O "$CACHE.tmp" "$URL" || err "download failed"
gunzip -t "$CACHE.tmp" 2>/dev/null || err "downloaded file is not gzip"
mv "$CACHE.tmp" "$CACHE"
fi
TMP=$(mktemp -d /tmp/tailscale.XXXXXX)
trap 'rm -rf "$TMP"' EXIT INT TERM
gunzip -c "$CACHE" | ( cd "$TMP" && tar xf - ) || err "extract failed"
SRC=
for d in "$TMP"/tailscale_*_arm; do
[ -d "$d" ] && SRC=$d && break
done
[ -n "$SRC" ] || err "no extracted dir found"
install -m 755 "$SRC/tailscale" "$BIN/tailscale"
install -m 755 "$SRC/tailscaled" "$BIN/tailscaled"
"$BIN/tailscale" version | head -n1
cat > /etc/init.d/S99tailscale <<'EOF'
#!/bin/sh
# tailscaled service. userspace-networking, state on sdcard.
TAILSCALE=/usr/sbin/tailscale
TAILSCALED=/usr/sbin/tailscaled
STATE_DIR=/mnt/sdcard/tailscale
STATE=$STATE_DIR/tailscaled.state
LOG=$STATE_DIR/tailscaled.log
SOCKET=/var/run/tailscale/tailscaled.sock
PID=/var/run/tailscaled.pid
start() {
printf "Starting tailscaled: "
mkdir -p "$STATE_DIR" "$(dirname "$SOCKET")"
[ -f "$LOG" ] && [ "$(stat -c %s "$LOG" 2>/dev/null || echo 0)" -gt 1048576 ] \
&& mv "$LOG" "$LOG.old"
start-stop-daemon -S -m -b -p "$PID" \
--exec /bin/sh -- -c \
"exec $TAILSCALED --tun=userspace-networking --state=$STATE --socket=$SOCKET --port=0 >>$LOG 2>&1"
[ $? = 0 ] && echo OK || echo FAIL
}
stop() {
printf "Stopping tailscaled: "
start-stop-daemon -K -q -p "$PID"
rm -f "$PID"
echo OK
}
status() {
if [ -f "$PID" ] && kill -0 "$(cat "$PID" 2>/dev/null)" 2>/dev/null; then
echo "tailscaled: running (PID $(cat "$PID"))"
out=$(timeout 2 "$TAILSCALE" status 2>/dev/null)
if [ -n "$out" ]; then
echo "$out" | head -n 5
else
echo "(not authenticated; run: tailscale up)"
fi
else
echo "tailscaled: not running"
return 1
fi
}
logs() {
[ -f "$LOG" ] || { echo "no log at $LOG"; exit 1; }
case "$1" in
-f|--follow|follow) tail -n 50 -f "$LOG" ;;
*) tail -n 50 "$LOG" ;;
esac
}
case "$1" in
start) start ;;
stop) stop ;;
restart|reload) stop; sleep 1; start ;;
status) status ;;
logs) shift; logs "$@" ;;
*) echo "usage: $0 {start|stop|restart|status|logs [-f]}"; exit 1 ;;
esac
EOF
chmod 755 /etc/init.d/S99tailscale
cat <<EOF
Installed. Next:
/etc/init.d/S99tailscale start
tailscale up --hostname=x1c
-> open the URL it prints, sign in at tailscale.com, approve
Service: /etc/init.d/S99tailscale {start|stop|restart|status|logs [-f]}
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment