Skip to content

Instantly share code, notes, and snippets.

@rizerzero
Created March 20, 2019 09:54
Show Gist options
  • Save rizerzero/60ec18b5775cb204b02c93f8ba2cb24c to your computer and use it in GitHub Desktop.
Save rizerzero/60ec18b5775cb204b02c93f8ba2cb24c to your computer and use it in GitHub Desktop.
Some useful bash scrips for AWS EC2. See how to use them at https://mexapi.macpress.com.br/2015/05/mail-calendar-server-p1.html
Hello,human. This is just for the gist title.
#!/bin/bash
#title :ec2sgdip
#description :Verify, compare and update AWS EC2 Security Groups with
# dynamic DNS IPs.
#author :Deny Dias (deny [at] macpress [dot] com [dot] br)
#date :2016.02.11
#version :1.0
#usage :-h for instructions. Run via cron.
#license :CC0
#==============================================================================
# Reset option index
OPTIND=1
# Usage
usage ()
{
cat <<EOT
USAGE:
ec2sgddns
-d <hostname> [-d <hostname> -d ...]
-s <security_group_id@region> [-s <security_group_id@region> -s ...]
[-t] [-v] [-h]
OPTIONS:
-d <hostname> (required)
A dynamic DNS hostname. Multiple hostnames are accepted by providing multiple
-d <hostname>.
-s <security_group_id@region> (required)
The AWS EC2 Security Group ID and its correlated region. Multiple security
groups are acceped by providing multiple -s <security_group_id@region>.
Each security group id and region must be typed together using '@' as
separator, e.g. sg-abcdef12@us-east-1, meaning security group sg-abcdef12 at
region us-east-1.
-t
Test (dry run). Do not change anything at AWS.
-v
Verbose. Print out lots of debugging output.
-h
Print out this help.
EXAMPLE:
./ec2sgddns -d host1.dyndns.com -d host2.noip.org
-s sg-abcdef12@us-east-1 -s sg-12345678@sa-east-1
EOT
}
#Initialize runtime arrays
sgid=()
sgrg=()
rdns=()
ip=""
dip=()
sgi=0
# Initialize argument parser
dflag=false
sflag=false
tflag=false
vflag=false
options=":d:s:tvh"
# Parse arguments
while getopts $options option; do
case "$option" in
d)
dflag=true
rdns+=($OPTARG)
;;
s)
sflag=true
sgr+=($OPTARG)
sgid+=($(echo $OPTARG | cut -d "@" -f1))
sgrg+=($(echo $OPTARG | cut -d "@" -f2))
;;
t)
tflag=true
;;
v)
vflag=true
;;
h)
usage
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 2
;;
*)
echo "Unknow option: -$OPTARG (try -h for help)" >&2
exit 3
;;
esac
done
# Test for required arguments
if ! $sflag || ! $dflag
then
echo "At least one security group with region pair and one DDNS are required." >&2
echo "Try -h for help."
exit 4
fi
# Register runtine initialization
echo "[$(date -Iseconds)] BEGIN AWS EC2 Security Groups update."
if $tflag
then
echo "[$(date -Iseconds)] WARNING! Running in test mode, not commiting changes."
fi
if $vflag
then
echo "[$(date -Iseconds)] WARNING! Running in verbose mode."
echo "[$(date -Iseconds)] Security Groups and Regions: ${sgr[*]}"
echo "[$(date -Iseconds)] Dynamic DNS Hostnames: ${rdns[*]}"
fi
# DDNS resolution
function resolvedns
{
local hname=$1
ip=$(dig +short $hname 2> /dev/null)
}
# IP validation
# Courtesy of Mitch Frazier
# http://www.linuxjournal.com/content/validating-ip-address-bash-script
function valid_ip()
{
local ip=$1
local stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return $stat
}
# Resolve and validate DDNS hostnames
if $vflag
then
echo "[$(date -Iseconds)] Resolving Dynamic DNS hostnames..."
fi
for host in ${rdns[@]}
do
if $vflag
then
echo "[$(date -Iseconds)] Resolving hostname: $host"
fi
resolvedns $host
if valid_ip $ip
then
dip+=($ip)
if $vflag
then
echo "[$(date -Iseconds)] $ip is a valid IP address."
fi
else
printf "[$(date -Iseconds)] $ip IS NOT a valid IP address. Exiting..."
exit 5
fi
if $vflag
then
echo "[$(date -Iseconds)] $host resolved to IP $ip"
fi
ip=""
done
echo "[$(date -Iseconds)] Dynamic DNS hostnames resolved: ${rdns[@]}"
# Log Dynamic DNS IPs
if $vflag
then
echo "[$(date -Iseconds)] DNS IPs: ${dip[@]}"
fi
# Main loop
for sg in ${sgid[@]}
do
if $vflag
then
echo "[$(date -Iseconds)] Verifying $sg@${sgrg[$sgi]} rules..."
fi
# Set EC2 SG command and store it in an array
describecmd="aws --region ${sgrg[$sgi]} ec2 describe-security-groups --group-ids $sg --query SecurityGroups[*].IpPermissions[*].IpRanges --output text | cut -d '/' -f1"
sgip=($(eval $describecmd))
if $vflag
then
echo "[$(date -Iseconds)] >>> $describecmd"
fi
# Log rules IPs
if $vflag
then
echo "[$(date -Iseconds)] AWS IPs: ${sgip[@]}"
fi
# If the security group is empty, populate and exit.
if [ -z ${sgip[0]} ];then
p=0
echo "[$(date -Iseconds)] $sg@${sgrg[$sgi]} is empty. Populating..."
for pg in ${dip[@]};do
authorizecmd="aws --region ${sgrg[$sgi]} ec2 authorize-security-group-ingress --group-id $sg --ip-permissions '{\"IpProtocol\": \"-1\", \"IpRanges\": [{\"CidrIp\": \"${dip[$p]}/32\"}]}' --output text"
if $vflag
then
echo "[$(date -Iseconds)] Trying to authorize IP ${dip[$p]}..."
echo "[$(date -Iseconds)] >>> $authorizecmd"
fi
if ! $tflag
then
eval $authorizecmd
fi
if $vflag
then
echo "[$(date -Iseconds)] Authorized IP: ${dip[$p]}"
fi
((p++))
done
echo "[$(date -Iseconds)] $sg@${sgrg[$sgi]} populated with IPs: ${dip[*]}"
fi
# Rule table setting (IP addresses count)
if $vflag
then
echo "[$(date -Iseconds)] Setting up rule matching table..."
fi
for tf in ${sgip[@]}
do
testfalse+=0
done
if $vflag
then
echo "[$(date -Iseconds)] Rule matching table set."
fi
# Iterates on each IP array pair, set true for matches, or false
if $vflag
then
echo "[$(date -Iseconds)] Matching IPs..."
fi
for ia in ${sgip[@]};do
for ib in ${dip[@]};do
if [[ $ia = $ib ]];then
match+=1
else
match+=0
fi
done
done;
if $vflag
then
echo "[$(date -Iseconds)] IP matching done."
fi
# If any of the DDNS IPs has changed, revoke all rules and authorize again
if $vflag
then
echo "[$(date -Iseconds)] Matching rules..."
fi
# Define the test groups (each with the same number of IP counts)
sgtest=(`echo ${match[@]} | sed -e 's/.\{'"${#sgip[@]}"'\}/&\n/g'`)
i=0
for it in ${sgtest[@]};do
testmatch=${sgtest[$i]}
if [ $testmatch -eq $testfalse ];then
echo "[$(date -Iseconds)] $sg@${sgrg[$sgi]} rules are outdated. Currently autorized IPs: ${sgip[@]}"
d=0
for r in ${sgip[@]};do
revokecmd="aws --region ${sgrg[$sgi]} ec2 revoke-security-group-ingress --group-id $sg --ip-permissions '{\"IpProtocol\": \"-1\", \"IpRanges\": [{\"CidrIp\": \"${sgip[$d]}/32\"}]}' --output text"
if $vflag
then
echo "[$(date -Iseconds)] Trying to revoke IP ${sgip[$d]}..."
echo "[$(date -Iseconds)] >>> $revokecmd"
fi
if ! $tflag
then
eval $revokecmd
fi
if $vflag
then
echo "[$(date -Iseconds)] Revoked IP: ${sgip[$d]}"
fi
((d++))
done
g=0
for a in ${dip[@]};do
authorizecmd="aws --region ${sgrg[$sgi]} ec2 authorize-security-group-ingress --group-id $sg --ip-permissions '{\"IpProtocol\": \"-1\", \"IpRanges\": [{\"CidrIp\": \"${dip[$g]}/32\"}]}' --output text"
if $vflag
then
echo "[$(date -Iseconds)] Trying to authorize IP ${dip[$g]}..."
echo "[$(date -Iseconds)] >>> $authorizecmd"
fi
if ! $tflag
then
eval $authorizecmd
fi
if $vflag
then
echo "[$(date -Iseconds)] Authorized IP: ${dip[$g]}"
fi
((g++))
done
fi
((i++))
done
# Reset match arrays
testfalse=()
match=()
echo "[$(date -Iseconds)] Rules matching done. $sg@${sgrg[$sgi]} authorized IPs: ${dip[*]}"
((sgi++))
done
# Finish runtime
echo "[$(date -Iseconds)] AWS EC2 Security Groups update DONE."
exit 0
#!/bin/sh
#title :s3bkp
#description :Backup selected databases and files to Amazon S3.
#author :Deny Dias (deny [at] macpress [dot] com [dot] br)
#date :2015.03.09
#version :0.2
#usage :Put this script in /usr/local/bin, chmod +x, run in cron.
# It requires s3cmd, an account with key and policies set and
# a S3 bucket in place.
#license :CC0
#==============================================================================
set -e
# Set runtime paths
RUNPATH=$( dirname "$0" )
RUNPATH=$( cd "$RUNPATH" && pwd )
# Execution time accounting
# Start timestamp
res1=$(date +%s)
# End timestamp and print total execution time
endexec () {
res2=$(date +%s)
dt=$(echo "$res2 - $res1" | bc)
dd=$(echo "$dt/86400" | bc)
dt2=$(echo "$dt-86400*$dd" | bc)
dh=$(echo "$dt2/3600" | bc)
dt3=$(echo "$dt2-3600*$dh" | bc)
dm=$(echo "$dt3/60" | bc)
ds=$(echo "$dt3-60*$dm" | bc)
printf "[`date -Iseconds`] Total runtime: %d:%02d:%02d:%02d\n" $dd $dh $dm $ds
}
# Check for root
isroot () {
if [ $EUID -ne 0 ]; then
echo "[`date -Iseconds`] This script must run as root."
exit 1
fi
}
# Import defaults
loaddefaults () {
RCFILE="${HOME}/.aws/s3bkprc"
if [ -f "$RCFILE" ]; then
echo "[`date -Iseconds`] Importing defaults from $RCFILE..."
. $RCFILE
else
echo "[`date -Iseconds`] Configuration file not found. Create it at $RCFILE."
exit 2
fi
}
# Check dependencies
dependencies () {
#if [ ! -x "$DBDUMP" ]; then
# echo "[`date -Iseconds`] Database dump utility $DBDUMP not found. Please install it."
# exit 3
#fi
if [ ! -x "$ARCH" ]; then
echo "[`date -Iseconds`] Archive utility $ARCH not found. Please install it."
exit 4
fi
if [ ! -x "$S3CMD" ]; then
echo "[`date -Iseconds`] Amazon S3 utility $S3CMD not found. Please install it."
exit 5
fi
}
# Create temporary directory
mktmp () {
if [ ! -d "$DUMPTMP" ]; then
echo "[`date -Iseconds`] Creating temporary directory $DUMPTMP..."
mkdir -p $DUMPTMP
fi
}
# List foreign packages
lspkg () {
echo "[`date -Iseconds`] Listing 3rd party packages..."
stat -c "%y %n" $LSPKG | sort > $DUMPTMP/3rdpkglist.txt
}
# Dump databases
dumpdb () {
for i in "${DBBKP[@]}"; do
echo "[`date -Iseconds`] Dumping $i database..."
mysqldump --user=$DBUSER --pass=$DBPASS --opt $i > $DUMPTMP/dbdump_$i.sql
echo "[`date -Iseconds`] $i database dump done."
done
}
# Create archive
archive () {
archdate=$(date "+%Y-%m-%d")
archhost=$(cat "/etc/HOSTNAME")
archive="$DUMPTMP/../"$archdate"_backup_$archhost.tar.gz"
echo "[`date -Iseconds`] Archiving files..."
GZIP=-6 $ARCH pczf $archive $FSBKP > /dev/null 2>&1
echo "[`date -Iseconds`] File archiving done."
}
# Create archive checsum
checksum () {
echo "[`date -Iseconds`] Creating archive checksum..."
md5sum $archive > $archive.sum
echo "[`date -Iseconds`] Archive checksum done."
}
# Send archive file to Amazon S3
sendtos3 () {
echo "[`date -Iseconds`] Putting archive to Amazon S3..."
echo "[`date -Iseconds`] Destination: $S3PATH"
$S3CMD -f -q put $archive $archive.sum $S3PATH
echo "[`date -Iseconds`] Archive sent to Amazon S3."
}
# Cleanup
cleanup () {
echo "[`date -Iseconds`] Cleaning up..."
rm -rf $archive $archive.sum $DUMPTMP
echo "[`date -Iseconds`] Clean up done."
}
# The main script
echo "[`date -Iseconds`] Backing up instance to Amazon S3..."
isroot
loaddefaults
dependencies
mktmp
lspkg
dumpdb
archive
checksum
sendtos3
endexec
cleanup
echo "[`date -Iseconds`] Instance back up to Amazon S3 done."
DBDUMP="/usr/bin/mysqldump"
ARCH="/usr/bin/tar"
S3CMD="/usr/bin/s3cmd"
DUMPTMP="/var/spool/mail/vmail/tmp/bkpdump"
DBUSER="root"
DBPASS="<MariaDB root password>"
DBBKP=( "horde" "mysql" "vimbadmin" )
LSPKG="/var/log/packages/*SBo /var/log/packages/*deny"
FSBKP="/etc /home /usr/local/bin /root /var/lib/sbopkg/queues"
FSBKP+=" /var/lib/spamassassin /var/lib/tor/hidden_service"
FSBKP+=" /var/spool/mail/vmail/exemplo.com /var/spool/mail/vmail/sieve*"
S3PATH="s3://example.s3.adm/backups/mail/"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment