Po około roku nieaudytowanego użytkowania stwierdziłem, że konieczne jest przeprowadzenie audytu moich grup bezpieczeństwa AWS EC2 i wyczyszczenie starszych, nieużywanych grup.
To było trudne zadanie do wykonania przez web GUI, więc spojrzałem na AWS CLI, aby to zadanie było łatwiejsze. Znalazłem wskazówki, jak to zrobić, w StackOverflow, ale było to dalekie od ukończenia. Postanowiłem więc napisać własny scenariusz. Użyłem interfejsu wiersza polecenia AWS, MySQL i jakiegoś „Bash-foo”, aby wykonać następujące czynności:
Uzyskaj listę wszystkich grup zabezpieczeń EC2. Przechowuję identyfikator grupy, nazwę grupy i opis w tabeli o nazwie „grupy” w bazie danych MySQL o nazwie aws_security_groups na hoście lokalnym. Całkowita liczba znalezionych grup jest raportowana użytkownikowi.
Uzyskaj listę wszystkich grup zabezpieczeń powiązanych z każdą z następujących usług i wyklucz je z tabeli: EC2 Istances EC2 Elastic Load Balancers AWS RDS Instances AWS OpsWorks (nie powinno być usuwane przez Amazon) Domyślne grupy zabezpieczeń (nie można usunąć ) ElastiCache
Dla każdej usługi podaję liczbę grup pozostawionych w tabeli po zakończeniu wykluczenia.
- Na koniec wyświetlam identyfikator grupy, nazwę grupy i opis pozostałych grup. Są to „nieużywane” grupy, które należy poddać audytowi i / lub usunąć. Odkryłem, że SG między instancjami i Elastic Load Balancers (ELB) często odnoszą się do siebie. Najlepszą praktyką jest ręczne zbadanie, aby upewnić się, że nie są one naprawdę używane, przed usunięciem odniesień i grupami zabezpieczeń. Ale mój scenariusz przynajmniej sprowadza to do czegoś łatwiejszego do opanowania.
UWAGI: 1. Będziesz chciał utworzyć plik do przechowywania twojego hosta MySQL, nazwy użytkownika i hasła i wskazać mu zmienną $ DBCONFIG. Powinien mieć następującą strukturę:
[mysql]
host=your-mysql-server-host.com
user=your-mysql-user
password=your-mysql-user-password
- Jeśli chcesz, możesz zmienić nazwę bazy danych - upewnij się, że zmieniłeś zmienną $ DB w skrypcie
Daj mi znać, jeśli uznasz to za przydatne lub masz jakieś uwagi, poprawki lub ulepszenia.
Oto skrypt.
#!/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/'
A oto sql do stworzenia bazy danych.
-- 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