This action installs SSH key in ~/.ssh
.
Useful for SCP, SFTP, and rsync
over SSH in deployment script.
tested on:
- all available virtual machines (Windows Server 2022/2019, macOS Monterey/Big Sur, and Ubuntu 22.04/20.04)
- Docker container (Ubuntu) / requires
openssh-client
package;apt install -y openssh-client
- Docker container (CentOS) / requires
openssh-clients
package;yum install -y openssh-clients
- Docker container (Alpine Linux) / requires
openssh-client
package;apk add openssh-client
Add your SSH key to your product secrets by clicking Settings
- Secrets
- Add a new secret
beforehand.
PEM(RSA), PKCS8, and RFC4716(OpenSSH) formats are OK.
runs-on: ubuntu-latest
steps:
- name: Install SSH key
uses: step-security/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY }}
name: id_rsa # optional
known_hosts: ${{ secrets.KNOWN_HOSTS }}
config: ${{ secrets.CONFIG }} # ssh_config; optional
if_key_exists: fail # replace / ignore / fail; optional (defaults to fail)
- name: rsync over SSH
run: rsync -r ./foo/ user@remote:bar/
See Workflow syntax for GitHub Actions for details.
NOTE:
- Server key of
github.com
will be always set toknown_hosts
. - SSH keys will be removed at the end of workflow.
If you want to install multiple keys, call this action multiple times. It is useful for port forwarding.
NOTE: When this action is called multiple times, the contents of known_hosts
and config
will be appended. key
must be saved as different name, by using name
option.
runs-on: ubuntu-latest
steps:
- name: Install SSH key of bastion
uses: step-security/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY_OF_BASTION }}
name: id_rsa-bastion
known_hosts: ${{ secrets.KNOWN_HOSTS_OF_BASTION }}
config: |
Host bastion
HostName xxx.xxx.xxx.xxx
User user-of-bastion
IdentityFile ~/.ssh/id_rsa-bastion
- name: Install SSH key of target
uses: step-security/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY_OF_TARGET }}
name: id_rsa-target
known_hosts: ${{ secrets.KNOWN_HOSTS_OF_TARGET }} # will be appended to existing .ssh/known_hosts
config: | # will be appended to existing .ssh/config
Host target
HostName yyy.yyy.yyy.yyy
User user-of-target
IdentityFile ~/.ssh/id_rsa-target
ProxyCommand ssh -W %h:%p bastion
- name: SCP via port-forwarding
run: scp ./foo/ target:bar/
Check below:
Host key verification failed.
:- Set
known_hosts
parameter correctly (usessh-keyscan
command).
- Set
Use if_key_exists
parameter.
replace
: replaces keyignore
: does nothingfail
: fails (default)
This action doesn't support encrypted key directly. Here are some solutions:
- decrypting key beforehand: best bet, and works on any VM
sshpass
command: next best bet, but not supported on Windowsexpect
command: be careful not to expose passphrase to consoleSSH_ASKPASS
environment variable: might be troublesome
Which one is the best way for transferring files, "direct SCP/SFTP/rsync" or "SCP/SFTP/rsync via bastion"?
I recommend rsync via bastion.
rsync -r -e "ssh bastion ssh" ./foo/ target:bar/
It has some advantages over other methods:
- "Rsync via bastion" doesn't require to update workflow files and
secrets
even if it is necessary to transfer files to multiple servers.- Other methods require to update
known_hosts
if servers have changed.
- Other methods require to update
- Rsync:
- is fastest of all.
- does NOT break files even if disconnected during transferring.
- can remove files that don't exist on server.
- SCP is deprecated by OpenSSH due to outdated and inflexible protocol.
- Using bastion is more secure because:
- it is not necessarily to expose SSH port on servers to public.
- Address filtering is less effective.
- Because Azure address range is very wide.
- And will be updated continuously.
- if security incident ―e.g., private key leaked― occurs, it's OK just to remove
authorized_keys
on bastion.
- it is not necessarily to expose SSH port on servers to public.
First of all, you have to understand that it is NOT secure to SSH with no known_hosts
and using StrictHostKeyChecking=no
option.
Why do you want to omit it?
If the reason is "I'm not understanding about the function of known_hosts
" or "It's bother to fetch server key", you should not omit.
If "It is hard to prefetch server key because the server will be created dynamically", you can use bastion server.
"known_hosts
is unnecessary because I'm using secure method for SSH, such as SSHFP and signed server key." — OK, here is a special value to omit known_hosts
.
You should use it ONLY IF you are using secure methods...
It is known_hosts: unnecessary
.
The scripts and documentation in this project are released under the MIT License