Compare commits
11 Commits
85df138d10
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 62e1629db6 | |||
| eba72013b9 | |||
| 08328c77e7 | |||
| c122007a46 | |||
| de05ffdb7d | |||
| b7b3a9beaa | |||
| 14079d889b | |||
| 5f5d2fa760 | |||
| d7014588f6 | |||
| b16826fa8e | |||
| 56dff3f22b |
26
README.md
26
README.md
@@ -28,12 +28,10 @@ This system implements a hub-and-spoke model where:
|
||||
tinyboard/
|
||||
├── hubspoke-helper.sh # Main management script
|
||||
├── hub/
|
||||
│ ├── rclone-mount@.service # Systemd user service template
|
||||
│ └── rclone.conf # Rclone SFTP configuration
|
||||
├── spoke/
|
||||
│ ├── compose.yaml # Docker Compose for autossh tunnel
|
||||
│ ├── Dockerfile # autossh container image
|
||||
│ ├── autossh-tunnel.service # Legacy systemd service (deprecated)
|
||||
│ ├── autohostname.sh # Hostname assignment by MAC address
|
||||
│ ├── aptprimary.sh # Initial package installation
|
||||
│ ├── clean_sensitive.sh # Clean WiFi/password from configs
|
||||
@@ -54,6 +52,7 @@ tinyboard/
|
||||
- `~/.config/rclone/rclone.conf` on hub must be manually created
|
||||
- Use `hub/rclone.conf` as a template
|
||||
- Update host, port, and key_file paths as needed
|
||||
- Manually create rclone mount and permission it (`/mnt/hub` for example)
|
||||
|
||||
### Systemd Service Files
|
||||
- `~/.config/systemd/user/rclone-mount@.service` must be manually copied from `hub/rclone-mount@.service`
|
||||
@@ -62,9 +61,9 @@ tinyboard/
|
||||
|
||||
### Initial Setup
|
||||
1. Write Armbian minimal image to SD card
|
||||
2. Copy `spoke/armb-not_logged_in_yet` to SD card root (contains WiFi credentials)
|
||||
2. Copy `spoke/armb-not_logged_in_yet` to SD card root `/root/.not_logged_in_yet` (contains WiFi credentials)
|
||||
3. Boot device, SSH in as root with password "1234"
|
||||
4. After first login, `armb-not_logged_in_yet` will be processed for root and armbian user credentials
|
||||
4. After first login and setup tasks, `.not_logged_in_yet` will be processed for root and armbian user credentials
|
||||
5. Clone this repository: `git clone <repo-url>`
|
||||
6. Run `spoke/aptprimary.sh` to install required packages
|
||||
7. Run `spoke/autohostname.sh` to assign hostname based on MAC address
|
||||
@@ -99,12 +98,6 @@ tinyboard/
|
||||
3. Copy and customize `hub/rclone.conf` to `~/.config/rclone/rclone.conf`
|
||||
4. Update key_file path to point to your SSH private key
|
||||
|
||||
### Systemd Service Setup
|
||||
1. Create user systemd directory: `mkdir -p ~/.config/systemd/user`
|
||||
2. Copy `hub/rclone-mount@.service` to `~/.config/systemd/user/`
|
||||
3. Enable lingering for user services: `sudo loginctl enable-linger $USER`
|
||||
4. Reload systemd: `systemctl --user daemon-reload`
|
||||
|
||||
### FUSE Configuration
|
||||
```bash
|
||||
# Allow other users to access mounts (if needed)
|
||||
@@ -118,6 +111,10 @@ sudo usermod -aG fuse $USER
|
||||
## Usage
|
||||
|
||||
### Managing Spoke Tunnels
|
||||
- Docker on spoke should handle autostart of spoke tunnel
|
||||
- Syncthing can be combined in this image
|
||||
- Rename syncthing image and host names per-device in the compose file.
|
||||
|
||||
```bash
|
||||
# Build autossh container
|
||||
./hubspoke-helper.sh spoke build
|
||||
@@ -136,6 +133,13 @@ sudo usermod -aG fuse $USER
|
||||
```
|
||||
|
||||
### Managing Hub Mounts
|
||||
|
||||
#### Crontab entry:
|
||||
```
|
||||
@reboot /home/armbian/tinyboard/hubspoke-helper.sh hub start-background
|
||||
```
|
||||
|
||||
#### Deprecated: systemd
|
||||
```bash
|
||||
# Install systemd service (after manual file placement)
|
||||
./hubspoke-helper.sh hub install
|
||||
@@ -158,7 +162,7 @@ Environment variables can override defaults:
|
||||
- `TUNNEL_DIR`: Directory containing spoke Docker files (default: `~/tinyboard/spoke`)
|
||||
- `COMPOSE_FILE`: Docker compose file path (default: `$TUNNEL_DIR/compose.yaml`)
|
||||
- `RCLONE_REMOTE`: Rclone remote name (default: `brie-remote`)
|
||||
- `MOUNT_POINT`: Mount point on hub (default: `~/mnt/brie`)
|
||||
- `MOUNT_POINT`: Mount point on hub (default: `~/mnt/hub`)
|
||||
|
||||
## Security Notes
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#~/.config/systemd/user/rclone-mount@.service
|
||||
|
||||
[Unit]
|
||||
Description=Rclone mount of %i
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/usr/bin/mkdir -p %h/mnt/%i
|
||||
ExecStart=/usr/bin/rclone mount %i: %h/mnt/%i \
|
||||
--config=%h/.config/rclone/rclone.conf \
|
||||
--vfs-cache-mode writes \
|
||||
--vfs-cache-max-size 256M \
|
||||
--allow-other \
|
||||
--log-level INFO \
|
||||
--log-file %h/.local/share/rclone-%i.log
|
||||
ExecStop=/bin/fusermount -u %h/mnt/%i
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
StartLimitInterval=60
|
||||
StartLimitBurst=3
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -7,3 +7,12 @@ shell_type = unix
|
||||
md5sum_command = md5sum
|
||||
sha1sum_command = sha1sum
|
||||
|
||||
#[new-remote]
|
||||
#type = sftp
|
||||
#host = localhost
|
||||
#port = 11112
|
||||
#key_file = /home/armbian/.ssh/a new priv key for tunnel back to new spoke
|
||||
#shell_type = unix
|
||||
#md5sum_command = md5sum
|
||||
#sha1sum_command = sha1sum
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# hubspoke-helper.sh - Manage hub/spoke rclone mounts
|
||||
# Assumes spoke Docker files exist in ~/autossh-tunnel/
|
||||
# Assumes hub rclone service template is manually placed (or not needed)
|
||||
# Simplified hub mount uses direct rclone commands (no systemd services)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -12,7 +12,7 @@ set -euo pipefail
|
||||
TUNNEL_DIR="${TUNNEL_DIR:-$HOME/tinyboard/spoke}"
|
||||
COMPOSE_FILE="${COMPOSE_FILE:-$TUNNEL_DIR/compose.yaml}"
|
||||
RCLONE_REMOTE="${RCLONE_REMOTE:-brie-remote}"
|
||||
MOUNT_POINT="${MOUNT_POINT:-$HOME/mnt/$RCLONE_REMOTE}"
|
||||
MOUNT_POINT="${MOUNT_POINT:-/mnt/hub/$RCLONE_REMOTE}"
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Usage
|
||||
@@ -30,11 +30,12 @@ SPOKE ACTIONS (docker-based, no systemd):
|
||||
logs Show container logs
|
||||
show-cmd Show manual autossh command (non-docker)
|
||||
|
||||
HUB ACTIONS (systemd user service for rclone mount):
|
||||
install Install the rclone user service (needs service file)
|
||||
start Start the rclone mount service
|
||||
stop Stop the rclone mount service
|
||||
status Show service status
|
||||
HUB ACTIONS (simplified rclone mount - no systemd):
|
||||
install Show simplified setup instructions
|
||||
start Start rclone mount in background (uses nohup)
|
||||
start-background Start rclone mount in background (for crontab)
|
||||
stop Stop rclone mount
|
||||
status Check mount status
|
||||
mount Manual foreground mount (testing)
|
||||
unmount Unmount manually
|
||||
|
||||
@@ -96,55 +97,72 @@ EOF
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Hub actions (rclone user service)
|
||||
# Hub actions (simplified - no systemd templates)
|
||||
# ------------------------------------------------------------
|
||||
hub_install() {
|
||||
local SERVICE_DIR="$HOME/.config/systemd/user"
|
||||
local SERVICE_FILE="$SERVICE_DIR/rclone-mount@.service"
|
||||
local TEMPLATE_FILE="$(dirname "$0")/hub/rclone-mount@.service"
|
||||
|
||||
echo "Installing rclone mount systemd user service..."
|
||||
|
||||
# Create service directory if it doesn't exist
|
||||
mkdir -p "$SERVICE_DIR"
|
||||
|
||||
# Check if template exists
|
||||
if [ ! -f "$TEMPLATE_FILE" ]; then
|
||||
die "Service template not found at $TEMPLATE_FILE"
|
||||
fi
|
||||
|
||||
# Copy service template
|
||||
cp "$TEMPLATE_FILE" "$SERVICE_FILE"
|
||||
echo "Copied service template to $SERVICE_FILE"
|
||||
|
||||
# Check if user linger is enabled
|
||||
if ! systemctl --user is-enabled --quiet user@$(id -u).service 2>/dev/null; then
|
||||
echo "WARNING: User linger may not be enabled. Run: sudo loginctl enable-linger $USER"
|
||||
echo "You may need to reboot for user services to start automatically."
|
||||
fi
|
||||
|
||||
# Reload systemd
|
||||
systemctl --user daemon-reload
|
||||
echo "Systemd user daemon reloaded."
|
||||
|
||||
echo "Simplified hub setup:"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Ensure /etc/fuse.conf has 'user_allow_other' uncommented"
|
||||
echo "2. Ensure you're in the 'fuse' group: sudo usermod -aG fuse $USER"
|
||||
echo "3. Start the service: $0 hub start"
|
||||
echo "4. Enable auto-start: systemctl --user enable rclone-mount@${RCLONE_REMOTE}.service"
|
||||
echo "1. Ensure /etc/fuse.conf has 'user_allow_other' uncommented:"
|
||||
echo " sudo sed -i 's/^#user_allow_other/user_allow_other/' /etc/fuse.conf"
|
||||
echo ""
|
||||
echo "2. Ensure you're in the 'fuse' group:"
|
||||
echo " sudo usermod -aG fuse $USER"
|
||||
echo " (You may need to log out and back in for this to take effect)"
|
||||
echo ""
|
||||
echo "3. Create mount point directory:"
|
||||
echo " mkdir -p \"$MOUNT_POINT\""
|
||||
echo ""
|
||||
echo "4. Test manual mount:"
|
||||
echo " $0 hub mount"
|
||||
echo ""
|
||||
echo "5. For auto-start, consider adding to crontab with @reboot:"
|
||||
echo " crontab -e"
|
||||
echo " Add: @reboot $0 hub start-background"
|
||||
echo ""
|
||||
echo "Note: This simplified version doesn't use systemd services."
|
||||
}
|
||||
|
||||
hub_start() {
|
||||
systemctl --user start "rclone-mount@${RCLONE_REMOTE}.service"
|
||||
echo "Starting rclone mount in background..."
|
||||
mkdir -p "$MOUNT_POINT"
|
||||
nohup rclone mount "${RCLONE_REMOTE}:" "$MOUNT_POINT" \
|
||||
--config "${HOME}/.config/rclone/rclone.conf" \
|
||||
--vfs-cache-mode writes \
|
||||
--allow-other \
|
||||
--daemon >/dev/null 2>&1 &
|
||||
echo "Mount started in background (PID: $!)"
|
||||
echo "Check status with: $0 hub status"
|
||||
}
|
||||
|
||||
hub_start_background() {
|
||||
# Internal function for crontab/auto-start
|
||||
mkdir -p "$MOUNT_POINT"
|
||||
rclone mount "${RCLONE_REMOTE}:" "$MOUNT_POINT" \
|
||||
--config "${HOME}/.config/rclone/rclone.conf" \
|
||||
--vfs-cache-mode writes \
|
||||
--allow-other \
|
||||
--daemon
|
||||
}
|
||||
|
||||
hub_stop() {
|
||||
systemctl --user stop "rclone-mount@${RCLONE_REMOTE}.service"
|
||||
echo "Stopping rclone mount..."
|
||||
if hub_unmount; then
|
||||
echo "Mount stopped."
|
||||
else
|
||||
echo "Could not unmount. Trying force unmount..."
|
||||
fusermount -uz "$MOUNT_POINT" 2>/dev/null && echo "Force unmounted." || echo "Still could not unmount."
|
||||
fi
|
||||
}
|
||||
|
||||
hub_status() {
|
||||
systemctl --user status "rclone-mount@${RCLONE_REMOTE}.service" --no-pager
|
||||
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
|
||||
echo "Mount point $MOUNT_POINT is mounted."
|
||||
mount | grep "$MOUNT_POINT"
|
||||
else
|
||||
echo "Mount point $MOUNT_POINT is NOT mounted."
|
||||
echo "Check if rclone process is running:"
|
||||
pgrep -af rclone || echo "No rclone mount processes found."
|
||||
fi
|
||||
}
|
||||
|
||||
hub_mount() {
|
||||
@@ -188,6 +206,7 @@ hub)
|
||||
case "$ACTION" in
|
||||
install) hub_install ;;
|
||||
start) hub_start ;;
|
||||
start-background) hub_start_background ;;
|
||||
stop) hub_stop ;;
|
||||
status) hub_status ;;
|
||||
mount) hub_mount ;;
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
FROM debian:bookworm-slim
|
||||
RUN apt-get update && apt-get install -y autossh openssh-client && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN echo "PermitRootLogin no" >> /etc/ssh/sshd_config
|
||||
RUN echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
|
||||
RUN echo "Subsystem sftp internal-sftp" >> /etc/ssh/sshd_config
|
||||
|
||||
ARG UID=1000
|
||||
ARG GID=1000
|
||||
RUN groupadd -g ${GID} armbian && useradd -m -u ${UID} -g armbian armbian
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# For now, deprecated in favor of docker tunnel
|
||||
|
||||
[Unit]
|
||||
Description=AutoSSH tunnel from spoke to hub
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Environment="AUTOSSH_GATETIME=0"
|
||||
ExecStart=/usr/bin/autossh -M 0 -NT -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R 11111:localhost:22 -i /home/armbian/.ssh/armbian-brie-202604 armbian@oily.dad
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
User=armbian
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -7,6 +7,7 @@ services:
|
||||
network_mode: host
|
||||
environment:
|
||||
- AUTOSSH_GATETIME=0
|
||||
# @@@@@@@@@ BEWARE THE REVERSE TUNNEL PORT AND KEYS WHEN RUNNING THIS ON A NEW SPOKE @@@@@@@@@@
|
||||
command: >
|
||||
autossh -M 0 -NT
|
||||
-o "ServerAliveInterval=60"
|
||||
@@ -17,4 +18,15 @@ services:
|
||||
volumes:
|
||||
- /home/armbian/.ssh/oilykey2026:/home/armbian/.ssh/oilykey2026:ro
|
||||
- /home/armbian/.ssh/known_hosts:/home/armbian/.ssh/known_hosts:ro
|
||||
- /home/armbian/share:/home/armbian/share
|
||||
# - /home/armbian/share:/home/armbian/
|
||||
syncthing:
|
||||
image: syncthing/syncthing
|
||||
container_name: spoke-syncthing
|
||||
hostname: spoke-syncthing
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
volumes:
|
||||
- /home/armbian/st:/var/syncthing
|
||||
|
||||
Reference in New Issue
Block a user