2019-05-15 00:32:43 +02:00
# 🚀 SSH for GitHub Actions
2019-05-14 18:31:53 +02:00
2019-09-30 05:35:28 +02:00
[GitHub Action ](https://github.com/features/actions ) for executing remote ssh commands.
2019-05-15 00:32:43 +02:00
2019-09-29 05:09:26 +02:00
![ssh workflow ](./images/ssh-workflow.png )
[![Actions Status ](https://github.com/appleboy/ssh-action/workflows/remote%20ssh%20command/badge.svg )](https://github.com/appleboy/ssh-action/actions)
2019-05-15 00:36:27 +02:00
2020-06-05 03:05:02 +02:00
**Important**: Only support **Linux** [docker ](https://www.docker.com/ ) container.
2020-05-08 13:05:47 +02:00
2019-05-15 00:32:43 +02:00
## Usage
2019-05-15 00:36:27 +02:00
Executing remote ssh commands.
2019-05-15 00:32:43 +02:00
2019-09-29 05:09:26 +02:00
```yaml
2019-09-29 08:16:47 +02:00
name: remote ssh command
on: [push]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: executing remote ssh commands using password
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
port: ${{ secrets.PORT }}
script: whoami
2019-05-15 00:32:43 +02:00
```
2019-09-29 05:09:26 +02:00
output:
```sh
======CMD======
whoami
======END======
out: ** *
2019-11-20 16:49:31 +01:00
==============================================
✅ Successfully executed commands to all host.
==============================================
2019-05-15 00:32:43 +02:00
```
2019-09-29 05:09:26 +02:00
## Input variables
2019-05-15 00:32:43 +02:00
2019-11-21 15:53:08 +01:00
See [action.yml ](./action.yml ) for more detailed information.
2019-05-15 00:47:53 +02:00
2020-02-13 14:17:09 +01:00
* host - ssh host
* port - ssh port, default is `22`
2019-11-21 15:53:08 +01:00
* username - ssh username
* password - ssh password
2019-12-30 12:54:28 +01:00
* passphrase - the passphrase is usually to encrypt the private key
2020-01-30 15:40:33 +01:00
* sync - synchronous execution if multiple hosts, default is false
2019-09-29 05:09:26 +02:00
* timeout - timeout for ssh to remote host, default is `30s`
2019-11-30 16:01:49 +01:00
* command_timeout - timeout for ssh command, default is `10m`
2019-09-29 05:09:26 +02:00
* key - content of ssh private key. ex raw content of ~/.ssh/id_rsa
* key_path - path of ssh private key
2020-05-19 08:21:26 +02:00
* fingerprint - fingerprint SHA256 of the host public key, default is to skip verification
2019-09-29 05:09:26 +02:00
* script - execute commands
* script_stop - stop script after first failure
* envs - pass environment variable to shell script
* debug - enable debug mode
2020-05-24 04:54:31 +02:00
* use_insecure_cipher - include more ciphers with use_insecure_cipher (see [#56 ](https://github.com/appleboy/ssh-action/issues/56 ))
2020-05-24 07:13:09 +02:00
* cipher - the allowed cipher algorithms. If unspecified then a sensible
2019-05-15 00:47:53 +02:00
2019-12-07 13:05:02 +01:00
SSH Proxy Setting:
* proxy_host - proxy host
* proxy_port - proxy port, default is `22`
* proxy_username - proxy username
* proxy_password - proxy password
2019-12-30 12:54:28 +01:00
* proxy_passphrase - the passphrase is usually to encrypt the private key
2019-12-07 13:05:02 +01:00
* proxy_timeout - timeout for ssh to proxy host, default is `30s`
* proxy_key - content of ssh proxy private key.
* proxy_key_path - path of ssh proxy private key
2020-05-19 08:21:26 +02:00
* proxy_fingerprint - fingerprint SHA256 of the proxy host public key, default is to skip verification
2020-05-24 04:54:31 +02:00
* proxy_use_insecure_cipher - include more ciphers with use_insecure_cipher (see [#56 ](https://github.com/appleboy/ssh-action/issues/56 ))
2020-05-24 07:13:09 +02:00
* proxy_cipher - the allowed cipher algorithms. If unspecified then a sensible
2019-12-07 13:05:02 +01:00
2020-08-12 19:03:55 +02:00
### Setting up SSH Key
2020-08-12 19:06:27 +02:00
Make sure to follow the below steps while creating SSH Keys and using them.
2020-10-31 00:03:29 +01:00
The best practice is create the SSH Keys on local machine not remote machine.
2020-08-12 19:06:27 +02:00
Login with username specified in Github Secrets. Generate a RSA Key-Pair:
```bash
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
```
Add newly generated key into Authorized keys. Read more about authorized keys [here ](https://www.ssh.com/ssh/authorized_keys/ ).
```bash
2020-10-31 00:03:29 +01:00
cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
2020-08-12 19:06:27 +02:00
```
Copy Private Key content and paste in Github Secrets.
```bash
clip < ~/.ssh/id_rsa
```
See the detail information about [SSH login without password ](http://www.linuxproblem.org/art_9.html )
2019-09-29 05:09:26 +02:00
### Example
2019-05-15 00:47:53 +02:00
2019-09-29 05:09:26 +02:00
Executing remote ssh commands using password.
```yaml
- name: executing remote ssh commands using password
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
port: ${{ secrets.PORT }}
2019-09-29 05:45:42 +02:00
script: whoami
2019-05-15 00:47:53 +02:00
```
Using private key
2019-09-29 05:09:26 +02:00
```yaml
- name: executing remote ssh commands using ssh key
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
script: whoami
2019-05-15 00:47:53 +02:00
```
2019-05-15 00:52:59 +02:00
Multiple Commands
2019-09-29 05:09:26 +02:00
```yaml
- name: multiple command
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
script: |
whoami
ls -al
2019-05-15 00:52:59 +02:00
```
2019-09-29 05:09:26 +02:00
![result ](./images/output-result.png )
2019-05-15 00:59:18 +02:00
2019-05-15 01:13:49 +02:00
Multiple Hosts
2019-09-29 05:09:26 +02:00
```diff
2019-11-20 16:49:31 +01:00
- name: multiple host
uses: appleboy/ssh-action@master
with:
- host: "foo.com"
+ host: "foo.com,bar.com"
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
script: |
whoami
ls -al
2019-05-15 01:13:49 +02:00
```
2019-09-29 05:23:40 +02:00
2020-01-30 15:40:33 +01:00
Synchronous execution on multiple hosts
```diff
- name: multiple host
uses: appleboy/ssh-action@master
with:
host: "foo.com,bar.com"
+ sync: true
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
script: |
whoami
ls -al
```
2019-09-29 05:23:40 +02:00
Pass environment variable to shell script
```diff
2019-11-20 16:49:31 +01:00
- name: pass environment
uses: appleboy/ssh-action@master
+ env:
+ FOO: "BAR"
2019-12-08 00:16:30 +01:00
+ BAR: "FOO"
2020-02-09 04:37:56 +01:00
+ SHA: ${{ github.sha }}
2019-11-20 16:49:31 +01:00
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
2019-12-08 00:16:30 +01:00
+ envs: FOO,BAR
2019-11-20 16:49:31 +01:00
script: |
echo "I am $FOO"
echo "I am $BAR"
2020-02-09 04:37:56 +01:00
echo "sha: $SHA"
2019-09-29 05:23:40 +02:00
```
2019-09-29 06:02:21 +02:00
2020-07-08 10:46:24 +02:00
_Inside `env` object, you need to pass every environment variable as a string, passing `Integer` data type or any other may output unexpected results._
2019-09-29 06:02:21 +02:00
Stop script after first failure. ex: missing `abc` folder
2019-11-20 16:49:31 +01:00
```diff
- name: stop script if command error
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
+ script_stop: true
script: |
mkdir abc/def
ls -al
```
output:
```sh
======CMD======
mkdir abc/def
ls -al
======END======
2019/11/21 01:16:21 Process exited with status 1
err: mkdir: cannot create directory ‘ abc/def’ : No such file or directory
##[error]Docker run failed with exit code 1
2019-09-29 06:02:21 +02:00
```
2019-12-07 13:05:02 +01:00
How to connect remote server using `ProxyCommand` ?
```bash
+--------+ +----------+ +-----------+
| Laptop | < -- > | Jumphost | < -- > | FooServer |
+--------+ +----------+ +-----------+
```
in your `~/.ssh/config` , you will see the following.
```bash
Host Jumphost
HostName Jumphost
User ubuntu
Port 22
IdentityFile ~/.ssh/keys/jump_host.pem
Host FooServer
HostName FooServer
User ubuntu
Port 22
ProxyCommand ssh -q -W %h:%p Jumphost
```
How to convert to YAML format of GitHubActions.
```diff
- name: ssh proxy command
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
+ proxy_host: ${{ secrets.PROXY_HOST }}
+ proxy_username: ${{ secrets.PROXY_USERNAME }}
+ proxy_key: ${{ secrets.PROXY_KEY }}
+ proxy_port: ${{ secrets.PROXY_PORT }}
script: |
mkdir abc/def
ls -al
```
2019-12-30 12:54:28 +01:00
Protecting a Private Key. The purpose of the passphrase is usually to encrypt the private key. This makes the key file by itself useless to an attacker. It is not uncommon for files to leak from backups or decommissioned hardware, and hackers commonly exfiltrate files from compromised systems.
```diff
- name: ssh key passphrase
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
+ passphrase: ${{ secrets.PASSPHRASE }}
script: |
whoami
ls -al
```