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).
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)
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 :)
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
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:
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.
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.
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
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
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 }
Unter anderem melden ScoutSuite und Prowler nicht verwendete EC2-Sicherheitsgruppen. Beide sind Open Source.
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())))
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
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))
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:
all_secgrp
all_instances
filter
-Funktion und Filtern mit diesem security-group-id
).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
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