Compare commits
	
		
			128 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 25ce8cbbcb | ||
|   | 58164d0dc2 | ||
|   | d732991ab0 | ||
|   | b4a07ca594 | ||
|   | eaeb06998d | ||
|   | 06fa62e61c | ||
|   | 28428a13f5 | ||
|   | 5ade826485 | ||
|   | 8b6078208d | ||
|   | 036cad7df7 | ||
|   | 71d43ea0f7 | ||
|   | 43895f2cd5 | ||
|   | b6941ae5d5 | ||
|   | 0c7561b1a3 | ||
|   | 5a8776fd15 | ||
|   | 97f8d752b5 | ||
|   | 9c32aa61f8 | ||
|   | f0e5a23d53 | ||
|   | fc1c1fce51 | ||
|   | aa293c24bb | ||
|   | 378323e4c8 | ||
|   | 815c5743ac | ||
|   | a39b3cce7d | ||
|   | 15b64dc891 | ||
|   | e40b597081 | ||
|   | f05aefe351 | ||
|   | acd41e5091 | ||
|   | da612c8015 | ||
|   | 2eeab5bdba | ||
|   | 977b74a12d | ||
|   | 0b0e77098a | ||
|   | 40aad53c5a | ||
|   | c8594ae37d | ||
|   | aabaf1254d | ||
|   | f916346256 | ||
|   | 551964ebda | ||
|   | d2d6858859 | ||
|   | dd0f09ca07 | ||
|   | 1991c553ec | ||
|   | fe44be0b96 | ||
|   | c78141851a | ||
|   | 8a779a5b1a | ||
|   | 9b978f09f2 | ||
|   | 029f5b4aee | ||
|   | d134a26a1f | ||
|   | 2451745138 | ||
|   | 1f3c338936 | ||
|   | 8f94919856 | ||
|   | 2344d97573 | ||
|   | b9f6bf6223 | ||
|   | 4330a1ea48 | ||
|   | 55dabf81b4 | ||
|   | 8d9094f3b1 | ||
|   | 5ac43dd762 | ||
|   | a01d3ea1df | ||
|   | c7d850f6cd | ||
|   | f579d71942 | ||
|   | d87d276960 | ||
|   | 3130c7a2bc | ||
|   | 2b7de38eed | ||
|   | 334f9259f2 | ||
|   | 6268c80dd6 | ||
|   | 5f64c95280 | ||
|   | 3cd1bcf771 | ||
|   | 6a1b59d972 | ||
|   | e4a881008d | ||
|   | 51b83ba474 | ||
|   | 495830820f | ||
|   | b601429988 | ||
|   | ae2bb3c3dc | ||
|   | 7bf58514db | ||
|   | c1965ddd25 | ||
|   | d91a1af6f5 | ||
|   | 4a03da89e5 | ||
|   | 0d5a3d0e48 | ||
|   | db9be1d5f2 | ||
|   | 9a7da95c8c | ||
|   | f23dd5c681 | ||
|   | cc051b07ed | ||
|   | f9010ff7f1 | ||
|   | e1116226a0 | ||
|   | a8d82ec39b | ||
|   | f82e23f1a3 | ||
|   | ed1f3fc7c1 | ||
|   | dce9d565de | ||
|   | ea5c23a2b5 | ||
|   | c732d38392 | ||
|   | ba1d4fb0eb | ||
|   | c7671d858f | ||
|   | 1a8b3784ea | ||
|   | 29007ce6fb | ||
|   | e59c0ee97a | ||
|   | c7104ccac4 | ||
|   | 63dd9dd662 | ||
|   | 61e292b601 | ||
|   | 1d1b21ca96 | ||
|   | 9fb11fb1f5 | ||
|   | fd39ef0f18 | ||
|   | ffff33f8fe | ||
|   | 8bd4933b73 | ||
|   | bf84735fa9 | ||
|   | d09b6e0211 | ||
|   | 3ac4675689 | ||
|   | 269a4479eb | ||
|   | a2f91cbad1 | ||
|   | e2cbea5f00 | ||
|   | 5711a203b3 | ||
|   | b315fb5f98 | ||
|   | 682eb0ddda | ||
|   | 03b440e441 | ||
|   | 1cb5cd31c9 | ||
|   | c9eebc1cde | ||
|   | 6b00175bad | ||
|   | a912e225ec | ||
|   | ad6643f705 | ||
|   | 26dd2b3a38 | ||
|   | 122f35dca5 | ||
|   | 03b5d10ad6 | ||
|   | fcfb760891 | ||
|   | fd81fae289 | ||
|   | 242a8e2e57 | ||
|   | cfe9c45db6 | ||
|   | 73767290ca | ||
|   | e5c07fceef | ||
|   | d690bdebf8 | ||
|   | f478af9b34 | ||
|   | d520c19f4f | ||
|   | 0dee98b334 | 
							
								
								
									
										13
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| # These are supported funding model platforms | ||||
|  | ||||
| github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] | ||||
| patreon: # Replace with a single Patreon username | ||||
| open_collective: ssh-action | ||||
| ko_fi: # Replace with a single Ko-fi username | ||||
| tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel | ||||
| community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry | ||||
| liberapay: # Replace with a single Liberapay username | ||||
| issuehunt: # Replace with a single IssueHunt username | ||||
| otechie: # Replace with a single Otechie username | ||||
| lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry | ||||
| custom: ['https://www.paypal.me/appleboy46'] | ||||
							
								
								
									
										43
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| --- | ||||
| name: Bug report | ||||
| about: Create a report to help us improve | ||||
| title: '' | ||||
| labels: bug | ||||
| assignees: appleboy | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## Describe the bug | ||||
|  | ||||
| A clear and concise description of what the bug is. If applicable, add screenshots to help explain your problem. | ||||
|  | ||||
| ## Yaml Config | ||||
|  | ||||
| Please post your Yaml configuration file along with the output results. | ||||
|  | ||||
| ```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.0.3 | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         password: ${{ secrets.PASSWORD }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script: whoami | ||||
| ``` | ||||
|  | ||||
| ## Related environment | ||||
|  | ||||
| Please provide the following information: | ||||
|  | ||||
| 1. Your hosting provider information, such as DigitalOcean, Linode, AWS, or GCP. | ||||
| 2. The version information of your host's SSH service. | ||||
| 3. The information from your host's SSH configuration file. | ||||
							
								
								
									
										62
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										62
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,62 +0,0 @@ | ||||
| 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 | ||||
|  | ||||
|     - 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 | ||||
|  | ||||
|     - 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 | ||||
|  | ||||
|     # - 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 | ||||
|  | ||||
|     - name: pass environment | ||||
|       uses: appleboy/ssh-action@master | ||||
|       env: | ||||
|         FOO: "BAR" | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         envs: FOO | ||||
|         script: | | ||||
|           echo "I am $FOO, thanks" | ||||
|           echo "I am $BAR, thanks" | ||||
							
								
								
									
										33
									
								
								.github/workflows/goreleaser.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								.github/workflows/goreleaser.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| name: Goreleaser | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     tags: | ||||
|       - "*" | ||||
|  | ||||
| permissions: | ||||
|   contents: write | ||||
|  | ||||
| jobs: | ||||
|   goreleaser: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v4 | ||||
|         with: | ||||
|           fetch-depth: 0 | ||||
|  | ||||
|       - name: Setup go | ||||
|         uses: actions/setup-go@v5 | ||||
|         with: | ||||
|           go-version: "^1" | ||||
|  | ||||
|       - name: Run GoReleaser | ||||
|         uses: goreleaser/goreleaser-action@v6 | ||||
|         with: | ||||
|           # either 'goreleaser' (default) or 'goreleaser-pro' | ||||
|           distribution: goreleaser | ||||
|           version: latest | ||||
|           args: release --clean | ||||
|         env: | ||||
|           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||
							
								
								
									
										513
									
								
								.github/workflows/main.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										513
									
								
								.github/workflows/main.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,513 @@ | ||||
| name: testing main branch | ||||
|  | ||||
| on: [push] | ||||
|  | ||||
| jobs: | ||||
|   default-user-name-password: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server \ | ||||
|           --hostname=openssh-server \ | ||||
|           -p 2222:2222 \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server sh -c "hostname -i" > ip.txt | ||||
|           echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV | ||||
|           cat ip.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip.txt | ||||
|           echo "======================================" | ||||
|           sleep 2 | ||||
|  | ||||
|       - name: ssh by username and password | ||||
|         uses: ./ | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           password: password | ||||
|           port: 2222 | ||||
|           script: whoami | ||||
|  | ||||
|   check-ssh-key: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: add public key to env | ||||
|         run: | | ||||
|           echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_rsa.pub >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= public key =========" | ||||
|           cat testdata/.ssh/id_rsa.pub | ||||
|           echo "============================" | ||||
|           echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_rsa >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= private key =========" | ||||
|           cat testdata/.ssh/id_rsa | ||||
|           echo "============================" | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server \ | ||||
|           --hostname=openssh-server \ | ||||
|           -p 2222:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server sh -c "hostname -i" > ip.txt | ||||
|           echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV | ||||
|           cat ip.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip.txt | ||||
|           echo "======================================" | ||||
|           sleep 2 | ||||
|  | ||||
|       - name: ssh by private key | ||||
|         uses: ./ | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script: whoami | ||||
|  | ||||
|       - name: wrong password but correct key | ||||
|         uses: ./ | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           password: "abcdef" | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script: whoami | ||||
|  | ||||
|       - name: correct password but wrong key | ||||
|         uses: ./ | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           password: password | ||||
|           key: password | ||||
|           port: 2222 | ||||
|           script: whoami | ||||
|  | ||||
|       - name: stop script if command error | ||||
|         uses: ./ | ||||
|         continue-on-error: true | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           password: password | ||||
|           key: password | ||||
|           port: 2222 | ||||
|           script_stop: true | ||||
|           sync: true | ||||
|           debug: true | ||||
|           script: | | ||||
|             mkdir abc/def | ||||
|             ls -al | ||||
|  | ||||
|   support-key-passphrase: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: add public key to env | ||||
|         run: | | ||||
|           echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_passphrase.pub >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= public key =========" | ||||
|           cat testdata/.ssh/id_passphrase.pub | ||||
|           echo "============================" | ||||
|           echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_passphrase >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= private key =========" | ||||
|           cat testdata/.ssh/id_passphrase | ||||
|           echo "============================" | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server \ | ||||
|           --hostname=openssh-server \ | ||||
|           -p 2222:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server sh -c "hostname -i" > ip.txt | ||||
|           echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV | ||||
|           cat ip.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip.txt | ||||
|           echo "======================================" | ||||
|           sleep 2 | ||||
|  | ||||
|       - name: ssh key passphrase | ||||
|         uses: ./ | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           passphrase: 1234 | ||||
|           script: | | ||||
|             whoami | ||||
|             ls -al | ||||
|  | ||||
|       - name: missing ssh key passphrase | ||||
|         uses: ./ | ||||
|         continue-on-error: true | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script: | | ||||
|             whoami | ||||
|             ls -al | ||||
|  | ||||
|       # https://github.com/appleboy/ssh-action/issues/75#issuecomment-668314271 | ||||
|       - name: Multiline SSH commands interpreted as single lines | ||||
|         uses: ./ | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           passphrase: 1234 | ||||
|           script_stop: true | ||||
|           script: | | ||||
|             ls \ | ||||
|               -lah | ||||
|           use_insecure_cipher: true | ||||
|  | ||||
|   multiple-server: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: add public key to env | ||||
|         run: | | ||||
|           echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_passphrase.pub >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= public key =========" | ||||
|           cat testdata/.ssh/id_passphrase.pub | ||||
|           echo "============================" | ||||
|           echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_passphrase >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= private key =========" | ||||
|           cat testdata/.ssh/id_passphrase | ||||
|           echo "============================" | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server-01 \ | ||||
|           --hostname=openssh-server-01 \ | ||||
|           -p 2222:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server-01 sh -c "hostname -i" > ip01.txt | ||||
|           echo "REMOTE_HOST_01<<EOF" >> $GITHUB_ENV | ||||
|           cat ip01.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip01.txt | ||||
|           echo "======================================" | ||||
|  | ||||
|           docker run -d \ | ||||
|           --name=openssh-server-02 \ | ||||
|           --hostname=openssh-server-02 \ | ||||
|           -p 2223:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server-02 sh -c "hostname -i" > ip02.txt | ||||
|           echo "REMOTE_HOST_02<<EOF" >> $GITHUB_ENV | ||||
|           cat ip02.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip02.txt | ||||
|           echo "======================================" | ||||
|  | ||||
|           sleep 2 | ||||
|  | ||||
|       # https://github.com/appleboy/ssh-action/issues/85 | ||||
|       - name: Deployment to multiple hosts with different ports | ||||
|         uses: ./ | ||||
|         with: | ||||
|           host: "${{ env.REMOTE_HOST_01 }}:2222,${{ env.REMOTE_HOST_02 }}:2222" | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           passphrase: 1234 | ||||
|           script_stop: true | ||||
|           script: | | ||||
|             whoami | ||||
|  | ||||
|   support-ed25519-key: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: add public key to env | ||||
|         run: | | ||||
|           echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_ed25519.pub >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= public key =========" | ||||
|           cat testdata/.ssh/id_ed25519.pub | ||||
|           echo "============================" | ||||
|           echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_ed25519 >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= private key =========" | ||||
|           cat testdata/.ssh/id_ed25519 | ||||
|           echo "============================" | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server \ | ||||
|           --hostname=openssh-server \ | ||||
|           -p 2222:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server sh -c "hostname -i" > ip.txt | ||||
|           echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV | ||||
|           cat ip.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip.txt | ||||
|           echo "======================================" | ||||
|           sleep 2 | ||||
|  | ||||
|       - name: testing id_ed25519 key | ||||
|         uses: ./ | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script: | | ||||
|             whoami | ||||
|             ls -al | ||||
|  | ||||
|   testing-with-env: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: add public key to env | ||||
|         run: | | ||||
|           echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_ed25519.pub >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= public key =========" | ||||
|           cat testdata/.ssh/id_ed25519.pub | ||||
|           echo "============================" | ||||
|           echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_ed25519 >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= private key =========" | ||||
|           cat testdata/.ssh/id_ed25519 | ||||
|           echo "============================" | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server \ | ||||
|           --hostname=openssh-server \ | ||||
|           -p 2222:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=true \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server sh -c "hostname -i" > ip.txt | ||||
|           echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV | ||||
|           cat ip.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip.txt | ||||
|           echo "======================================" | ||||
|           sleep 2 | ||||
|  | ||||
|       - name: testing id_ed25519 key | ||||
|         uses: ./ | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script: | | ||||
|             whoami | ||||
|             ls -al | ||||
|  | ||||
|       - name: pass environment | ||||
|         uses: ./ | ||||
|         env: | ||||
|           FOO: "BAR" | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           envs: FOO | ||||
|           script: | | ||||
|             echo "I am $FOO, thanks" | ||||
|             echo "I am $BAR, thanks" | ||||
|  | ||||
|       - name: pass multiple environment | ||||
|         uses: ./ | ||||
|         env: | ||||
|           FOO: "BAR" | ||||
|           BAR: "FOO" | ||||
|           SHA: ${{ github.sha }} | ||||
|           PORT: ${{ secrets.PORT }} | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           envs: FOO,BAR,SHA,PORT | ||||
|           script: | | ||||
|             echo "I am $FOO, thanks" | ||||
|             echo "I am $BAR, thanks" | ||||
|             echo "sha: $SHA" | ||||
|             echo "port: $PORT" | ||||
|  | ||||
|       - name: custom envs format | ||||
|         uses: ./ | ||||
|         env: | ||||
|           FOO: "BAR" | ||||
|           AAA: "BBB" | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           envs: FOO,BAR,AAA | ||||
|           envs_format: export TEST_{NAME}={VALUE} | ||||
|           script: | | ||||
|             echo "I am $TEST_FOO, thanks" | ||||
|             echo "I am $TEST_BAR, thanks" | ||||
|             echo "I am $BAR, thanks" | ||||
|             echo "I am $TEST_AAA, thanks" | ||||
|  | ||||
|       - name: pass all ENV variables to script | ||||
|         uses: ./ | ||||
|         env: | ||||
|           INPUT_FOO: "BAR" | ||||
|           INPUT_AAA: "BBB" | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           allenvs: true | ||||
|           script: | | ||||
|             echo "I am $INPUT_FOO, thanks" | ||||
|             echo "I am $INPUT_AAA, thanks" | ||||
|             echo "$GITHUB_BASE_REF" | ||||
|             echo "$GITHUB_REF" | ||||
|  | ||||
|       - name: pass secret variable in shell | ||||
|         uses: ./ | ||||
|         continue-on-error: true | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script: cd ${{ secrets.PORT }} | ||||
|  | ||||
|       - name: switch to root user | ||||
|         uses: ./ | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script_stop: true | ||||
|           request_pty: true | ||||
|           command_timeout: 30s | ||||
|           script: | | ||||
|             whoami && echo 'hello world' && touch todo.txt | ||||
|             sudo whoami | ||||
|  | ||||
|   testing06: | ||||
|     name: testing ipv6 | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: checkout | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: Set up WARP | ||||
|         uses: fscarmen/warp-on-actions@v1.1 | ||||
|         with: | ||||
|           stack: dual | ||||
|  | ||||
|       - name: testing ipv6 for command | ||||
|         run: | | ||||
|           curl -m 9 --ipv6 --verbose https://google.com | ||||
|  | ||||
|       - name: testing ipv6 | ||||
|         uses: ./ | ||||
|         continue-on-error: true | ||||
|         with: | ||||
|           host: 2402:1f00:8000:800::2628 | ||||
|           username: ubuntu | ||||
|           password: ${{ secrets.OVH_PASSWORD }} | ||||
|           protocol: tcp6 | ||||
|           port: 22 | ||||
|           command_timeout: 30s | ||||
|           script: | | ||||
|             whoami | ||||
							
								
								
									
										474
									
								
								.github/workflows/stable.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										474
									
								
								.github/workflows/stable.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,474 @@ | ||||
| name: testing stable version | ||||
|  | ||||
| on: [push] | ||||
|  | ||||
| jobs: | ||||
|   default-user-name-password: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server \ | ||||
|           --hostname=openssh-server \ | ||||
|           -p 2222:2222 \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server sh -c "hostname -i" > ip.txt | ||||
|           echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV | ||||
|           cat ip.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip.txt | ||||
|           echo "======================================" | ||||
|           sleep 2 | ||||
|  | ||||
|       - name: ssh by username and password | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           password: password | ||||
|           port: 2222 | ||||
|           script: whoami | ||||
|  | ||||
|   check-ssh-key: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: add public key to env | ||||
|         run: | | ||||
|           echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_rsa.pub >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= public key =========" | ||||
|           cat testdata/.ssh/id_rsa.pub | ||||
|           echo "============================" | ||||
|           echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_rsa >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= private key =========" | ||||
|           cat testdata/.ssh/id_rsa | ||||
|           echo "============================" | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server \ | ||||
|           --hostname=openssh-server \ | ||||
|           -p 2222:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server sh -c "hostname -i" > ip.txt | ||||
|           echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV | ||||
|           cat ip.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip.txt | ||||
|           echo "======================================" | ||||
|           sleep 2 | ||||
|  | ||||
|       - name: ssh by private key | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script: whoami | ||||
|  | ||||
|       - name: wrong password but correct key | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           password: "abcdef" | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script: whoami | ||||
|  | ||||
|       - name: correct password but wrong key | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           password: password | ||||
|           key: password | ||||
|           port: 2222 | ||||
|           script: whoami | ||||
|  | ||||
|       - name: stop script if command error | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         continue-on-error: true | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           password: password | ||||
|           key: password | ||||
|           port: 2222 | ||||
|           script_stop: true | ||||
|           sync: true | ||||
|           debug: true | ||||
|           script: | | ||||
|             mkdir abc/def | ||||
|             ls -al | ||||
|  | ||||
|   support-key-passphrase: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: add public key to env | ||||
|         run: | | ||||
|           echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_passphrase.pub >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= public key =========" | ||||
|           cat testdata/.ssh/id_passphrase.pub | ||||
|           echo "============================" | ||||
|           echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_passphrase >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= private key =========" | ||||
|           cat testdata/.ssh/id_passphrase | ||||
|           echo "============================" | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server \ | ||||
|           --hostname=openssh-server \ | ||||
|           -p 2222:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server sh -c "hostname -i" > ip.txt | ||||
|           echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV | ||||
|           cat ip.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip.txt | ||||
|           echo "======================================" | ||||
|           sleep 2 | ||||
|  | ||||
|       - name: ssh key passphrase | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           passphrase: 1234 | ||||
|           script: | | ||||
|             whoami | ||||
|             ls -al | ||||
|  | ||||
|       - name: missing ssh key passphrase | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         continue-on-error: true | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script: | | ||||
|             whoami | ||||
|             ls -al | ||||
|  | ||||
|       # https://github.com/appleboy/ssh-action/issues/75#issuecomment-668314271 | ||||
|       - name: Multiline SSH commands interpreted as single lines | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           passphrase: 1234 | ||||
|           script_stop: true | ||||
|           script: | | ||||
|             ls \ | ||||
|               -lah | ||||
|           use_insecure_cipher: true | ||||
|  | ||||
|   multiple-server: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: add public key to env | ||||
|         run: | | ||||
|           echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_passphrase.pub >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= public key =========" | ||||
|           cat testdata/.ssh/id_passphrase.pub | ||||
|           echo "============================" | ||||
|           echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_passphrase >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= private key =========" | ||||
|           cat testdata/.ssh/id_passphrase | ||||
|           echo "============================" | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server-01 \ | ||||
|           --hostname=openssh-server-01 \ | ||||
|           -p 2222:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server-01 sh -c "hostname -i" > ip01.txt | ||||
|           echo "REMOTE_HOST_01<<EOF" >> $GITHUB_ENV | ||||
|           cat ip01.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip01.txt | ||||
|           echo "======================================" | ||||
|  | ||||
|           docker run -d \ | ||||
|           --name=openssh-server-02 \ | ||||
|           --hostname=openssh-server-02 \ | ||||
|           -p 2223:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server-02 sh -c "hostname -i" > ip02.txt | ||||
|           echo "REMOTE_HOST_02<<EOF" >> $GITHUB_ENV | ||||
|           cat ip02.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip02.txt | ||||
|           echo "======================================" | ||||
|  | ||||
|           sleep 2 | ||||
|  | ||||
|       # https://github.com/appleboy/ssh-action/issues/85 | ||||
|       - name: Deployment to multiple hosts with different ports | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         with: | ||||
|           host: "${{ env.REMOTE_HOST_01 }}:2222,${{ env.REMOTE_HOST_02 }}:2222" | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           passphrase: 1234 | ||||
|           script_stop: true | ||||
|           script: | | ||||
|             whoami | ||||
|  | ||||
|   support-ed25519-key: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: add public key to env | ||||
|         run: | | ||||
|           echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_ed25519.pub >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= public key =========" | ||||
|           cat testdata/.ssh/id_ed25519.pub | ||||
|           echo "============================" | ||||
|           echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_ed25519 >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= private key =========" | ||||
|           cat testdata/.ssh/id_ed25519 | ||||
|           echo "============================" | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server \ | ||||
|           --hostname=openssh-server \ | ||||
|           -p 2222:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=false \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_PASSWORD=password  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server sh -c "hostname -i" > ip.txt | ||||
|           echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV | ||||
|           cat ip.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip.txt | ||||
|           echo "======================================" | ||||
|           sleep 2 | ||||
|  | ||||
|       - name: testing id_ed25519 key | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script: | | ||||
|             whoami | ||||
|             ls -al | ||||
|  | ||||
|   testing-with-env: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout code | ||||
|         uses: actions/checkout@v4 | ||||
|  | ||||
|       - name: add public key to env | ||||
|         run: | | ||||
|           echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_ed25519.pub >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= public key =========" | ||||
|           cat testdata/.ssh/id_ed25519.pub | ||||
|           echo "============================" | ||||
|           echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV | ||||
|           cat testdata/.ssh/id_ed25519 >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= private key =========" | ||||
|           cat testdata/.ssh/id_ed25519 | ||||
|           echo "============================" | ||||
|  | ||||
|       - name: create new ssh server | ||||
|         run: | | ||||
|           docker run -d \ | ||||
|           --name=openssh-server \ | ||||
|           --hostname=openssh-server \ | ||||
|           -p 2222:2222 \ | ||||
|           -e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \ | ||||
|           -e SUDO_ACCESS=true \ | ||||
|           -e PASSWORD_ACCESS=true  \ | ||||
|           -e USER_NAME=linuxserver.io \ | ||||
|           --restart unless-stopped \ | ||||
|           lscr.io/linuxserver/openssh-server:latest | ||||
|           docker exec openssh-server sh -c "hostname -i" > ip.txt | ||||
|           echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV | ||||
|           cat ip.txt >> $GITHUB_ENV | ||||
|           echo "EOF" >> $GITHUB_ENV | ||||
|           echo "======= container ip address =========" | ||||
|           cat ip.txt | ||||
|           echo "======================================" | ||||
|           sleep 2 | ||||
|  | ||||
|       - name: testing id_ed25519 key | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script: | | ||||
|             whoami | ||||
|             ls -al | ||||
|  | ||||
|       - name: pass environment | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         env: | ||||
|           FOO: "BAR" | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           envs: FOO | ||||
|           script: | | ||||
|             echo "I am $FOO, thanks" | ||||
|             echo "I am $BAR, thanks" | ||||
|  | ||||
|       - name: pass multiple environment | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         env: | ||||
|           FOO: "BAR" | ||||
|           BAR: "FOO" | ||||
|           SHA: ${{ github.sha }} | ||||
|           PORT: ${{ secrets.PORT }} | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           envs: FOO,BAR,SHA,PORT | ||||
|           script: | | ||||
|             echo "I am $FOO, thanks" | ||||
|             echo "I am $BAR, thanks" | ||||
|             echo "sha: $SHA" | ||||
|             echo "port: $PORT" | ||||
|  | ||||
|       - name: custom envs format | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         env: | ||||
|           FOO: "BAR" | ||||
|           AAA: "BBB" | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           envs: FOO,BAR,AAA | ||||
|           envs_format: export TEST_{NAME}={VALUE} | ||||
|           script: | | ||||
|             echo "I am $TEST_FOO, thanks" | ||||
|             echo "I am $TEST_BAR, thanks" | ||||
|             echo "I am $BAR, thanks" | ||||
|             echo "I am $TEST_AAA, thanks" | ||||
|  | ||||
|       - name: pass all ENV variables to script | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         env: | ||||
|           INPUT_FOO: "BAR" | ||||
|           INPUT_AAA: "BBB" | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           allenvs: true | ||||
|           script: | | ||||
|             echo "I am $INPUT_FOO, thanks" | ||||
|             echo "I am $INPUT_AAA, thanks" | ||||
|             echo "$GITHUB_BASE_REF" | ||||
|             echo "$GITHUB_REF" | ||||
|  | ||||
|       - name: switch to root user | ||||
|         uses: appleboy/ssh-action@v1.0.3 | ||||
|         with: | ||||
|           host: ${{ env.REMOTE_HOST }} | ||||
|           username: linuxserver.io | ||||
|           key: ${{ env.PRIVATE_KEY }} | ||||
|           port: 2222 | ||||
|           script_stop: true | ||||
|           request_pty: true | ||||
|           command_timeout: 30s | ||||
|           script: | | ||||
|             whoami && echo 'hello world' && touch todo.txt | ||||
|             sudo whoami | ||||
							
								
								
									
										28
									
								
								.goreleaser.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								.goreleaser.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
| @@ -1,5 +0,0 @@ | ||||
| FROM appleboy/drone-ssh:1.5.4-linux-amd64 | ||||
|  | ||||
| ADD entrypoint.sh /entrypoint.sh | ||||
| RUN chmod +x /entrypoint.sh | ||||
| ENTRYPOINT ["/entrypoint.sh"] | ||||
							
								
								
									
										334
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										334
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,11 +1,57 @@ | ||||
| # 🚀 SSH for GitHub Actions | ||||
|  | ||||
| [繁體中文](./README.zh-tw.md) | ||||
| [简体中文](./README.zh-cn.md) | ||||
|  | ||||
| [GitHub Action](https://github.com/features/actions) for executing remote ssh commands. | ||||
|  | ||||
|  | ||||
|  | ||||
| [](https://github.com/appleboy/ssh-action/actions) | ||||
|  | ||||
| **Important**: Only support **Linux** [docker](https://www.docker.com/) container. | ||||
|  | ||||
| This thing is built using [Golang](https://go.dev) and [drone-ssh](https://github.com/appleboy/drone-ssh). 🚀 | ||||
|  | ||||
| ## Input variables | ||||
|  | ||||
| See [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                                           | false         | | ||||
| | use_insecure_cipher       | Include more ciphers with use_insecure_cipher                                            | false         | | ||||
| | cipher                    | Allowed cipher algorithms. If unspecified, a sensible default                            |               | | ||||
| | 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_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_stop               | Stop script after first failure                                                          | false         | | ||||
| | envs                      | Pass environment variables to 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         | | ||||
|  | ||||
| ## Usage | ||||
|  | ||||
| Executing remote ssh commands. | ||||
| @@ -20,7 +66,7 @@ jobs: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - name: executing remote ssh commands using password | ||||
|       uses: appleboy/ssh-action@master | ||||
|       uses: appleboy/ssh-action@v1.0.3 | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
| @@ -41,30 +87,102 @@ out: *** | ||||
| ============================================== | ||||
| ``` | ||||
|  | ||||
| ## Input variables | ||||
| ### Setting up a SSH Key | ||||
|  | ||||
| See [action.yml](./action.yml) for more detailed information. | ||||
| Make sure to follow the below steps while creating SSH Keys and using them. | ||||
| The best practice is create the SSH Keys on local machine not remote machine. | ||||
| Login with username specified in Github Secrets. Generate a RSA Key-Pair: | ||||
|  | ||||
| * host - remote host | ||||
| * port - remote port, default is `22` | ||||
| * username - ssh username | ||||
| * password - ssh password | ||||
| * timeout - timeout for ssh to remote host, default is `30s` | ||||
| * command_timeout - timeout for ssh command, default is `10m` | ||||
| * key - content of ssh private key. ex raw content of ~/.ssh/id_rsa | ||||
| * key_path - path of ssh private key | ||||
| * script - execute commands | ||||
| * script_stop - stop script after first failure | ||||
| * envs - pass environment variable to shell script | ||||
| * debug - enable debug mode | ||||
| ### 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 newly generated key into 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 Private Key content and paste in Github Secrets. | ||||
|  | ||||
| ### Copy rsa Private key | ||||
|  | ||||
| Before copying the private key, install `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 | ||||
| ``` | ||||
|  | ||||
| ### Copy ed25519 Private key | ||||
|  | ||||
| ```bash | ||||
| # macOS | ||||
| pbcopy < ~/.ssh/id_ed25519 | ||||
| # Ubuntu | ||||
| xclip < ~/.ssh/id_ed25519 | ||||
| ``` | ||||
|  | ||||
| See the detail information about [SSH login without password](http://www.linuxproblem.org/art_9.html). | ||||
|  | ||||
| **A note** from one of our readers: Depending on your version of SSH you might also have to do 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] | ||||
| ``` | ||||
|  | ||||
| Make sure that your key algorithm of choice 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 (which is 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 could 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. | ||||
| #### Executing remote ssh commands using password | ||||
|  | ||||
| ```yaml | ||||
| - name: executing remote ssh commands using password | ||||
|   uses: appleboy/ssh-action@master | ||||
|   uses: appleboy/ssh-action@v1.0.3 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
| @@ -73,11 +191,11 @@ Executing remote ssh commands using password. | ||||
|     script: whoami | ||||
| ``` | ||||
|  | ||||
| Using private key | ||||
| #### Using private key | ||||
|  | ||||
| ```yaml | ||||
| - name: executing remote ssh commands using ssh key | ||||
|   uses: appleboy/ssh-action@master | ||||
|   uses: appleboy/ssh-action@v1.0.3 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
| @@ -86,11 +204,11 @@ Using private key | ||||
|     script: whoami | ||||
| ``` | ||||
|  | ||||
| Multiple Commands | ||||
| #### Multiple Commands | ||||
|  | ||||
| ```yaml | ||||
| - name: multiple command | ||||
|   uses: appleboy/ssh-action@master | ||||
|   uses: appleboy/ssh-action@v1.0.3 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
| @@ -103,11 +221,11 @@ Multiple Commands | ||||
|  | ||||
|  | ||||
|  | ||||
| Multiple Hosts | ||||
| #### Multiple Hosts | ||||
|  | ||||
| ```diff | ||||
|   - name: multiple host | ||||
|     uses: appleboy/ssh-action@master | ||||
|     uses: appleboy/ssh-action@v1.0.3 | ||||
|     with: | ||||
| -     host: "foo.com" | ||||
| +     host: "foo.com,bar.com" | ||||
| @@ -119,29 +237,69 @@ Multiple Hosts | ||||
|         ls -al | ||||
| ``` | ||||
|  | ||||
| Pass environment variable to shell script | ||||
| The default value of `port` is `22`. | ||||
|  | ||||
| #### Multiple hosts with different port | ||||
|  | ||||
| ```diff | ||||
|   - name: multiple host | ||||
|     uses: appleboy/ssh-action@v1.0.3 | ||||
|     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.0.3 | ||||
|     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@master | ||||
|     uses: appleboy/ssh-action@v1.0.3 | ||||
| +   env: | ||||
| +     FOO: "BAR" | ||||
| +     BAR: "FOO" | ||||
| +     SHA: ${{ github.sha }} | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
|       key: ${{ secrets.KEY }} | ||||
|       port: ${{ secrets.PORT }} | ||||
| +     envs: FOO | ||||
| +     envs: FOO,BAR,SHA | ||||
|       script: | | ||||
|         echo "I am $FOO" | ||||
|         echo "I am $BAR" | ||||
|         echo "sha: $SHA" | ||||
| ``` | ||||
|  | ||||
| Stop script after first failure. ex: missing `abc` folder | ||||
| _Inside `env` object, you need to pass every environment variable as a string, passing `Integer` data type or any other may output unexpected results._ | ||||
|  | ||||
| #### Stop script after first failure | ||||
|  | ||||
| > ex: missing `abc` folder | ||||
|  | ||||
| ```diff | ||||
|   - name: stop script if command error | ||||
|     uses: appleboy/ssh-action@master | ||||
|     uses: appleboy/ssh-action@v1.0.3 | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
| @@ -165,3 +323,123 @@ ls -al | ||||
| err: mkdir: cannot create directory ‘abc/def’: No such file or directory | ||||
| ##[error]Docker run failed with exit code 1 | ||||
| ``` | ||||
|  | ||||
| #### 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.0.3 | ||||
|     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.0.3 | ||||
|     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.0.3 | ||||
|     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. | ||||
|  | ||||
| Basically, 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` | ||||
| ``` | ||||
|  | ||||
| just comment out the line that returns early and everything should work fine, or you can use the real paths of the commands that you would like 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) | ||||
|   | ||||
							
								
								
									
										393
									
								
								README.zh-cn.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								README.zh-cn.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,393 @@ | ||||
| # 🚀 用于 GitHub Actions 的 SSH | ||||
|  | ||||
| [GitHub Action](https://github.com/features/actions) 用于执行远程 SSH 命令。 | ||||
|  | ||||
|  | ||||
|  | ||||
| [](https://github.com/appleboy/ssh-action/actions) | ||||
|  | ||||
| **注意**: 只支持在 **Linux** [docker](https://www.docker.com/) 容器上执行。 | ||||
|  | ||||
| ## 输入变量 | ||||
|  | ||||
| 更详细的信息,请参考 [action.yml](./action.yml)。 | ||||
|  | ||||
| * `host` - SSH 主机 | ||||
| * `port` - SSH 连接端口,默认为 `22` | ||||
| * `username` - SSH 用户名称 | ||||
| * `password` - SSH 密码 | ||||
| * `passphrase` - 通常用于加密私钥的 passphrase | ||||
| * `sync` - 同步执行多个主机上的命令,默认为 false | ||||
| * `timeout` - SSH 连接到远程主机的超时时间,默认为 `30s` | ||||
| * `command_timeout` - SSH 命令超时时间,默认为 10m | ||||
| * `key` - SSH 私钥的内容,例如 ~/.ssh/id_rsa 的原始内容,请记得包含 BEGIN 和 END 行 | ||||
| * `key_path` - SSH 私钥的路径 | ||||
| * `fingerprint` - 主机公钥的 SHA256 指纹,默认为跳过验证 | ||||
| * `script` - 执行命令 | ||||
| * `script_stop` - 当出现第一个错误时停止执行命令 | ||||
| * `envs` - 传递环境变量到 shell script | ||||
| * `debug` - 启用调试模式 | ||||
| * `use_insecure_cipher` - 使用不安全的密码(ciphers)进行加密,详见 [#56](https://github.com/appleboy/ssh-action/issues/56) | ||||
| * `cipher` - 允许使用的密码(ciphers)算法。如果未指定,则使用适当的算法 | ||||
|  | ||||
| SSH 代理设置: | ||||
|  | ||||
| * `proxy_host` - 代理主机 | ||||
| * `proxy_port` - 代理端口,默认为 `22` | ||||
| * `proxy_username` - 代理用户名 | ||||
| * `proxy_password` - 代理密码 | ||||
| * `proxy_passphrase` - 密码通常用于加密私有密钥 | ||||
| * `proxy_timeout` - SSH 连接至代理主机的超时时间,默认为 `30s` | ||||
| * `proxy_key` - SSH 代理私有密钥内容 | ||||
| * `proxy_key_path` - SSH 代理私有密钥路径 | ||||
| * `proxy_fingerprint` - 代理主机公钥的 SHA256 指纹,默认为跳过验证 | ||||
| * `proxy_use_insecure_cipher` - 使用不安全的加密方式,详见 [#56](https://github.com/appleboy/ssh-action/issues/56) | ||||
| * `proxy_cipher` - 允许的加密算法。如果未指定,则使用合理的算法 | ||||
|  | ||||
| ## 使用方法 | ||||
|  | ||||
| 执行远程 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.0.3 | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         password: ${{ secrets.PASSWORD }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script: whoami | ||||
| ``` | ||||
|  | ||||
| 画面输出 | ||||
|  | ||||
| ```sh | ||||
| ======CMD====== | ||||
| whoami | ||||
| ======END====== | ||||
| out: *** | ||||
| ============================================== | ||||
| ✅ Successfully executed commands to all host. | ||||
| ============================================== | ||||
| ``` | ||||
|  | ||||
| ### 设置 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 私钥内容 | ||||
|  | ||||
| ```bash | ||||
| clip < ~/.ssh/id_rsa | ||||
| ``` | ||||
|  | ||||
| ### 复制 ed25519 私钥内容 | ||||
|  | ||||
| ```bash | ||||
| clip < ~/.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.0.3 | ||||
|   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.0.3 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
|     key: ${{ secrets.KEY }} | ||||
|     port: ${{ secrets.PORT }} | ||||
|     script: whoami | ||||
| ``` | ||||
|  | ||||
| #### 多个命令 | ||||
|  | ||||
| ```yaml | ||||
| - name: multiple command | ||||
|   uses: appleboy/ssh-action@v1.0.3 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
|     key: ${{ secrets.KEY }} | ||||
|     port: ${{ secrets.PORT }} | ||||
|     script: | | ||||
|       whoami | ||||
|       ls -al | ||||
| ``` | ||||
|  | ||||
|  | ||||
|  | ||||
| #### 多台主机 | ||||
|  | ||||
| ```diff | ||||
|   - name: multiple host | ||||
|     uses: appleboy/ssh-action@v1.0.3 | ||||
|     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.0.3 | ||||
|     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.0.3 | ||||
|     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.0.3 | ||||
| +   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` 数据类型或任何其他类型可能会产生意外结果。_ | ||||
|  | ||||
| #### 在第一次失败后停止脚本 | ||||
|  | ||||
| > ex: missing `abc` folder | ||||
|  | ||||
| ```diff | ||||
|   - name: stop script if command error | ||||
|     uses: appleboy/ssh-action@v1.0.3 | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
|       key: ${{ secrets.KEY }} | ||||
|       port: ${{ secrets.PORT }} | ||||
| +     script_stop: true | ||||
|       script: | | ||||
|         mkdir abc/def | ||||
|         ls -al | ||||
| ``` | ||||
|  | ||||
| 画面输出: | ||||
|  | ||||
| ```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 | ||||
| ``` | ||||
|  | ||||
| #### 如何使用 `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.0.3 | ||||
|     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.0.3 | ||||
|     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.0.3 | ||||
|     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) 许可证 发布。 | ||||
							
								
								
									
										393
									
								
								README.zh-tw.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								README.zh-tw.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,393 @@ | ||||
| # 🚀 用於 GitHub Actions 的 SSH | ||||
|  | ||||
| [GitHub Action](https://github.com/features/actions) for executing remote ssh commands. | ||||
|  | ||||
|  | ||||
|  | ||||
| [](https://github.com/appleboy/ssh-action/actions) | ||||
|  | ||||
| **注意**: 只支援在 **Linux** [docker](https://www.docker.com/) 容器上執行。 | ||||
|  | ||||
| ## 輸入變數 | ||||
|  | ||||
| 更詳細的資訊,請參閱 [action.yml](./action.yml)。 | ||||
|  | ||||
| * `host` - SSH 主機 | ||||
| * `port` - SSH 連接埠,預設為 `22` | ||||
| * `username` - SSH 使用者名稱 | ||||
| * `password` - SSH 密碼 | ||||
| * `passphrase` - 通常用於加密私鑰的 passphrase | ||||
| * `sync` - 同步執行多個主機上的命令,預設為 false | ||||
| * `timeout` - SSH 連接到遠端主機的超時時間,預設為 `30s` | ||||
| * `command_timeout` - SSH 命令超時時間,預設為 10m | ||||
| * `key` - SSH 私鑰的內容,例如 ~/.ssh/id_rsa 的原始內容,請記得包含 BEGIN 和 END 行 | ||||
| * `key_path` - SSH 私鑰的路徑 | ||||
| * `fingerprint` - 主機公鑰的 SHA256 指紋,預設為略過驗證 | ||||
| * `script` - 執行命令 | ||||
| * `script_stop` - 當出現第一個錯誤時停止執行命令 | ||||
| * `envs` - 傳遞環境變數到 shell script | ||||
| * `debug` - 啟用偵錯模式 | ||||
| * `use_insecure_cipher` - 使用不安全的密碼(ciphers)進行加密,參見 [#56](https://github.com/appleboy/ssh-action/issues/56) | ||||
| * `cipher` - 允許使用的密碼(ciphers)演算法。如果未指定,則使用適當的演算法 | ||||
|  | ||||
| SSH 代理設置: | ||||
|  | ||||
| * `proxy_host` - 代理主機 | ||||
| * `proxy_port` - 代理端口,預設為 `22` | ||||
| * `proxy_username` - 代理使用者名稱 | ||||
| * `proxy_password` - 代理密碼 | ||||
| * `proxy_passphrase` - 密碼通常用於加密私有金鑰 | ||||
| * `proxy_timeout` - SSH 連線至代理主機的逾時時間,預設為 `30s` | ||||
| * `proxy_key` - SSH 代理私有金鑰內容 | ||||
| * `proxy_key_path` - SSH 代理私有金鑰路徑 | ||||
| * `proxy_fingerprint` - 代理主機公鑰的 SHA256 指紋,預設為跳過驗證 | ||||
| * `proxy_use_insecure_cipher` - 使用不安全的加密方式,請參閱 [#56](https://github.com/appleboy/ssh-action/issues/56) | ||||
| * `proxy_cipher` - 允許的加密算法。如果未指定,則使用合理的算法 | ||||
|  | ||||
| ## 使用方式 | ||||
|  | ||||
| 執行遠端 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.0.3 | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         password: ${{ secrets.PASSWORD }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script: whoami | ||||
| ``` | ||||
|  | ||||
| 畫面輸出 | ||||
|  | ||||
| ```sh | ||||
| ======CMD====== | ||||
| whoami | ||||
| ======END====== | ||||
| out: *** | ||||
| ============================================== | ||||
| ✅ Successfully executed commands to all host. | ||||
| ============================================== | ||||
| ``` | ||||
|  | ||||
| ### 設置 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 私鑰內容 | ||||
|  | ||||
| ```bash | ||||
| clip < ~/.ssh/id_rsa | ||||
| ``` | ||||
|  | ||||
| ### 複製 ed25519 私鑰內容 | ||||
|  | ||||
| ```bash | ||||
| clip < ~/.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.0.3 | ||||
|   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.0.3 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
|     key: ${{ secrets.KEY }} | ||||
|     port: ${{ secrets.PORT }} | ||||
|     script: whoami | ||||
| ``` | ||||
|  | ||||
| #### 多個命令 | ||||
|  | ||||
| ```yaml | ||||
| - name: multiple command | ||||
|   uses: appleboy/ssh-action@v1.0.3 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
|     key: ${{ secrets.KEY }} | ||||
|     port: ${{ secrets.PORT }} | ||||
|     script: | | ||||
|       whoami | ||||
|       ls -al | ||||
| ``` | ||||
|  | ||||
|  | ||||
|  | ||||
| #### 多台主機 | ||||
|  | ||||
| ```diff | ||||
|   - name: multiple host | ||||
|     uses: appleboy/ssh-action@v1.0.3 | ||||
|     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.0.3 | ||||
|     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.0.3 | ||||
|     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.0.3 | ||||
| +   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` 數據類型或任何其他類型可能會產生意外結果。_ | ||||
|  | ||||
| #### 在第一次失敗後停止腳本 | ||||
|  | ||||
| > ex: missing `abc` folder | ||||
|  | ||||
| ```diff | ||||
|   - name: stop script if command error | ||||
|     uses: appleboy/ssh-action@v1.0.3 | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
|       key: ${{ secrets.KEY }} | ||||
|       port: ${{ secrets.PORT }} | ||||
| +     script_stop: true | ||||
|       script: | | ||||
|         mkdir abc/def | ||||
|         ls -al | ||||
| ``` | ||||
|  | ||||
| 畫面輸出: | ||||
|  | ||||
| ```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 | ||||
| ``` | ||||
|  | ||||
| #### 如何使用 `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.0.3 | ||||
|     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.0.3 | ||||
|     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.0.3 | ||||
|     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) 許可證 發布。 | ||||
							
								
								
									
										128
									
								
								action.yml
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								action.yml
									
									
									
									
									
								
							| @@ -1,40 +1,124 @@ | ||||
| name: 'SSH Remote Commands' | ||||
| description: 'Executing remote ssh commands' | ||||
| author: 'Bo-Yi Wu' | ||||
| name: "SSH Remote Commands" | ||||
| description: "Executing remote ssh commands" | ||||
| author: "Bo-Yi Wu" | ||||
| inputs: | ||||
|   host: | ||||
|     description: 'ssh remote host' | ||||
|     description: "SSH host address." | ||||
|   port: | ||||
|     description: 'ssh remote port' | ||||
|     default: 22 | ||||
|     description: "SSH port number." | ||||
|     default: "22" | ||||
|   passphrase: | ||||
|     description: "Passphrase for the SSH key." | ||||
|   username: | ||||
|     description: 'ssh username' | ||||
|     description: "SSH username." | ||||
|   password: | ||||
|     description: 'ssh password' | ||||
|     description: "SSH password." | ||||
|   protocol: | ||||
|     description: 'The IP protocol to use. Valid values are "tcp". "tcp4" or "tcp6". Default to tcp.' | ||||
|     default: "tcp" | ||||
|   sync: | ||||
|     description: "Enable synchronous execution if multiple hosts are involved." | ||||
|   use_insecure_cipher: | ||||
|     description: "Include more ciphers by using insecure ciphers." | ||||
|   cipher: | ||||
|     description: "Allowed cipher algorithms. If unspecified, a sensible default is used." | ||||
|   timeout: | ||||
|     description: 'timeout for ssh to remote host' | ||||
|     description: "Timeout duration for establishing SSH connection to the host." | ||||
|     default: "30s" | ||||
|   command_timeout: | ||||
|     description: 'timeout for ssh command' | ||||
|     description: "Timeout duration for SSH commands execution." | ||||
|     default: "10m" | ||||
|   key: | ||||
|     description: 'content of ssh private key. ex raw content of ~/.ssh/id_rsa' | ||||
|     description: "Content of the SSH private key. For example, the raw content of ~/.ssh/id_rsa." | ||||
|   key_path: | ||||
|     description: 'path of ssh private key' | ||||
|     description: "Path to the SSH private key file." | ||||
|   fingerprint: | ||||
|     description: "SHA256 fingerprint of the host public key." | ||||
|   proxy_host: | ||||
|     description: "SSH proxy host address." | ||||
|   proxy_port: | ||||
|     description: "SSH proxy port number." | ||||
|     default: "22" | ||||
|   proxy_username: | ||||
|     description: "SSH proxy username." | ||||
|   proxy_password: | ||||
|     description: "SSH proxy password." | ||||
|   proxy_passphrase: | ||||
|     description: "SSH proxy key passphrase." | ||||
|   proxy_timeout: | ||||
|     description: "Timeout duration for establishing SSH connection to the proxy host." | ||||
|     default: "30s" | ||||
|   proxy_key: | ||||
|     description: "Content of the SSH proxy private key. For example, the raw content of ~/.ssh/id_rsa." | ||||
|   proxy_key_path: | ||||
|     description: "Path to the SSH proxy private key file." | ||||
|   proxy_fingerprint: | ||||
|     description: "SHA256 fingerprint of the proxy host public key." | ||||
|   proxy_cipher: | ||||
|     description: "Allowed cipher algorithms for the proxy. If unspecified, a sensible default is used." | ||||
|   proxy_use_insecure_cipher: | ||||
|     description: "Include more ciphers for the proxy by using insecure ciphers." | ||||
|   script: | ||||
|     description: 'execute commands' | ||||
|     description: "Commands to be executed." | ||||
|   script_stop: | ||||
|     description: 'stop script after first failure' | ||||
|     default: false | ||||
|     description: "Stop the script after the first failure." | ||||
|   envs: | ||||
|     description: 'pass environment variable to shell script' | ||||
|     description: "Environment variables to be passed to the shell script." | ||||
|   envs_format: | ||||
|     description: "Flexible configuration for environment value transfer." | ||||
|   debug: | ||||
|     description: 'enable debug mode' | ||||
|     default: false | ||||
|     description: "Enable debug mode." | ||||
|   allenvs: | ||||
|     description: "pass all environment variable to shell script." | ||||
|   request_pty: | ||||
|     description: "Request a pseudo-terminal from the server." | ||||
|  | ||||
| runs: | ||||
|   using: 'docker' | ||||
|   image: 'Dockerfile' | ||||
|   using: "composite" | ||||
|   steps: | ||||
|     - name: Set GitHub Path | ||||
|       run: echo "$GITHUB_ACTION_PATH" >> $GITHUB_PATH | ||||
|       shell: bash | ||||
|       env: | ||||
|         GITHUB_ACTION_PATH: ${{ github.action_path }} | ||||
|     - 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_STOP: ${{ inputs.script_stop }} | ||||
|         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 }} | ||||
|  | ||||
| branding: | ||||
|   icon: 'terminal' | ||||
|   color: 'gray-dark' | ||||
|   icon: "terminal" | ||||
|   color: "gray-dark" | ||||
|   | ||||
| @@ -1,7 +1,69 @@ | ||||
| #!/bin/sh | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| set -eu | ||||
| set -o errexit | ||||
| set -o nounset | ||||
| set -o pipefail | ||||
|  | ||||
| export GITHUB="true" | ||||
|  | ||||
| sh -c "/bin/drone-ssh $*" | ||||
| 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.7.7}" | ||||
|  | ||||
| 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 "===========================" | ||||
| sh -c "${TARGET} $*" # run the command | ||||
|   | ||||
							
								
								
									
										7
									
								
								testdata/.ssh/id_ed25519
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								testdata/.ssh/id_ed25519
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| -----BEGIN OPENSSH PRIVATE KEY----- | ||||
| b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW | ||||
| QyNTUxOQAAACDoi7FltQCqpWporKh61nJUPIeazUYdzdstncoeU5XS2AAAAKBF5e2SReXt | ||||
| kgAAAAtzc2gtZWQyNTUxOQAAACDoi7FltQCqpWporKh61nJUPIeazUYdzdstncoeU5XS2A | ||||
| AAAEBrsLG1vSg08yaQgYM46KQW93Lz2ZikS1tTMH35gfHhpOiLsWW1AKqlamisqHrWclQ8 | ||||
| h5rNRh3N2y2dyh5TldLYAAAAFnlvdXJfZW1haWxAZXhhbXBsZS5jb20BAgMEBQYH | ||||
| -----END OPENSSH PRIVATE KEY----- | ||||
							
								
								
									
										1
									
								
								testdata/.ssh/id_ed25519.pub
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								testdata/.ssh/id_ed25519.pub
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOiLsWW1AKqlamisqHrWclQ8h5rNRh3N2y2dyh5TldLY your_email@example.com | ||||
							
								
								
									
										39
									
								
								testdata/.ssh/id_passphrase
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								testdata/.ssh/id_passphrase
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| -----BEGIN OPENSSH PRIVATE KEY----- | ||||
| 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 | ||||
| h55pSap77CEhEhE5FPZKuH9f7/E= | ||||
| -----END OPENSSH PRIVATE KEY----- | ||||
							
								
								
									
										1
									
								
								testdata/.ssh/id_passphrase.pub
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								testdata/.ssh/id_passphrase.pub
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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 | ||||
							
								
								
									
										27
									
								
								testdata/.ssh/id_rsa
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								testdata/.ssh/id_rsa
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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----- | ||||
							
								
								
									
										1
									
								
								testdata/.ssh/id_rsa.pub
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								testdata/.ssh/id_rsa.pub
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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 | ||||
							
								
								
									
										50
									
								
								testdata/.ssh/test
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								testdata/.ssh/test
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| -----BEGIN OPENSSH PRIVATE KEY----- | ||||
| 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 | ||||
| l4njcaMpg4tpQMHtCBOicGyV0= | ||||
| -----END OPENSSH PRIVATE KEY----- | ||||
							
								
								
									
										1
									
								
								testdata/.ssh/test.pub
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								testdata/.ssh/test.pub
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -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 | ||||
		Reference in New Issue
	
	Block a user