Skip to content

nelssec/qualys-sensor-guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 

Repository files navigation

Qualys Container Sensor Deployment Guide

Prerequisites

Infrastructure Requirements

Kubernetes Cluster: EKS cluster running Kubernetes 1.19+ Node Resources: Minimum 2 CPU cores and 4GB RAM per node where sensors will run Network Access: Outbound HTTPS (443) access to Qualys Cloud Platform Storage: Persistent storage for sensor data and logs (recommended: 10GB minimum)

Access Requirements

Qualys Subscription: Active Qualys VMDR or Container Security subscription Service Account: Qualys service account with Container Security permissions Kubernetes Access: kubectl access with cluster-admin privileges Helm: Helm 3.x installed and configured

Required Information

For Helm Chart Deployment: Customer ID: Your Qualys Customer ID Activation ID: Obtained from Qualys console Gateway URL: Your Qualys platform gateway URL CMSQAG Public URL: Your Qualys container management service URL AWS EKS Cluster ARN: Your cluster's AWS Resource Name (for AWS deployments) Cluster Name: Your cluster name (for self-managed K8s deployments)

For QScanner Integration: Access Token: Qualys API access token Pod: Your Qualys pod identifier (e.g., US2, US3, EU1, etc.)

Deployment Architecture

The Qualys Container Sensor deploys using the unified helm chart 'qualys-tc' which can install multiple sensor types.

Available Sensor Components: Cluster Sensor: Provides cluster-level visibility and scanning QCS Sensor: Container Security sensor for vulnerability scanning and SCA Admission Controller: Policy enforcement at container admission time Runtime Sensor: Real-time runtime protection and monitoring

Deployment Resources: DaemonSet: Runs on each node to scan running containers Deployment: Central sensor management component ConfigMaps: Configuration and policy definitions Secrets: Secure credential storage Services: Internal communication endpoints

QCS Sensor Features: SCA Scanning: Software Composition Analysis (performScaScan=true) Storage Driver: Enhanced container filesystem access (enableStorageDriver=true) Console Logs: Real-time logging output (enableConsoleLogs=true) Storage Options: Persistent or non-persistent storage modes

Step 1: Prepare Your Environment

Install Prerequisites

# Install Helm (if not already installed)
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# Verify Helm installation
helm version

Add Qualys Helm Repository

# Add Qualys Helm repository
helm repo add qualys-helm-chart https://qualys.github.io/Qualys-Helm-Charts/

# Update repository
helm repo update

Gather Required Information

Get your AWS EKS cluster ARN:

# Get your cluster ARN
aws eks describe-cluster --name <your-cluster-name>

# Look for output similar to:
# "arn": "arn:aws:eks:us-west-2:123456789012:cluster/your-cluster-name"

Step 2: Deploy Qualys Container Sensor

Comprehensive Sensor Deployment

Deploy all Qualys sensors using the official qualys-tc Helm chart:

# Install Qualys Container Sensor with all components enabled
helm upgrade --install qualys-tc qualys-helm-chart/qualys-tc \
  --set global.customerId=<your-customer-id> \
  --set global.activationId=<your-activation-id> \
  --set global.cmsqagPublicUrl=<your-cmsqag-public-url> \
  --set global.gatewayUrl=<your-gateway-url> \
  --set clusterSensor.enabled=true \
  --set qcsSensor.enabled=true \
  --set admissionController.enabled=true \
  --set runtimeSensor.enabled=true \
  --set qcsSensor.qualys.args.performScaScan=true \
  --set qcsSensor.qualys.args.enableStorageDriver=true \
  --set qcsSensor.qualys.args.withoutPersistentStorage=true \
  --set qcsSensor.qualys.args.enableConsoleLogs=true \
  --set qcsSensor.qualys.args.storageDriverType=overlay \
  --set global.clusterInfoArgs.cloudProvider=AWS \
  --set global.clusterInfoArgs.AWS.arn=<your-cluster-arn> \
  --namespace qualys \
  --create-namespace

Self-Managed Kubernetes Deployment

For self-managed Kubernetes clusters:

# Install for self-managed K8s cluster
helm upgrade --install qualys-tc qualys-helm-chart/qualys-tc \
  --set global.customerId=<your-customer-id> \
  --set global.activationId=<your-activation-id> \
  --set global.cmsqagPublicUrl=<your-cmsqag-public-url> \
  --set global.gatewayUrl=<your-gateway-url> \
  --set clusterSensor.enabled=true \
  --set qcsSensor.enabled=true \
  --set admissionController.enabled=true \
  --set runtimeSensor.enabled=true \
  --set qcsSensor.qualys.args.performScaScan=true \
  --set qcsSensor.qualys.args.enableStorageDriver=true \
  --set qcsSensor.qualys.args.withoutPersistentStorage=true \
  --set qcsSensor.qualys.args.enableConsoleLogs=true \
  --set qcsSensor.qualys.args.storageDriverType=overlay \
  --set global.clusterInfoArgs.cloudProvider=SELF_MANAGED_K8S \
  --set global.clusterInfoArgs.SELF_MANAGED_K8S.clusterName=<your-cluster-name> \
  --namespace qualys \
  --create-namespace

Selective Sensor Deployment

You can enable specific sensors based on your requirements:

# Deploy only Cluster Sensor and QCS Sensor
helm upgrade --install qualys-tc qualys-helm-chart/qualys-tc \
  --set global.customerId=<your-customer-id> \
  --set global.activationId=<your-activation-id> \
  --set global.cmsqagPublicUrl=<your-cmsqag-public-url> \
  --set global.gatewayUrl=<your-gateway-url> \
  --set clusterSensor.enabled=true \
  --set qcsSensor.enabled=true \
  --set admissionController.enabled=false \
  --set runtimeSensor.enabled=false \
  --set global.clusterInfoArgs.cloudProvider=AWS \
  --set global.clusterInfoArgs.AWS.arn=<your-cluster-arn> \
  --namespace qualys \
  --create-namespace

Deployment Verification

# Check deployment status
helm status qualys-tc -n qualys

# Verify all sensor pods are running
kubectl get pods -n qualys

# Check DaemonSets (for Runtime and QCS sensors)
kubectl get daemonset -n qualys

# Check Deployments (for Cluster sensor and Admission Controller)
kubectl get deployment -n qualys

# View specific sensor logs
kubectl logs -l app.kubernetes.io/name=cluster-sensor -n qualys --tail=50
kubectl logs -l app.kubernetes.io/name=qcs-sensor -n qualys --tail=50
kubectl logs -l app.kubernetes.io/name=runtime-sensor -n qualys --tail=50

Understanding Sensor Parameters

Global Configuration: global.customerId: Your unique Qualys customer identifier global.activationId: Activation token for sensor registration global.gatewayUrl: Qualys platform gateway for API communication global.cmsqagPublicUrl: Container management service endpoint

QCS Sensor Configuration: qcsSensor.qualys.args.performScaScan=true: Enables Software Composition Analysis qcsSensor.qualys.args.enableStorageDriver=true: Provides deeper filesystem access qcsSensor.qualys.args.withoutPersistentStorage=true: Uses ephemeral storage qcsSensor.qualys.args.storageDriverType=overlay: Specifies storage driver type

Cloud Provider Settings: For AWS: Use cloudProvider=AWS and provide cluster ARN For Self-managed: Use cloudProvider=SELF_MANAGED_K8S and provide cluster name

Step 3: Jenkins Integration with QScanner

What is QScanner

QScanner is a command-line utility that scans for vulnerabilities with inline vulnerability reports directly in your command-line interface. It integrates into existing workflows with zero installation required.

Key QScanner Features: Zero Installation: Standalone executable with no setup required Versatile Image Scanning: Supports Docker, Containerd, Cri-O, Podman, and remote registries Immediate Results: Instant vulnerability reports in console with multiple output formats Fast Performance: Utilizes local caching for quicker scans Policy Enforcement: Centralized policy management through Qualys Portal Comprehensive Security: Enterprise-grade vulnerability management

Download and Setup QScanner

# Download QScanner (replace with your platform-specific binary)
curl -L -o qscanner https://downloads.qualys.com/qscanner/linux/qscanner
chmod +x qscanner

# Verify installation
./qscanner --help

Jenkins Pipeline Integration

Basic Pipeline Example

pipeline {
    agent any
    
    environment {
        QUALYS_ACCESS_TOKEN = credentials('qualys-access-token')
        QUALYS_POD = 'US2'
        IMAGE_NAME = "myapp:${BUILD_NUMBER}"
    }
    
    stages {
        stage('Build') {
            steps {
                script {
                    // Build your container image
                    sh "docker build -t ${IMAGE_NAME} ."
                }
            }
        }
        
        stage('Security Scan with QScanner') {
            steps {
                script {
                    // Download QScanner if not available
                    sh '''
                        if [ ! -f "./qscanner" ]; then
                            curl -L -o qscanner https://downloads.qualys.com/qscanner/linux/qscanner
                            chmod +x qscanner
                        fi
                    '''
                    
                    // Run QScanner on the built image
                    sh """
                        ./qscanner image ${IMAGE_NAME} \
                          --access-token \$QUALYS_ACCESS_TOKEN \
                          --pod \$QUALYS_POD
                    """
                }
            }
            post {
                always {
                    // Archive any scan output files
                    archiveArtifacts artifacts: '*.json', allowEmptyArchive: true
                }
            }
        }
        
        stage('Deploy') {
            when {
                expression { 
                    currentBuild.result == null || currentBuild.result == 'SUCCESS' 
                }
            }
            steps {
                // Deploy only if scan passes
                sh 'kubectl apply -f k8s-manifests/'
            }
        }
    }
}

Advanced Pipeline with Multiple Images

pipeline {
    agent any
    
    environment {
        QUALYS_ACCESS_TOKEN = credentials('qualys-access-token')
        QUALYS_POD = 'US2'
        IMAGE_NAME = "myapp:${BUILD_NUMBER}"
        REGISTRY = "your-ecr-registry.amazonaws.com"
    }
    
    stages {
        stage('Build & Push') {
            steps {
                script {
                    // Build and push to registry
                    sh "docker build -t ${REGISTRY}/${IMAGE_NAME} ."
                    sh "docker push ${REGISTRY}/${IMAGE_NAME}"
                }
            }
        }
        
        stage('Security Scan') {
            steps {
                script {
                    // Download QScanner
                    sh '''
                        if [ ! -f "./qscanner" ]; then
                            curl -L -o qscanner https://downloads.qualys.com/qscanner/linux/qscanner
                            chmod +x qscanner
                        fi
                    '''
                    
                    // Get image ID from the pushed image
                    def imageId = sh(
                        script: "docker images ${REGISTRY}/${IMAGE_NAME} --format '{{.ID}}' | head -1",
                        returnStdout: true
                    ).trim()
                    
                    // Run QScanner on the image
                    sh """
                        ./qscanner image ${imageId} \
                          --access-token \$QUALYS_ACCESS_TOKEN \
                          --pod \$QUALYS_POD
                    """
                }
            }
            post {
                always {
                    // Archive any generated results
                    archiveArtifacts artifacts: '*.json', allowEmptyArchive: true
                }
                failure {
                    emailext(
                        subject: "Security scan failed for ${IMAGE_NAME}",
                        body: "Container image ${IMAGE_NAME} failed security scan. Check Jenkins logs for details.",
                        to: "${env.CHANGE_AUTHOR_EMAIL}"
                    )
                }
            }
        }
        
        stage('Deploy to EKS') {
            when {
                branch 'main'
                expression { currentBuild.result == null || currentBuild.result == 'SUCCESS' }
            }
            steps {
                withKubeConfig([credentialsId: 'eks-kubeconfig']) {
                    sh """
                        helm upgrade --install myapp ./helm-chart \
                          --set image.repository=${REGISTRY}/myapp \
                          --set image.tag=${BUILD_NUMBER} \
                          --namespace production
                    """
                }
            }
        }
    }
}

Multi-Stage Pipeline with Multiple Images

pipeline {
    agent any
    
    environment {
        QUALYS_ACCESS_TOKEN = credentials('qualys-access-token')
        QUALYS_POD = 'US2'
    }
    
    stages {
        stage('Parallel Security Scanning') {
            parallel {
                stage('Scan Development Images') {
                    steps {
                        script {
                            def devImages = ['dev-app:latest', 'dev-api:latest']
                            devImages.each { image ->
                                // Get image ID
                                def imageId = sh(
                                    script: "docker images ${image} --format '{{.ID}}' | head -1",
                                    returnStdout: true
                                ).trim()
                                
                                // Scan each image
                                sh """
                                    ./qscanner image ${imageId} \
                                      --access-token \$QUALYS_ACCESS_TOKEN \
                                      --pod \$QUALYS_POD
                                """
                            }
                        }
                    }
                }
                
                stage('Scan Production Images') {
                    steps {
                        script {
                            def prodImages = ['prod-app:latest', 'prod-api:latest']
                            prodImages.each { image ->
                                // Get image ID
                                def imageId = sh(
                                    script: "docker images ${image} --format '{{.ID}}' | head -1",
                                    returnStdout: true
                                ).trim()
                                
                                sh """
                                    ./qscanner image ${imageId} \
                                      --access-token \$QUALYS_ACCESS_TOKEN \
                                      --pod \$QUALYS_POD
                                """
                            }
                        }
                    }
                }
            }
        }
    }
}

Step 4: QScanner Configuration Options

Authentication Methods

# Using access token and pod identifier directly
./qscanner image myapp:latest --access-token $QUALYS_ACCESS_TOKEN --pod $QUALYS_POD

# Using image ID instead of name
./qscanner image ab0d83586b6e --access-token $QUALYS_ACCESS_TOKEN --pod $QUALYS_POD

# Using environment variables
export QUALYS_ACCESS_TOKEN=your-access-token
export QUALYS_POD=US2

./qscanner image myapp:latest --access-token $QUALYS_ACCESS_TOKEN --pod $QUALYS_POD

Basic Usage Examples

# Scan by image name
./qscanner image nginx:latest --access-token $QUALYS_ACCESS_TOKEN --pod US2

# Scan by image ID (more reliable in CI/CD)
./qscanner image ab0d83586b6e --access-token $QUALYS_ACCESS_TOKEN --pod US2

# Check available options
./qscanner --help
./qscanner image --help

Step 5: Monitoring and Maintenance

Monitor Sensor Health

# Check sensor connectivity in cluster
kubectl exec -it deployment/qualys-tc -n qualys -- \
  qualys-sensor status

# View detailed logs
kubectl logs deployment/qualys-tc -n qualys -f

# Check resource usage
kubectl top pods -n qualys

Upgrade Procedures

# Update Helm repository
helm repo update qualys-helm-chart

# Check for available updates
helm search repo qualys-helm-chart/qualys-tc --versions

# Upgrade sensor
helm upgrade qualys-tc qualys-helm-chart/qualys-tc \
  --namespace qualys \
  --reuse-values

QScanner Updates

# Check QScanner version
./qscanner --version

# Download latest version
curl -L -o qscanner-new https://downloads.qualys.com/qscanner/linux/qscanner
chmod +x qscanner-new
mv qscanner-new qscanner

Best Practices

Security Considerations

Store Qualys credentials securely in Jenkins credential store Use dedicated service accounts with minimal required permissions Enable network policies to restrict sensor communication Regularly rotate API credentials Monitor sensor logs for security events

Performance Optimization

Use QScanner's local caching for faster CI/CD builds Implement parallel scanning for multiple images Configure appropriate resource limits for Helm deployments Consider dedicated nodes for security scanning workloads

Operational Excellence

Implement monitoring and alerting for sensor health Automate sensor updates through GitOps workflows Maintain documentation for incident response procedures Regular backup of sensor configurations and policies Use centralized policy management in Qualys Portal

CI/CD Integration Tips

Cache QScanner binary in your build agents Use policy enforcement to maintain consistent security standards Generate multiple output formats for different stakeholders Integrate scan results with notification systems Archive scan results for compliance and audit purposes

Troubleshooting Common Issues

Sensor Connectivity Issues

# Check network connectivity from cluster
kubectl exec -it deployment/qualys-tc -n qualys -- \
  nslookup qualysapi.qg2.apps.qualys.com

# Verify cluster configuration
helm get values qualys-tc -n qualys

QScanner Issues

# Test basic QScanner functionality
./qscanner --help

# Run with a simple test image to verify connectivity
./qscanner image hello-world:latest --access-token $QUALYS_ACCESS_TOKEN --pod US2

# Check if image exists locally
docker images | grep myapp

Performance Issues

Increase resource limits in Helm values Use faster storage classes for persistent volumes Optimize QScanner caching in CI/CD environments

Additional Resources

Qualys Container Security Documentation: https://docs.qualys.com/en/cs/latest/ QScanner Documentation: https://docs.qualys.com/en/qscanner/latest/ Official Qualys Helm Charts: https://artifacthub.io/packages/helm/qualys-helm-chart/qualys-tc Qualys API Reference: https://www.qualys.com/docs/qualys-api-vmpc-user-guide.pdf EKS Best Practices Guide: https://aws.github.io/aws-eks-best-practices/

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published