Aide-Mémoire Forseti Security
Aperçu
Forseti Security est une boîte à outils de sécurité open-source pour Google Cloud Platform (GCP) qui fournit une surveillance de sécurité complète, l'application de politiques et la gestion de conformité. Développé à l'origine par Google, Forseti Security aide les organisations à maintenir leur posture de sécurité dans leurs environnements GCP grâce à l'analyse automatisée, la validation de politiques et la surveillance en temps réel. La plateforme offre des capacités de gestion d'inventaire, d'application de politiques et de détection de violations qui sont essentielles pour maintenir une infrastructure cloud sécurisée et conforme.
💡 Fonctionnalités Clés : Analyse d'inventaire en temps réel, moteur d'application de politiques, surveillance de conformité, détection de violations de sécurité, remédiation automatisée, support multi-projets, moteur de règles personnalisées, et intégration avec Cloud Security Command Center.
Installation et Configuration
Prérequis et Configuration d'Environnement
# Vérification des exigences système
echo "Vérification des exigences système pour Forseti Security..."
# Vérifier l'installation Python (Python 3.6+ requis)
if command -v python3 &> /dev/null; then
python_version=$(python3 --version | awk '{print $2}')
echo "✅ Python trouvé : $python_version"
else
echo "❌ Python non trouvé. Installation de Python 3..."
sudo apt update
sudo apt install -y python3 python3-pip python3-venv
fi
# Vérifier l'installation de gcloud CLI
if command -v gcloud &> /dev/null; then
gcloud_version=$(gcloud --version | head -n1)
echo "✅ Google Cloud CLI trouvé : $gcloud_version"
else
echo "❌ Google Cloud CLI non trouvé. Installation de gcloud..."
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
gcloud init
fi
# Vérifier l'installation Terraform (pour configuration d'infrastructure)
if command -v terraform &> /dev/null; then
terraform_version=$(terraform --version | head -n1)
echo "✅ Terraform trouvé : $terraform_version"
else
echo "❌ Terraform non trouvé. Installation de Terraform..."
| wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg |
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
fi
# Vérifier l'installation Docker (pour déploiement conteneurisé)
if command -v docker &> /dev/null; then
docker_version=$(docker --version)
echo "✅ Docker trouvé : $docker_version"
else
echo "❌ Docker non trouvé. Installation de Docker..."
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
fi
# Vérifier les installations
echo "Vérification des installations..."
python3 --version
gcloud --version
terraform --version
docker --version
echo "Vérification des prérequis terminée"
Configuration de Projet GCP et Authentification
# Configurer le projet GCP pour Forseti Security
export PROJECT_ID="votre-projet-forseti"
export ORGANIZATION_ID="votre-id-organisation"
export BILLING_ACCOUNT="votre-compte-facturation"
# S'authentifier avec Google Cloud
gcloud auth login
gcloud auth application-default login
# Créer ou sélectionner le projet
gcloud projects create $PROJECT_ID --organization=$ORGANIZATION_ID
gcloud config set project $PROJECT_ID
# Lier le compte de facturation
gcloud billing projects link $PROJECT_ID --billing-account=$BILLING_ACCOUNT
# Activer les APIs requises
echo "Activation des APIs GCP requises..."
gcloud services enable cloudasset.googleapis.com
gcloud services enable cloudresourcemanager.googleapis.com
gcloud services enable compute.googleapis.com
gcloud services enable container.googleapis.com
gcloud services enable iam.googleapis.com
gcloud services enable logging.googleapis.com
gcloud services enable monitoring.googleapis.com
gcloud services enable securitycenter.googleapis.com
gcloud services enable sql-component.googleapis.com
gcloud services enable storage-api.googleapis.com
gcloud services enable storage-component.googleapis.com
# Attendre l'activation des APIs
echo "Attente de l'activation des APIs..."
sleep 30
# Vérifier l'activation des APIs
gcloud services list --enabled --filter="name:cloudasset.googleapis.com OR name:cloudresourcemanager.googleapis.com"
# Créer le compte de service Forseti
gcloud iam service-accounts create forseti-security \
--display-name="Compte de Service Forseti Security" \
--description="Compte de service pour les opérations Forseti Security"
# Obtenir l'email du compte de service
export FORSETI_SA_EMAIL="forseti-security@${PROJECT_ID}.iam.gserviceaccount.com"
# Accorder les permissions nécessaires au compte de service Forseti
echo "Attribution des permissions au compte de service Forseti..."
# Permissions au niveau organisation
gcloud organizations add-iam-policy-binding $ORGANIZATION_ID \
--member="serviceAccount:$FORSETI_SA_EMAIL" \
--role="roles/browser"
gcloud organizations add-iam-policy-binding $ORGANIZATION_ID \
--member="serviceAccount:$FORSETI_SA_EMAIL" \
--role="roles/cloudasset.viewer"
gcloud organizations add-iam-policy-binding $ORGANIZATION_ID \
--member="serviceAccount:$FORSETI_SA_EMAIL" \
--role="roles/iam.securityReviewer"
gcloud organizations add-iam-policy-binding $ORGANIZATION_ID \
--member="serviceAccount:$FORSETI_SA_EMAIL" \
--role="roles/securitycenter.findingsEditor"
# Permissions au niveau projet
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$FORSETI_SA_EMAIL" \
--role="roles/cloudsql.client"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$FORSETI_SA_EMAIL" \
--role="roles/compute.instanceAdmin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$FORSETI_SA_EMAIL" \
--role="roles/storage.objectAdmin"
# Créer et télécharger la clé du compte de service
gcloud iam service-accounts keys create forseti-security-key.json \
--iam-account=$FORSETI_SA_EMAIL
echo "Configuration du projet GCP terminée"
echo "Email du compte de service : $FORSETI_SA_EMAIL"
echo "Clé du compte de service sauvegardée dans : forseti-security-key.json"
Déploiement d'Infrastructure Terraform
# Créer la configuration Terraform pour l'infrastructure Forseti Security
mkdir -p forseti-terraform
cd forseti-terraform
# Créer la configuration Terraform principale
cat > main.tf << 'EOF'
terraform {
required_version = ">= 0.14"
required_providers {
google = {
source = "hashicorp/google"
version = "~> 4.0"
}
google-beta = {
source = "hashicorp/google-beta"
version = "~> 4.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
zone = var.zone
}
provider "google-beta" {
project = var.project_id
region = var.region
zone = var.zone
}
# Variables
variable "project_id" {
description = "ID du Projet GCP"
type = string
}
variable "organization_id" {
description = "ID de l'Organisation GCP"
type = string
}
variable "region" {
description = "Région GCP"
type = string
default = "us-central1"
}
variable "zone" {
description = "Zone GCP"
type = string
default = "us-central1-a"
}
variable "forseti_version" {
description = "Version de Forseti Security"
type = string
default = "v2.25.1"
}
# Réseau VPC pour Forseti
resource "google_compute_network" "forseti_network" {
name = "forseti-security-network"
auto_create_subnetworks = false
description = "Réseau VPC pour Forseti Security"
}
resource "google_compute_subnetwork" "forseti_subnetwork" {
name = "forseti-security-subnetwork"
ip_cidr_range = "10.0.0.0/24"
region = var.region
network = google_compute_network.forseti_network.id
description = "Sous-réseau pour Forseti Security"
}
# Règles de pare-feu
resource "google_compute_firewall" "forseti_server_allow_grpc" {
name = "forseti-server-allow-grpc"
network = google_compute_network.forseti_network.name
allow {
protocol = "tcp"
ports = ["50051"]
}
source_ranges = ["10.0.0.0/24"]
target_tags = ["forseti-server"]
description = "Autoriser la communication gRPC vers le serveur Forseti"
}
resource "google_compute_firewall" "forseti_allow_ssh" {
name = "forseti-allow-ssh"
network = google_compute_network.forseti_network.name
allow {
protocol = "tcp"
ports = ["22"]
}
source_ranges = ["0.0.0.0/0"]
target_tags = ["forseti-security"]
description = "Autoriser l'accès SSH aux instances Forseti"
}
# Instance Cloud SQL pour la base de données Forseti
resource "google_sql_database_instance" "forseti_database" {
name = "forseti-security-db"
database_version = "MYSQL_8_0"
region = var.region
deletion_protection = false
settings {
tier = "db-n1-standard-1"
activation_policy = "ALWAYS"
availability_type = "ZONAL"
backup_configuration {
enabled = true
start_time = "03:00"
location = var.region
binary_log_enabled = true
transaction_log_retention_days = 7
}
database_flags {
name = "slow_query_log"
value = "on"
}
ip_configuration {
ipv4_enabled = true
private_network = google_compute_network.forseti_network.id
require_ssl = true
authorized_networks {
name = "forseti-subnetwork"
value = "10.0.0.0/24"
}
}
maintenance_window {
day = 7
hour = 3
update_track = "stable"
}
}
depends_on = [google_service_networking_connection.private_vpc_connection]
}
# Connexion de service privé pour Cloud SQL
resource "google_compute_global_address" "private_ip_address" {
name = "forseti-private-ip-address"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.forseti_network.id
}
resource "google_service_networking_connection" "private_vpc_connection" {
network = google_compute_network.forseti_network.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.private_ip_address.name]
}
# Base de données Forseti
resource "google_sql_database" "forseti_database" {
name = "forseti_security"
instance = google_sql_database_instance.forseti_database.name
}
# Utilisateur de base de données Forseti
resource "google_sql_user" "forseti_user" {
name = "forseti_security_user"
instance = google_sql_database_instance.forseti_database.name
password = random_password.forseti_db_password.result
}
resource "random_password" "forseti_db_password" {
length = 16
special = true
}
# Bucket Cloud Storage pour Forseti
resource "google_storage_bucket" "forseti_server_bucket" {
name = "${var.project_id}-forseti-security-bucket"
location = var.region
force_destroy = true
uniform_bucket_level_access = true
versioning {
enabled = true
}
lifecycle_rule {
condition {
age = 30
}
action {
type = "Delete"
}
}
}
# Instance VM Serveur Forseti
resource "google_compute_instance" "forseti_server" {
name = "forseti-security-server"
machine_type = "n1-standard-2"
zone = var.zone
tags = ["forseti-server", "forseti-security"]
boot_disk {
initialize_params {
image = "ubuntu-os-cloud/ubuntu-2004-lts"
size = 50
type = "pd-standard"
}
}
network_interface {
network = google_compute_network.forseti_network.name
subnetwork = google_compute_subnetwork.forseti_subnetwork.name
access_config {
// IP publique éphémère
}
}
service_account {
email = google_service_account.forseti_server_sa.email
scopes = ["cloud-platform"]
}
metadata = {
enable-oslogin = "TRUE"
}
metadata_startup_script = templatefile("${path.module}/startup-script.sh", {
project_id = var.project_id
forseti_version = var.forseti_version
db_host = google_sql_database_instance.forseti_database.private_ip_address
db_name = google_sql_database.forseti_database.name
db_user = google_sql_user.forseti_user.name
db_password = google_sql_user.forseti_user.password
bucket_name = google_storage_bucket.forseti_server_bucket.name
organization_id = var.organization_id
})
depends_on = [
google_sql_database_instance.forseti_database,
google_storage_bucket.forseti_server_bucket
]
}
# Instance VM Client Forseti
resource "google_compute_instance" "forseti_client" {
name = "forseti-security-client"
machine_type = "n1-standard-1"
zone = var.zone
tags = ["forseti-client", "forseti-security"]
boot_disk {
initialize_params {
image = "ubuntu-os-cloud/ubuntu-2004-lts"
size = 30
type = "pd-standard"
}
}
network_interface {
network = google_compute_network.forseti_network.name
subnetwork = google_compute_subnetwork.forseti_subnetwork.name
access_config {
// IP publique éphémère
}
}
service_account {
email = google_service_account.forseti_client_sa.email
scopes = ["cloud-platform"]
}
metadata = {
enable-oslogin = "TRUE"
}
metadata_startup_script = templatefile("${path.module}/client-startup-script.sh", {
project_id = var.project_id
forseti_version = var.forseti_version
server_ip = google_compute_instance.forseti_server.network_interface[0].network_ip
})
}
# Comptes de service
resource "google_service_account" "forseti_server_sa" {
account_id = "forseti-server-gcp-sa"
display_name = "Compte de Service Serveur Forseti"
description = "Compte de service pour le serveur Forseti Security"
}
resource "google_service_account" "forseti_client_sa" {
account_id = "forseti-client-gcp-sa"
display_name = "Compte de Service Client Forseti"
description = "Compte de service pour le client Forseti Security"
}
# Liaisons IAM pour le compte de service serveur Forseti
resource "google_organization_iam_member" "forseti_server_browser" {
org_id = var.organization_id
role = "roles/browser"
member = "serviceAccount:${google_service_account.forseti_server_sa.email}"
}
resource "google_organization_iam_member" "forseti_server_cloudasset_viewer" {
org_id = var.organization_id
role = "roles/cloudasset.viewer"
member = "serviceAccount:${google_service_account.forseti_server_sa.email}"
}
resource "google_organization_iam_member" "forseti_server_security_reviewer" {
org_id = var.organization_id
role = "roles/iam.securityReviewer"
member = "serviceAccount:${google_service_account.forseti_server_sa.email}"
}
resource "google_organization_iam_member" "forseti_server_security_center" {
org_id = var.organization_id
role = "roles/securitycenter.findingsEditor"
member = "serviceAccount:${google_service_account.forseti_server_sa.email}"
}
# Liaisons IAM au niveau projet
resource "google_project_iam_member" "forseti_server_cloudsql_client" {
project = var.project_id
role = "roles/cloudsql.client"
member = "serviceAccount:${google_service_account.forseti_server_sa.email}"
}
resource "google_project_iam_member" "forseti_server_storage_admin" {
project = var.project_id
role = "roles/storage.objectAdmin"
member = "serviceAccount:${google_service_account.forseti_server_sa.email}"
}
# Sorties
output "forseti_server_ip" {
description = "Adresse IP interne du serveur Forseti"
value = google_compute_instance.forseti_server.network_interface[0].network_ip
}
output "forseti_server_external_ip" {
description = "Adresse IP externe du serveur Forseti"
value = google_compute_instance.forseti_server.network_interface[0].access_config[0].nat_ip
}
output "forseti_client_ip" {
description = "Adresse IP interne du client Forseti"
value = google_compute_instance.forseti_client.network_interface[0].network_ip
}
output "forseti_database_ip" {
description = "Adresse IP privée de la base de données Forseti"
value = google_sql_database_instance.forseti_database.private_ip_address
}
output "forseti_bucket_name" {
description = "Nom du bucket Forseti Security"
value = google_storage_bucket.forseti_server_bucket.name
}
EOF
# Créer le fichier de variables Terraform
cat > terraform.tfvars << EOF
project_id = "$PROJECT_ID"
organization_id = "$ORGANIZATION_ID"
region = "us-central1"
zone = "us-central1-a"
forseti_version = "v2.25.1"
EOF
# Créer le script de démarrage pour le serveur Forseti
cat > startup-script.sh << 'EOF'
#!/bin/bash
# Variables passées par Terraform
PROJECT_ID="${project_id}"
FORSETI_VERSION="${forseti_version}"
DB_HOST="${db_host}"
DB_NAME="${db_name}"
DB_USER="${db_user}"
DB_PASSWORD="${db_password}"
BUCKET_NAME="${bucket_name}"
ORGANIZATION_ID="${organization_id}"
# Mise à jour du système
apt-get update
apt-get install -y python3 python3-pip python3-venv git mysql-client
# Créer l'utilisateur forseti
useradd -m -s /bin/bash forseti
usermod -aG sudo forseti
# Créer le répertoire d'installation Forseti
mkdir -p /home/forseti
cd /home/forseti
# Télécharger et installer Forseti Security
git clone https://github.com/forseti-security/forseti-security.git
cd forseti-security
git checkout $FORSETI_VERSION
# Créer l'environnement virtuel Python
python3 -m venv forseti-env
source forseti-env/bin/activate
# Installer les dépendances Forseti
pip install --upgrade pip
pip install -r requirements.txt
pip install .
# Créer la configuration Forseti
mkdir -p /home/forseti/forseti-security/configs
cat > /home/forseti/forseti-security/configs/forseti_conf_server.yaml << YAML
global:
dummy_key: dummy_value
inventory:
gcs_path: gs://$BUCKET_NAME/inventory
scanner:
gcs_path: gs://$BUCKET_NAME/scanner
notifier:
gcs_path: gs://$BUCKET_NAME/notifier
explain:
gcs_path: gs://$BUCKET_NAME/explain
database:
host: $DB_HOST
user: $DB_USER
password: $DB_PASSWORD
name: $DB_NAME
model:
gcs_path: gs://$BUCKET_NAME/model
server:
host: 0.0.0.0
port: 50051
rules:
gcs_path: gs://$BUCKET_NAME/rules
YAML
# Configurer les permissions
chown -R forseti:forseti /home/forseti
chmod +x /home/forseti/forseti-security/install/gcp/scripts/run_forseti.sh
# Créer le service systemd pour Forseti Server
cat > /etc/systemd/system/forseti-server.service << SERVICE
[Unit]
Description=Forseti Security Server
After=network.target
[Service]
Type=simple
User=forseti
WorkingDirectory=/home/forseti/forseti-security
Environment=PATH=/home/forseti/forseti-security/forseti-env/bin
ExecStart=/home/forseti/forseti-security/forseti-env/bin/python -m google.cloud.forseti.services.server --config_file_path=/home/forseti/forseti-security/configs/forseti_conf_server.yaml
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
SERVICE
# Activer et démarrer le service Forseti
systemctl daemon-reload
systemctl enable forseti-server
systemctl start forseti-server
# Créer un script de vérification de santé
cat > /home/forseti/health_check.sh << 'HEALTH'
#!/bin/bash
echo "Vérification de l'état de Forseti Security Server..."
# Vérifier le statut du service
if systemctl is-active --quiet forseti-server; then
echo "✅ Service Forseti Server actif"
else
echo "❌ Service Forseti Server inactif"
systemctl status forseti-server
fi
# Vérifier la connectivité à la base de données
if mysql -h $DB_HOST -u $DB_USER -p$DB_PASSWORD -e "SELECT 1;" > /dev/null 2>&1; then
echo "✅ Connexion à la base de données réussie"
else
echo "❌ Échec de connexion à la base de données"
fi
# Vérifier l'accès au bucket
if gsutil ls gs://$BUCKET_NAME > /dev/null 2>&1; then
echo "✅ Accès au bucket Cloud Storage réussi"
else
echo "❌ Échec d'accès au bucket Cloud Storage"
fi
echo "Vérification de santé terminée"
HEALTH
chmod +x /home/forseti/health_check.sh
chown forseti:forseti /home/forseti/health_check.sh
echo "Installation du serveur Forseti Security terminée"
EOF
# Créer le script de démarrage pour le client Forseti
cat > client-startup-script.sh << 'EOF'
#!/bin/bash
# Variables passées par Terraform
PROJECT_ID="${project_id}"
FORSETI_VERSION="${forseti_version}"
SERVER_IP="${server_ip}"
# Mise à jour du système
apt-get update
apt-get install -y python3 python3-pip python3-venv git
# Créer l'utilisateur forseti
useradd -m -s /bin/bash forseti
usermod -aG sudo forseti
# Créer le répertoire d'installation Forseti
mkdir -p /home/forseti
cd /home/forseti
# Télécharger et installer Forseti Security
git clone https://github.com/forseti-security/forseti-security.git
cd forseti-security
git checkout $FORSETI_VERSION
# Créer l'environnement virtuel Python
python3 -m venv forseti-env
source forseti-env/bin/activate
# Installer les dépendances Forseti
pip install --upgrade pip
pip install -r requirements.txt
pip install .
# Créer la configuration client Forseti
mkdir -p /home/forseti/forseti-security/configs
cat > /home/forseti/forseti-security/configs/forseti_conf_client.yaml << YAML
server:
host: $SERVER_IP
port: 50051
YAML
# Configurer les permissions
chown -R forseti:forseti /home/forseti
# Créer des scripts utilitaires pour le client
cat > /home/forseti/forseti_client.sh << 'CLIENT'
#!/bin/bash
cd /home/forseti/forseti-security
source forseti-env/bin/activate
python -m google.cloud.forseti.services.cli --config_file_path=/home/forseti/forseti-security/configs/forseti_conf_client.yaml "$@"
CLIENT
chmod +x /home/forseti/forseti_client.sh
chown forseti:forseti /home/forseti/forseti_client.sh
echo "Installation du client Forseti Security terminée"
EOF
# Rendre les scripts exécutables
chmod +x startup-script.sh client-startup-script.sh
# Initialiser Terraform
terraform init
# Planifier le déploiement
terraform plan
echo "Configuration Terraform créée. Exécutez 'terraform apply' pour déployer l'infrastructure."
Opérations Forseti Security
Gestion d'Inventaire
# Se connecter au serveur Forseti
gcloud compute ssh forseti-security-server --zone=us-central1-a
# Activer l'environnement virtuel Forseti
sudo su - forseti
cd /home/forseti/forseti-security
source forseti-env/bin/activate
# Exécuter une analyse d'inventaire complète
forseti_inventory --config_file_path=configs/forseti_conf_server.yaml
# Lister les inventaires disponibles
forseti_inventory --list
# Obtenir des détails sur un inventaire spécifique
forseti_inventory --inventory_id=INVENTORY_ID --describe
# Exporter l'inventaire vers Cloud Storage
forseti_inventory --inventory_id=INVENTORY_ID --export --output_path=gs://votre-bucket/inventaire/
# Analyser l'inventaire par type de ressource
forseti_inventory --inventory_id=INVENTORY_ID --resource_type=project
forseti_inventory --inventory_id=INVENTORY_ID --resource_type=instance
forseti_inventory --inventory_id=INVENTORY_ID --resource_type=firewall
forseti_inventory --inventory_id=INVENTORY_ID --resource_type=bucket
# Comparer deux inventaires
forseti_inventory --compare --inventory_id_1=ID1 --inventory_id_2=ID2
# Nettoyer les anciens inventaires (garder les 5 derniers)
forseti_inventory --cleanup --keep=5
# Programmer des analyses d'inventaire automatiques
cat > /home/forseti/inventory_cron.sh << 'CRON'
#!/bin/bash
cd /home/forseti/forseti-security
source forseti-env/bin/activate
forseti_inventory --config_file_path=configs/forseti_conf_server.yaml
CRON
chmod +x /home/forseti/inventory_cron.sh
# Ajouter à crontab (exécution toutes les 6 heures)
(crontab -l 2>/dev/null; echo "0 */6 * * * /home/forseti/inventory_cron.sh") | crontab -
Configuration et Gestion des Politiques
# Créer un répertoire pour les règles personnalisées
mkdir -p /home/forseti/custom-rules
# Créer une règle personnalisée pour les instances Compute Engine
cat > /home/forseti/custom-rules/instance_security_rules.yaml << 'RULES'
rules:
- name: "Instances sans IP publique"
description: "Détecter les instances avec des IPs publiques non autorisées"
resource:
- type: "instance"
mode: blacklist
match:
- access_configs:
- type: "ONE_TO_ONE_NAT"
- name: "Instances avec ports SSH ouverts"
description: "Détecter les instances avec SSH ouvert depuis Internet"
resource:
- type: "firewall"
mode: blacklist
match:
- direction: "INGRESS"
source_ranges: ["0.0.0.0/0"]
allowed:
- ports: ["22"]
- name: "Buckets publics"
description: "Détecter les buckets Cloud Storage avec accès public"
resource:
- type: "bucket"
mode: blacklist
match:
- iam_policy:
bindings:
- members: ["allUsers", "allAuthenticatedUsers"]
RULES
# Créer une règle pour la conformité IAM
cat > /home/forseti/custom-rules/iam_compliance_rules.yaml << 'IAM_RULES'
rules:
- name: "Comptes de service avec clés externes"
description: "Détecter les comptes de service avec des clés créées en dehors de GCP"
resource:
- type: "serviceaccount"
mode: blacklist
match:
- keys:
- key_type: "USER_MANAGED"
- name: "Utilisateurs avec rôles d'administration"
description: "Surveiller les utilisateurs avec des rôles d'administration élevés"
resource:
- type: "iam_policy"
mode: whitelist
match:
- bindings:
- role: "roles/owner"
members: ["user:admin@votre-domaine.com"]
- role: "roles/editor"
members: ["user:admin@votre-domaine.com"]
- name: "Comptes de service inactifs"
description: "Identifier les comptes de service non utilisés depuis 90 jours"
resource:
- type: "serviceaccount"
mode: blacklist
match:
- last_authenticated: "> 90 days"
IAM_RULES
# Créer une règle pour la sécurité réseau
cat > /home/forseti/custom-rules/network_security_rules.yaml << 'NET_RULES'
rules:
- name: "Règles de pare-feu trop permissives"
description: "Détecter les règles de pare-feu avec des plages source trop larges"
resource:
- type: "firewall"
mode: blacklist
match:
- direction: "INGRESS"
source_ranges: ["0.0.0.0/0"]
allowed:
- ports: ["*"]
- name: "VPC sans logs de flux"
description: "Identifier les sous-réseaux sans logs de flux activés"
resource:
- type: "subnetwork"
mode: blacklist
match:
- enable_flow_logs: false
- name: "Instances sans étiquettes de sécurité"
description: "Détecter les instances sans étiquettes de classification de sécurité"
resource:
- type: "instance"
mode: blacklist
match:
- labels: null
- labels:
security_level: null
NET_RULES
# Télécharger les règles vers Cloud Storage
gsutil cp /home/forseti/custom-rules/*.yaml gs://votre-bucket-forseti/rules/
# Mettre à jour la configuration Forseti pour utiliser les règles personnalisées
cat >> /home/forseti/forseti-security/configs/forseti_conf_server.yaml << 'CONFIG'
rules:
gcs_path: gs://votre-bucket-forseti/rules/
scanner:
rules:
- instance_security_rules.yaml
- iam_compliance_rules.yaml
- network_security_rules.yaml
CONFIG
# Redémarrer le service Forseti pour appliquer les nouvelles règles
sudo systemctl restart forseti-server
# Vérifier que les règles sont chargées
forseti_scanner --rules_path=gs://votre-bucket-forseti/rules/ --list_rules
Analyse et Détection de Violations
# Exécuter une analyse complète avec toutes les règles
forseti_scanner --config_file_path=configs/forseti_conf_server.yaml
# Exécuter une analyse pour un type de ressource spécifique
forseti_scanner --config_file_path=configs/forseti_conf_server.yaml --resource_type=instance
forseti_scanner --config_file_path=configs/forseti_conf_server.yaml --resource_type=firewall
forseti_scanner --config_file_path=configs/forseti_conf_server.yaml --resource_type=bucket
# Exécuter une analyse avec des règles spécifiques
forseti_scanner --config_file_path=configs/forseti_conf_server.yaml --rules=instance_security_rules.yaml
# Lister les analyses disponibles
forseti_scanner --list_scans
# Obtenir les résultats d'une analyse spécifique
forseti_scanner --scan_id=SCAN_ID --get_results
# Exporter les résultats d'analyse
forseti_scanner --scan_id=SCAN_ID --export --format=json --output_path=/tmp/scan_results.json
forseti_scanner --scan_id=SCAN_ID --export --format=csv --output_path=/tmp/scan_results.csv
# Filtrer les violations par sévérité
forseti_scanner --scan_id=SCAN_ID --filter_severity=HIGH
forseti_scanner --scan_id=SCAN_ID --filter_severity=MEDIUM,HIGH
# Obtenir un résumé des violations
forseti_scanner --scan_id=SCAN_ID --summary
# Créer un rapport détaillé des violations
cat > /home/forseti/generate_violation_report.py << 'REPORT'
#!/usr/bin/env python3
import json
import sys
from datetime import datetime
def generate_violation_report(scan_results_file):
"""Générer un rapport détaillé des violations Forseti"""
with open(scan_results_file, 'r') as f:
scan_data = json.load(f)
report = {
'timestamp': datetime.now().isoformat(),
'summary': {
'total_violations': 0,
'high_severity': 0,
'medium_severity': 0,
'low_severity': 0
},
'violations_by_type': {},
'violations_by_project': {},
'detailed_violations': []
}
for violation in scan_data.get('violations', []):
# Compter les violations
report['summary']['total_violations'] += 1
severity = violation.get('severity', 'UNKNOWN')
if severity == 'HIGH':
report['summary']['high_severity'] += 1
elif severity == 'MEDIUM':
report['summary']['medium_severity'] += 1
elif severity == 'LOW':
report['summary']['low_severity'] += 1
# Grouper par type de ressource
resource_type = violation.get('resource_type', 'UNKNOWN')
if resource_type not in report['violations_by_type']:
report['violations_by_type'][resource_type] = 0
report['violations_by_type'][resource_type] += 1
# Grouper par projet
project_id = violation.get('project_id', 'UNKNOWN')
if project_id not in report['violations_by_project']:
report['violations_by_project'][project_id] = 0
report['violations_by_project'][project_id] += 1
# Ajouter aux violations détaillées
report['detailed_violations'].append({
'rule_name': violation.get('rule_name'),
'resource_type': resource_type,
'resource_id': violation.get('resource_id'),
'project_id': project_id,
'severity': severity,
'description': violation.get('violation_data', {}).get('description'),
'recommendation': violation.get('violation_data', {}).get('recommendation')
})
return report
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python3 generate_violation_report.py <scan_results.json>")
sys.exit(1)
report = generate_violation_report(sys.argv[1])
# Afficher le résumé
print("=== RAPPORT DE VIOLATIONS FORSETI SECURITY ===")
print(f"Généré le : {report['timestamp']}")
print(f"Total des violations : {report['summary']['total_violations']}")
print(f"Sévérité élevée : {report['summary']['high_severity']}")
print(f"Sévérité moyenne : {report['summary']['medium_severity']}")
print(f"Sévérité faible : {report['summary']['low_severity']}")
print()
print("=== VIOLATIONS PAR TYPE DE RESSOURCE ===")
for resource_type, count in report['violations_by_type'].items():
print(f"{resource_type}: {count}")
print()
print("=== VIOLATIONS PAR PROJET ===")
for project_id, count in report['violations_by_project'].items():
print(f"{project_id}: {count}")
print()
print("=== TOP 10 VIOLATIONS DÉTAILLÉES ===")
for i, violation in enumerate(report['detailed_violations'][:10], 1):
print(f"{i}. {violation['rule_name']} ({violation['severity']})")
print(f" Ressource: {violation['resource_type']} - {violation['resource_id']}")
print(f" Projet: {violation['project_id']}")
print(f" Description: {violation['description']}")
print()
# Sauvegarder le rapport complet
with open('/tmp/forseti_violation_report.json', 'w') as f:
json.dump(report, f, indent=2)
print(f"Rapport complet sauvegardé dans : /tmp/forseti_violation_report.json")
REPORT
chmod +x /home/forseti/generate_violation_report.py
# Utiliser le script de rapport
python3 /home/forseti/generate_violation_report.py /tmp/scan_results.json
Cette aide-mémoire couvre les fonctionnalités principales de Forseti Security pour implémenter une surveillance de sécurité complète et la gestion de conformité dans vos environnements Google Cloud Platform. Adaptez les commandes selon vos besoins spécifiques et votre environnement.