Skip to content

Hardening CIS Benchmarks

Introduction

Les CIS (Center for Internet Security) Benchmarks fournissent des recommandations de sécurité pour durcir les systèmes. Cette section applique les contrôles CIS à l'infrastructure OpenStack pour répondre aux exigences de sécurité gouvernementales.

Prérequis

  • OpenStack en production
  • Accès root aux serveurs
  • Compréhension des implications des changements de sécurité

Points à apprendre

Framework CIS pour OpenStack

graph TB
    subgraph CIS_Controls["CIS Controls"]
        os["1. OS Hardening"]
        net["2. Network Security"]
        access["3. Access Control"]
        log["4. Logging & Monitoring"]
        data["5. Data Protection"]
    end

    subgraph OpenStack_Components["OpenStack Components"]
        ctrl["Controllers"]
        compute["Compute Nodes"]
        storage["Storage (Ceph)"]
        network["Network Nodes"]
    end

    os --> ctrl
    os --> compute
    net --> network
    access --> ctrl
    log --> ctrl
    data --> storage

Hardening OS (Ubuntu/RHEL)

#!/bin/bash
# cis-os-hardening.sh

# === 1. Filesystem Configuration ===

# 1.1 Disable unused filesystems
cat >> /etc/modprobe.d/CIS.conf << EOF
install cramfs /bin/true
install freevxfs /bin/true
install jffs2 /bin/true
install hfs /bin/true
install hfsplus /bin/true
install squashfs /bin/true
install udf /bin/true
EOF

# 1.2 Ensure /tmp is configured
echo "tmpfs /tmp tmpfs defaults,rw,nosuid,nodev,noexec,relatime 0 0" >> /etc/fstab

# 1.3 Ensure nodev,nosuid,noexec on /dev/shm
echo "tmpfs /dev/shm tmpfs defaults,nodev,nosuid,noexec 0 0" >> /etc/fstab

# === 2. Services Configuration ===

# 2.1 Disable unnecessary services
systemctl disable --now avahi-daemon 2>/dev/null
systemctl disable --now cups 2>/dev/null
systemctl disable --now rpcbind 2>/dev/null
systemctl disable --now nfs-server 2>/dev/null

# 2.2 Ensure time synchronization
apt install -y chrony
systemctl enable --now chrony

# === 3. Network Configuration ===

# 3.1 Disable IP forwarding (sauf network nodes)
if [ "$ROLE" != "network" ]; then
    echo "net.ipv4.ip_forward = 0" >> /etc/sysctl.d/99-cis.conf
fi

# 3.2 Disable ICMP redirects
cat >> /etc/sysctl.d/99-cis.conf << EOF
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
EOF

# 3.3 Disable source routing
cat >> /etc/sysctl.d/99-cis.conf << EOF
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0
EOF

# 3.4 Enable TCP SYN cookies
echo "net.ipv4.tcp_syncookies = 1" >> /etc/sysctl.d/99-cis.conf

sysctl --system

# === 4. Logging ===

# 4.1 Configure rsyslog
apt install -y rsyslog
systemctl enable --now rsyslog

# 4.2 Ensure logging is configured
cat >> /etc/rsyslog.d/50-default.conf << EOF
*.emerg                                 :omusrmsg:*
auth,authpriv.*                         /var/log/auth.log
cron.*                                  /var/log/cron.log
EOF

# === 5. Access Control ===

# 5.1 Configure SSH
cat > /etc/ssh/sshd_config.d/cis.conf << EOF
Protocol 2
LogLevel INFO
MaxAuthTries 4
IgnoreRhosts yes
HostbasedAuthentication no
PermitRootLogin no
PermitEmptyPasswords no
PermitUserEnvironment no
ClientAliveInterval 300
ClientAliveCountMax 0
LoginGraceTime 60
Banner /etc/issue.net
AllowTcpForwarding no
X11Forwarding no
MaxSessions 4
UsePAM yes
EOF

systemctl restart sshd

# 5.2 Configure password policy
apt install -y libpam-pwquality
cat > /etc/security/pwquality.conf << EOF
minlen = 14
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
EOF

# 5.3 Configure account lockout
cat >> /etc/pam.d/common-auth << EOF
auth required pam_tally2.so onerr=fail audit silent deny=5 unlock_time=900
EOF

echo "Hardening complete. Reboot required."

Hardening Docker

#!/bin/bash
# cis-docker-hardening.sh

# === Docker daemon configuration ===
cat > /etc/docker/daemon.json << EOF
{
    "icc": false,
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "100m",
        "max-file": "3"
    },
    "live-restore": true,
    "userland-proxy": false,
    "no-new-privileges": true,
    "seccomp-profile": "/etc/docker/seccomp/default.json",
    "storage-driver": "overlay2",
    "userns-remap": "default"
}
EOF

# === Audit rules for Docker ===
cat >> /etc/audit/rules.d/docker.rules << EOF
-w /usr/bin/docker -k docker
-w /var/lib/docker -k docker
-w /etc/docker -k docker
-w /usr/lib/systemd/system/docker.service -k docker
-w /usr/lib/systemd/system/docker.socket -k docker
-w /etc/default/docker -k docker
-w /etc/docker/daemon.json -k docker
-w /usr/bin/containerd -k docker
-w /usr/bin/containerd-shim -k docker
-w /usr/bin/runc -k docker
EOF

augenrules --load
systemctl restart auditd

# === Redémarrer Docker ===
systemctl restart docker

Hardening Kolla-Ansible

# /etc/kolla/globals.yml - Options de sécurité

# TLS partout
kolla_enable_tls_internal: "yes"
kolla_enable_tls_external: "yes"
kolla_copy_ca_into_containers: "yes"

# Sécurité des containers
docker_namespace: "kolla"
openstack_logging_debug: "False"

# Mots de passe forts
passwords_file: "/etc/kolla/passwords.yml"
# Générer avec: kolla-genpwd

# Désactiver les options debug
nova_logging_debug: "False"
neutron_logging_debug: "False"

Checklist CIS OpenStack

# Audit CIS OpenStack

1_system_configuration:
  - name: "Ensure AIDE is installed"
    check: "dpkg -l aide"
    remediation: "apt install aide"

  - name: "Ensure filesystem integrity checking"
    check: "aideinit && aide --check"

  - name: "Ensure separate partition for /var/log"
    check: "mount | grep /var/log"

2_ssh_configuration:
  - name: "SSH Protocol 2"
    check: "sshd -T | grep protocol"
    expected: "protocol 2"

  - name: "SSH root login disabled"
    check: "sshd -T | grep permitrootlogin"
    expected: "permitrootlogin no"

3_openstack_api_security:
  - name: "TLS enabled on all endpoints"
    check: "openstack endpoint list -c URL | grep https"

  - name: "API rate limiting configured"
    check: "grep rate_limit /etc/kolla/config/*/api-paste.ini"

4_database_security:
  - name: "MariaDB TLS enabled"
    check: "docker exec mariadb mysql -e 'SHOW VARIABLES LIKE \"%ssl%\"'"

  - name: "Database users with minimal privileges"
    check: "docker exec mariadb mysql -e 'SELECT user,host FROM mysql.user'"

5_message_queue_security:
  - name: "RabbitMQ TLS enabled"
    check: "docker exec rabbitmq rabbitmqctl status | grep listeners"

6_logging_auditing:
  - name: "Audit daemon running"
    check: "systemctl is-active auditd"

  - name: "OpenStack audit logging enabled"
    check: "grep notification_driver /etc/kolla/config/*/*.conf"

Script d'audit automatisé

#!/bin/bash
# cis-audit.sh

REPORT_FILE="/var/log/cis-audit-$(date +%Y%m%d).txt"

echo "CIS Audit Report - $(date)" > $REPORT_FILE
echo "==============================" >> $REPORT_FILE

check() {
    local name=$1
    local cmd=$2
    local expected=$3

    result=$(eval $cmd 2>/dev/null)
    if echo "$result" | grep -q "$expected"; then
        echo "[PASS] $name" >> $REPORT_FILE
    else
        echo "[FAIL] $name" >> $REPORT_FILE
        echo "       Expected: $expected" >> $REPORT_FILE
        echo "       Got: $result" >> $REPORT_FILE
    fi
}

# SSH Checks
echo -e "\n=== SSH Configuration ===" >> $REPORT_FILE
check "SSH Protocol 2" "sshd -T | grep ^protocol" "protocol 2"
check "SSH PermitRootLogin" "sshd -T | grep ^permitrootlogin" "permitrootlogin no"
check "SSH PasswordAuth" "sshd -T | grep ^passwordauthentication" "passwordauthentication no"

# System Checks
echo -e "\n=== System Configuration ===" >> $REPORT_FILE
check "IP Forwarding disabled" "sysctl net.ipv4.ip_forward" "= 0"
check "SYN Cookies enabled" "sysctl net.ipv4.tcp_syncookies" "= 1"
check "Audit daemon" "systemctl is-active auditd" "active"

# Docker Checks
echo -e "\n=== Docker Configuration ===" >> $REPORT_FILE
check "Docker userns-remap" "docker info | grep 'Security Options'" "userns"
check "Docker no-new-privileges" "docker info" "no-new-privileges"

# OpenStack Checks
echo -e "\n=== OpenStack Configuration ===" >> $REPORT_FILE
check "TLS on Keystone" "openstack endpoint list --service identity -c URL -f value" "https"
check "Debug mode disabled" "grep -r 'debug = False' /etc/kolla/config/" "debug = False"

echo -e "\n=== Summary ===" >> $REPORT_FILE
PASS=$(grep -c "\[PASS\]" $REPORT_FILE)
FAIL=$(grep -c "\[FAIL\]" $REPORT_FILE)
echo "Passed: $PASS" >> $REPORT_FILE
echo "Failed: $FAIL" >> $REPORT_FILE

cat $REPORT_FILE

Diagramme de compliance

graph TB
    subgraph Infrastructure
        os["OS Hardening<br/>✓ 45/50 controls"]:::green
        ssh["SSH Security<br/>✓ 12/12 controls"]:::green
        docker["Docker Security<br/>⚠ 8/10 controls"]:::yellow
    end

    subgraph OpenStack
        api["API Security<br/>✓ 15/15 controls"]:::green
        tls["TLS Configuration<br/>✓ 8/8 controls"]:::green
        log["Logging/Audit<br/>⚠ 6/8 controls"]:::yellow
    end

    subgraph Data_Layer["Data Layer"]
        db["Database<br/>✓ 10/10 controls"]:::green
        mq["Message Queue<br/>✓ 5/5 controls"]:::green
        storage["Storage (Ceph)<br/>✓ 8/8 controls"]:::green
    end

    docker -.->|Actions:<br/>- Enable user namespaces<br/>- Configure seccomp profiles| docker
    log -.->|Actions:<br/>- Enable CADF audit<br/>- Configure log rotation| log

    classDef green fill:#90EE90,stroke:#333,stroke-width:2px
    classDef yellow fill:#FFFF99,stroke:#333,stroke-width:2px

Exemples pratiques

Ansible playbook hardening

# hardening.yml
---
- name: CIS Hardening
  hosts: all
  become: yes
  tasks:
    - name: Disable unused filesystems
      copy:
        dest: /etc/modprobe.d/CIS.conf
        content: |
          install cramfs /bin/true
          install freevxfs /bin/true
          install jffs2 /bin/true
          install hfs /bin/true
          install hfsplus /bin/true

    - name: Configure sysctl security parameters
      sysctl:
        name: "{{ item.name }}"
        value: "{{ item.value }}"
        state: present
        reload: yes
      loop:
        - { name: 'net.ipv4.conf.all.send_redirects', value: '0' }
        - { name: 'net.ipv4.conf.default.send_redirects', value: '0' }
        - { name: 'net.ipv4.tcp_syncookies', value: '1' }

    - name: Configure SSH
      template:
        src: sshd_config.j2
        dest: /etc/ssh/sshd_config.d/cis.conf
      notify: restart sshd

  handlers:
    - name: restart sshd
      service:
        name: sshd
        state: restarted

Ressources

Checkpoint

  • Script de hardening OS exécuté
  • SSH configuré selon CIS
  • Docker daemon sécurisé
  • Audit daemon configuré
  • Filesystem partitions sécurisées
  • Network hardening appliqué
  • Audit automatisé en place
  • Rapport de compliance généré