#!/bin/sh # get.ajo.me/join — bring a fresh Linux machine under master-control management. # # curl -fsSL https://get.ajo.me/join | sudo sh # # 1. Installs + starts OpenSSH server # 2. Installs master-control's SSH public key for root # 3. Installs Tailscale and starts a login against ts.tiko.cloud (Tiko Connect) # 4. Waits for approval — tell Claude "it's waiting"; Claude approves it via /ts-add # # No secrets in here: the node can't join until it's approved by hand. # Hardening (firewall, password auth, netfilter mode, updates) is done # afterwards by Claude over SSH. Safe to re-run. # Source: master-control:~/maintenance-logs/servers/flake/scripts/get.ajo.me/join set -eu LOGIN_SERVER="https://ts.tiko.cloud" MC_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOv6+uKIN/jm8e0zw+NwSi3My/IaMQ88Wsjzo3cYK47A tb@master-control" say() { printf '\n\033[1;36m==> %s\033[0m\n' "$*"; } die() { printf '\n\033[1;31mERROR: %s\033[0m\n' "$*" >&2; exit 1; } [ "$(uname -s)" = "Linux" ] || die "Linux only." [ "$(id -u)" -eq 0 ] || die "Run as root: curl -fsSL https://get.ajo.me/join | sudo sh" pkg_install() { if command -v apt-get >/dev/null 2>&1; then DEBIAN_FRONTEND=noninteractive apt-get update -qq DEBIAN_FRONTEND=noninteractive apt-get install -y -qq "$@" elif command -v dnf >/dev/null 2>&1; then dnf install -y -q "$@" elif command -v yum >/dev/null 2>&1; then yum install -y -q "$@" elif command -v zypper >/dev/null 2>&1; then zypper -n -q install "$@" elif command -v pacman >/dev/null 2>&1; then pacman -Sy --noconfirm --needed "$@" elif command -v apk >/dev/null 2>&1; then apk add -q "$@" else die "No supported package manager found (apt/dnf/yum/zypper/pacman/apk)." fi } # --- 1. OpenSSH server ------------------------------------------------------- say "OpenSSH server" if ! command -v sshd >/dev/null 2>&1 && [ ! -x /usr/sbin/sshd ]; then if command -v apt-get >/dev/null 2>&1 || command -v zypper >/dev/null 2>&1; then pkg_install openssh-server elif command -v pacman >/dev/null 2>&1 || command -v apk >/dev/null 2>&1; then pkg_install openssh else pkg_install openssh-server fi fi command -v curl >/dev/null 2>&1 || pkg_install curl if command -v systemctl >/dev/null 2>&1; then for unit in ssh sshd; do if systemctl list-unit-files "$unit.service" >/dev/null 2>&1 \ && systemctl list-unit-files "$unit.service" | grep -q "^$unit.service"; then systemctl enable --now "$unit.service" >/dev/null 2>&1 || true # Ubuntu 24.04+ uses socket activation; make sure the socket is up too systemctl enable --now "$unit.socket" >/dev/null 2>&1 || true break fi done elif command -v rc-service >/dev/null 2>&1; then rc-update add sshd default >/dev/null 2>&1 || true rc-service sshd start >/dev/null 2>&1 || true fi # Root must be allowed to log in with a key (prohibit-password = keys only) SSHD=$(command -v sshd || echo /usr/sbin/sshd) if "$SSHD" -T 2>/dev/null | grep -qi '^permitrootlogin no$'; then if [ -d /etc/ssh/sshd_config.d ] && grep -qiE '^\s*Include\s+/etc/ssh/sshd_config.d' /etc/ssh/sshd_config; then echo "PermitRootLogin prohibit-password" > /etc/ssh/sshd_config.d/00-master-control.conf else sed -i 's/^\s*PermitRootLogin.*/PermitRootLogin prohibit-password/I' /etc/ssh/sshd_config fi (systemctl reload ssh 2>/dev/null || systemctl reload sshd 2>/dev/null || rc-service sshd reload 2>/dev/null) || true fi # --- 2. master-control key --------------------------------------------------- say "Installing master-control SSH key for root" mkdir -p /root/.ssh chmod 700 /root/.ssh touch /root/.ssh/authorized_keys grep -qF "$MC_KEY" /root/.ssh/authorized_keys || echo "$MC_KEY" >> /root/.ssh/authorized_keys chmod 600 /root/.ssh/authorized_keys chown -R root:root /root/.ssh command -v restorecon >/dev/null 2>&1 && restorecon -R /root/.ssh || true # --- 3. Tailscale ------------------------------------------------------------ say "Tailscale" if ! command -v tailscale >/dev/null 2>&1; then curl -fsSL https://tailscale.com/install.sh | sh fi if command -v systemctl >/dev/null 2>&1; then systemctl enable --now tailscaled >/dev/null 2>&1 || true fi if tailscale status >/dev/null 2>&1; then say "Already on a tailnet: $(tailscale ip -4 2>/dev/null | head -1)" tailscale status --self --peers=false 2>/dev/null || true exit 0 fi # --- 4. Log in and wait for approval ----------------------------------------- cat </dev/null | head -1) cat <