feat(issue-17): add Tailscale VPN setup for container remote access #21
@@ -284,6 +284,90 @@ scp -P 2222 ./local-file <username>@<host-ip>:/path/in/container
|
||||
|
||||
---
|
||||
|
||||
## Remote Access via Tailscale (Optional)
|
||||
|
||||
Tailscale provides VPN access without requiring a public IP on the host. Each container gets its own unique Tailscale IP and can be accessed from any device on your Tailscale network.
|
||||
|
||||
### Why Tailscale?
|
||||
|
||||
| | Port Forwarding | Tailscale |
|
||||
|--|-----------------|-----------|
|
||||
| Public IP required | Yes | No |
|
||||
| Firewall config | Needed | Not needed |
|
||||
| Cross-network access | Limited | Full |
|
||||
| Setup complexity | Higher | Lower |
|
||||
|
||||
### Automated Setup
|
||||
|
||||
Run the Tailscale setup script inside your container:
|
||||
|
||||
```bash
|
||||
chmod +x skills/kugetsu/scripts/tailscale-setup.sh
|
||||
bash skills/kugetsu/scripts/tailscale-setup.sh <username> <device-name>
|
||||
```
|
||||
|
||||
Arguments:
|
||||
- `<username>`: SSH user that will be created (defaults to current user)
|
||||
- `<device-name>`: Tailscale hostname (defaults to current hostname)
|
||||
|
||||
### Authentication Methods
|
||||
|
||||
The script will prompt you to choose:
|
||||
|
||||
**1. AUTHKEY (Recommended for automation)**
|
||||
- Pre-generate an auth key from: https://login.tailscale.com/admin/settings/keys
|
||||
- Click "Generate auth key", copy the key (starts with `tskey-auth-`)
|
||||
- Paste it when prompted
|
||||
|
||||
**2. Headless (Browser-based)**
|
||||
- Script will show a login URL
|
||||
- Open the URL in your browser and authenticate
|
||||
- Return to complete setup
|
||||
|
||||
### After Setup
|
||||
|
||||
1. Install Tailscale on your other devices: https://tailscale.com/download
|
||||
2. Log in with the same Tailscale account
|
||||
3. Connect via SSH using your device name:
|
||||
```bash
|
||||
ssh <username>@<device-name>
|
||||
```
|
||||
|
||||
Or use the Tailscale IP directly:
|
||||
```bash
|
||||
ssh <username>@<tailscale-ip>
|
||||
```
|
||||
|
||||
### Verify Connection
|
||||
|
||||
Inside the container:
|
||||
```bash
|
||||
tailscale status
|
||||
tailscale ip -4
|
||||
```
|
||||
|
||||
### Tailscale + SSH
|
||||
|
||||
Tailscale handles the network connection. Once connected via Tailscale, you can SSH normally and use kugetsu:
|
||||
|
||||
```bash
|
||||
ssh <username>@<device-name>
|
||||
kugetsu list
|
||||
kugetsu start github.com/shoko/kugetsu#11 "Fix bug"
|
||||
```
|
||||
|
||||
### Uninstall Tailscale
|
||||
|
||||
```bash
|
||||
sudo systemctl stop tailscaled
|
||||
sudo systemctl disable tailscaled
|
||||
sudo dnf remove tailscale # Fedora
|
||||
# or
|
||||
sudo apt remove tailscale # Debian/Ubuntu
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Notes
|
||||
|
||||
- **Key-only authentication**: Password authentication is disabled
|
||||
|
||||
@@ -235,6 +235,35 @@ kugetsu continue github.com/shoko/kugetsu#14
|
||||
|
||||
See [docs/kugetsu-setup.md](../../docs/kugetsu-setup.md) for full remote access setup including host-side port forwarding and firewall configuration.
|
||||
|
||||
### Tailscale VPN (Alternative)
|
||||
|
||||
If your host does not have a public IP or you need access across different networks, Tailscale provides a VPN solution.
|
||||
|
||||
**Benefits:**
|
||||
- No public IP required
|
||||
- Each container gets its own unique Tailscale IP
|
||||
- Access from anywhere via Tailscale network
|
||||
- Normal internet access still works
|
||||
|
||||
**Setup:**
|
||||
|
||||
```bash
|
||||
chmod +x skills/kugetsu/scripts/tailscale-setup.sh
|
||||
bash skills/kugetsu/scripts/tailscale-setup.sh <username> <device-name>
|
||||
```
|
||||
|
||||
The script will:
|
||||
1. Install Tailscale (supports Debian/Ubuntu, Fedora)
|
||||
2. Start the tailscaled daemon
|
||||
3. Prompt for AUTHKEY or browser-based login
|
||||
4. Configure device name (defaults to current hostname)
|
||||
|
||||
**After Setup:**
|
||||
- From any Tailscale device: `ssh <username>@<device-name>`
|
||||
- Works across different networks without port forwarding
|
||||
|
||||
See [docs/kugetsu-setup.md](../../docs/kugetsu-setup.md) for full Tailscale setup documentation.
|
||||
|
||||
## Without kugetsu
|
||||
|
||||
If kugetsu is not available, use opencode directly:
|
||||
|
||||
164
skills/kugetsu/scripts/tailscale-setup.sh
Normal file
164
skills/kugetsu/scripts/tailscale-setup.sh
Normal file
@@ -0,0 +1,164 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
USERNAME="${1:-$(whoami)}"
|
||||
HOSTNAME="${2:-$(hostname)}"
|
||||
|
||||
echo "=== kugetsu Tailscale Setup ==="
|
||||
echo "Target user: $USERNAME"
|
||||
echo "Device name: $HOSTNAME"
|
||||
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"
|
||||
|
||||
echo ""
|
||||
echo "=== Step 1: Installing Tailscale ==="
|
||||
|
||||
install_tailscale() {
|
||||
case "$OS_TYPE" in
|
||||
debian)
|
||||
echo "Installing Tailscale via apt (Debian/Ubuntu)..."
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
;;
|
||||
fedora)
|
||||
echo "Installing Tailscale via dnf (Fedora/RHEL)..."
|
||||
# Add Tailscale repo
|
||||
dnf config-manager --add-repo https://pkgs.tailscale.com/stable/tailscale.repo
|
||||
dnf install -y tailscale
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Unsupported OS. Please install Tailscale manually."
|
||||
echo "See: https://tailscale.com/download"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if command -v tailscale &> /dev/null; then
|
||||
echo "Tailscale is already installed: $(tailscale --version)"
|
||||
else
|
||||
install_tailscale
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Step 2: Verify Tailscale installation ==="
|
||||
if ! command -v tailscale &> /dev/null; then
|
||||
echo "ERROR: Tailscale installation failed."
|
||||
exit 1
|
||||
fi
|
||||
echo "Tailscale binary: $(which tailscale)"
|
||||
echo "Tailscale version: $(tailscale --version)"
|
||||
|
||||
echo ""
|
||||
echo "=== Step 3: Start tailscaled daemon ==="
|
||||
systemctl enable --now tailscaled
|
||||
sleep 2
|
||||
|
||||
if systemctl is-active --quiet tailscaled; then
|
||||
echo "SUCCESS: tailscaled is running."
|
||||
else
|
||||
echo "ERROR: tailscaled failed to start."
|
||||
echo "Debug: systemctl status tailscaled"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Step 4: Authentication ==="
|
||||
|
||||
auth_method() {
|
||||
echo "Choose authentication method:"
|
||||
echo " 1) AUTHKEY - Use a pre-generated auth key (headless/scripted)"
|
||||
echo " 2) Headless - Get a login URL to click in browser"
|
||||
echo ""
|
||||
read -p "Enter choice [1/2]: " choice
|
||||
|
||||
case "$choice" in
|
||||
1)
|
||||
echo ""
|
||||
echo "To generate an AUTHKEY:"
|
||||
echo " 1. Go to: https://login.tailscale.com/admin/settings/keys"
|
||||
echo " 2. Click 'Generate auth key'"
|
||||
echo " 3. Copy the key (starts with 'tskey-auth-')"
|
||||
echo ""
|
||||
read -p "Paste your AUTHKEY (or press Enter to cancel): " AUTHKEY
|
||||
|
||||
if [ -z "$AUTHKEY" ]; then
|
||||
echo "Cancelled."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ! "$AUTHKEY" =~ ^tskey-auth ]]; then
|
||||
echo "ERROR: AUTHKEY should start with 'tskey-auth-'. Please check and try again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Connecting with AUTHKEY..."
|
||||
tailscale up --authkey="$AUTHKEY" --hostname="$HOSTNAME" --operator="$USERNAME"
|
||||
;;
|
||||
2|"")
|
||||
echo ""
|
||||
echo "Getting login URL..."
|
||||
echo "After you click the URL and authenticate in browser, this script will continue."
|
||||
echo ""
|
||||
tailscale up --hostname="$HOSTNAME" --operator="$USERNAME"
|
||||
;;
|
||||
*)
|
||||
echo "Invalid choice. Please enter 1 or 2."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
auth_method
|
||||
|
||||
echo ""
|
||||
echo "=== Step 5: Verify Tailscale connection ==="
|
||||
sleep 2
|
||||
|
||||
if tailscale status &> /dev/null; then
|
||||
echo "SUCCESS: Connected to Tailscale!"
|
||||
echo ""
|
||||
echo "Your Tailscale IP:"
|
||||
tailscale ip -4
|
||||
echo ""
|
||||
echo "Your Tailscale hostname: $HOSTNAME"
|
||||
echo ""
|
||||
echo "To connect from another Tailscale device:"
|
||||
echo " ssh $USERNAME@$HOSTNAME"
|
||||
echo ""
|
||||
echo "Or directly via IP:"
|
||||
echo " ssh $USERNAME@$(tailscale ip -4)"
|
||||
else
|
||||
echo "WARNING: Tailscale may not be fully connected yet."
|
||||
echo "Check status with: tailscale status"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Setup Complete ==="
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " - Install Tailscale on your other devices: https://tailscale.com/download"
|
||||
echo " - Add this device to your tailnet"
|
||||
echo " - SSH from anywhere using: ssh $USERNAME@$HOSTNAME"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user