Merge pull request 'feat(issue-11): add SSH setup script and remote access documentation' (#16) from feat/issue-11-ssh-setup into main
This commit was merged in pull request #16.
This commit is contained in:
334
docs/kugetsu-setup.md
Normal file
334
docs/kugetsu-setup.md
Normal file
@@ -0,0 +1,334 @@
|
||||
# kugetsu Setup Guide
|
||||
|
||||
This guide covers setting up a server/container with kugetsu for remote agent interaction.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Prerequisites](#prerequisites)
|
||||
2. [Container Setup](#container-setup)
|
||||
3. [SSH Setup](#ssh-setup)
|
||||
4. [kugetsu Installation](#kugetsu-installation)
|
||||
5. [Usage](#usage)
|
||||
6. [Remote Access via SSH](#remote-access-via-ssh)
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Linux container (Incus, Docker, Podman, etc.)
|
||||
- systemd available inside container
|
||||
- SSH key for authentication (RSA, ED25519, or ECDSA)
|
||||
|
||||
---
|
||||
|
||||
## Container Setup
|
||||
|
||||
### Incus
|
||||
|
||||
```bash
|
||||
# Create container (Debian/Ubuntu)
|
||||
incus launch images:debian/12 <container-name>
|
||||
|
||||
# Or create Fedora container
|
||||
incus launch images:fedora/43 <container-name>
|
||||
|
||||
# Or use an existing container
|
||||
incus exec <container-name> -- bash
|
||||
|
||||
# Ensure systemd is installed
|
||||
# For Debian/Ubuntu:
|
||||
incus exec <container-name> -- apt-get update
|
||||
incus exec <container-name> -- apt-get install -y systemd
|
||||
|
||||
# For Fedora:
|
||||
incus exec <container-name> -- dnf install -y systemd
|
||||
|
||||
# Enable systemd in container (Incus specific - verify with your setup)
|
||||
incus config set <container-name> security.syscalls.intercept.systemd true
|
||||
|
||||
> **Note:** Container must be privileged or have CAP_SYS_ADMIN for systemd features.
|
||||
> The exact command may vary by Incus version - check Incus documentation for your setup.
|
||||
|
||||
---
|
||||
|
||||
## SSH Setup
|
||||
|
||||
### Automated Setup
|
||||
|
||||
Run the setup script inside your container:
|
||||
|
||||
```bash
|
||||
chmod +x skills/kugetsu/scripts/sshd-setup.sh
|
||||
bash skills/kugetsu/scripts/sshd-setup.sh <username>
|
||||
```
|
||||
|
||||
Replace `<username>` with your preferred username, or omit to use default `kugetsu`.
|
||||
|
||||
**The script automatically detects your OS and installs the correct packages.**
|
||||
|
||||
Supported OSes: Debian, Ubuntu, Fedora, RHEL, CentOS
|
||||
|
||||
### Manual Setup
|
||||
|
||||
If you prefer to set up SSH manually:
|
||||
|
||||
#### 1. Install openssh-server
|
||||
|
||||
**Debian/Ubuntu:**
|
||||
```bash
|
||||
apt-get update && apt-get install -y openssh-server sudo
|
||||
```
|
||||
|
||||
**Fedora/RHEL/CentOS:**
|
||||
```bash
|
||||
dnf install -y openssh-server sudo
|
||||
```
|
||||
|
||||
#### 2. Verify installation
|
||||
|
||||
```bash
|
||||
which sshd
|
||||
sshd -V
|
||||
```
|
||||
|
||||
#### 2. Create non-root user
|
||||
|
||||
```bash
|
||||
# Create user (e.g., 'agent')
|
||||
useradd -m -s /bin/bash agent
|
||||
|
||||
# Or use an existing user
|
||||
```
|
||||
|
||||
#### 3. Configure SSH
|
||||
|
||||
Edit `/etc/ssh/sshd_config`:
|
||||
|
||||
```
|
||||
PasswordAuthentication no
|
||||
PubkeyAuthentication yes
|
||||
PermitRootLogin no
|
||||
```
|
||||
|
||||
#### 4. Add SSH public key
|
||||
|
||||
```bash
|
||||
mkdir -p /home/<username>/.ssh
|
||||
chmod 700 /home/<username>/.ssh
|
||||
echo 'YOUR_PUBLIC_KEY' >> /home/<username>/.ssh/authorized_keys
|
||||
chmod 600 /home/<username>/.ssh/authorized_keys
|
||||
chown -R <username>:<username> /home/<username>/.ssh
|
||||
```
|
||||
|
||||
#### 5. Configure sudo for passwordless access
|
||||
|
||||
```bash
|
||||
echo '<username> ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/<username>
|
||||
chmod 0440 /etc/sudoers.d/<username>
|
||||
```
|
||||
|
||||
#### 6. Start sshd
|
||||
|
||||
```bash
|
||||
systemctl enable sshd
|
||||
systemctl start sshd
|
||||
```
|
||||
|
||||
### Host-Side Port Forwarding
|
||||
|
||||
To access SSH from outside the host, configure port forwarding:
|
||||
|
||||
#### Incus
|
||||
|
||||
```bash
|
||||
# On the HOST (not inside container)
|
||||
incus config device add <container-name> sshd proxy listen=tcp:0.0.0.0:2222 connect=tcp:127.0.0.1:22
|
||||
```
|
||||
|
||||
#### Firewall
|
||||
|
||||
```bash
|
||||
# Allow SSH on host
|
||||
ufw allow 2222/tcp
|
||||
|
||||
# Or using iptables
|
||||
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
|
||||
```
|
||||
|
||||
### Verify SSH Setup
|
||||
|
||||
```bash
|
||||
# Test connection from host to container
|
||||
ssh -p 2222 <username>@localhost
|
||||
|
||||
# Verify sudo access
|
||||
ssh -p 2222 <username>@localhost sudo systemctl status sshd
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## kugetsu Installation
|
||||
|
||||
### Automated Install
|
||||
|
||||
```bash
|
||||
# If you have cloned the repository
|
||||
bash skills/kugetsu/scripts/kugetsu-install.sh
|
||||
|
||||
# Reload shell or source bashrc
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
kugetsu provides session management for opencode.
|
||||
|
||||
### Initialize
|
||||
|
||||
```bash
|
||||
# Create base session (requires TTY)
|
||||
kugetsu init
|
||||
```
|
||||
|
||||
### Start Task
|
||||
|
||||
```bash
|
||||
# Start new session for an issue
|
||||
kugetsu start <issue-ref> <message>
|
||||
|
||||
# Example
|
||||
kugetsu start github.com/shoko/kugetsu#11 "Implement SSH setup"
|
||||
```
|
||||
|
||||
### Continue Task
|
||||
|
||||
```bash
|
||||
# Continue existing session
|
||||
kugetsu continue <issue-ref> [message]
|
||||
|
||||
# Resume with auto-filled last message
|
||||
kugetsu continue github.com/shoko/kugetsu#11
|
||||
```
|
||||
|
||||
### List Sessions
|
||||
|
||||
```bash
|
||||
# List interrupted sessions (default)
|
||||
kugetsu list
|
||||
|
||||
# List all sessions
|
||||
kugetsu list --all
|
||||
```
|
||||
|
||||
### Destroy Session
|
||||
|
||||
```bash
|
||||
# Destroy session for issue
|
||||
kugetsu destroy <issue-ref> [-y]
|
||||
|
||||
# Destroy base session
|
||||
kugetsu destroy --base [-y]
|
||||
```
|
||||
|
||||
### Help
|
||||
|
||||
```bash
|
||||
kugetsu help
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Remote Access via SSH
|
||||
|
||||
Once SSH is configured, you can interact with kugetsu from anywhere:
|
||||
|
||||
### Basic SSH Access
|
||||
|
||||
```bash
|
||||
# Connect to container
|
||||
ssh -p 2222 <username>@<host-ip>
|
||||
|
||||
# Run kugetsu commands
|
||||
kugetsu list
|
||||
kugetsu start github.com/shoko/kugetsu#11 "Fix bug"
|
||||
```
|
||||
|
||||
### Spawn and Forget
|
||||
|
||||
For long-running tasks, SSH and spawn:
|
||||
|
||||
```bash
|
||||
ssh -p 2222 <username>@<host-ip> \
|
||||
"kugetsu start github.com/shoko/kugetsu#11 'Implement feature' && echo 'Task done' | tee /tmp/task.log"
|
||||
```
|
||||
|
||||
### Port Forwarding for Web UI
|
||||
|
||||
If opencode has a web UI:
|
||||
|
||||
```bash
|
||||
ssh -p 2222 -L 3000:localhost:3000 <username>@<host-ip>
|
||||
```
|
||||
|
||||
### SCP/File Transfer
|
||||
|
||||
```bash
|
||||
# Copy files from container
|
||||
scp -P 2222 <username>@<host-ip>:/path/in/container ./local-path
|
||||
|
||||
# Copy files to container
|
||||
scp -P 2222 ./local-file <username>@<host-ip>:/path/in/container
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Notes
|
||||
|
||||
- **Key-only authentication**: Password authentication is disabled
|
||||
- **Non-root user**: SSH user has limited privileges but can sudo
|
||||
- **Firewall**: Only port 2222 is exposed (not 22 on host)
|
||||
- **Container isolation**: Host filesystem is protected by container boundaries
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### SSH Connection Refused
|
||||
|
||||
```bash
|
||||
# Check sshd status inside container
|
||||
ssh -p 2222 <username>@<host-ip> sudo systemctl status sshd
|
||||
|
||||
# Restart sshd
|
||||
ssh -p 2222 <username>@<host-ip> sudo systemctl restart sshd
|
||||
```
|
||||
|
||||
### Permission Denied (Public Key)
|
||||
|
||||
```bash
|
||||
# Verify authorized_keys on container
|
||||
ssh -p 2222 <username>@<host-ip> cat ~/.ssh/authorized_keys
|
||||
|
||||
# Check key permissions
|
||||
ssh -p 2222 <username>@<host-ip> ls -la ~/.ssh/
|
||||
```
|
||||
|
||||
### kugetsu Command Not Found
|
||||
|
||||
```bash
|
||||
# Check PATH
|
||||
ssh -p 2222 <username>@<host-ip> 'echo $PATH'
|
||||
|
||||
# Re-run install (if repo is cloned on container)
|
||||
ssh -p 2222 <username>@<host-ip> 'bash ~/path/to/kugetsu/skills/kugetsu/scripts/kugetsu-install.sh'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [kugetsu Skill](../skills/kugetsu/SKILL.md) - Full kugetsu documentation
|
||||
- [kugetsu Architecture](kugetsu-architecture.md) - Technical details
|
||||
- [Subagent Workflow](SUBAGENT_WORKFLOW.md) - Multi-agent orchestration
|
||||
@@ -192,6 +192,49 @@ If opencode sessions become out of sync:
|
||||
2. `kugetsu prune` removes orphaned files
|
||||
3. For full reset: `kugetsu destroy --base -y && kugetsu init`
|
||||
|
||||
## Remote Access via SSH (Optional)
|
||||
|
||||
To access kugetsu from a remote machine, SSH setup is required.
|
||||
|
||||
### Automated Setup
|
||||
|
||||
Run the SSH setup script inside your container:
|
||||
|
||||
```bash
|
||||
chmod +x skills/kugetsu/scripts/sshd-setup.sh
|
||||
bash skills/kugetsu/scripts/sshd-setup.sh <username>
|
||||
```
|
||||
|
||||
Omit `<username>` to use default user `kugetsu`.
|
||||
|
||||
### What It Does
|
||||
|
||||
- Checks systemd prerequisite
|
||||
- Creates non-root user
|
||||
- Configures SSH for key-only authentication
|
||||
- Enables passwordless sudo for the user
|
||||
- Starts sshd via systemd
|
||||
|
||||
### After Setup
|
||||
|
||||
1. Add your SSH public key to `~/.ssh/authorized_keys` on the container
|
||||
2. Configure port forwarding on the host (see [docs/kugetsu-setup.md](../../docs/kugetsu-setup.md))
|
||||
3. Connect: `ssh -p 2222 <username>@<host-ip>`
|
||||
|
||||
### Remote Usage
|
||||
|
||||
Once connected via SSH, kugetsu works the same as local:
|
||||
|
||||
```bash
|
||||
kugetsu list
|
||||
kugetsu start github.com/shoko/kugetsu#14 "fix bug"
|
||||
kugetsu continue github.com/shoko/kugetsu#14
|
||||
```
|
||||
|
||||
### Documentation
|
||||
|
||||
See [docs/kugetsu-setup.md](../../docs/kugetsu-setup.md) for full remote access setup including host-side port forwarding and firewall configuration.
|
||||
|
||||
## Without kugetsu
|
||||
|
||||
If kugetsu is not available, use opencode directly:
|
||||
|
||||
@@ -38,6 +38,14 @@ add_to_shell "$HOME/.bashrc"
|
||||
add_to_shell "$HOME/.zshrc"
|
||||
|
||||
echo ""
|
||||
echo "=== Verifying installation ==="
|
||||
if [ ! -f "$BIN_DIR/kugetsu" ]; then
|
||||
echo "ERROR: kugetsu was not installed correctly."
|
||||
exit 1
|
||||
fi
|
||||
echo "kugetsu installed at: $BIN_DIR/kugetsu"
|
||||
echo ""
|
||||
|
||||
echo "Installation complete!"
|
||||
echo ""
|
||||
echo "Run this to start using kugetsu immediately:"
|
||||
|
||||
153
skills/kugetsu/scripts/sshd-setup.sh
Normal file
153
skills/kugetsu/scripts/sshd-setup.sh
Normal file
@@ -0,0 +1,153 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
USERNAME="${1:-kugetsu}"
|
||||
|
||||
echo "=== kugetsu SSH Setup ==="
|
||||
echo "Target user: $USERNAME"
|
||||
echo ""
|
||||
|
||||
detect_os() {
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
case "$ID" in
|
||||
debian|ubuntu|"noble"|"jammy"|"focal"|"bionic"|"bullseye"|"bookworm"|"trixie"|"sid")
|
||||
echo "debian"
|
||||
;;
|
||||
fedora|rhel|centos|rocky|alma)
|
||||
echo "fedora"
|
||||
;;
|
||||
*)
|
||||
echo "unknown"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo "unknown"
|
||||
fi
|
||||
}
|
||||
|
||||
OS_TYPE=$(detect_os)
|
||||
echo "Detected OS: $OS_TYPE"
|
||||
|
||||
if ! command -v systemctl &> /dev/null; then
|
||||
echo "ERROR: systemd not found."
|
||||
echo ""
|
||||
echo "This script requires systemd to be installed and running inside the container."
|
||||
echo "Please install systemd first:"
|
||||
case "$OS_TYPE" in
|
||||
debian)
|
||||
echo " apt-get update && apt-get install -y systemd"
|
||||
;;
|
||||
fedora)
|
||||
echo " dnf install -y systemd"
|
||||
;;
|
||||
*)
|
||||
echo " Install systemd using your package manager"
|
||||
;;
|
||||
esac
|
||||
echo ""
|
||||
echo "If you are running in a container that doesn't support systemd, consider:"
|
||||
echo " - Using a container image with systemd support"
|
||||
echo " - Running sshd directly (without systemd) - manual setup required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Step 1: Install openssh-server ==="
|
||||
case "$OS_TYPE" in
|
||||
debian)
|
||||
echo "Using apt-get (Debian/Ubuntu)..."
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq openssh-server sudo
|
||||
;;
|
||||
fedora)
|
||||
echo "Using dnf (Fedora/RHEL)..."
|
||||
dnf install -y -q openssh-server sudo
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Unsupported OS. Please install openssh-server and sudo manually."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo "=== Step 2: Verify installation ==="
|
||||
if ! command -v sshd &> /dev/null; then
|
||||
echo "ERROR: sshd installation failed."
|
||||
echo "Please verify openssh-server was installed correctly."
|
||||
exit 1
|
||||
fi
|
||||
echo "sshd binary: $(which sshd)"
|
||||
echo "sshd version: $(sshd -V 2>&1 | head -1)"
|
||||
|
||||
echo ""
|
||||
echo "=== Step 3: Create user '$USERNAME' ==="
|
||||
if ! id "$USERNAME" &> /dev/null; then
|
||||
useradd -m -s /bin/bash "$USERNAME"
|
||||
echo "User '$USERNAME' created."
|
||||
else
|
||||
echo "User '$USERNAME' already exists."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Step 4: Configure SSH for key-only authentication ==="
|
||||
SSHD_CONFIG="/etc/ssh/sshd_config"
|
||||
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' "$SSHD_CONFIG"
|
||||
sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' "$SSHD_CONFIG"
|
||||
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' "$SSHD_CONFIG"
|
||||
echo "SSH configured: key-only auth, root login disabled."
|
||||
|
||||
echo ""
|
||||
echo "=== Step 5: Configure sudo for passwordless access ==="
|
||||
SUDOERS_FILE="/etc/sudoers.d/$USERNAME"
|
||||
echo "$USERNAME ALL=(ALL) NOPASSWD: ALL" > "$SUDOERS_FILE"
|
||||
chmod 0440 "$SUDOERS_FILE"
|
||||
echo "Sudo configured: $USERNAME can run sudo without password."
|
||||
|
||||
echo ""
|
||||
echo "=== Step 6: Enable and start sshd ==="
|
||||
systemctl enable sshd
|
||||
systemctl restart sshd
|
||||
|
||||
sleep 1
|
||||
|
||||
echo ""
|
||||
echo "=== Step 7: Verify sshd is running ==="
|
||||
if systemctl is-active --quiet sshd; then
|
||||
echo "SUCCESS: sshd is running."
|
||||
echo "Status:"
|
||||
systemctl status sshd --no-pager | head -5
|
||||
else
|
||||
echo "ERROR: sshd is not running."
|
||||
echo "Debug info:"
|
||||
systemctl status sshd --no-pager
|
||||
journalctl -u sshd -n 10 --no-pager
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Setup Complete ==="
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo ""
|
||||
echo "1. Add your SSH public key to authorized_keys:"
|
||||
echo " mkdir -p /home/$USERNAME/.ssh"
|
||||
echo " chmod 700 /home/$USERNAME/.ssh"
|
||||
echo " echo 'YOUR_PUBLIC_KEY' >> /home/$USERNAME/.ssh/authorized_keys"
|
||||
echo " chmod 600 /home/$USERNAME/.ssh/authorized_keys"
|
||||
echo " chown -R $USERNAME:$USERNAME /home/$USERNAME/.ssh"
|
||||
echo ""
|
||||
echo "2. Connect from remote:"
|
||||
echo " ssh -p 2222 $USERNAME@<container-host-ip>"
|
||||
echo ""
|
||||
echo "3. Verify SSH access:"
|
||||
echo " ssh -p 2222 $USERNAME@<container-host-ip> sudo systemctl status sshd"
|
||||
echo ""
|
||||
echo "=== Troubleshooting ==="
|
||||
echo ""
|
||||
echo "If SSH connection fails:"
|
||||
echo " - Check sshd is running: systemctl status sshd"
|
||||
echo " - Check sshd logs: journalctl -u sshd -n 20"
|
||||
echo " - Verify user exists: id $USERNAME"
|
||||
echo " - Verify SSH key was added: cat /home/$USERNAME/.ssh/authorized_keys"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user