Después de aproximadamente un año de uso sin auditar, me pareció necesario auditar mis grupos de seguridad de AWS EC2 y limpiar los grupos heredados no utilizados.
Esta fue una tarea desalentadora de realizar a través de la GUI web, por lo que busqué la AWS CLI para facilitar la tarea. Encontré un comienzo sobre cómo hacer esto en StackOverflow, pero estaba lejos de ser completo. Así que decidí escribir mi propio guión. Usé AWS CLI, MySQL y algo de "Bash-foo" para realizar lo siguiente:
Obtenga una lista de todos los grupos de seguridad de EC2. Guardo la identificación del grupo, el nombre del grupo y la descripción en una tabla llamada "grupos" en una base de datos MySQL llamada aws_security_groups en el localhost. El número total de grupos encontrados se informa al usuario.
Obtenga una lista de todos los grupos de seguridad asociados con cada uno de los siguientes servicios y exclúyalos de la tabla: EC2 Istances EC2 Elastic Load Balancers AWS RDS Instances AWS OpsWorks (no debe eliminarse por Amazon) Grupos de seguridad predeterminados (no se puede eliminar ) ElastiCache
Para cada servicio, informo un recuento del número de grupos que quedan en la tabla después de que se completa la exclusión.
- Finalmente, muestro la identificación del grupo, el nombre del grupo y la descripción de los grupos que quedan. Estos son los grupos "no utilizados" que necesitan ser auditados y / o eliminados. Descubrí que los SG entre instancias y los Elastic Load Balancers (ELB) a menudo se refieren entre sí. Es una buena práctica realizar una investigación manual para asegurarse de que realmente no estén en uso antes de eliminar las referencias cruzadas y eliminar los grupos de seguridad. Pero mi guión al menos reduce esto a algo más manejable.
NOTAS: 1. Querrá crear un archivo para almacenar su host MySQL, nombre de usuario y contraseña y apuntar la variable $ DBCONFIG hacia él. Debería estar estructurado así:
[mysql]
host=your-mysql-server-host.com
user=your-mysql-user
password=your-mysql-user-password
- Puede cambiar el nombre de la base de datos si lo desea; asegúrese de cambiar la variable $ DB en el script
Avíseme si lo encuentra útil o si tiene algún comentario, corrección o mejora.
Aquí está el guión.
#!/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/'
Y aquí está el sql para crear la base de datos.
-- 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