Allowing GitHub Actions to SSH into Your Server
In this article, we will discuss how to configure your AWS environment to allow GitHub Actions to SSH into your server. This setup is essential for automating deployments and other tasks that require server access.
Overview
To enable GitHub Actions to connect to your AWS EC2 instance via SSH, you need to configure IAM roles, Security Groups, and set up a GitHub Actions workflow. This ensures that your server remains secure while allowing automated processes to run smoothly.
Steps to Configure AWS
1. Setting up GitHub OIDC Provider
- Go to the IAM console in AWS
- Navigate to Identity providers
- Click “Add provider”
- Select “OpenID Connect”
- Provider URL:
https://token.actions.githubusercontent.com
- Audience:
sts.amazonaws.com
- Click “Add provider”
2. Security Group
Create a security group named github-actions-ec2-ssh
with no rules configured. Attach this to your EC2 instance.
To create the security group:
- Go to the EC2 console
- Navigate to Security Groups
- Click “Create security group”
- Name it
github-actions-ec2-ssh
- Attach it to your EC2 instance
3. IAM Role
Create an IAM role called Github-Action-Assume-Role
with the following trust relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::AWS_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:GITHUB_ORG/*"
}
}
}
]
}
4. Policy
Create a policy named manage-security-group-ingress
and attach it to your IAM Role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:RevokeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupIngress"
],
"Resource": "arn:aws:ec2:AWS_REGION:AWS_ACCOUNT_ID:security-group/SECURITY_GROUP_ID"
}
]
}
Steps to Configure GitHub Actions
1. Update Security Group Rules
To allow GitHub Actions to connect to your EC2 instance via SSH, you need to add rules to your github-actions-ec2-ssh
security group. You can do this through the AWS Management Console or by using the AWS CLI.
Example CLI Command
You can use the following command to authorize SSH access from GitHub Actions:
aws ec2 authorize-security-group-ingress \
--group-id SECURITY_GROUP_ID \
--protocol tcp \
--port 22 \
--cidr GITHUB_ACTIONS_IP/32
Replace GITHUB_ACTIONS_IP
with the IP address or CIDR range from GitHub’s published list of Action runner IPs.
2. GitHub Actions Workflow Setup
Now that your IAM role and Security Group are configured, you can set up your GitHub Actions workflow.
Ensure you have configured the following secrets in your GitHub repository settings: AWS_ASSUME_ROLE
(ARN of the IAM Role), AWS_REGION
, AWS_SECURITY_GROUP
(ID of the github-actions-ec2-ssh group), DEPLOY_USER
, HOSTNAME
, and SSH_PRIVATE_KEY
.”
Below is an example of a job in a workflow that allows GitHub Actions to SSH into your server:
deploy:
name: Deploy
runs-on: ubuntu-24.04
outputs:
ipv4: ${{ steps.ip.outputs.ipv4 }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }}
role-session-name: github-runner-${{ env.APP_ENV }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Public IP
id: ip
run: |
ipv4=$(dig +short -4 txt ch whoami.cloudflare @1.0.0.1)
echo "ipv4=$ipv4" >> $GITHUB_OUTPUT
- name: Add Github Actions IP to Security group
run: |
aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SECURITY_GROUP }} \
--ip-permissions IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges="[{CidrIp=${{ steps.ip.outputs.ipv4 }}/32,Description='Github Action'}]"
- name: Prepare SSH configuration.
run: |
mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/known_hosts
shell: bash
- name: Add SSH key.
run: |
ssh-agent -a $SSH_AUTH_SOCK > /dev/null
echo "$SSH_KEY" | ssh-add -
env:
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
shell: bash
- name: Verify SSH Connection
run: |
attempt_ssh_connection() {
local ssh_options="$1"
timeout 10s ssh $ssh_options -p 22 ${{ secrets.DEPLOY_USER }}@${{ secrets.HOSTNAME }} exit 2>/dev/null
}
connection_successful=false
if attempt_ssh_connection "-o BatchMode=yes -o ConnectTimeout=5 -o StrictHostKeyChecking=no"; then
echo "SSH connection successful"
connection_successful=true
fi
if $connection_successful; then
exit 0
fi
echo "CONNECTION FAILED"
ssh -vvv -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p 22 ${{ secrets.DEPLOY_USER }}@${{ secrets.HOSTNAME }}
exit 1
shell: bash
env:
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
- name: ssh-keyscan to get the public key of the remote server.
run: |
ssh-keyscan -p 22 -H ${{ secrets.HOSTNAME }} >> ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
shell: bash
env:
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
# Additional steps for deployment can be added here...
revokeSecurityGroup:
name: Revoke Security Group Ingress
runs-on: ubuntu-24.04
needs: deploy
if: always()
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }}
role-session-name: github-runner-${{ env.APP_ENV }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Remove Github Actions IP from Security group
run: |
aws ec2 revoke-security-group-ingress --group-id ${{ secrets.AWS_SECURITY_GROUP }} --protocol tcp --port 22 --cidr ${{ needs.deploy.outputs.ipv4 }}/32
Best Practices
-
Security
- Regularly rotate SSH keys
- Use the principle of least privilege for IAM roles
- Monitor security group changes
- Consider using AWS CloudTrail to audit changes
- Consider using AWS Systems Manager Session Manager for alternative access methods
-
Maintenance
- Keep track of GitHub Actions IP ranges
- Regularly review IAM permissions
- Monitor failed deployment attempts
Conclusion
By following the steps outlined in this article, you can successfully configure your AWS environment to allow GitHub Actions to SSH into your server. This setup enhances your deployment automation while maintaining security.
In future articles, we will explore how we are using Github Actions with PHP Deployer or Docker Swarm to handle deployments.