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é