setup-ssh-client/README.md

6.4 KiB

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

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)

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

- 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

- 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)

- 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:

Use shell: ssh-remote in any step to execute the entire script on the remote server:

- 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:

- 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

# 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:

    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:

    cat github_actions_key.pub >> ~/.ssh/authorized_keys
    

Getting Known Hosts

To pre-populate known hosts (recommended for security):

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 file for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.