I wrote a tool called Amigo that uses the GCP API to fetch an organization's project data and, with a set of customizable rules, searches for security risks!
How Amigo Works
i) Amigo retrieves the GCP project list and their attributes (defined in a config.yaml
file).
ii) For each attribute in a project, Amigo creates an updated report.
iii) Amigo checks the previous report for differences (verifying when the data was modified). If there is a diff, Amigo logs the report for this diff.
iv) Amigo saves the resources data in a database, and then it checks the custom rules specified in rules.yaml
, reporting everything that violates those rules.
v) The science generated by Amigo can be fed into ELK.
Setting up and Running Amigo
Setting a Virtual Environment
$ make venv
$ source venv/bin/activate
Installing Amigo
$ make install
Creating a Service Account
It should be done once, for the first time you run Amigo:
-
Create a project and a service account at https://console.cloud.google.com/iam-admin/serviceaccounts.
-
Add the IAM roles Security Reviewer and Viewer permissions to the service account.
-
Download the Service Account JSON credential file to a safe directory (e.g. your home directory). If amigo runs in other machines (or other people in the same organization is running Amigo), this key can be shared (and step 1. and 2. do not need to be repeated).
Setting gcloud
Install gcloud SDK and authenticate with:
$ gcloud auth application-default login
You can also check whether env variable GOOGLE_APPLICATION_CREDENTIALS
is pointing to the Service Account JSON credential file.
Setting the Config file
Copy config.yaml_example
to config.yaml
and customize it.
In the bottom of this file you can edit the attributes that you want to report on:
### Attributes to inspect
gcp_attributes:
compute:
- firewalls
- networks
- snapshots
Setting the Rules file
Inspect rules.yaml
either removing or adding rules that should be searched in the reports.
Running Amigo
Run amigo with:
$ sudo amigo
This retrieves the data from GCP and generates JSON reports. These reports will be saved where is reports_dir
in the config file.
It is advised to watch for STERR and STDOUT in the log_file
file defined in config.yaml
(default to amigo_log.txt
):
$ tail -f amigo_log.txt
Alerting with Amigo
Relevant reports (e.g., diff reports) are generated inside the directory defined as results_dir
, in the file results.log
(e.g., /log/amigo.log
). This is a JSON file that can be fed to ELK.
Creating Custom rules
Firewalls Resource
Firewall reports have this format:
{
"kind": "compute#firewall",
"network": "https://www.googleapis.com/compute/v1/projects/<name>/global/networks/default",
"direction": "INGRESS",
"sourceRanges": [
"0.0.0.0/0"
],
"name": "default-allow-icmp",
"priority": 65534,
"allowed": [
{
"IPProtocol": "icmp"
}
],
"creationTimestamp": <Time stamp>,
"id": <ID>,
"selfLink": "https://www.googleapis.com/compute/v1/projects/<name>/global/firewalls/default-allow-icmp",
"description": "Allow ICMP from anywhere"
}
Networks Resource
Snapshot reports have this format:
{
"kind": "compute#network",
"description": "Default network for the project",
"subnetworks": [
"https://www.googleapis.com/compute/v1/projects/<name>/regions/<region>/subnetworks/default",
],
"autoCreateSubnetworks": true,
"routingConfig": {
"routingMode": "REGIONAL"
},
"creationTimestamp": <Time stamp>,
"id": <ID>,
"selfLink": "https://www.googleapis.com/compute/v1/projects/<name>/global/networks/default",
"name": "default"
}
Snapshots Resource
Snapshot reports have this format:
{
"status": "READY",
"kind": "compute#snapshot",
"storageBytes": <number>,
"name": <name>,
"sourceDisk": "https://www.googleapis.com/compute/v1/projects/<name>/zones/us-central1-c/disks/deployhost",
"storageBytesStatus": "UP_TO_DATE",
"labelFingerprint": <code>,
"sourceDiskId": <ID>,
"diskSizeGb": <size>,
"licenses": [
"https://www.googleapis.com/compute/v1/projects/centos-cloud/global/licenses/centos-7"
],
"creationTimestamp": <time stamp>,
"id": <ID>,
"selfLink": "https://www.googleapis.com/compute/v1/projects/<name>/global/snapshots/snapshot-1-deployhost"
}
Instance Template Resource
Instance Template reports have this format:
{
"kind": "compute#instanceTemplate",
"description": "",
"properties": {
"machineType": <type>,
"tags": {
"items": [
<items>
]
},
"disks": [
{
"deviceName": "persistent-disk-0",
"kind": "compute#attachedDisk",
"initializeParams": {
"sourceImage": "global/images/<name>",
"diskType": "pd-standard"
},
"autoDelete": true,
"index": 0,
"boot": true,
"mode": "READ_WRITE",
"interface": "SCSI",
"type": "PERSISTENT"
}
],
"scheduling": {
"automaticRestart": true,
"preemptible": false,
"onHostMaintenance": "MIGRATE"
},
"serviceAccounts": [
{
"scopes": [
"https://www.googleapis.com/auth/compute.readonly"
],
"email": <service-account-email>
}
],
"metadata": {
"items": [
<metadata>
"kind": "compute#metadata",
}
},
"creationTimestamp": "2017-11-14T12:24:00.744-08:00",
"id": <ID>
"selfLink": "https://www.googleapis.com/compute/v1/projects/<project-name>/global/instanceTemplates/",
"name": <name>
}