Skip to content

This repo is a proof of concept on how to use Syft and Grype to scan you containers and use a job to aggregate all results and display these in grafana.

Notifications You must be signed in to change notification settings

pabes74/ContainerVulnerabilityScanner.POC

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C# .NET Badge Docker Badge Grafana Badge InfluxDB Badge

ContainerVulnarabilityScanner.POC

Retreives the results of a Syft/Grype container/dependency vulnerability scan from a build artifact in Azure DevOps and pushes this to a InFluxDB bucket. This also includes a Grafana dashboard definition to display these vulnerabilities.

Prerequisites

  1. Install .NET SDK:

    • Ensure you have the .NET SDK installed on your machine. You can download it from the .NET download page.
  2. Verify Installation:

    • Open a terminal or command prompt and run the following command to verify the installation:
      dotnet --version
    • This should output the version of the .NET SDK installed.

Docker

Docker is required to run the Syft/Grype container scans. Follow the steps below to install Docker on your system.

Install Docker on Windows

  1. Download Docker Desktop: Visit the Docker Desktop for Windows page and download the installer.

  2. Run the Installer: Follow the on-screen instructions to complete the installation.

  3. Verify Installation: Open PowerShell and run the following command to verify that Docker is installed correctly:

    docker --version

Alternatively, you can install Docker using PowerShell:

  1. Open PowerShell as Administrator: Right-click on the PowerShell icon and select "Run as administrator".

  2. Run the Installation Command: Execute the following command to install Docker:

    Invoke-WebRequest -Uri https://desktop.docker.com/win/stable/Docker%20Desktop%20Installer.exe -OutFile DockerDesktopInstaller.exe
    Start-Process -FilePath .\DockerDesktopInstaller.exe -ArgumentList "/quiet", "/norestart" -Wait
    Remove-Item -Force DockerDesktopInstaller.exe
  3. Start Docker Desktop: After installation, start Docker Desktop from the Start menu.

  4. Verify Installation: Run the following command to verify that Docker is installed correctly:

    docker --version

For more detailed instructions, refer to the official Docker documentation.

Get Started (local machine)

  1. Start the Containers: Open a terminal in your project directory and run the following command to start the InfluxDB and Grafana containers:

    docker-compose up -d

    The -d flag runs the containers in detached mode.

  2. Access InfluxDB and Grafana:

    • InfluxDB: Open your browser and go to http://localhost:8086 to access the InfluxDB UI.
    • Grafana: Open your browser and go to http://localhost:3000 to access the Grafana UI. Log in with the credentials specified in the docker-compose.yml file.

For more detailed instructions on using Docker Compose, refer to the official Docker Compose documentation.

Set up Azure DevOps

The actual creation of the of the vulnerability scanning of all dependencies is done in Azure DevOps. There need to be one or more pipelines that perform the scan using Syft and Grype. An example of a pipeline can be found here:

trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

variables:
  CONTAINER_IMAGE: '[your_container_registry].azurecr.io/[containername]:latest'

jobs:
- job: ScanContainer
  displayName: 'Scan Container for Vulnerabilities'
  steps:
  - task: AzureCLI@2
    inputs:
      azureSubscription: '[your_service_connection]'
      scriptType: 'bash'
      scriptLocation: 'inlineScript'
      inlineScript: |
        echo "Installing Syft"
        curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin

        echo "Installing Grype"
        curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
    displayName: 'Install Syft and Grype'

  - task: AzureCLI@2
    inputs:
      azureSubscription: '[your_service_connection]'
      scriptType: 'bash'
      scriptLocation: 'inlineScript'
      inlineScript: |
        echo "Logging into Azure Container Registry"
        az acr login --name [your_container_registry]
    displayName: 'Login to Azure Container Registry'

  - task: AzureCLI@2
    inputs:
      azureSubscription: '[your_service_connection]'
      scriptType: 'bash'
      scriptLocation: 'inlineScript'
      inlineScript: |
        echo "Generating SBOM with Syft"
        syft $CONTAINER_IMAGE -o json > sbom.json
    displayName: 'Generate SBOM with Syft'

  - task: AzureCLI@2
    inputs:
      azureSubscription: '[your_service_connection]'
      scriptType: 'bash'
      scriptLocation: 'inlineScript'
      inlineScript: |
        echo "Scanning for vulnerabilities with Grype"
        grype sbom:sbom.json
        # Save results in JSON format
        grype sbom:sbom.json -o json > grype-scan-results.json
    displayName: 'Scan for Vulnerabilities with Grype'
  
  - task: PublishBuildArtifacts@1
    inputs:
      PathtoPublish: 'grype-scan-results.json'
      ArtifactName: 'GrypeScanResults'
      publishLocation: 'Container'
    displayName: 'Publish Grype Scan Results as Build Artifact'

⚠️ NOTICE That the name of this pipeline must correspond with the postfix as configured in the appsettings.json. You can create as many pipelines for different services as needed as long as the postfix corresponds the results wil be picked up and pushed to Influx and eventualy displayed in grafana.

Once this is done, this app needs to able to access the Azure DevOps api's. Therefor you need to create a PAT token in Azure DevOps.

Creating a Personal Access Token (PAT) in Azure DevOps

A Personal Access Token (PAT) is required to authenticate and access Azure DevOps APIs. Follow the steps below to create a PAT:

Step-by-Step Guide

  1. Sign in to Azure DevOps:

  2. Navigate to User Settings:

    • Click on your profile picture in the top right corner.
    • Select "Security" from the dropdown menu.
  3. Create a New Token:

    • In the "Personal Access Tokens" section, click on "New Token".
  4. Configure the Token:

    • Name: Enter a descriptive name for the token (e.g., "SyftGrypeScraper Access Token").
    • Organization: Select the organization for which the token will be used.
    • Scopes: Choose the scopes required for your application. For accessing build artifacts and pipelines, you typically need:
      • Build (Read): To read build information.
      • Artifacts (Read): To read artifacts.
      • Project and Team (Read): To read project and team information.
    • Expiration: Set the expiration date for the token. Choose a duration that balances security and convenience.
  5. Create the Token:

    • Click on "Create" to generate the token.
  6. Copy the Token:

    • Important: Copy the token and store it securely. You will not be able to see the token again once you close the window.
    • Use this token in your application to authenticate API requests.

Example Usage in appsettings.json

Add the PAT token to your appsettings.json file:

{
  "AzureDevOps": {
    "Org": "[ORGANIZATION_NAME]",
    "Project": "[PROJECT_NAME]",
    "Pat": "[PESRONAL_ACCESS_TOKEN]",
    "PipelinePostfix": "Scan",
    "ArtifactName": "GrypeScanResults",
    "ApiVersion": "6.0"
  },
  "InfluxDb": {
    "Url": "http://localhost:8086/",
    "Token": "[INFLUXDB_TOKEN]",
    "Org": "GrypeScanOrg",
    "Bucket": "GrypeScanResults"
  },
  "ApplicationInsights": {
    "InstrumentationKey": "[INSTRUMENTATION_CONNECTION_STRING]"
  }
}

Setup InfluxDB

Step-by-Step Guide

  1. Access InfluxDB UI:

    • Open your web browser and go to http://localhost:8086.
  2. Sign In:

    • Sign in with your InfluxDB credentials.
  3. Create a Bucket:

    • Navigate to the "Buckets" section in the left-hand menu.
    • Click on "Create Bucket".
    • Name: Enter a name for your bucket (e.g., "GrypeScanResults").
    • Retention Rules: Set the retention period for the data in the bucket. You can choose a specific duration or keep it as "Infinite".
    • Click on "Create" to create the bucket.
  4. Create a Token:

    • Navigate to the "Tokens" section in the left-hand menu.
    • Click on "Generate Token" and select "Read/Write Token".
    • Description: Enter a description for the token (e.g., "GrypeScanResults Token").
    • Bucket Permissions: Select the bucket you created (e.g., "GrypeScanResults") and set the permissions to Read/Write.
    • Click on "Save" to generate the token.
    • Important: Copy the token and store it securely. You will not be able to see the token again once you close the window.

Example Usage in appsettings.json

Add the InfluxDB URL, token, organization, and bucket to your appsettings.json file:

{
  "AzureDevOps": {
    "Org": "your_organization",
    "Project": "your_project",
    "Pat": "your_pat_token",
    "ApiVersion": "6.0",
    "PipelinePostfix": "your_pipeline_postfix"
  },
  "InfluxDb": {
    "Url": "http://localhost:8086",
    "Token": "your_influxdb_token",
    "Org": "your_influxdb_org",
    "Bucket": "GrypeScanResults"
  }
}

Setup .NET Console Application

Step-by-Step Guide

  1. Navigate to the Project Directory:

    • Open a terminal or command prompt.
    • Navigate to the directory containing your .NET project. For example:
      cd path/to/your/project
  2. Run the Application:

    • Use the dotnet run command to run the application:
      dotnet run

Example Output

When you run the application, you should see output similar to the following:

Pipeline: Service-******* VulnerabilityScan, Latest Build Number: *****
Writing vulnerability GHSA-m5vv-6r4h-3vj9 to InfluxDB
Writing vulnerability GHSA-x674-v45j-fwxw to InfluxDB
Writing vulnerability GHSA-59j7-ghrg-fj52 to InfluxDB
Writing vulnerability GHSA-6qmf-mmc7-6c2p to InfluxDB
Writing vulnerability GHSA-g3q9-xf95-8hp5 to InfluxDB

Setup Grafana

If setting up grafana to run in Azure Container Apps you need a storage for the grafana configuration. There are multiple options, a relative simple way is a volume mapping unsing SQLite. If you want to to this follow this blog: https://blog.rishabkumar.com/grafana-on-azure-web-app-containers#heading-initiate-an-empty-sqlite-database

Step-by-Step Guide

1. Create a Personal Access Token (PAT) in InfluxDB

  1. Access InfluxDB UI:

    • Open your web browser and go to http://localhost:8086.
  2. Sign In:

    • Sign in with your InfluxDB credentials.
  3. Create a Token:

    • Navigate to the "Tokens" section in the left-hand menu.
    • Click on "Generate Token" and select "Read/Write Token".
    • Description: Enter a description for the token (e.g., "Grafana Access Token").
    • Bucket Permissions: Select the bucket you want to use (e.g., "GrypeScanResults") and set the permissions to Read/Write.
    • Click on "Save" to generate the token.
    • Important: Copy the token and store it securely. You will not be able to see the token again once you close the window.

2. Add InfluxDB as a Data Source in Grafana

  1. Add Data Source:

    • In Grafana, click on the "Configuration" (gear icon) in the left-hand menu.
    • Select "Data Sources".
    • Click on "Add data source".
  2. Configure InfluxDB Data Source:

    • Select "InfluxDB" from the list of data sources.
    • HTTP:
      • URL: http://influxdb:8086
    • Auth:
      • Token: Paste the PAT token you generated in InfluxDB.
    • InfluxDB Details:
      • Organization: Enter your InfluxDB organization name.
      • Bucket: Enter the bucket name (e.g., "GrypeScanResults").
    • Click on "Save & Test" to verify the connection.

3. Import Dashboard from JSON

Grafana Dashboard Screenshot

  1. Import Dashboard:
    • In Grafana, click on the "+" icon in the left-hand menu and select "Import".
    • Upload JSON File:
      • Click on "Upload JSON file" and select the GrafanaDashboard/Dashboard.json file from your project directory.
    • Load:
      • Click on "Load" to load the dashboard configuration.
    • Select Data Source:
      • Select the InfluxDB data source you configured earlier.
    • Click on "Import" to add the dashboard.

Deploy container images to Azure

Prerequisites

  1. Azure Subscription: Ensure you have an active Azure subscription.
  2. Azure DevOps Account: Ensure you have an Azure DevOps account and a project created.
  3. Service Connection: Create a service connection in Azure DevOps to your Azure subscription.

Steps

  1. Clone the Repository:
  • Clone the repository to your local machine or directly to your Azure DevOps project.
  1. Navigate to Pipelines:
  • In your Azure DevOps project, navigate to Pipelines > Pipelines.
  1. Create a New Pipeline:
  • Click on New Pipeline.
  • Select the repository where your code is hosted (e.g., Azure Repos Git, GitHub, etc.).
  • Follow the prompts to configure the pipeline.
  1. Configure the Pipeline:
  • When prompted to configure the pipeline, select Existing Azure Pipelines YAML file.
  • Choose the azure-pipelines.yml file located in the pipelines folder of your repository.
  1. Review and Run the Pipeline:
  • Review the pipeline configuration.
  • Click on Run to start the pipeline.
  1. Monitor the Pipeline:
  • Monitor the pipeline execution in the Azure DevOps portal.
  • Ensure all steps complete successfully.

The azure-pipelines.yml file includes steps to:

  • Build the Docker image.
  • Push the Docker image to Azure Container Registry (ACR).
  • Deploy the container to Azure Container Apps.

Summary

By following these steps, you will have set up AzureDevOps with vulnerability scanners, psuh this data to InfluxDB, and setup Grafana on localhost:3000, created a PAT in InfluxDB, added InfluxDB as a data source in Grafana, and imported a dashboard from a JSON file.

About

This repo is a proof of concept on how to use Syft and Grype to scan you containers and use a job to aggregate all results and display these in grafana.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published