it-swarm.com.de

So finden Sie nicht verwendete Amazon EC2-Sicherheitsgruppen

Ich versuche, einen Weg zu finden, um die Sicherheitsgruppen für Waisenkinder zu bestimmen, damit ich sie aufräumen und beseitigen kann. Kennt jemand eine Möglichkeit, ungenutzte Sicherheitsgruppen zu finden?.

Entweder über die Konsole oder mit den Befehlszeilentools funktioniert (Ausführen von Befehlszeilentools auf Linux- und OSX-Computern).

62
Ray

Hinweis: Dies berücksichtigt nur die Sicherheitsanwendung in EC2, nicht jedoch andere Dienste wie RDS. Um Sicherheitsgruppen einzubinden, die außerhalb von EC2 verwendet werden, müssen Sie noch mehr arbeiten. Die gute Sache ist, dass Sie aktive Sicherheitsgruppen nicht einfach löschen können (wenn nicht sogar möglich), wenn Sie einen zugehörigen Dienst vermissen.

Mit dem neueren AWS CLI-Tool habe ich einen einfachen Weg gefunden, um das zu bekommen, was ich brauche:

Rufen Sie zunächst eine Liste aller Sicherheitsgruppen ab

 aws ec2 describe-security-groups --query 'SecurityGroups[*].GroupId'  --output text | tr '\t' '\n'

Dann werden alle Sicherheitsgruppen an eine Instanz gebunden und dann an sort und dann an uniq geleitet:

aws ec2 describe-instances --query 'Reservations[*].Instances[*].SecurityGroups[*].GroupId' --output text | tr '\t' '\n' | sort | uniq

Dann stellen Sie es zusammen und vergleichen Sie die beiden Listen und sehen Sie anhand der Master-Liste, was nicht verwendet wird:

 comm -23  <(aws ec2 describe-security-groups --query 'SecurityGroups[*].GroupId'  --output text | tr '\t' '\n'| sort) <(aws ec2 describe-instances --query 'Reservations[*].Instances[*].SecurityGroups[*].GroupId' --output text | tr '\t' '\n' | sort | uniq)
66
Ray

Wenn Sie alle Sicherheitsgruppen in der EC2-Konsole auswählen und dann auf Aktionen -> Sicherheitsgruppen löschen klicken, wird ein Popup-Fenster mit der Meldung angezeigt, dass Sie Sicherheitsgruppen nicht löschen können, die mit Instanzen, anderen Sicherheitsgruppen oder Netzwerkschnittstellen verbunden sind listet die Sicherheitsgruppen auf, die Sie löschen können; dh die nicht verwendeten Sicherheitsgruppen :)

35
NLail

Dies ist der in boto (Python SDK für AWS) geschriebene Beispielcode, um die Sicherheitsgruppe nach der Anzahl der Instanzen aufzulisten, denen sie zugeordnet ist.

Sie können diese Logik verwenden, um dieselbe Funktion auch in der Befehlszeile zu erhalten

Boto-Code

import boto
ec2 = boto.connect_ec2()
sgs = ec2.get_all_security_groups()
for sg in sgs:
    print sg.name, len(sg.instances())

Ausgabe

Security-Group-1 0
Security-Group-2 1
Security-Group-3 0
Security-Group-4 3
21
Naveen Vijay

Nach etwa einem Jahr ungeprüften Einsatz war es für mich notwendig, meine AWS EC2-Sicherheitsgruppen zu überprüfen und alte, nicht verwendete Gruppen zu bereinigen.

Dies war eine schwierige Aufgabe, die über die Web-GUI ausgeführt werden musste. Daher habe ich zur AWS-CLI gesucht, um die Aufgabe zu erleichtern. Ich habe bei StackOverflow einen Anfang gefunden, wie das geht, aber es war noch lange nicht abgeschlossen. Also entschied ich mich, mein eigenes Skript zu schreiben. Ich habe die AWS CLI, MySQL und ein paar "Bash-foo" verwendet, um Folgendes auszuführen:

  1. Rufen Sie eine Liste aller EC2-Sicherheitsgruppen ab Ich speichere die Gruppen-ID, den Gruppennamen und die Beschreibung in einer Tabelle mit dem Namen "groups" in einer MySQL-Datenbank mit dem Namen aws_security_groups auf dem localhost. Die Gesamtzahl der gefundenen Gruppen wird dem Benutzer gemeldet.

  2. Rufen Sie eine Liste aller Sicherheitsgruppen ab, die den folgenden Diensten zugeordnet sind, und schließen Sie sie aus der Tabelle aus: EC2-Istanzen EC2 Elastic Load BalancersAWS RDS-InstanzenAWS OpsWorks (sollte nicht entfernt werden per Amazon) Standard-Sicherheitsgruppen (Kann nicht gelöscht werden) ElastiCache

Für jeden Dienst melde ich die Anzahl der Gruppen an, die nach Abschluss des Ausschlusses in der Tabelle verbleiben.

  1. Schließlich zeige ich die Gruppen-ID, den Gruppennamen und die Beschreibung für die verbleibenden Gruppen an. Dies sind die "nicht verwendeten" Gruppen, die geprüft und/oder gelöscht werden müssen. Ich habe festgestellt, dass SGs zwischen Instanzen und Elastic Load Balancers (ELBs) sich häufig auf einander beziehen. Es empfiehlt sich, einige manuelle Untersuchungen durchzuführen, um sicherzustellen, dass sie wirklich nicht verwendet werden, bevor die Querverweise entfernt und die Sicherheitsgruppen gelöscht werden. Aber mein Drehbuch reduziert das zumindest auf etwas Verwaltbareres.

HINWEISE: 1. Sie sollten eine Datei erstellen, um Ihren MySQL-Host, Ihren Benutzernamen und Ihr Kennwort zu speichern und die Variable $ DBCONFIG darauf zu verweisen. Es sollte so strukturiert sein:

[mysql]
Host=your-mysql-server-Host.com
user=your-mysql-user
password=your-mysql-user-password
  1. Sie können den Namen der Datenbank ändern, wenn Sie möchten. Stellen Sie sicher, dass Sie die Variable $ DB im Skript ändern

Lassen Sie mich wissen, wenn Sie dies als nützlich empfinden oder über Kommentare, Korrekturen oder Verbesserungen verfügen.

Hier ist das Skript.

#!/bin/bash
# Initialize Variables
DBCONFIG="--defaults-file=mysql-defaults.cnf"
DB="aws_security_groups"
SGLOOP=0
EC2LOOP=0
ELBLOOP=0
RDSLOOP=0
DEFAULTLOOP=0
OPSLOOP=0
CACHELOOP=0
DEL_GROUP=""

# Function to report back # of rows
function Rows {
    ROWS=`echo "select count(*) from groups" | mysql $DBCONFIG --skip-column-names $DB`
#   echo -e "Excluding $1 Security Groups.\nGroups Left to audit: "$ROWS
    echo -e $ROWS" groups left after Excluding $1 Security Groups."
}


# Empty the table
echo -e "delete from groups where groupid is not null" | mysql $DBCONFIG $DB

# Get all Security Groups
aws ec2 describe-security-groups --query "SecurityGroups[*].[GroupId,GroupName,Description]" --output text > /tmp/security_group_audit.txt
while IFS=$'\t' read -r -a myArray
do
    if [ $SGLOOP -eq 0 ];
    then
        VALUES="(\""${myArray[0]}"\",\""${myArray[1]}"\",\""${myArray[2]}"\")"
    else
        VALUES=$VALUES",(\""${myArray[0]}"\",\""${myArray[1]}"\",\""${myArray[2]}"\")"
    fi
    let SGLOOP="$SGLOOP + 1"
done < /tmp/security_group_audit.txt
echo -e "insert into groups (groupid, groupname, description) values $VALUES" | mysql $DBCONFIG $DB
echo -e $SGLOOP" security groups total."


# Exclude Security Groups assigned to Instances
for groupId in `aws ec2 describe-instances --output json | jq -r ".Reservations[].Instances[].SecurityGroups[].GroupId" | sort | uniq`
do
    if [ $EC2LOOP -eq 0 ];
    then
        DEL_GROUP="'$groupId'"
    else
        DEL_GROUP=$DEL_GROUP",'$groupId'"
    fi
    let EC2LOOP="$EC2LOOP + 1"
done
echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "EC2 Instance"
DEL_GROUP=""


# Exclude groups assigned to Elastic Load Balancers
for elbGroupId in `aws elb describe-load-balancers --output json | jq -c -r ".LoadBalancerDescriptions[].SecurityGroups" | tr -d "\"[]\"" | sort | uniq`
do
    if [ $ELBLOOP -eq 0 ];
    then
        DEL_GROUP="'$elbGroupId'"
    else
        DEL_GROUP=$DEL_GROUP",'$elbGroupId'"
    fi
    let ELBLOOP="$ELBLOOP + 1"
done
    echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "Elastic Load Balancer"
DEL_GROUP=""


# Exclude groups assigned to RDS
for RdsGroupId in `aws rds describe-db-instances --output json | jq -c -r ".DBInstances[].VpcSecurityGroups[].VpcSecurityGroupId" | sort | uniq`
do
    if [ $RDSLOOP -eq 0 ];
    then
        DEL_GROUP="'$RdsGroupId'"
    else
        DEL_GROUP=$DEL_GROUP",'$RdsGroupId'"
    fi
    let RDSLOOP="$RDSLOOP + 1"
done
    echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "RDS Instances"
DEL_GROUP=""

# Exclude groups assigned to OpsWorks
for OpsGroupId in `echo -e "select groupid from groups where groupname like \"AWS-OpsWorks%\"" | mysql $DBCONFIG $DB`
do
    if [ $OPSLOOP -eq 0 ];
    then
        DEL_GROUP="'$OpsGroupId'"
    else
        DEL_GROUP=$DEL_GROUP",'$OpsGroupId'"
    fi
    let OPSLOOP="$OPSLOOP + 1"
done
echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "OpsWorks"
DEL_GROUP=""

# Exclude default groups (can't be deleted)
for DefaultGroupId in `echo -e "select groupid from groups where groupname like \"default%\"" | mysql $DBCONFIG $DB`
do
    if [ $DEFAULTLOOP -eq 0 ];
    then
        DEL_GROUP="'$DefaultGroupId'"
    else
        DEL_GROUP=$DEL_GROUP",'$DefaultGroupId'"
    fi
    let DEFAULTLOOP="$DEFAULTLOOP + 1"
done
echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "Default"
DEL_GROUP=""

# Exclude Elasticache groups
for CacheGroupId in `aws elasticache describe-cache-clusters --output json | jq -r ".CacheClusters[].SecurityGroups[].SecurityGroupId" | sort | uniq`
do
    if [ $CACHELOOP -eq 0 ];
    then
        DEL_GROUP="'$CacheGroupId'"
    else
        DEL_GROUP=$DEL_GROUP",'$CacheGroupId'"
    fi
    let CACHELOOP="$CACHELOOP + 1"
done
echo -e "delete from groups where groupid in ($DEL_GROUP)" | mysql $DBCONFIG $DB
Rows "ElastiCache"

# Display Security Groups left to audit / delete
echo "select * from groups order by groupid" | mysql $DBCONFIG $DB | sed 's/groupid\t/groupid\t\t/'

Und hier ist die SQL zum Erstellen der Datenbank.

-- MySQL dump 10.13  Distrib 5.5.41, for debian-linux-gnu (x86_64)
--
-- Host:  localhost   Database: aws_security_groups
-- ------------------------------------------------------
-- Server version   5.5.40-log

/*!40101 SET @[email protected]@CHARACTER_SET_CLIENT */;
/*!40101 SET @[email protected]@CHARACTER_SET_RESULTS */;
/*!40101 SET @[email protected]@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @[email protected]@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @[email protected]@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @[email protected]@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `groups`
--

DROP TABLE IF EXISTS `groups`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `groups` (
  `groupid` varchar(12) DEFAULT NULL,
  `groupname` varchar(200) DEFAULT NULL,
  `description` varchar(200) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `groups`
--

LOCK TABLES `groups` WRITE;
/*!40000 ALTER TABLE `groups` DISABLE KEYS */;
/*!40000 ALTER TABLE `groups` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET [email protected]_TIME_ZONE */;

/*!40101 SET [email protected]_SQL_MODE */;
/*!40014 SET [email protected]_FOREIGN_KEY_CHECKS */;
/*!40014 SET [email protected]_UNIQUE_CHECKS */;
/*!40101 SET [email protected]_CHARACTER_SET_CLIENT */;
/*!40101 SET [email protected]_CHARACTER_SET_RESULTS */;
/*!40101 SET [email protected]_COLLATION_CONNECTION */;
/*!40111 SET [email protected]_SQL_NOTES */;

-- Dump completed on 2015-01-27 16:07:44
2
user2962402

Verwenden des node.js AWS SDK Ich kann bestätigen, dass AWS das Löschen von Sicherheitsgruppen nicht zulässt. Ich habe ein Skript geschrieben, das einfach versucht, alle Gruppen zu löschen und die Fehler elegant zu behandeln. Dies funktioniert für klassische und moderne VPCs. Die Fehlermeldung ist unten zu sehen.

Err { [DependencyViolation: resource sg-12345678 has a dependent object]
  message: 'resource sg-12345678 has a dependent object',
  code: 'DependencyViolation',
  time: Mon Dec 07 2015 12:12:43 GMT-0500 (EST),
  statusCode: 400,
  retryable: false,
  retryDelay: 30 }
2
Michael Connor

Unter anderem melden ScoutSuite und Prowler nicht verwendete EC2-Sicherheitsgruppen. Beide sind Open Source.

1
Nan Zhong

Ein Boto-Beispiel zum Drucken der Gruppen-IDs und Namen only der Sicherheitsgruppen, für die keine aktuellen Instanzen vorhanden sind.

Es zeigt auch, wie Sie angeben, um welche Region es sich handelt.

import boto
import boto.ec2
EC2_REGION='ap-southeast-2'
ec2region = boto.ec2.get_region(EC2_REGION)
ec2 = boto.connect_ec2(region=ec2region)
sgs = ec2.get_all_security_groups()
for sg in sgs:
    if len(sg.instances()) == 0:
        print ("{0}\t{1}".format(sg.id, sg.name))

Um zu bestätigen, welche Sicherheitsgruppen sind noch verwendet werden, sollten Sie den if len(sg.instances()) == 0-Test stornieren oder entfernen und den len(sg.instances())-Wert ausdrucken.

Z.B.

print ("{0}\t{1}\t{2} instances".format(sg.id, sg.name, len(sg.instances())))
1
Akira Kurogane

An die an die Netzwerkschnittstellen angeschlossenen SGs:

Namentlich:

aws ec2 describe-network-interfaces --output text --query NetworkInterfaces[*].Groups[*].GroupName | tr -d '\r' | tr "\t" "\n" | sort | uniq

Nach ID:

aws ec2 describe-network-interfaces --output text --query NetworkInterfaces[*].Groups[*].GroupId | tr -d '\r' | tr "\t" "\n" | sort | uniq
1
Trane9991

Dies ist ein schwieriges Problem, wenn Sie Sicherheitsgruppen haben, die auf andere Sicherheitsgruppen in den Regeln verweisen. Wenn ja, müssen Sie DependencyErrors auflösen, was nicht trivial ist.

Wenn Sie nur IP-Adressen verwenden, funktioniert diese Lösung, nachdem Sie einen boto3-Client erstellt haben:

# pull all security groups from all vpcs in the given profile and region and save as a set
all_sgs = {sg['GroupId'] for sg in client.describe_security_groups()['SecurityGroups']}

# create a new set for all of the security groups that are currently in use
in_use = set()

# cycle through the ENIs and add all found security groups to the in_use set
for eni in client.describe_network_interfaces()['NetworkInterfaces']:
    for group in eni['Groups']:
        in_use.add(group['GroupId'])

unused_security_groups = all_sgs - in_use

for security_group in unused_security_groups:
    try:
        response = client.delete_security_group(GroupId=security_group)
    except ClientError as e:
        if e.response['Error']['Code'] == 'DependencyViolation':
            print('EC2/Security Group Dependencies Exist')
    else:
        print('Unexpected error: {}'.format(e))
0
PythonNoob

Leider ist die gewählte Antwort nicht so genau wie ich brauche (ich habe versucht, das Warum zu untersuchen, habe es aber vorgezogen, es zu implementieren).
Wenn ich ALL NetworkInterfaces überprüfe und nach Anhängen an SecurityGroup suche, erhält ich teilweise Ergebnisse. Wenn ich nur auf EC2Instances überprüfe, werden mir auch Teilergebnisse zurückgegeben. 

Das ist meine Herangehensweise an das Problem: 

  1. Ich erhalte ALLE EC2-Sicherheitsgruppen -> all_secgrp 
  2. Ich bekomme ALLE EC2-Instanzen -> all_instances 
  3. Für jede Instanz bekomme ich alle damit verbundenen SecurityGroups
    1. Ich entferne aus all_secgrp jede dieser SecurityGroup (weil verbunden) 
  4. Für jede SecurityGroup überprüfe ich eine Verknüpfung mit beliebigen NetworkInterfaces (mithilfe der filter-Funktion und Filtern mit diesem security-group-id).
    1. Wenn keine Zuordnung gefunden wird, entferne ich die Sicherheitsgruppe aus all_secgrp

Im Anhang sehen Sie ein Codefragment. Beschweren Sie sich nicht für die Effizienz, sondern versuchen Sie es zu optimieren, wenn Sie möchten. 

all_secgrp = list(ec2_connector.security_groups.all())
all_instances = ec2_connector.instances.all()

for single_instance in all_instances:
    instance_secgrp = ec2_connector.Instance(single_instance.id).security_groups
    for single_sec_grp in instance_secgrp:
        if ec2.SecurityGroup(id=single_sec_grp['GroupId']) in all_secgrp:
            all_secgrp.remove(ec2.SecurityGroup(id=single_sec_grp['GroupId']))

all_secgrp_detached_tmp = all_secgrp[:]
for single_secgrp in all_secgrp_detached_tmp:
    try:
        print(single_secgrp.id)
        if len(list(ec2_connector.network_interfaces.filter(Filters=[{'Name': 'group-id', 'Values': [single_secgrp.id]}]))) > 0:
            all_secgrp.remove(single_secgrp)
    except Exception:
        all_secgrp.remove(single_secgrp)

return all_secgrp_detached  
0
Echoes_86

Es gibt ein Tool auf dem AWS-Marktplatz, das dies viel einfacher macht. Es zeigt Ihnen, welche Gruppen zum leichteren Löschen angehängt/getrennt sind, vergleicht jedoch auch Ihre VPC-Ablaufprotokolle mit den Sicherheitsgruppenregeln und zeigt Ihnen, welche SG-Regeln verwendet oder nicht verwendet werden. AWS stellte hierfür eine ELK-Stack-Lösung bereit, die jedoch lächerlich komplex war.

Hier ist das Tool und ein Haftungsausschluss, an dem ich gearbeitet habe. Aber ich hoffe, Sie finden es alle passend: https://www.piasoftware.net/single-post/2018/04/24/VIDEO-Watch-as-we-clean-up-EC2-security- Gruppen in wenigen Minuten

0
rajat banerjee