Nguyen Tien Hung
Nguyen Tien Hung

Reputation: 53

How to execute command from Github Action via SSH into whitelisted server?

I met a problem when trying to apply CI/CD into our project using Github Action. The server has the firewall to enable access for a listed ip only.

I have found a method by using Github meta api https://api.github.com/meta but they denied to apply.

Is there any other way to apply this?

Our current ci.yml

name: remote ssh
on:
  push:
    branches: [ master ]

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: execute ssh command via using private key
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.REMOTE_HOST }}
          username: ${{ secrets.REMOTE_USER }}
          key: ${{ secrets.CICD_SSH_KEY }}
          port: ${{ secrets.PORT }}
          script:
            pwd

Upvotes: 3

Views: 7004

Answers (3)

Eric
Eric

Reputation: 1126

My workaround around this is using a self hosted GitHub runner.
Read more here.
A self hosted runner bypasses the need to ssh into your server from GitHub by simply setting a listener application on you server that will react based on the events from GitHub. Instead of github notifying your server of new changes, your server keeps checking Github for any new changes.


Here is a sample yaml for deploying new code changes
on:
  push:
    branches: [ "main", "stage" ]

permissions:
  contents: read

jobs:
  deploy-prod:
    runs-on: self-hosted
    if: github.ref == 'refs/heads/main'
    steps:
    - name: Pull Updated Code
      run: |
        cd /home/odoo/odoo && git pull origin main

    - name: Updating Prod Server
      run: |
        export TMPDIR=$HOME/tmp && cd /home/odoo/odoo && sh scripts/update_server.sh

  deploy-stage:
    runs-on: self-hosted
    if: github.ref == 'refs/heads/stage'
    steps:
    - name: Pull Updated Code
      run: |
        cd /home/odoo/stage && git pull origin stage
        
    - name: Updating Stage Server
      run: |
        export TMPDIR=$HOME/tmp && cd /home/odoo/stage && sh scripts/update_server.sh


Upvotes: 0

Ratul Hasan
Ratul Hasan

Reputation: 600

Aside OpenVPN, you can use Cloudflare WARP 1.1.1.1, its easy to use and no need for running any server or any kind of log in.

just make a job

name: remote ssh command to deploy
on:
  push:
    branches: [ master ]

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Check Connect VPN
        run: |
          curl https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
          echo "deb [arch=amd64 signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list
          sudo apt update
          sudo apt install cloudflare-warp
          warp-cli --accept-tos register
          warp-cli --accept-tos connect

put this there. Boom you're ready to go and surf anywhere. Note:

  1. the 1st line is to add the Cloudflare pkg host to apt host list because apt only use microsoft hosted pkg only, and it's not there. 2nd line for same reason.
  2. 5th line to register the service. --accept-tos part is for accepting TOS which needed to be done by human input if omitted
  3. 6th line Runs the service.

Full documentation here:

  1. https://pkg.cloudflareclient.com/install
  2. https://developers.cloudflare.com/warp-client/get-started/linux/

Upvotes: 0

In my case, I use an OpenVPN to access to the server.

About security. I think you should not load file VPN config to Git.

This is my config file.

name: remote ssh command to deploy
on:
  push:
    branches: [ master ]

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1

      - name: Install Open VPN
        run: |
          sudo apt-get install openvpn
          echo "${{ secrets.VPN_FILE }}" > .github/vpn/config.ovpn

      - name: Connect VPN
        uses: golfzaptw/action-connect-ovpn@master
        id: connect_vpn
        with:
          PING_URL: ${{ secrets.REMOTE_HOST }}
          FILE_OVPN: '.github/vpn/config.ovpn'
        env:
          CA_CRT: ${{ secrets.CA_CRT}}
          USER_CRT: ${{ secrets.USER_CRT }}
          USER_KEY: ${{ secrets.USER_KEY }}

      - name: Check Connect VPN
        run: echo ${{ steps.connect_vpn.outputs.STATUS }}

      - name: Execute ssh command via using private key
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.REMOTE_HOST }}
          username: ${{ secrets.REMOTE_USER }}
          key: ${{ secrets.CICD_SSH_KEY }}
          port: ${{ secrets.PORT }}
          script: |
            pwd
            cd ${{ secrets.REMOTE_TARGET }}
            git pull

      - name: kill vpn
        if: always()
        run: sudo killall openvpn

Follow https://github.com/marketplace/actions/connect-vpn#Example-prepare-file-.ovpn:

  1. Copy data inside tag to encode base64 after that save to secret env github actions

  2. Remove tag and replace to ca ca.crt cert user.crt key user.key

Upvotes: 9

Related Questions