Add vpn-data-mount: SMB mount from a NetBird-connected home box

Offered right after NetBird setup during required/base setup, matching
the requested flow (base packages -> NetBird -> data mount). Repeatable
by design rather than a one-shot step, since different services can have
data on different home boxes — asks for a home box IP every time and can
be run again for additional boxes/shares.

Flow: test for existing passwordless SSH first (covers "both boxes already
share a key via GitHub import, or any other means" for free — if it
already works, nothing else runs). If not, generate an SSH keypair and
offer ssh-copy-id or a manual/GitHub-import fallback (ssh-import-id, the
same mechanism base.sh's own SSH setup already uses) — needed because a
home box that took base.sh's "disable password login" option won't accept
ssh-copy-id at all. Once passwordless SSH works, use it to remotely
install and configure Samba on the home box for a chosen path, then mount
it locally over CIFS with a tagged /etc/fstab entry.

SMB over NFS/SSHFS per this session's direction: not a "huge" speed gap
for normal use, and SSHFS's own encryption is redundant overhead once the
VPN tunnel already encrypts everything. Guest-accessible (no separate
Samba credentials) since the VPN is the real access control — only
NetBird-connected peers can reach the home box's NetBird IP at all.

Also:
- cifs-utils added to base.sh's always-installed packages, same reasoning
  as Docker/Compose being unconditional there instead of installed lazily
  on first mount.
- is_installed()/install_count() in setup.sh gained a vpn-data-mount case
  (state lives in tagged /etc/fstab entries, not $DOCKER_DIR, since this
  isn't a Docker service) — mirrors wordpress's "count real instances"
  handling rather than a flat 0/1.
- Every SSH call in the new service explicitly runs as $ACTUAL_USER
  (sudo -u), not root — the script itself runs as root throughout, but the
  SSH key lives in $ACTUAL_HOME/.ssh, so a bare `ssh` call would silently
  use root's own ~/.ssh instead and never find it. Caught by review before
  this shipped, not after.
- UNATTENDED mode skips outright with a message instead of spinning
  forever on prompt_text's always-blank default under --unattended, since
  none of this flow's prompts (home box IP, remote path, ...) have a
  sane non-interactive default.
This commit is contained in:
Claude
2026-08-10 17:56:50 +00:00
parent 63c227f101
commit 0e42de1cda
4 changed files with 373 additions and 5 deletions
+28 -2
View File
@@ -18,6 +18,7 @@ install_base() {
echo "[DRY-RUN] Would offer SSH key import from GitHub/Launchpad"
echo "[DRY-RUN] Would offer to disable SSH password auth"
echo "[DRY-RUN] Would offer NetBird install with --allow-server-ssh"
echo "[DRY-RUN] Would offer to mount SMB data from a NetBird-connected home box (if NetBird is present)"
echo "[DRY-RUN] Would offer Caddy reverse proxy install (full repo only)"
echo "[DRY-RUN] Would offer CrowdSec intrusion prevention install (full repo only)"
echo "[DRY-RUN] Would offer to add SSH Host aliases to ~/.ssh/config"
@@ -26,10 +27,14 @@ install_base() {
run_cmd apt-get update -y
# Core utilities present on every install.
# Core utilities present on every install. cifs-utils here (not lazily
# installed on first use, the way tools/mount-network-drive.sh and
# vpn-data-mount.sh's own local-mount step would otherwise do it) so SMB
# mounts work immediately whenever they're set up later, same reasoning
# as Docker/Compose being unconditional here instead of on-demand.
run_cmd apt-get install -y \
net-tools ncdu git curl wget htop btop tree zip unzip \
ca-certificates gnupg jq rsync ssh-import-id \
ca-certificates gnupg jq rsync ssh-import-id cifs-utils \
|| log_warning "Some essential packages failed to install"
# glow — terminal markdown reader (charmbracelet). Not in Ubuntu repos,
@@ -51,6 +56,14 @@ install_base() {
# ── NetBird ──────────────────────────────────────────────────────────────
_base_setup_netbird
# ── VPN-connected data mount ────────────────────────────────────────────
# Only offered if NetBird is actually present (installed just now, or
# already there from a prior run) — chained here rather than folded into
# _base_setup_netbird itself since it's independently repeatable (see
# services/vpn-data-mount.sh's own header) and users may want to run it
# again later for another home box without re-touching NetBird at all.
_base_setup_vpn_mount
# ── Caddy + CrowdSec ──────────────────────────────────────────────────────
# Not this script's own install — just an early, recommended nudge toward
# two services most other things in this repo end up wanting (a reverse
@@ -214,6 +227,19 @@ _base_setup_netbird() {
fi
}
_base_setup_vpn_mount() {
command -v netbird >/dev/null 2>&1 || return 0
# Only available when the full repo is sourced (setup.sh loads every
# services/*.sh up front) — a standalone copy of base.sh doesn't have
# install_vpn-data-mount, so skip silently rather than error.
declare -F install_vpn-data-mount >/dev/null 2>&1 || return 0
local SETUP_MOUNT=""
prompt_yn "Mount data from a NetBird-connected home box now? (y/n):" "n" SETUP_MOUNT
[[ "$SETUP_MOUNT" =~ ^[Yy]$ ]] || return 0
install_vpn-data-mount
}
_base_setup_caddy() {
if [[ -d "$DOCKER_DIR/caddy" ]]; then
log_info "Caddy already installed."