Kullanılmayan Amazon EC2 Güvenlik grupları nasıl bulunur?


93

Yetim güvenlik gruplarını belirlemenin bir yolunu bulmaya çalışıyorum, böylece temizleyip onlardan kurtulabileyim. Kullanılmayan güvenlik gruplarını keşfetmenin bir yolunu bilen var mı?

Ya konsol aracılığıyla ya da komut satırı araçlarıyla çalışacaktır (Linux ve OSX makinelerinde komut satırı araçlarını çalıştırma).


4
Kendilerine SG'leri atanabilen ve 'tümünü seç, sonra sil' içermeyen uzun ömürlü Örnek olmayan nesneler (RDS, ELB'ler, ALB'ler) istisnasız bu soruyu tam olarak yanıtlayan bir cevap için My Kingdom - yok edici yaklaşımı. :)
Jesse Adelman

Yanıtlar:


78

Not: Bu yalnızca EC2'de güvenlik kullanımını dikkate alır, RDS gibi diğer hizmetleri dikkate almaz. EC2 dışında kullanılan güvenlik gruplarını dahil etmek için daha fazla iş yapmanız gerekecek. İşin iyi yanı, başka bir hizmetle ilişkili bir hizmeti kaçırırsanız, etkin güvenlik gruplarını kolayca silememeniz (hatta mümkün olmayabilir).

Daha yeni AWS CLI aracını kullanarak ihtiyacım olanı elde etmenin kolay bir yolunu buldum:

Öncelikle, tüm güvenlik gruplarının bir listesini alın

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

Ardından bir örneğe bağlı tüm güvenlik gruplarını alın, ardından sort o zaman uniq:

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

Sonra bir araya getirin ve 2 listeyi karşılaştırın ve ana listeden neyin kullanılmadığını görün:

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)

1
@Erik Evet, yalnızca tek bir bölgem var ve AWS komut dosyalarının ana bölgeleri çevresel değişkenler aracılığıyla ayarlanmış. Bu komut dosyasının çok bölgeli bir sürümünü görmek isterim.
Ray

1
vpc'niz için bir --filter eklemek isteyebilirsiniz, böylece diğer varsayılan vpc sg
shadowbq

2
Bir güvenlik grubu da bir ELB tarafından kullanılıyor olabilir. Bu komut, varsayılan bölgede ELB'ler tarafından referans verilen benzersiz güvenlik grubu kimlikleri kümesini listeleyecektir:aws elb describe-load-balancers --query 'LoadBalancerDescriptions[*].SecurityGroups[*]' --output text | tr '\t' '\n' | sort | uniq
astletron

2
Bir EC2 güvenlik grubu, bir RDS örneği tarafından da kullanılıyor olabilir. Bu komut, varsayılan bölgede RDS örnekleri tarafından kullanılan güvenlik grubu kimliklerini listeleyecektir:aws rds describe-db-security-groups --query 'DBSecurityGroups[*].EC2SecurityGroups[*].EC2SecurityGroupId' --output text | tr '\t' '\n' | sort | uniq
aharden

2
Yalnızca aws ec2 describe-network-interfaces --query 'NetworkInterfaces[*].Groups[*].GroupId' --output text| tr '\t' '\n' | sort | uniqağ arayüzlerini tanımlamak için de kullanabilirsiniz .
Jonathan

63

EC2 konsolunda tüm güvenlik gruplarınızı seçerseniz, eylemler -> Güvenlik Gruplarını Sil'e basın, örneklere, diğer güvenlik gruplarına veya ağ arayüzlerine bağlı güvenlik gruplarını silemeyeceğinizi söyleyen bir açılır pencere görünecektir ve silebileceğiniz güvenlik gruplarını listeler; yani kullanılmayan güvenlik grupları :)


15
Kabul etmem gerekse de, "tümünü seç + sil" seçeneğini kullanmak genellikle iyi bir alışkanlık değildir.
Balmipour

3
Çalışıp çalışmayacağından emin değilseniz, sadece sahte bir güvenlik grubu oluşturabilir ve ona bir şey ekleyebilir, silmeyi deneyebilir ve bunun size izin vermeyeceğini görebilirsiniz.
NLail

2
Silme işlemini gerçekten onaylamanıza gerek yoktur, açılır pencerede size hangilerinin silinebileceğini (yetim) ve hangilerinin silemeyeceğini gösteren bir döküm gösterilir. Daha sonra iptal düğmesine basıp yetim olanları silebilirsiniz.
rjarmstrong

4
Anlamadığım şey şu: Bu scary.maneuver yaptığınızda AWS konsolu bu bilgiyi sunabiliyorsa, API aracılığıyla aynı şeyi nasıl yapacaklarını neden paylaşmıyorlar? Kahverengi tarla ortamlarında muhtemelen gerekli olan bir şey değil ...
Jesse Adelman

1
be brave :: do it
zanuka

29

Bu, Güvenlik Grubunu ilişkili olduğu bulut sunucularının sayısına göre listelemek için boto'da (AWS için Python SDK) yazılmış örnek koddur.

Aynı mantığı komut satırında da elde etmek için bu mantığı kullanabilirsiniz.

Boto Kodu

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

Çıktı

Security-Group-1 0
Security-Group-2 1
Security-Group-3 0
Security-Group-4 3

Güzel ve kolay! Teşekkürler
Chris Koston

6
iyi, evet, ama ne var elbler?
Ilja

Ayrıca bunun yalnızca çalışan örnekleri içerdiğini unutmayın. Durdurulmuş bir örneğe bağlı bir SG'yi de silemezsiniz.
AgDude

6
Bu, RDS gibi hizmetlerden gelen arabirimleri yok sayar. RDS, örneğin sahibidir, ancak ENI'ye sahipsiniz. Bence ElasticSearch ve ELB benzer şekilde çalışıyor ve bu senaryo ile
görünmeyecek

6

Yaklaşık bir yıllık denetlenmemiş kullanımdan sonra AWS EC2 güvenlik gruplarımı denetlemeyi ve eski, kullanılmayan grupları temizlemeyi gerekli buldum.

Bu, web GUI aracılığıyla gerçekleştirilmesi zor bir görevdi, bu yüzden görevi kolaylaştırmak için AWS CLI'ye baktım. StackOverflow'da bunun nasıl yapılacağına dair bir başlangıç ​​buldum, ancak tamamlanmaktan uzaktı. Bu yüzden kendi senaryomu yazmaya karar verdim. Aşağıdakileri gerçekleştirmek için AWS CLI, MySQL ve biraz "Bash-foo" kullandım:

  1. Tüm EC2 güvenlik gruplarının bir listesini alın. Grup kimliğini, grup adını ve açıklamasını localhost'ta aws_security_groups adlı bir MySQL veritabanındaki "gruplar" adlı bir tabloda saklıyorum. Bulunan toplam grup sayısı kullanıcıya bildirilir.

  2. Aşağıdaki hizmetlerin her biriyle ilişkili tüm güvenlik gruplarının bir listesini alın ve bunları tablodan hariç tutun: EC2 Istances EC2 Elastic Load Balancers AWS RDS Instances AWS OpsWorks (Amazon başına kaldırılmamalıdır) Varsayılan güvenlik grupları (Silinemez ElastiCache

Her hizmet için, dışlama tamamlandıktan sonra tabloda kalan grupların sayısını rapor ediyorum.

  1. Son olarak, kalan grupların grup kimliğini, grup adını ve açıklamasını görüntülerim. Bunlar denetlenmesi ve / veya silinmesi gereken "kullanılmayan" gruplardır. Örnekler arasındaki SG'lerin ve Elastic Load Balancer'ların (ELB'ler) genellikle birbirlerini ifade ettiğini buldum. Çapraz referansları kaldırmadan ve güvenlik gruplarını silmeden önce gerçekten kullanımda olmadıklarından emin olmak için bazı manuel araştırmalar yapmak en iyi uygulamadır. Ama benim senaryom en azından bunu daha yönetilebilir bir şeye indirgiyor.

NOTLAR: 1. MySQL sunucunuzu, kullanıcı adınızı ve şifrenizi saklamak için bir dosya oluşturmak ve $ DBCONFIG değişkenini ona yönlendirmek isteyeceksiniz. Şu şekilde yapılandırılmalıdır:

[mysql]
host=your-mysql-server-host.com
user=your-mysql-user
password=your-mysql-user-password
  1. İsterseniz veritabanının adını değiştirebilirsiniz - koddaki $ DB değişkenini değiştirdiğinizden emin olun

Bunu yararlı bulursanız veya herhangi bir yorumunuz, düzeltmeniz veya geliştirmeniz varsa bize bildirin.

İşte senaryo.

#!/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/'

Ve işte veritabanını oluşturmak için sql.

-- 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 @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@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 TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

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

3

Yalnızca geçerli örneği olmayan güvenlik gruplarının Grup Kimliklerini ve Adlarını yazdıran bir boto örneği.

Ayrıca hangi bölgeyle ilgilendiğinizi nasıl belirleyeceğinizi gösterir.

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))

Onayla hangi için güvenlik grupları şunlardır hala ters veya kaldırmak gerekir kullanılıyor if len(sg.instances()) == 0testi ve baskı len(sg.instances())değerini.

Örneğin

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

3

Node.js AWS SDK'sını kullanarak AWS'nin kullanımda olan güvenlik gruplarını silmenize izin vermediğini doğrulayabilirim. Tüm grupları silmeye çalışan ve hataları incelikle ele alan bir komut dosyası yazdım. Bu, klasik ve modern VPC için işe yarar. Hata mesajı aşağıda görülebilir.

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 }


1

Ağ arayüzlerine bağlı SG'lere:

İsimle:

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

Kimliğe göre:

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

0

AWS pazarında bunu çok daha kolaylaştıran bir araç var. Size kolay silme için hangi grupların eklendiğini / çıkarıldığını gösterir, ancak aynı zamanda VPC Akış Günlüklerinizi güvenlik grubu kurallarıyla karşılaştırır ve hangi SG kurallarının kullanımda veya kullanılmadığını gösterir. AWS bunu yapmak için bir ELK yığını çözümü yayınladı, ancak bu gülünç derecede karmaşıktı.

İşte araç ve üzerinde çalıştığım bir sorumluluk reddi beyanı. Ama umarım hepiniz uygun bulursunuz: https://www.piasoftware.net/single-post/2018/04/24/VIDEO-Watch-as-we-clean-up-EC2-security-groups-in-just -birkaç dakika


0

Maalesef seçilen cevap ihtiyacım olduğu kadar doğru değil (nedenini araştırmaya çalıştım ama uygulamayı tercih ettim).
TÜMÜNÜ işaretlersem NetworkInterfaces, herhangi birine ek ararsam , SecurityGroupbana kısmi sonuçlar verir. Yalnızca kontrol edersem EC2Instances, kısmi sonuçları da geri alır.

İşte soruna yaklaşımım bu:

  1. TÜM EC2 Güvenlik Gruplarını alıyorum -> all_secgrp
  2. TÜM EC2 Bulut Sunucularını alıyorum -> all_instances
  3. Her Örnek için ona bağlı tüm Güvenlik Gruplarını alıyorum
    1. Bu Güvenlik Grubunun her birini all_secgrp'den kaldırıyorum (ekli olduğu için)
  4. Her bir Güvenlik Grubu için, herhangi bir Ağ Arayüzüyle bir ilişkiyi kontrol ederim ( filterişlevi kullanarak ve bunu kullanarak filtreleme security-group-id)
    1. İlişki bulunmazsa, güvenlik grubunu şuradan kaldırırım all_secgrp

Ekte bir kod parçası görebilirsiniz. Verimlilikten şikayet etmeyin, ancak isterseniz optimize etmeye çalışın.

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

Kurallarda diğer güvenlik gruplarına başvuran güvenlik gruplarınız varsa, bu zor bir sorundur. Öyleyse, önemsiz olmayan DependencyErrors'ı çözmeniz gerekir.

Yalnızca IP adreslerini kullanıyorsanız, bir boto3 istemcisi oluşturduktan sonra bu çözüm işe yarayacaktır:

# 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))

Bu, RDS tarafından kullanılan SG'leri kapsamaz
alexandernst
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.