commit 0b79cf89175323a5f6253c33104f67f282084697 Author: Muhammed Can Date: Thu Mar 13 08:03:01 2025 +0300 first commit diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..01b1081 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,28 @@ +builds: + - # If true, skip the build. + # Useful for library projects. + # Default is false + skip: true + +changelog: + use: github + groups: + - title: Features + regexp: "^.*feat[(\\w)]*:+.*$" + order: 0 + - title: "Bug fixes" + regexp: "^.*fix[(\\w)]*:+.*$" + order: 1 + - title: "Enhancements" + regexp: "^.*chore[(\\w)]*:+.*$" + order: 2 + - title: "Refactor" + regexp: "^.*refactor[(\\w)]*:+.*$" + order: 3 + - title: "Build process updates" + regexp: ^.*?(build|ci)(\(.+\))??!?:.+$ + order: 4 + - title: "Documentation updates" + regexp: ^.*?docs?(\(.+\))??!?:.+$ + order: 4 + - title: Others diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dc6b84f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Bo-Yi Wu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..aea5988 --- /dev/null +++ b/README.md @@ -0,0 +1,428 @@ +# 🚀 SSH for GitHub Actions + +English | [繁體中文](./README.zh-tw.md) | [简体中文](./README.zh-cn.md) + +A [GitHub Action](https://github.com/features/actions) for executing remote SSH commands. + +![ssh workflow](./images/ssh-workflow.png) + +[![testing main branch](https://github.com/appleboy/ssh-action/actions/workflows/main.yml/badge.svg)](https://github.com/appleboy/ssh-action/actions/workflows/main.yml) + +This project is built with [Golang](https://go.dev) and [drone-ssh](https://github.com/appleboy/drone-ssh). 🚀 + +## Input variables + +Refer to [action.yml](./action.yml) for more detailed information. + +| Input Parameter | Description | Default Value | +| ------------------------- | ---------------------------------------------------------------------------------------- | ------------- | +| host | SSH host address | | +| port | SSH port number | 22 | +| passphrase | SSH key passphrase | | +| username | SSH username | | +| password | SSH password | | +| protocol | SSH protocol version (tcp, tcp4, tcp6) | tcp | +| sync | Enable synchronous execution if multiple hosts are specified | false | +| use_insecure_cipher | Include more ciphers with use_insecure_cipher | false | +| cipher | Allowed cipher algorithms. If unspecified, sensible defaults are used | | +| timeout | Timeout duration for SSH to host | 30s | +| command_timeout | Timeout duration for SSH command | 10m | +| key | Content of SSH private key. e.g., raw content of ~/.ssh/id_rsa | | +| key_path | Path of SSH private key | | +| fingerprint | SHA256 fingerprint of the host public key | | +| proxy_host | SSH proxy host | | +| proxy_port | SSH proxy port | 22 | +| proxy_protocol | SSH proxy protocol version (tcp, tcp4, tcp6) | tcp | +| proxy_username | SSH proxy username | | +| proxy_password | SSH proxy password | | +| proxy_passphrase | SSH proxy key passphrase | | +| proxy_timeout | Timeout for SSH to proxy host | 30s | +| proxy_key | Content of SSH proxy private key | | +| proxy_key_path | Path of SSH proxy private key | | +| proxy_fingerprint | SHA256 fingerprint of the proxy host public key | | +| proxy_cipher | Allowed cipher algorithms for the proxy | | +| proxy_use_insecure_cipher | Include more ciphers with use_insecure_cipher for the proxy | false | +| script | Execute commands | | +| script_path | Execute commands from a file | | +| envs | Pass environment variables to the shell script | | +| envs_format | Flexible configuration of environment value transfer | | +| debug | Enable debug mode | false | +| allenvs | Pass the environment variables with prefix value of `GITHUB_` and `INPUT_` to the script | false | +| request_pty | Request a pseudo-terminal from the server | false | + +**Note:** Users can add `set -e` in their shell script to achieve similar functionality to the removed `script_stop` option. + +## Usage + +Executing remote SSH commands. + +```yaml +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@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: linuxserver.io + password: ${{ secrets.PASSWORD }} + port: ${{ secrets.PORT }} + script: whoami +``` + +output: + +```sh +======CMD====== +whoami +======END====== +linuxserver.io +=============================================== +✅ Successfully executed commands to all hosts. +=============================================== +``` + +### Setting up a SSH Key + +Follow the steps below to create and use SSH Keys. +It is best practice to create SSH Keys on your local machine, not on a remote machine. +Log in with the username specified in GitHub Secrets and generate an RSA Key-Pair: + +### Generate rsa key + +```bash +ssh-keygen -t rsa -b 4096 -C "your_email@example.com" +``` + +### Generate ed25519 key + +```bash +ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" +``` + +Add the newly generated key to the Authorized keys. Read more about authorized keys [here](https://www.ssh.com/ssh/authorized_keys/). + +### Add rsa key into Authorized keys + +```bash +cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys' +``` + +### Add ed25519 key into Authorized keys + +```bash +cat .ssh/id_ed25519.pub | ssh b@B 'cat >> .ssh/authorized_keys' +``` + +Copy the Private Key content and paste it into GitHub Secrets. + +### Copy rsa Private key + +Before copying the private key, install the `clip` command as shown below: + +```bash +# Ubuntu +sudo apt-get install xclip +``` + +Copy the private key: + +```bash +# macOS +pbcopy < ~/.ssh/id_rsa +# Ubuntu +xclip < ~/.ssh/id_rsa +``` + +Starting from and including the comment section `-----BEGIN OPENSSH PRIVATE KEY-----` and ending at and including the comment section `-----END OPENSSH PRIVATE KEY-----`, copy the private key and paste it into GitHub Secrets. + +### Copy ed25519 Private key + +```bash +# macOS +pbcopy < ~/.ssh/id_ed25519 +# Ubuntu +xclip < ~/.ssh/id_ed25519 +``` + +See detailed information about [SSH login without a password](http://www.linuxproblem.org/art_9.html). + +**Note**: Depending on your version of SSH, you might also need to make the following changes: + +- Put the public key in `.ssh/authorized_keys2` +- Change the permissions of `.ssh` to 700 +- Change the permissions of `.ssh/authorized_keys2` to 640 + +### If you are using OpenSSH + +If you are currently using OpenSSH and are getting the following error: + +```bash +ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey] +``` + +Ensure that your chosen key algorithm is supported. On Ubuntu 20.04 or later, you must explicitly allow the use of the ssh-rsa algorithm. Add the following line to your OpenSSH daemon file (either `/etc/ssh/sshd_config` or a drop-in file under `/etc/ssh/sshd_config.d/`): + +```bash +CASignatureAlgorithms +ssh-rsa +``` + +Alternatively, `ed25519` keys are accepted by default in OpenSSH. You can use this instead of rsa if needed: + +```bash +ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" +``` + +### Example + +#### Executing remote ssh commands using password + +```yaml +- name: executing remote ssh commands using password + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + password: ${{ secrets.PASSWORD }} + port: ${{ secrets.PORT }} + script: whoami +``` + +#### Using private key + +```yaml +- name: executing remote ssh commands using ssh key + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: whoami +``` + +#### Multiple Commands + +```yaml +- name: multiple command + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + whoami + ls -al +``` + +![result](./images/output-result.png) + +#### Commands from a file + +```yaml +- name: file commands + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script_path: scripts/script.sh +``` + +#### Multiple Hosts + +```diff + - name: multiple host + uses: appleboy/ssh-action@v1.2.2 + with: +- host: "foo.com" ++ host: "foo.com,bar.com" + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + whoami + ls -al +``` + +The default value of `port` is `22`. + +#### Multiple hosts with different port + +```diff + - name: multiple host + uses: appleboy/ssh-action@v1.2.2 + with: +- host: "foo.com" ++ host: "foo.com:1234,bar.com:5678" + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + script: | + whoami + ls -al +``` + +#### Synchronous execution on multiple hosts + +```diff + - name: multiple host + uses: appleboy/ssh-action@v1.2.2 + with: + host: "foo.com,bar.com" ++ sync: true + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + whoami + ls -al +``` + +#### Pass environment variable to shell script + +```diff + - name: pass environment + uses: appleboy/ssh-action@v1.2.2 ++ env: ++ FOO: "BAR" ++ BAR: "FOO" ++ SHA: ${{ github.sha }} + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} ++ envs: FOO,BAR,SHA + script: | + echo "I am $FOO" + echo "I am $BAR" + echo "sha: $SHA" +``` + +_Inside `env` object, you need to pass every environment variable as a string, passing `Integer` data type or any other may output unexpected results._ + +#### 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@v1.2.2 + 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 +``` + +#### 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@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} ++ passphrase: ${{ secrets.PASSPHRASE }} + script: | + whoami + ls -al +``` + +#### Using host fingerprint verification + +Setting up SSH host fingerprint verification can help to prevent Person-in-the-Middle attacks. Before setting this up, run the command below to get your SSH host fingerprint. Remember to replace `ed25519` with your appropriate key type (`rsa`, `dsa`, etc.) that your server is using and `example.com` with your host. + +In modern OpenSSH releases, the _default_ key types to be fetched are `rsa` (since version 5.1), `ecdsa` (since version 6.0), and `ed25519` (since version 6.7). + +```sh +ssh example.com ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub | cut -d ' ' -f2 +``` + +Now you can adjust you config: + +```diff + - name: ssh key passphrase + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} ++ fingerprint: ${{ secrets.FINGERPRINT }} + script: | + whoami + ls -al +``` + +## Q&A + +### Command not found (npm or other command) + +See the [issue comment](https://github.com/appleboy/ssh-action/issues/31#issuecomment-1006565847) about interactive vs non interactive shell. Thanks @kocyigityunus for the solution. + +If you are running a command in a non-interactive shell, like ssh-action, on many Linux distros, + +`/etc/bash.bashrc` file has a specific command that returns only, so some of the files didn't run and some specific commands doesn't add to path, + +```sh +# /etc/bash.bashrc +# System-wide .bashrc file for interactive bash(1) shells. + +# To enable the settings / commands in this file for login shells as well, +# this file has to be sourced in /etc/profile. + +# If not running interactively, don't do anything +[ -z "$PS1" ] && return` +``` + +comment out the line that returns early, and everything should work fine. Alternatively, you can use the real paths of the commands you want to use. + +## Contributing + +We would love for you to contribute to `appleboy/ssh-action`, pull requests are welcome! + +## License + +The scripts and documentation in this project are released under the [MIT License](LICENSE) diff --git a/README.zh-cn.md b/README.zh-cn.md new file mode 100644 index 0000000..034837e --- /dev/null +++ b/README.zh-cn.md @@ -0,0 +1,403 @@ +# 🚀 用于 GitHub Actions 的 SSH + +[English](./README.md) | [繁體中文](./README.zh-tw.md) | 简体中文 + +一个用于执行远程 SSH 命令的 [GitHub Action](https://github.com/features/actions)。 + +![ssh workflow](./images/ssh-workflow.png) + +[![testing main branch](https://github.com/appleboy/ssh-action/actions/workflows/main.yml/badge.svg)](https://github.com/appleboy/ssh-action/actions/workflows/main.yml) + +该项目使用 [Golang](https://go.dev) 和 [drone-ssh](https://github.com/appleboy/drone-ssh) 构建。🚀 + +## 输入变量 + +有关更详细的信息,请参阅 [action.yml](./action.yml)。 + +| 输入参数 | 描述 | 默认值 | +| ------------------------- | ----------------------------------------------------- | ------ | +| host | SSH 主机地址 | | +| port | SSH 端口号 | 22 | +| passphrase | SSH 密钥密码短语 | | +| username | SSH 用户名 | | +| password | SSH 密码 | | +| protocol | SSH 协议版本(tcp, tcp4, tcp6) | tcp | +| sync | 如果指定了多个主机,则启用同步执行 | false | +| use_insecure_cipher | 使用不安全的密码算法 | false | +| cipher | 允许的密码算法。如果未指定,则使用适当的默认值 | | +| timeout | SSH 连接到主机的超时时间 | 30s | +| command_timeout | SSH 命令的超时时间 | 10m | +| key | SSH 私钥的内容,例如 ~/.ssh/id_rsa 的原始内容 | | +| key_path | SSH 私钥的路径 | | +| fingerprint | 主机公钥的 SHA256 指纹 | | +| proxy_host | SSH 代理主机 | | +| proxy_port | SSH 代理端口 | 22 | +| proxy_protocol | SSH 代理协议版本(tcp, tcp4, tcp6) | tcp | +| proxy_username | SSH 代理用户名 | | +| proxy_password | SSH 代理密码 | | +| proxy_passphrase | SSH 代理密钥密码短语 | | +| proxy_timeout | SSH 连接到代理主机的超时时间 | 30s | +| proxy_key | SSH 代理私钥的内容 | | +| proxy_key_path | SSH 代理私钥的路径 | | +| proxy_fingerprint | 代理主机公钥的 SHA256 指纹 | | +| proxy_cipher | 代理允许的密码算法 | | +| proxy_use_insecure_cipher | 使用不安全的密码算法 | false | +| script | 执行命令 | | +| script_path | 从文件执行命令 | | +| envs | 传递环境变量到 shell 脚本 | | +| envs_format | 环境变量传递的灵活配置 | | +| debug | 启用调试模式 | false | +| allenvs | 将带有 `GITHUB_` 和 `INPUT_` 前缀的环境变量传递给脚本 | false | +| request_pty | 请求伪终端 | false | + +**注意:** 用户可以在他们的 shell 脚本中添加 `set -e` 以实现类似于已删除的 `script_stop` 选项的功能。 + +## 使用方法 + +执行远程 SSH 命令。 + +```yaml +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@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: linuxserver.io + password: ${{ secrets.PASSWORD }} + port: ${{ secrets.PORT }} + script: whoami +``` + +输出: + +```sh +======CMD====== +whoami +======END====== +linuxserver.io +=============================================== +✅ Successfully executed commands to all hosts. +=============================================== +``` + +### 设置 SSH 密钥 + +请按照以下步骤创建和使用 SSH 密钥。 +最佳做法是在本地机器上创建 SSH 密钥,而不是在远程机器上。 +使用 GitHub Secrets 中指定的用户名登录并生成 RSA 密钥对: + +### 生成 RSA 密钥 + +```bash +ssh-keygen -t rsa -b 4096 -C "your_email@example.com" +``` + +### 生成 ed25519 密钥 + +```bash +ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" +``` + +将新生成的密钥添加到已授权的密钥中。详细了解已授权的密钥请点[此处](https://www.ssh.com/ssh/authorized_keys/)。 + +### 将 RSA 密钥添加到已授权密钥中 + +```bash +cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys' +``` + +### 将 ed25519 密钥添加到已授权密钥中 + +```bash +cat .ssh/id_ed25519.pub | ssh b@B 'cat >> .ssh/authorized_keys' +``` + +复制私钥内容,然后将其粘贴到 GitHub Secrets 中。 + +### 复制 RSA 私钥内容 + +在复制私钥之前,按照以下步骤安装 `clip` 命令: + +```bash +# Ubuntu +sudo apt-get install xclip +``` + +复制私钥: + +```bash +# macOS +pbcopy < ~/.ssh/id_rsa +# Ubuntu +xclip < ~/.ssh/id_rsa +``` + +从包含注释部分 `-----BEGIN OPENSSH PRIVATE KEY-----` 开始,到包含注释部分 `-----END OPENSSH PRIVATE KEY-----` 结束,复制私钥并将其粘贴到 GitHub Secrets 中。 + +### 复制 ed25519 私钥内容 + +```bash +# macOS +pbcopy < ~/.ssh/id_ed25519 +# Ubuntu +xclip < ~/.ssh/id_ed25519 +``` + +有关无需密码登录 SSH 的详细信息,请[见该网站](http://www.linuxproblem.org/art_9.html)。 + +**注意**:根据您的 SSH 版本,您可能还需要进行以下更改: + +- 将公钥放在 `.ssh/authorized_keys2` 中 +- 将 `.ssh` 的权限更改为 700 +- 将 `.ssh/authorized_keys2` 的权限更改为 640 + +### 如果你使用的是 OpenSSH + +如果您正在使用 OpenSSH,并出现以下错误: + +```bash +ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey] +``` + +请确保您所选择的密钥算法得到支持。在 Ubuntu 20.04 或更高版本上,您必须明确允许使用 ssh-rsa 算法。请在 OpenSSH 守护进程文件中添加以下行(它可以是 `/etc/ssh/sshd_config` 或 `/etc/ssh/sshd_config.d/` 中的一个附加文件): + +```bash +CASignatureAlgorithms +ssh-rsa +``` + +或者,`ed25519` 密钥在 OpenSSH 中默认被接受。如果需要,您可以使用它来替代 RSA: + +```bash +ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" +``` + +### 示例 + +#### 使用密码执行远程 SSH 命令 + +```yaml +- name: executing remote ssh commands using password + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + password: ${{ secrets.PASSWORD }} + port: ${{ secrets.PORT }} + script: whoami +``` + +#### 使用私钥 + +```yaml +- name: executing remote ssh commands using ssh key + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: whoami +``` + +#### 多个命令 + +```yaml +- name: multiple command + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + whoami + ls -al +``` + +![result](./images/output-result.png) + +#### 从文件执行命令 + +```yaml +- name: file commands + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script_path: scripts/script.sh +``` + +#### 多台主机 + +```diff + - name: multiple host + uses: appleboy/ssh-action@v1.2.2 + with: +- host: "foo.com" ++ host: "foo.com,bar.com" + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + whoami + ls -al +``` + +默认的 `port` 值是 `22`。 + +#### 多个不同端口的主机 + +```diff + - name: multiple host + uses: appleboy/ssh-action@v1.2.2 + with: +- host: "foo.com" ++ host: "foo.com:1234,bar.com:5678" + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + script: | + whoami + ls -al +``` + +#### 在多台主机上同步执行 + +```diff + - name: multiple host + uses: appleboy/ssh-action@v1.2.2 + with: + host: "foo.com,bar.com" ++ sync: true + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + whoami + ls -al +``` + +#### 将环境变量传递到 shell 脚本 + +```diff + - name: pass environment + uses: appleboy/ssh-action@v1.2.2 ++ env: ++ FOO: "BAR" ++ BAR: "FOO" ++ SHA: ${{ github.sha }} + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} ++ envs: FOO,BAR,SHA + script: | + echo "I am $FOO" + echo "I am $BAR" + echo "sha: $SHA" +``` + +_在 `env` 对象中,您需要将每个环境变量作为字符串传递,传递 `Integer` 数据类型或任何其他类型可能会产生意外结果。_ + +#### 如何使用 `ProxyCommand` 连接远程服务器? + +```bash ++--------+ +----------+ +-----------+ +| Laptop | <--> | Jumphost | <--> | FooServer | ++--------+ +----------+ +-----------+ +``` + +在您的 `~/.ssh/config` 文件中,您会看到以下内容。 + +```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 +``` + +#### 如何将其转换为 GitHubActions 的 YAML 格式? + +```diff + - name: ssh proxy command + uses: appleboy/ssh-action@v1.2.2 + 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 +``` + +#### 保护私钥 + +密码短语通常用于加密私钥。这使得密钥文件本身对攻击者无用。文件泄露可能来自备份或停用的硬件,黑客通常可以从受攻击系统中泄露文件。 + +```diff + - name: ssh key passphrase + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} ++ passphrase: ${{ secrets.PASSPHRASE }} + script: | + whoami + ls -al +``` + +#### 使用主机指纹验证 + +设置 SSH 主机指纹验证可以帮助防止中间人攻击。在设置之前,运行以下命令以获取 SSH 主机指纹。请记得将 `ed25519` 替换为您适当的密钥类型(`rsa`、 `dsa`等),而 `example.com` 则替换为您的主机。 + +在现代 OpenSSH 版本中,默认提取的密钥类型是 `rsa`(从版本 5.1 开始)、`ecdsa`(从版本 6.0 开始)和 `ed25519`(从版本 6.7 开始)。 + +```sh +ssh example.com ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub | cut -d ' ' -f2 +``` + +现在您可以调整您的配置: + +```diff + - name: ssh key passphrase + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} ++ fingerprint: ${{ secrets.FINGERPRINT }} + script: | + whoami + ls -al +``` + +## 贡献 + +我们非常希望您为 `appleboy/ssh-action` 做出贡献,欢迎提交请求! + +## 授权方式 + +本项目中的脚本和文档采用 [MIT 许可证](LICENSE) 发布。 diff --git a/README.zh-tw.md b/README.zh-tw.md new file mode 100644 index 0000000..b2a86e9 --- /dev/null +++ b/README.zh-tw.md @@ -0,0 +1,399 @@ +# 🚀 GitHub Actions 的 SSH + +[English](./README.md) | 繁體中文 | [简体中文](./README.zh-cn.md) + +[GitHub Action](https://github.com/features/actions) 用於執行遠端 SSH 命令。 + +![ssh workflow](./images/ssh-workflow.png) + +[![testing main branch](https://github.com/appleboy/ssh-action/actions/workflows/main.yml/badge.svg)](https://github.com/appleboy/ssh-action/actions/workflows/main.yml) + +此專案使用 [Golang](https://go.dev) 和 [drone-ssh](https://github.com/appleboy/drone-ssh) 建立。🚀 + +## 輸入變數 + +請參閱 [action.yml](./action.yml) 以獲取更詳細的信息。 + +| 輸入參數 | 描述 | 預設值 | +| ------------------------- | ----------------------------------------------------- | ------ | +| host | SSH 主機地址 | | +| port | SSH 埠號 | 22 | +| passphrase | SSH 金鑰密碼 | | +| username | SSH 使用者名稱 | | +| password | SSH 密碼 | | +| protocol | SSH 協議版本 (tcp, tcp4, tcp6) | tcp | +| sync | 如果有多個主機,啟用同步執行 | false | +| use_insecure_cipher | 包含更多不安全的加密算法 | false | +| cipher | 允許的加密算法。如果未指定,則使用合理的預設值 | | +| timeout | SSH 連接主機的超時時間 | 30s | +| command_timeout | SSH 命令的超時時間 | 10m | +| key | SSH 私鑰的內容。例如,~/.ssh/id_rsa 的原始內容 | | +| key_path | SSH 私鑰的路徑 | | +| fingerprint | 主機公鑰的 SHA256 指紋 | | +| proxy_host | SSH 代理主機 | | +| proxy_port | SSH 代理埠號 | 22 | +| proxy_protocol | SSH 代理協議版本 (tcp, tcp4, tcp6) | tcp | +| proxy_username | SSH 代理使用者名稱 | | +| proxy_password | SSH 代理密碼 | | +| proxy_passphrase | SSH 代理金鑰密碼 | | +| proxy_timeout | SSH 連接代理主機的超時時間 | 30s | +| proxy_key | SSH 代理私鑰的內容 | | +| proxy_key_path | SSH 代理私鑰的路徑 | | +| proxy_fingerprint | 代理主機公鑰的 SHA256 指紋 | | +| proxy_cipher | 代理允許的加密算法 | | +| proxy_use_insecure_cipher | 包含更多不安全的加密算法 | false | +| script | 執行命令 | | +| script_path | 從文件中執行命令 | | +| envs | 將環境變數傳遞給 shell 腳本 | | +| envs_format | 環境值傳遞的靈活配置 | | +| debug | 啟用調試模式 | false | +| allenvs | 將帶有 `GITHUB_` 和 `INPUT_` 前綴的環境變數傳遞給腳本 | false | +| request_pty | 從伺服器請求偽終端 | false | + +**注意:** 用戶可以在他們的 shell 腳本中添加 `set -e` 以實現類似於已刪除的 `script_stop` 選項的功能。 + +## 用法 + +執行遠端 SSH 命令 + +```yaml +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@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: linuxserver.io + password: ${{ secrets.PASSWORD }} + port: ${{ secrets.PORT }} + script: whoami +``` + +畫面輸出 + +```sh +======CMD====== +whoami +======END====== +linuxserver.io +=============================================== +✅ Successfully executed commands to all hosts. +=============================================== +``` + +### 設置 SSH 金鑰 + +請在創建 SSH 金鑰並使用 SSH 金鑰時遵循以下步驟。最佳做法是在本地機器上創建 SSH 金鑰而不是遠端機器上。請使用 Github Secrets 中指定的用戶名登錄。生成 RSA 金鑰: + +### 生成 RSA 金鑰 + +```bash +ssh-keygen -t rsa -b 4096 -C "your_email@example.com" +``` + +### 生成 ed25519 金鑰 + +```bash +ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" +``` + +將新生成的金鑰添加到已授權的金鑰中。詳細了解已授權的金鑰請點擊[此處](https://www.ssh.com/ssh/authorized_keys/). + +### 將 RSA 金鑰添加到已授權金鑰中 + +```bash +cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys' +``` + +### 將 ed25519 金鑰添加到已授權金鑰中 + +```bash +cat .ssh/id_ed25519.pub | ssh b@B 'cat >> .ssh/authorized_keys' +``` + +複製私鑰內容,然後將其粘貼到 Github Secrets 中。 + +### 複製 rsa 私鑰內容 + +在複製私鑰之前,請按照以下說明安裝 `clip` 命令: + +```bash +# Ubuntu +sudo apt-get install xclip +``` + +複製私鑰: + +```bash +# macOS +pbcopy < ~/.ssh/id_rsa +# Ubuntu +xclip < ~/.ssh/id_rsa +``` + +從包含註釋部分 `-----BEGIN OPENSSH PRIVATE KEY-----` 開始,到包含註釋部分 `-----END OPENSSH PRIVATE KEY-----` 結束,複製私鑰並將其粘貼到 GitHub Secrets 中。 + +### 複製 ed25519 私鑰內容 + +```bash +# macOS +pbcopy < ~/.ssh/id_ed25519 +# Ubuntu +xclip < ~/.ssh/id_ed25519 +``` + +有關無需密碼登錄 SSH 的詳細信息,請[參見該網站](http://www.linuxproblem.org/art_9.html)。 + +**注意**:根據您的 SSH 版本,您可能還需要進行以下更改: + +- 將公鑰放在 `.ssh/authorized_keys2` 中 +- 將 `.ssh` 的權限更改為 700 +- 將 `.ssh/authorized_keys2` 的權限更改為 640 + +### 如果你使用的是 OpenSSH + +如果您正在使用 OpenSSH,並出現以下錯誤: + +```bash +ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey] +``` + +請確保您所選擇的密鑰演算法得到支援。在 Ubuntu 20.04 或更高版本上,您必須明確允許使用 SSH-RSA 演算法。請在 OpenSSH 守護進程文件中添加以下行(它可以是 `/etc/ssh/sshd_config` 或 `/etc/ssh/sshd_config.d/` 中的一個附著文件): + +```bash +CASignatureAlgorithms +ssh-rsa +``` + +或者,`Ed25519` 密鑰在 OpenSSH 中默認被接受。如果需要,您可以使用它來替代 RSA。 + +```bash +ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" +``` + +### Example + +#### 使用密碼執行遠端 SSH 命令 + +```yaml +- name: executing remote ssh commands using password + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + password: ${{ secrets.PASSWORD }} + port: ${{ secrets.PORT }} + script: whoami +``` + +#### 使用私鑰 + +```yaml +- name: executing remote ssh commands using ssh key + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: whoami +``` + +#### 多個命令 + +```yaml +- name: multiple command + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + whoami + ls -al +``` + +![result](./images/output-result.png) + +#### 從文件中執行命令 + +```yaml +- name: file commands + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script_path: scripts/script.sh +``` + +#### 多台主機 + +```diff + - name: multiple host + uses: appleboy/ssh-action@v1.2.2 + with: +- host: "foo.com" ++ host: "foo.com,bar.com" + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + whoami + ls -al +``` + +#### 多個不同端口的主機 + +```diff + - name: multiple host + uses: appleboy/ssh-action@v1.2.2 + with: +- host: "foo.com" ++ host: "foo.com:1234,bar.com:5678" + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + script: | + whoami + ls -al +``` + +#### 在多個主機上同步執行 + +```diff + - name: multiple host + uses: appleboy/ssh-action@v1.2.2 + with: + host: "foo.com,bar.com" ++ sync: true + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} + script: | + whoami + ls -al +``` + +#### 將環境變量傳遞到 Shell 腳本 + +```diff + - name: pass environment + uses: appleboy/ssh-action@v1.2.2 ++ env: ++ FOO: "BAR" ++ BAR: "FOO" ++ SHA: ${{ github.sha }} + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} ++ envs: FOO,BAR,SHA + script: | + echo "I am $FOO" + echo "I am $BAR" + echo "sha: $SHA" +``` + +_在 `env` 對象中,您需要將每個環境變量作為字符串傳遞,傳遞 `Integer` 數據類型或任何其他類型可能會產生意外結果。_ + +#### 如何使用 `ProxyCommand` 連接遠程服務器? + +```bash ++--------+ +----------+ +-----------+ +| Laptop | <--> | Jumphost | <--> | FooServer | ++--------+ +----------+ +-----------+ +``` + +在您的 `~/.ssh/config` 文件中,您會看到以下內容。 + +```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 +``` + +#### 如何將其轉換為 GitHubActions 的 YAML 格式? + +```diff + - name: ssh proxy command + uses: appleboy/ssh-action@v1.2.2 + 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 +``` + +#### 如何保護私鑰? + +密碼短語通常用於加密私鑰。這使得攻擊者無法單獨使用密鑰文件。文件泄露可能來自備份或停用的硬件,黑客通常可以從受攻擊系統中洩露文件。因此,保護私鑰非常重要。 + +```diff + - name: ssh key passphrase + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} ++ passphrase: ${{ secrets.PASSPHRASE }} + script: | + whoami + ls -al +``` + +#### 使用主機指紋驗證 + +設置 SSH 主機指紋驗證可以幫助防止中間人攻擊。在設置之前,運行以下命令以獲取 SSH 主機指紋。請記得將 `ed25519` 替換為您的適當金鑰類型(`rsa`、 `dsa`等),而 `example.com` 則替換為您的主機。 + +現代 OpenSSH 版本中,需要提取的**默認金鑰**類型是 `rsa`(從版本 5.1 開始)、`ecdsa`(從版本 6.0 開始)和 `ed25519`(從版本 6.7 開始)。 + +```sh +ssh example.com ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub | cut -d ' ' -f2 +``` + +現在您可以調整您的配置: + +```diff + - name: ssh key passphrase + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + port: ${{ secrets.PORT }} ++ fingerprint: ${{ secrets.FINGERPRINT }} + script: | + whoami + ls -al +``` + +## 貢獻 + +我們非常希望您為 `appleboy/ssh-action` 做出貢獻,歡迎提交請求! + +## 授權方式 + +本項目中的腳本和文檔采用 [MIT](LICENSE) 許可證 發布。 diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..c3af2a4 --- /dev/null +++ b/action.yml @@ -0,0 +1,137 @@ +name: "SSH Remote Commands" +description: "Executing remote ssh commands" +author: "Bo-Yi Wu" +inputs: + host: + description: "SSH host address or IP to connect to." + port: + description: "SSH port number for the connection." + default: "22" + passphrase: + description: "Passphrase to decrypt the SSH private key if protected." + username: + description: "SSH username for authentication on the remote server." + password: + description: "SSH password for authentication (use secrets for sensitive data)." + protocol: + description: 'IP protocol version to use. Options: "tcp" (default), "tcp4" (IPv4 only), or "tcp6" (IPv6 only).' + default: "tcp" + sync: + description: "When true, executes commands synchronously across multiple hosts (one after another)." + use_insecure_cipher: + description: "Enable additional legacy ciphers that might be less secure but more compatible with older systems." + cipher: + description: "Specify custom cipher algorithms for encryption. Leave empty to use secure defaults." + timeout: + description: "Maximum time to wait when establishing the SSH connection, e.g., '30s', '1m'." + default: "30s" + command_timeout: + description: "Maximum execution time for the remote commands before terminating, e.g., '10m', '1h'." + default: "10m" + key: + description: "Raw content of the SSH private key for authentication (use secrets for sensitive data)." + key_path: + description: "Path to the SSH private key file on the runner." + fingerprint: + description: "SHA256 fingerprint of the host public key for verification to prevent MITM attacks." + proxy_host: + description: "Proxy server hostname or IP if connecting through an SSH jump host." + proxy_port: + description: "SSH port number for the proxy connection." + default: "22" + proxy_username: + description: "Username for authentication on the proxy server." + proxy_password: + description: "Password for authentication on the proxy server (use secrets for sensitive data)." + proxy_protocol: + description: 'IP protocol version for proxy. Options: "tcp" (default), "tcp4" (IPv4 only), or "tcp6" (IPv6 only).' + default: "tcp" + proxy_passphrase: + description: "Passphrase to decrypt the proxy SSH private key if protected." + proxy_timeout: + description: "Maximum time to wait when establishing the proxy SSH connection, e.g., '30s', '1m'." + default: "30s" + proxy_key: + description: "Raw content of the SSH proxy private key for authentication (use secrets for sensitive data)." + proxy_key_path: + description: "Path to the SSH proxy private key file on the runner." + proxy_fingerprint: + description: "SHA256 fingerprint of the proxy host public key for verification." + proxy_cipher: + description: "Specify custom cipher algorithms for proxy connection encryption." + proxy_use_insecure_cipher: + description: "Enable additional legacy ciphers for proxy connections (less secure but more compatible)." + script: + description: "Commands to execute on the remote server (inline script string)." + script_path: + description: "Path to a local file containing commands to execute on the remote server." + envs: + description: "Environment variables to expose to the remote script, format: key=value,key2=value2." + envs_format: + description: "Format specification for environment variable transfer (for advanced usage)." + debug: + description: "Set to true to enable verbose logging for troubleshooting connection issues." + allenvs: + description: "When true, passes all GitHub Actions environment variables to the remote script." + request_pty: + description: "Request a pseudo-terminal from the server (required for interactive commands or sudo)." + capture_stdout: + description: "When true, captures and returns standard output from the commands as action output." + default: "false" + +outputs: + stdout: + description: "Standard output of the executed commands when capture_stdout is enabled." + value: ${{ steps.entrypoint.outputs.stdout }} + +runs: + using: "composite" + steps: + - name: Set GitHub Path + run: echo "$GITHUB_ACTION_PATH" >> $GITHUB_PATH + shell: bash + env: + GITHUB_ACTION_PATH: ${{ github.action_path }} + - id: entrypoint + name: Run entrypoint.sh + run: entrypoint.sh + shell: bash + env: + GITHUB_ACTION_PATH: ${{ github.action_path }} + INPUT_HOST: ${{ inputs.host }} + INPUT_PORT: ${{ inputs.port }} + INPUT_PROTOCOL: ${{ inputs.protocol }} + INPUT_USERNAME: ${{ inputs.username }} + INPUT_PASSWORD: ${{ inputs.password }} + INPUT_PASSPHRASE: ${{ inputs.passphrase }} + INPUT_KEY: ${{ inputs.key }} + INPUT_KEY_PATH: ${{ inputs.key_path }} + INPUT_FINGERPRINT: ${{ inputs.fingerprint }} + INPUT_PROXY_HOST: ${{ inputs.proxy_host }} + INPUT_PROXY_PORT: ${{ inputs.proxy_port }} + INPUT_PROXY_USERNAME: ${{ inputs.proxy_username }} + INPUT_PROXY_PASSWORD: ${{ inputs.proxy_password }} + INPUT_PROXY_PASSPHRASE: ${{ inputs.proxy_passphrase }} + INPUT_PROXY_KEY: ${{ inputs.proxy_key }} + INPUT_PROXY_KEY_PATH: ${{ inputs.proxy_key_path }} + INPUT_PROXY_FINGERPRINT: ${{ inputs.proxy_fingerprint }} + INPUT_TIMEOUT: ${{ inputs.timeout }} + INPUT_PROXY_TIMEOUT: ${{ inputs.proxy_timeout }} + INPUT_COMMAND_TIMEOUT: ${{ inputs.command_timeout }} + INPUT_SCRIPT: ${{ inputs.script }} + INPUT_SCRIPT_FILE: ${{ inputs.script_path }} + INPUT_ENVS: ${{ inputs.envs }} + INPUT_ENVS_FORMAT: ${{ inputs.envs_format }} + INPUT_DEBUG: ${{ inputs.debug }} + INPUT_ALL_ENVS: ${{ inputs.allenvs }} + INPUT_REQUEST_PTY: ${{ inputs.request_pty }} + INPUT_USE_INSECURE_CIPHER: ${{ inputs.use_insecure_cipher }} + INPUT_CIPHER: ${{ inputs.cipher }} + INPUT_PROXY_USE_INSECURE_CIPHER: ${{ inputs.proxy_use_insecure_cipher }} + INPUT_PROXY_CIPHER: ${{ inputs.proxy_cipher }} + INPUT_SYNC: ${{ inputs.sync }} + INPUT_CAPTURE_STDOUT: ${{ inputs.capture_stdout }} + +branding: + icon: "terminal" + color: "gray-dark" diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..17dbeda --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +export GITHUB="true" + +GITHUB_ACTION_PATH="${GITHUB_ACTION_PATH%/}" +DRONE_SSH_RELEASE_URL="${DRONE_SSH_RELEASE_URL:-https://github.com/appleboy/drone-ssh/releases/download}" +DRONE_SSH_VERSION="${DRONE_SSH_VERSION:-1.8.1}" + +function detect_client_info() { + if [ -n "${SSH_CLIENT_OS-}" ]; then + CLIENT_PLATFORM="${SSH_CLIENT_OS}" + else + local kernel + kernel="$(uname -s)" + case "${kernel}" in + Darwin) + CLIENT_PLATFORM="darwin" + ;; + Linux) + CLIENT_PLATFORM="linux" + ;; + Windows) + CLIENT_PLATFORM="windows" + ;; + *) + echo "Unknown, unsupported platform: ${kernel}." >&2 + echo "Supported platforms: Linux, Darwin and Windows." >&2 + echo "Bailing out." >&2 + exit 2 + ;; + esac + fi + + if [ -n "${SSH_CLIENT_ARCH-}" ]; then + CLIENT_ARCH="${SSH_CLIENT_ARCH}" + else + local machine + machine="$(uname -m)" + case "${machine}" in + x86_64* | i?86_64* | amd64*) + CLIENT_ARCH="amd64" + ;; + aarch64* | arm64*) + CLIENT_ARCH="arm64" + ;; + *) + echo "Unknown, unsupported architecture (${machine})." >&2 + echo "Supported architectures x86_64, i686, arm64." >&2 + echo "Bailing out." >&2 + exit 3 + ;; + esac + fi +} + +detect_client_info +DOWNLOAD_URL_PREFIX="${DRONE_SSH_RELEASE_URL}/v${DRONE_SSH_VERSION}" +CLIENT_BINARY="drone-ssh-${DRONE_SSH_VERSION}-${CLIENT_PLATFORM}-${CLIENT_ARCH}" +TARGET="${GITHUB_ACTION_PATH}/${CLIENT_BINARY}" +echo "Will download ${CLIENT_BINARY} from ${DOWNLOAD_URL_PREFIX}" +curl -fsSL --retry 5 --keepalive-time 2 "${DOWNLOAD_URL_PREFIX}/${CLIENT_BINARY}" -o ${TARGET} +chmod +x ${TARGET} + +echo "======= CLI Version =======" +sh -c "${TARGET} --version" # print version +echo "===========================" +if [[ "$INPUT_CAPTURE_STDOUT" == 'true' ]]; then + echo 'stdout<>$GITHUB_OUTPUT # use heredoc for multiline output + sh -c "${TARGET} $*" | tee -a $GITHUB_OUTPUT # run the command + echo 'EOF' >>$GITHUB_OUTPUT +else + sh -c "${TARGET} $*" # run the command +fi diff --git a/images/output-result.png b/images/output-result.png new file mode 100644 index 0000000..7b453ee Binary files /dev/null and b/images/output-result.png differ diff --git a/images/ssh-workflow.png b/images/ssh-workflow.png new file mode 100644 index 0000000..9f2b541 Binary files /dev/null and b/images/ssh-workflow.png differ diff --git a/testdata/.ssh/id_ed25519 b/testdata/.ssh/id_ed25519 new file mode 100644 index 0000000..9dc32bb --- /dev/null +++ b/testdata/.ssh/id_ed25519 @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACDoi7FltQCqpWporKh61nJUPIeazUYdzdstncoeU5XS2AAAAKBF5e2SReXt +kgAAAAtzc2gtZWQyNTUxOQAAACDoi7FltQCqpWporKh61nJUPIeazUYdzdstncoeU5XS2A +AAAEBrsLG1vSg08yaQgYM46KQW93Lz2ZikS1tTMH35gfHhpOiLsWW1AKqlamisqHrWclQ8 +h5rNRh3N2y2dyh5TldLYAAAAFnlvdXJfZW1haWxAZXhhbXBsZS5jb20BAgMEBQYH +-----END OPENSSH PRIVATE KEY----- diff --git a/testdata/.ssh/id_ed25519.pub b/testdata/.ssh/id_ed25519.pub new file mode 100644 index 0000000..14f2085 --- /dev/null +++ b/testdata/.ssh/id_ed25519.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOiLsWW1AKqlamisqHrWclQ8h5rNRh3N2y2dyh5TldLY your_email@example.com diff --git a/testdata/.ssh/id_passphrase b/testdata/.ssh/id_passphrase new file mode 100644 index 0000000..089d425 --- /dev/null +++ b/testdata/.ssh/id_passphrase @@ -0,0 +1,39 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +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 +h55pSap77CEhEhE5FPZKuH9f7/E= +-----END OPENSSH PRIVATE KEY----- diff --git a/testdata/.ssh/id_passphrase.pub b/testdata/.ssh/id_passphrase.pub new file mode 100644 index 0000000..1d84832 --- /dev/null +++ b/testdata/.ssh/id_passphrase.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCuWKQh09Vlv3IRu/+oK18ws72VQS7PCXJaIEp1L+7HqC/6+plizaVgd9SjAg0UJSqvp+WfpU5I53hevE0Ip3s71Tsoeu1azWoi2Mbq3ycZ5ysh4htZZklKBkYsyW+2EdITPcmhA8rF+KiDRyuvk7fDo08G3YWgbCScY6VkLA06ReThCehAY54WNvgbx7lyvCWj1qYG0XjM7mTQHr3QN0JHJNdFaG3MCi1rTG2hK/owOlzcesIbzfM1VMIQG5HT4vNg/ULP0BTZ7pGtdvWlvR/660KQwc1tBxLqxI1dYoCgiS/gMyPxhOtNKTvhR/NR7e2sp/StkXURIxTHhj0KjKbnpXTQ2IndnesHAG9kDJ7c31SXastWpbXWhCIdRZk+KQsnmwobZlw3w1vfx2Dm7M2ZCcCgG/ArUPjY44nGOWO5Nz98QHyz3IocsKJXrGVo/3YpNNu72jkw7UGVMqh1dAe3ZMaCAC5pAAa0HKvkid7jdXawL2b//+vsAPSHdnEjP58= mtk10671@NB22040567 diff --git a/testdata/.ssh/id_rsa b/testdata/.ssh/id_rsa new file mode 100644 index 0000000..6270f55 --- /dev/null +++ b/testdata/.ssh/id_rsa @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA4e2D/qPN08pzTac+a8ZmlP1ziJOXk45CynMPtva0rtK/RB26 +VbfAF0hIJji7ltvnYnqCU9oFfvEM33cTn7T96+od8ib/Vz25YU8ZbstqtIskPuwC +bv3K0mAHgsviJyRD7yM+QKTbBQEgbGuW6gtbMKhiYfiIB4Dyj7AdS/fk3v26wDgz +7SHI5OBqu9bv1KhxQYdFEnU3PAtAqeccgzNpbH3eYLyGzuUxEIJlhpZ/uU2G9ppj +/cSrONVPiI8Ahi4RrlZjmP5l57/sq1ClGulyLpFcMw68kP5FikyqHpHJHRBNgU57 +1y0Ph33SjBbs0haCIAcmreWEhGe+/OXnJe6VUQIDAQABAoIBAH97emORIm9DaVSD +7mD6DqA7c5m5Tmpgd6eszU08YC/Vkz9oVuBPUwDQNIX8tT0m0KVs42VVPIyoj874 +bgZMJoucC1G8V5Bur9AMxhkShx9g9A7dNXJTmsKilRpk2TOk7wBdLp9jZoKoZBdJ +jlp6FfaazQjjKD6zsCsMATwAoRCBpBNsmT6QDN0n0bIgY0tE6YGQaDdka0dAv68G +R0VZrcJ9voT6+f+rgJLoojn2DAu6iXaM99Gv8FK91YCymbQlXXgrk6CyS0IHexN7 +V7a3k767KnRbrkqd3o6JyNun/CrUjQwHs1IQH34tvkWScbseRaFehcAm6mLT93RP +muauvMECgYEA9AXGtfDMse0FhvDPZx4mx8x+vcfsLvDHcDLkf/lbyPpu97C27b/z +ia07bu5TAXesUZrWZtKA5KeRE5doQSdTOv1N28BEr8ZwzDJwfn0DPUYUOxsN2iIy +MheO5A45Ko7bjKJVkZ61Mb1UxtqCTF9mqu9R3PBdJGthWOd+HUvF460CgYEA7QRf +Z8+vpGA+eSuu29e0xgRKnRzed5zXYpcI4aERc3JzBgO4Z0er9G8l66OWVGdMfpe6 +CBajC5ToIiT8zqoYxXwqJgN+glir4gJe3mm8J703QfArZiQrdk0NTi5bY7+vLLG/ +knTrtpdsKih6r3kjhuPPaAsIwmMxIydFvATKjLUCgYEAh/y4EihRSk5WKC8GxeZt +oiZ58vT4z+fqnMIfyJmD5up48JuQNcokw/LADj/ODiFM7GUnWkGxBrvDA3H67WQm +49bJjs8E+BfUQFdTjYnJRlpJZ+7Zt1gbNQMf5ENw5CCchTDqEq6pN0DVf8PBnSIF +KvkXW9KvdV5J76uCAn15mDkCgYA1y8dHzbjlCz9Cy2pt1aDfTPwOew33gi7U3skS +RTerx29aDyAcuQTLfyrROBkX4TZYiWGdEl5Bc7PYhCKpWawzrsH2TNa7CRtCOh2E +R+V/84+GNNf04ALJYCXD9/ugQVKmR1XfDRCvKeFQFE38Y/dvV2etCswbKt5tRy2p +xkCe/QKBgQCkLqafD4S20YHf6WTp3jp/4H/qEy2X2a8gdVVBi1uKkGDXr0n+AoVU +ib4KbP5ovZlrjL++akMQ7V2fHzuQIFWnCkDA5c2ZAqzlM+ZN+HRG7gWur7Bt4XH1 +7XC9wlRna4b3Ln8ew3q1ZcBjXwD4ppbTlmwAfQIaZTGJUgQbdsO9YA== +-----END RSA PRIVATE KEY----- diff --git a/testdata/.ssh/id_rsa.pub b/testdata/.ssh/id_rsa.pub new file mode 100644 index 0000000..2983f04 --- /dev/null +++ b/testdata/.ssh/id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDh7YP+o83TynNNpz5rxmaU/XOIk5eTjkLKcw+29rSu0r9EHbpVt8AXSEgmOLuW2+dieoJT2gV+8QzfdxOftP3r6h3yJv9XPblhTxluy2q0iyQ+7AJu/crSYAeCy+InJEPvIz5ApNsFASBsa5bqC1swqGJh+IgHgPKPsB1L9+Te/brAODPtIcjk4Gq71u/UqHFBh0USdTc8C0Cp5xyDM2lsfd5gvIbO5TEQgmWGln+5TYb2mmP9xKs41U+IjwCGLhGuVmOY/mXnv+yrUKUa6XIukVwzDryQ/kWKTKoekckdEE2BTnvXLQ+HfdKMFuzSFoIgByat5YSEZ7785ecl7pVR drone-scp@localhost diff --git a/testdata/.ssh/test b/testdata/.ssh/test new file mode 100644 index 0000000..89cc6ec --- /dev/null +++ b/testdata/.ssh/test @@ -0,0 +1,50 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +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 +l4njcaMpg4tpQMHtCBOicGyV0= +-----END OPENSSH PRIVATE KEY----- diff --git a/testdata/.ssh/test.pub b/testdata/.ssh/test.pub new file mode 100644 index 0000000..559daf2 --- /dev/null +++ b/testdata/.ssh/test.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDz6aZ1jY2onnuj2YNHJ/HhfvIu0B973v/+pFFOavnTUOhEEKEy3TASu+s9CkHrYZAtRc+QYIkNZI31mhHBhotdeP/7GoO2UirkFtrzyQKPNJxEcv0RBoG9ssN8jex0PyK6DHIYYFnIWadVBEEOh/H+rK7j7u2/big3oTzYBuFrCwmYFcz5na99MzFeAUhazF44gVBma+zO+1quGeqF51UDIg1SMGvX8I7LNEqrKEBaIUQJKFQcxlOWlRLQsjJCymrOujsXsRrXHAQWcnxDcNevv2ZMOUl0ybvv9yH0BiGbRBd1Hy8/QPILbAQaqu0oQE7fubN8Q8lqb3Jg0loID4x/5GPhSY8WAXpuLcXTOrb93SnCw1JsAgJDNqpuuRFy3BSZ7wBOr1jfeIoo7xk14OHiUjJ0uXDL9cLMkcw6ElWz81mrD2VCkXUz+qFyjJ+G7aGWRtctZoOzKln4yfNfUmwW8/8ra3QnmrMZ2xW2Ylw3ZhO+tLi7jINHYFb54bAdLVPUU1ctIuJns2qkWnjJCxxMiynIqCif20/OU1n8CTJuOWiURmRdmvKOH4PE3JxC2Qnk/3tV3Cf8hp1CH5VjBZ9AjGj5MDMHXyu34VY2WvYo5QyzfS3ySPoT8kCO0G0xpvjwCMHOK+G2RP4kqb/KKZguiKdgintBXuskTlJmD7kcMQ== deploy@easyssh diff --git a/testdata/test.sh b/testdata/test.sh new file mode 100644 index 0000000..a229cae --- /dev/null +++ b/testdata/test.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -e +whoami