# Setup SSH Client A composite GitHub Action that configures SSH client for running remote commands securely. ## Features - 🔐 Secure SSH key management - 🔧 Automatic SSH configuration - 🔑 Known hosts setup with ssh-keyscan fallback - ✅ Connection validation - 🎯 Simple, reusable configuration - 🚀 Custom shell wrapper for seamless remote command execution ## Usage ### Basic Example with Custom Shell ```yaml name: Deploy Application on: [push] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup SSH uses: your-username/setup-ssh-client@v1 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} ssh-host: ${{ secrets.SSH_HOST }} ssh-user: ${{ secrets.SSH_USER }} - name: Run remote commands with custom shell shell: ssh-remote run: | cd /var/www git pull origin main npm install systemctl restart myapp - name: Or use direct SSH commands run: | ssh github-action-host "uptime" ssh github-action-host "df -h" ``` ### Basic Example (Direct SSH) ```yaml name: Deploy Application on: [push] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup SSH uses: your-username/setup-ssh-client@v1 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} ssh-host: ${{ secrets.SSH_HOST }} ssh-user: ${{ secrets.SSH_USER }} - name: Run remote commands run: | ssh github-action-host "cd /var/www && git pull" ssh github-action-host "systemctl restart myapp" ``` ### Advanced Example ```yaml - name: Setup SSH with custom configuration uses: your-username/setup-ssh-client@v1 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} ssh-host: example.com ssh-user: deploy ssh-port: '2222' strict-host-key-checking: 'yes' ssh-known-hosts: | example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... - name: Deploy application run: | ssh github-action-host "cd /var/www/app && ./deploy.sh" ``` ### Using Different Remote Shells ```yaml - name: Setup SSH with zsh uses: your-username/setup-ssh-client@v1 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} ssh-host: example.com ssh-user: deploy remote-shell: 'zsh' - name: Run commands in remote zsh shell: ssh-remote run: | source ~/.zshrc echo "Running in zsh: $SHELL" ``` ### Disable Shell Wrapper (SSH Direct Only) ```yaml - name: Setup SSH without shell wrapper uses: your-username/setup-ssh-client@v1 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} ssh-host: example.com ssh-user: deploy use-shell-wrapper: 'false' - name: Use direct SSH commands run: | ssh github-action-host "command1" ssh github-action-host "command2" ``` ## Inputs | Input | Description | Required | Default | |-------|-------------|----------|---------| | `ssh-private-key` | SSH private key for authentication | Yes | - | | `ssh-host` | SSH host to connect to | Yes | - | | `ssh-user` | SSH username | Yes | - | | `ssh-port` | SSH port | No | `22` | | `ssh-known-hosts` | Known hosts content (uses ssh-keyscan if not provided) | No | `''` | | `strict-host-key-checking` | Enable strict host key checking (`yes`/`no`/`accept-new`) | No | `accept-new` | | `use-shell-wrapper` | Create shell wrapper for remote execution (enables `shell: ssh-remote`) | No | `true` | | `remote-shell` | Shell to use on remote server (`bash`, `sh`, `zsh`, etc.) | No | `bash` | ## Outputs | Output | Description | |--------|-------------| | `ssh-config-path` | Path to the SSH config file | | `ssh-key-path` | Path to the SSH private key | | `shell-wrapper-path` | Path to the SSH remote shell wrapper script | ## Remote Command Execution This action provides two ways to execute commands remotely: ### 1. Custom Shell Wrapper (Recommended) Use `shell: ssh-remote` in any step to execute the entire script on the remote server: ```yaml - name: Deploy application shell: ssh-remote run: | cd /var/www/myapp git pull origin main npm install --production pm2 restart myapp ``` **Benefits:** - Natural multi-line script syntax - Automatic error handling with `set -e` - Works like a local shell - No need to wrap commands in SSH ### 2. SSH Host Alias (Direct) Use the `github-action-host` alias for direct SSH commands: ```yaml - name: Run single commands run: | ssh github-action-host "uptime" ssh github-action-host "df -h" ``` This eliminates the need to specify the host, user, port, and key path in every SSH command. ## Security Best Practices ### Generating SSH Keys ```bash # Generate a dedicated SSH key pair for GitHub Actions ssh-keygen -t ed25519 -C "github-actions" -f github_actions_key # Or use RSA if ed25519 is not supported ssh-keygen -t rsa -b 4096 -C "github-actions" -f github_actions_key ``` ### Setting up Secrets 1. Copy your private key content: ```bash cat github_actions_key ``` 2. Add it to GitHub Secrets: - Go to your repository → Settings → Secrets and variables → Actions - Click "New repository secret" - Name: `SSH_PRIVATE_KEY` - Value: Paste the entire private key content 3. Add the public key to your server: ```bash cat github_actions_key.pub >> ~/.ssh/authorized_keys ``` ### Getting Known Hosts To pre-populate known hosts (recommended for security): ```bash ssh-keyscan -H your-server.com ``` Add the output to a GitHub secret named `SSH_KNOWN_HOSTS`. ## Troubleshooting ### Connection Timeout If the connection test fails with a timeout: - Verify the host and port are correct - Check firewall rules allow connections from GitHub Actions IPs - Ensure SSH service is running on the remote server ### Permission Denied If you get "Permission denied": - Verify the public key is in `~/.ssh/authorized_keys` on the remote server - Check the private key format is correct (should include header/footer) - Ensure the SSH user has appropriate permissions ### Host Key Verification Failed If you encounter host key verification issues: - Set `strict-host-key-checking: 'no'` (not recommended for production) - Or provide `ssh-known-hosts` input with the correct host key ## License MIT License - see [LICENSE](LICENSE) file for details ## Contributing Contributions are welcome! Please feel free to submit a Pull Request.