Configurazione e verifica della conformità al CIS

Questo documento spiega cos'è il benchmark CIS, come si relaziona a Container-Optimized OS (COS), come controllare lo stato di conformità nell'istanza e come risolvere i problemi in caso di errore.

Panoramica

Il Center for Internet Security (CIS) pubblica benchmark per i consigli di sicurezza delle best practice per varie piattaforme. Il benchmark CIS di Container-Optimized OS è un insieme di consigli per configurare le istanze che utilizzano Container-Optimized OS al fine di supportare una solida strategia di sicurezza. Le immagini COS x86 e ARM sono conformi a CIS.

Accesso al benchmark

Il benchmark CIS di Container-Optimized OS è disponibile sul sito web di CIS:

Livelli di consigli di sicurezza

CIS definisce i seguenti livelli di consigli per Container-Optimized OS.

Livello 1

I consigli a questo livello sono pensati per essere applicabili alla maggior parte degli ambienti. Questo livello include consigli come i seguenti:

  • La casualizzazione dello spazio degli indirizzi è attivata
  • /tmp non può essere utilizzato per l'esecuzione di file binari eseguibili
  • L'invio del reindirizzamento dei pacchetti è disattivato

Livello 2

I consigli a questo livello estendono i consigli di livello 1, creando un ambiente di sicurezza più rigoroso. I consigli di livello 2 non sono necessariamente applicabili a tutti i casi, in quanto potrebbero richiedere modifiche all'applicazione. Prima di applicarli, valuta i consigli di livello 2 per il tuo ambiente. Questo livello include consigli come i seguenti:

  • Esistono regole firewall per tutte le porte aperte
  • I reindirizzamenti ICMP e gli annunci del router non sono accettati
  • Il timeout della shell utente predefinita è di 900 secondi o meno

In che modo Container-Optimized OS è conforme ai benchmark CIS

A partire dalla milestone 97, le immagini di Container-Optimized OS sono conformi al livello 1 di CIS per impostazione predefinita e offrono un'opzione per la conformità al livello 2 di CIS. Forniamo anche uno scanner che puoi utilizzare per controllare la conformità della tua istanza ai livelli di consigli di CIS.

La configurazione CIS che definisce i consigli è presente in /usr/share/google/security/cis-compliance/cis_config.textproto. Lo scanner CIS utilizza la configurazione per controllare lo stato di conformità dell'istanza. I risultati di ogni esecuzione dello scanner di conformità di livello CIS vengono scritti in /var/lib/google/cis_scanner_scan_result.textproto. Questo file viene sovrascritto a ogni esecuzione dello scanner CIS. Se una delle scansioni di livello 1 o 2 di CIS non va a buon fine, il file cis_scanner_scan_result.textproto conterrà un elenco di tutti i controlli non riusciti.

Controllare lo stato di conformità dell'istanza

Le immagini di Container-Optimized OS forniscono i seguenti servizi systemd per il controllo e la configurazione della conformità:

  • cis-level1.service: attivato per impostazione predefinita e avviato all'avvio. Quando il servizio viene avviato, controlla se l'istanza è conforme al livello 1 di CIS.
  • cis-level2.service: disattivato per impostazione predefinita. Questo servizio ti consente di configurare l'istanza in modo che sia conforme al livello 2 di CIS e controlla lo stato di conformità rispetto al livello 1 e al livello 2.

Le sezioni seguenti spiegano come controllare lo stato di conformità dell'istanza e come automatizzare il processo di controllo.

Controllare lo stato di conformità di livello 1 di CIS

Per verificare se la tua istanza è conforme al livello 1 di CIS, controlla lo stato di cis-level1.service:

systemctl status cis-level1

L'output è simile al seguente:

Reading scan config from /usr/share/google/security/cis-compliance/cis_config.textproto
Running scan of 62 benchmarks
Scan status: SUCCEEDED
Found 0 non-compliant benchmarks
Writing scan results to /var/lib/google/cis_scanner_scan_result.textproto

Se vengono rilevati controlli non conformi, consulta Controlli di conformità di livello 1/livello 2 di CIS non riusciti.

cis-level1.service controlla la conformità di livello 1 di CIS una sola volta, all'avvio dell'istanza. Per configurare il controllo periodico della conformità, consulta Controllo periodico dello stato di conformità di CIS.

Configurare la conformità di livello 2 di CIS e controllare lo stato

Puoi utilizzare il servizio cis-level2 per configurare l'istanza in modo che sia conforme al livello 2 di CIS e per controllare lo stato di conformità rispetto al livello 1 e al livello 2. Il servizio systemd supporta tutti i consigli di livello 2 di CIS tranne i seguenti:

  • 4.1.1.2 Assicurati che la registrazione sia in esecuzione (ID: logging-service-running)

    Questo consiglio è disattivato per impostazione predefinita, ma può essere riattivato eliminando l'ID dall'elenco di disattivazione che si trova nel file /etc/cis-scanner/env_vars. Questo controllo esiste solo nelle milestone 109 e successive. Nelle milestone precedenti, l'attivazione della registrazione ti rende conforme a questo consiglio. Se annulli la disattivazione, l'esecuzione del servizio cis-level2 esegue uno script che avvia la registrazione di fluent-bit. Mantieni logging-service-running disattivato se non vuoi utilizzare la nostra registrazione predefinita o se vuoi utilizzare la tua registrazione.

Per i seguenti consigli, il servizio cis-level2 configura l'istanza, ma non verifica lo stato di conformità:

  • 105 e versioni precedenti:

    • 3.3.1.1 Assicurati che sia presente una policy del firewall di negazione predefinita per IPv6
    • 3.3.1.2 Assicurati che il traffico di loopback IPv6 sia configurato
    • 3.3.1.3 Assicurati che le connessioni in uscita e stabilite IPv6 siano configurate
    • 3.3.1.4 Assicurati che esistano regole firewall IPv6 per tutte le porte aperte
    • 3.3.2.1 Assicurati che sia presente una policy del firewall di negazione predefinita
    • 3.3.2.2 Assicurati che il traffico di loopback sia configurato
    • 3.3.2.3 Assicurati che le connessioni in uscita e stabilite siano configurate
  • 109 e versioni successive:

    • 3.3.1.4 Assicurati che esistano regole firewall IPv6 per tutte le porte aperte

Il servizio cis-level2 è disattivato per impostazione predefinita. Per avviare il servizio, esegui il seguente comando:

systemctl start cis-level2.service

Per verificare se l'istanza è stata configurata correttamente ed è conforme ai consigli di livello 2 di CIS, controlla lo stato di cis-level2.service:

systemctl status cis-level2

L'output è simile al seguente:

Reading scan config from /usr/share/google/security/cis-compliance/cis_config.textproto
Running scan of 112 benchmarks
Scan status: SUCCEEDED
Found 0 non-compliant benchmarks
Writing scan results to /var/lib/google/cis_scanner_scan_result.textproto

Se la configurazione dell'istanza non va a buon fine o se vengono rilevati controlli non conformi, consulta Risoluzione dei problemi.

Il servizio cis-level2 configura l'istanza e controlla la conformità di livello 2 di CIS una sola volta. Per configurare il controllo periodico della conformità, consulta Controllo periodico dello stato di conformità di CIS.

Controllo periodico dello stato di conformità di CIS

Le immagini di Container-Optimized OS includono i seguenti servizi per controllare periodicamente la conformità di CIS:

  • cis-compliance-scanner.service: controlla lo stato di conformità in base alle variabili di ambiente definite in /etc/cis-scanner/env_vars. Per impostazione predefinita, questo servizio controlla la conformità di livello 1 di CIS ed è disattivato.
  • cis-compliance-scanner.timer: esegue cis-compliance-scanner.service periodicamente. Il periodo predefinito è una volta al giorno.

Configurare il servizio scanner

cis-compliance-scanner.service è responsabile del controllo dello stato di conformità di CIS in base alle variabili di ambiente definite in /etc/cis-scanner/env_vars. Per impostazione predefinita, questo servizio controlla la conformità di livello 1 di CIS.

Per controllare la conformità di livello 2 di CIS, imposta la variabile di ambiente LEVEL in /etc/cis-scanner/env_vars su 2. Il file /etc/cis-scanner/env_vars è simile al seguente:

# cis-compliance-scanner.service environment variables
# The config file defines which checks to perform by cis_scanner
CONFIG="/usr/share/google/security/cis-compliance/cis_config.textproto"
# Where to store the result of the scan
RESULT="/var/lib/google/cis_scanner_scan_result.textproto"
# Upto which level to scan. It can be 1 or 2
LEVEL="2"
# Extra options that can be passed to cis_scanner
# For valid options, see output of `cis_scanner -h`
EXTRA_OPTIONS=""

Configurare il timer

Per configurare la scansione periodica della conformità, avvia l'unità cis-compliance-scanner.timer:

systemctl start cis-compliance-scanner.timer

Per impostazione predefinita, cis-compliance-scanner.timer avvia cis-compliance-scanner.service una volta al giorno. Per modificare il periodo di scansione, esegui l'override del campo OnUnitActiveSec dell'unità cis-compliance-scanner.timer:

sudo mkdir /etc/systemd/system/cis-compliance-scanner.timer.d
sudo tee /etc/systemd/system/cis-compliance-scanner.timer.d/override.conf <<EOF
[Unit]
Description=Run CIS Scanner once an hour
[Timer]
OnUnitActiveSec=1h
EOF

Questo esempio imposta il periodo dello scanner su una volta ogni ora.

Per applicare le modifiche, ricarica le unità systemd:

systemctl daemon-reload

Disattivare controlli di conformità di CIS specifici

I consigli di livello 1 e 2 di CIS sono pensati per essere applicabili alla maggior parte degli ambienti. Tuttavia ,alcuni consigli potrebbero non essere applicabili al tuo ambiente specifico. Per disattivare consigli specifici, utilizza la variabile di ambiente EXTRA_OPTIONS in /etc/cis-scanner/env_vars.

Il seguente file env_vars di esempio disattiva il consiglio etc-passwd-permissions:

# cis-compliance-scanner.service environment variables
# The config file defines which checks to perform by cis_scanner
CONFIG="/usr/share/google/security/cis-compliance/cis_config.textproto"
# Where to store the result of the scan
RESULT="/var/lib/google/cis_scanner_scan_result.textproto"
# Upto which level to scan. It can be 1 or 2
LEVEL="1"
# Extra options that can be passed to cis_scanner
# For valid options:`cis_scanner -h`
EXTRA_OPTIONS="--benchmark-opt-out-ids=etc-passwd-permissions"

Automatizzare l'attivazione e il controllo dello stato di conformità di CIS

Puoi automatizzare il processo di controllo della conformità per le tue istanze utilizzando cloud-init o la policy del sistema operativo. Gli esempi seguenti mostrano alcuni casi d'uso con ogni strumento:

  • Esempio 1: controlla la conformità di livello 1 di CIS una volta al giorno.
  • Esempio 2: controlla la conformità di livello 1 di CIS una volta all'ora.
  • Esempio 3: controlla la conformità di livello 2 di CIS una volta al giorno.
  • Esempio 4: disattiva un controllo di conformità di CIS specifico.

Utilizzo di cloud-init

Prima di provare gli esempi seguenti, assicurati di avere familiarità con la configurazione di un'istanza COS con cloud-init seguendo le istruzioni riportate in Utilizzo di cloud-init con il formato di configurazione cloud.

Esempio 1

La seguente configurazione di esempio avvia la scansione periodica di livello 1 di CIS con il periodo predefinito di una volta al giorno.

#cloud-config

runcmd:
# Check the compliance status of the instance once a day.
- systemctl start cis-compliance-scanner.timer

Esempio 2

Il seguente esempio configura la scansione periodica di livello 1 di CIS una volta ogni ora.

#cloud-config

# Override cis-compliance-scanner.timer with 1 hour frequency.
write_files:

- path: /etc/systemd/system/cis-compliance-scanner.timer.d/override.conf
  permissions: 0600
  owner: root
  content: |
    [Unit]
    Description=Run CIS Scanner once an hour

    [Timer]
    OnUnitActiveSec=1h

runcmd:
# Reload systemd units.
- systemctl daemon-reload
# Check the compliance status of the instance once an hour.
- systemctl start cis-compliance-scanner.timer

Esempio 3

Il seguente esempio configura la scansione periodica di livello 2 di CIS con il periodo predefinito di una volta al giorno.

#cloud-config

runcmd:
# Configure the instance for CIS level 2.
- systemctl start cis-level2.service
# Change the scan level to CIS Level 2.
- sed -i 's/^LEVEL=.*$/LEVEL="2"/' /etc/cis-scanner/env_vars
# Check the compliance status of the instance once a day.
- systemctl start cis-compliance-scanner.timer

Esempio 4

Il seguente esempio configura lo scanner in modo che venga eseguito una volta al giorno e disattiva un consiglio di CIS specifico.

#cloud-config

runcmd:
# Opt-out of the etc-passwd-permissions check.
- sed -i 's/^EXTRA.*$/EXTRA_OPTIONS="--benchmark-opt-out-ids=etc-passwd-permissions"/' /etc/cis-scanner/env_vars
# Check the compliance of the instance once a day.
- systemctl start cis-compliance-scanner.timer

Utilizzo della policy del sistema operativo

Puoi utilizzare una policy del sistema operativo per configurare la scansione del benchmark CIS. Prima di iniziare, assicurati di avere familiarità con la policy del sistema operativo, inclusi i seguenti aspetti:

Inoltre, devi aggiungere le opzioni instanceFilter e rollout negli esempi seguenti per il deployment.

Esempio 1

La seguente configurazione di esempio avvia la scansione periodica di livello 1 di CIS con il periodo predefinito di una volta al giorno.

# An OS policy to check CIS level 1 compliance once a day.
id: ensure-cis-level1-compliance-once-a-day-policy
mode: ENFORCEMENT
resourceGroups:
  - resources:
      id: ensure-cis-level1-compliance-once-a-day
      exec:
        validate:
          interpreter: SHELL
          # If cis-compliance-scanner.service is active, return an exit code
          # 100 to indicate that the instance is in compliant state.
          # Otherwise, return an exit code of 101 to run `enforce` step.
          script: |-
            is_active=$(systemctl is-active cis-compliance-scanner.timer)
            result=$(systemctl show -p Result --value cis-compliance-scanner.service)

            if [ "$is_active" == "active" ] && [ "$result" == "success" ]; then
              exit 100;
            else
              exit 101;
            fi
        enforce:
          interpreter: SHELL
          # COS 97 images are by-default CIS Level 1 compliant and there is no
          # additional configuration needed. However, if certain changes
          # cause non-compliance because of the workload on the instance, this
          # section can be used to automate to make fixes. For example, the
          # workload might generate a file that does not comply with the
          # recommended file permissions.
          # Return an exit code of 100 to indicate that the desired changes
          # successfully applied.
          script: |-
            # optional <your code>
            # Check the compliance of the instance once a day.
            systemctl start cis-compliance-scanner.timer && exit 100

Esempio 2

Il seguente esempio configura la scansione periodica di livello 1 di CIS una volta ogni ora.

# An OS policy to check CIS level 1 compliance once an hour.
id: ensure-cis-level1-compliance-once-an-hour-policy
mode: ENFORCEMENT
resourceGroups:
  - resources:
      id: ensure-cis-level1-compliance-once-an-hour
      exec:
        validate:
          interpreter: SHELL
          # If cis-compliance-scanner.service is active, return an exit code
          # 100 to indicate that the instance is in compliant state.
          # Otherwise, return an exit code of 101 to run `enforce` step.
          script: |-
            is_active=$(systemctl is-active cis-compliance-scanner.timer)
            result=$(systemctl show -p Result --value cis-compliance-scanner.service)

            if [ "$is_active" == "active" ] && [ "$result" == "success" ]; then
              exit 100;
            else
              exit 101;
            fi
        enforce:
          interpreter: SHELL
          # Return an exit code of 100 to indicate that the desired changes
          # were successfully applied.
          script: |-
            # Overwrite "OnUnitActiveSec" field of the
            # cis-compliance-scanner.timer to trigger
            # cis-compliance-scanner.service once an hour
            # instead of once a day.
            mkdir /etc/systemd/system/cis-compliance-scanner.timer.d
            tee /etc/systemd/system/cis-compliance-scanner.timer.d/override.conf <<EOF
            [Unit]
            Description=Run CIS Scanner once an hour

            [Timer]
            OnUnitActiveSec=1h
            EOF
            # Reload systemd units.
            systemctl daemon-reload
            # Check the compliance of the instance once an hour.
            systemctl start cis-compliance-scanner.timer && exit 100

Esempio 3

Il seguente esempio configura la scansione periodica di livello 2 di CIS con il periodo predefinito di una volta al giorno.

# An OS policy to check CIS level 2 compliance once a day.
id: ensure-cis-level2-compliance-once-a-day-policy
mode: ENFORCEMENT
resourceGroups:
  - resources:
      id: ensure-cis-level2-compliance-once-a-day
      exec:
        validate:
          interpreter: SHELL
          # If cis-compliance-scanner.service is active, return an exit code
          # 100 to indicate that the instance is in compliant state.
          # Otherwise, return an exit code of 101 to run `enforce` step.
          script: |-
            is_active=$(systemctl is-active cis-compliance-scanner.timer)
            result=$(systemctl show -p Result --value cis-compliance-scanner.service)

            if [ "$is_active" == "active" ] && [ "$result" == "success" ]; then
              exit 100;
            else
              exit 101;
            fi
        enforce:
          interpreter: SHELL
          # Return an exit code of 100 to indicate that the desired changes
          # were successfully applied.
          script: |-
            # Configure the instance for CIS level 2.
            systemctl start cis-level2.service
            # Change the scan level to 2.
            sed -i 's/^LEVEL=.*$/LEVEL="2"/' /etc/cis-scanner/env_vars
            # Check the compliance of the instance once a day.
            systemctl start cis-compliance-scanner.timer && exit 100

Esempio 4

Il seguente esempio configura lo scanner in modo che venga eseguito una volta al giorno e disattiva un consiglio di CIS specifico.

# An OS policy to opt-out of CIS check and check compliance status once a day.
id: exclude-cis-check-and-check-compliance-once-a-day-policy
mode: ENFORCEMENT
resourceGroups:
  - resources:
      id: exclude-cis-check-and-check-compliance-once-a-day
      exec:
        validate:
          interpreter: SHELL
          # If cis-compliance-scanner.service is active, return an exit code
          # 100 to indicate that the instance is in compliant state.
          # Otherwise, return an exit code of 101 to run `enforce` step.
          script: |-
            is_active=$(systemctl is-active cis-compliance-scanner.timer)
            result=$(systemctl show -p Result --value cis-compliance-scanner.service)

            if [ "$is_active" == "active" ] && [ "$result" == "success" ]; then
              exit 100;
            else
              exit 101;
            fi
        enforce:
          interpreter: SHELL
          # Return an exit code of 100 to indicate that the desired changes
          # were successfully applied.
          script: |-
            # Opt-out of the etc-passwd-permissions check.
            sed -i 's/^EXTRA.*$/EXTRA_OPTIONS="--benchmark-opt-out-ids=etc-passwd-permissions"/' /etc/cis-scanner/env_vars &&
            # Check the compliance of the instance once a day.
            systemctl start cis-compliance-scanner.timer
            # Ensure cis-compliance-scanner completes before exiting
            PID=$(systemctl show --property MainPID --value cis-compliance-scanner.service) &&
            timeout 5m bash -c -- 'while [ -e /proc/'$PID' ]; do echo "CIS Scanner with PID:'$PID' is still running"; sleep 1; done' &&
            exit 100

Risoluzione dei problemi

Questa sezione descrive come risolvere i problemi relativi alla scansione del benchmark CIS.

La configurazione di un'istanza in modo che sia conforme ai consigli di livello 2 di CIS non va a buon fine

Il servizio cis-level2 configura prima l'istanza in modo che sia conforme ai consigli di livello 2 di CIS e poi controlla la conformità sia al livello 1 che al livello 2 di CIS. Se la configurazione dell'istanza non va a buon fine, il servizio cis-level2 viene chiuso con il seguente messaggio di errore:

Job for cis-level2.service failed because the control process exited with error code.
See "systemctl status cis-level2.service" and "journalctl -xeu cis-level2.service" for details.

I log del journal menzioneranno i consigli che non sono stati applicati all'istanza e che hanno causato l'errore del servizio systemd cis-level2.

Il controllo di conformità di livello 1 o 2 di CIS non va a buon fine

I risultati della scansione per ogni esecuzione della conformità di livello CIS vengono scritti in /var/lib/google/cis_scanner_scan_result.textproto. Se una delle scansioni di livello 1 o 2 di CIS non va a buon fine, il file textproto conterrà l'elenco di tutti i controlli non riusciti, come nell'esempio seguente:

cat /var/lib/google/cis_scanner_scan_result.textproto

# Output
start_time: {
  seconds: 1648241700
  nanos: 763152171
}
end_time: {
  seconds: 1648241700
  nanos: 812992527
}
scanner_version: "1.1.4.3"
benchmark_version: "1.0.0"
status: {
  status: SUCCEEDED
}
non_compliant_benchmarks: {
  id: "etc-passwd-permissions"
  compliance_occurrence: {
    non_compliant_files: {
      path: "/etc/passwd"
      reason: "File permission is 0664, expected the following bits to be set: 0444 and the following bits to be clear: 0133"
    }
  }
}
compliant_benchmarks:  {
  id:  "etc-passwd-permissions"
  compliance_occurrence:  {}
}

Per risolvere i controlli non riusciti, utilizza il benchmark CIS e segui i passaggi nella sezione Remediation per il controllo non riuscito per rendere l'istanza conforme. Per trovare il consiglio corrispondente a un controllo non riuscito nel benchmark CIS, cerca l'non_compliant_benchmark's ID nel file di configurazione dello scanner CIS che si trova in /usr/share/google/security/cis-compliance/cis_config.textproto.