Automated SSL Certificate Expiry Monitoring with Slack Notifications

Task 1

  • Create a GitHub workflow to check the SSL expiry status of the domain and send an alert notification in Slack .

Note:

  • You can use any type of script to perform this function, But the script should be run using the GitHub workflow.

  • Workflow should trigger automatically everyday once and also allow it to trigger manually.

  • Should check the list of domains one by one and send the alert separately.

  • Do not keep the domain names in the script itself, like this

  • Do not expose the Slack webhook URL; keep it in GitHub secret.

  • The script should be dynamic and allow for easy customization without altering the core functionality of the script.

  • The alert message format should be as below:

SSL Expiry Alert
Domain : <domain_name> Warning : The SSL certificate for <domain_name> will expire in <count_of_remaining_days_to_expire> days.
-----------------------------------------------------------------------

Workflow Setup

  1. Workflow File (yaml file)

    First, let's define the GitHub Workflow in a YAML file named ssl_expiry_check.yml.

     name: SSL Expiry Check
    
     on:
       schedule:
         - cron: '0 0 * * *'  # Run every day at midnight
       workflow_dispatch:  # Allow manual triggering
    
     jobs:
       ssl_expiry_check:
         runs-on: ubuntu-latest
    
         steps:
         - name: Checkout code
           uses: actions/checkout@v2
    
         - name: Set up Python
           uses: actions/setup-python@v2
           with:
             python-version: 3.8
    
         - name: Install dependencies
           run: |
             python -m pip install --upgrade pip
             pip install requests pyopenssl
    
         - name: Run SSL Expiry Check
           env:
             SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
           run: |
             python ssl_expiry_check.py
    

    This YAML file sets up a GitHub Workflow that runs on a daily schedule and can also be manually triggered.

  2. Python Script (ssl_expiry_check.py)

    The Python script ssl_expiry_check.py is responsible for checking the SSL expiry of the specified domains and sending alerts to Slack.

     import json
     import ssl
     import socket
     import datetime
     import requests
     import os
    
     def get_ssl_expiry(domain):
         context = ssl.create_default_context()
         with socket.create_connection((domain, 443)) as sock:
             with context.wrap_socket(sock, server_hostname=domain) as sslsock:
                 cert = sslsock.getpeercert()
                 return datetime.datetime.strptime(cert['notAfter'], "%b %d %H:%M:%S %Y %Z")
     def main():
         with open('domains.json') as config_file:
             config = json.load(config_file)
             domains = config.get('domains', [])
    
             for domain in domains:
                 expiry_date = get_ssl_expiry(domain)
                 remaining_days = (expiry_date - datetime.datetime.now()).days
                 message = (
                     f"SSL Expiry Alert\n"
                     f"* Domain : {domain}\n"
                     f"* Warning : The SSL certificate for {domain} will expire in {remaining_days} days."
                 )
    
                 payload = {"text": message}
                 slack_webhook_url = os.environ.get("SLACK_WEBHOOK_URL")
                 if slack_webhook_url:
                     response = requests.post(slack_webhook_url, json=payload)
                     print("Response content:", response.content)
                     print("Response status code:", response.status_code)
                     if response.status_code == 200:
                         print(f"Alert sent for {domain}")
                     else:
                         print(f"Failed to send alert for {domain}: {response.status_code}")
                 else:
                     print("No Slack webhook URL provided. Skipping alert.")
    
     if __name__ == "__main__":
         main()
    

    The Python script contains functions to retrieve SSL expiry information and send alerts.

  3. Domains Configuration File (domains.json)

    The domains.json file contains the list of domains to be checked for SSL expiry.

     {
         "domains": [
           "facebook.com",
           "tesla.com",
           "google.com"
         ]
     }
    

Workflow Execution

When the GitHub Workflow runs, it performs the following steps:

  1. Checks the SSL expiry status of each domain listed in domains.json.

  2. If a certificate is about to expire, it sends an alert message to Slack via a webhook.

Integrating with Slack

To integrate the GitHub Workflow with Slack for sending alerts, we need to create a Slack webhook and store it as a secret in the GitHub repository.

  1. Create Slack Webhook

    Create a Slack webhook by following these steps:

    • In your Slack workspace, navigate to Settings & administration > Manage apps.

    • Search for "Incoming WebHooks" and click "Add to Slack."

    • Follow the setup process to choose a channel and obtain the webhook URL.

  2. Store Webhook URL as GitHub Secret

    In your GitHub repository, go to Settings > Secrets and create a secret named SLACK_WEBHOOK_URL. Paste the Slack webhook URL as the secret's value.

Screenshots:

Slack:

Online tool to check if the expiry date is correct

Task 2

  • Do something in the Server (Instance, VM, etc) by authenticating into the server by using GitHub workflow.

  • Note: Make Sure you are handling the credentials securely

(Do not expose credentials anywhere).

Workflow Setup

  1. Workflow File (yaml file)

    To begin, we define a GitHub Workflow in a YAML file named ssh_aws_instance.yml. The workflow is triggered by a push event.

     name: SSH into AWS Instance
    
     on: [push]
    
     jobs:
       deploy:
         runs-on: ubuntu-latest
    
         steps:
           - name: Checkout code
             uses: actions/checkout@v2
    
           - name: Set up SSH
             uses: webfactory/ssh-agent@v0.5.1
             with:
               ssh-private-key: ${{ secrets.SSH_KEY }}
    
           - name: SSH into AWS Instance
             run: |
               ssh -o StrictHostKeyChecking=no <Public DNS> 'ls -l'
    

    This YAML file sets up a GitHub Workflow that is triggered by a push event. It performs the following steps:

    • Checks out the repository code.

    • Sets up the SSH agent with the private key stored in a GitHub secret.

    • Executes an SSH command to connect to the AWS instance and list files.

  2. Storing the SSH Private Key

    For security reasons, we store the SSH private key as a secret in the GitHub repository.

    • Go to your GitHub repository and navigate to Settings > Secrets.

    • Create a secret named SSH_KEY and paste your SSH private key as the value.

Screenshot: