Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Aws lambda function that allows a user to hit a url and get added to an aws security group, and another function to cleanup old entries in the group
"use strict";
var AWS = require("aws-sdk");
var ec2 = new AWS.EC2();
var securityGroup = "sg-XXX";
exports.handler = (event, context, callback) => {
ec2.describeSecurityGroups({ GroupIds: [securityGroup] }, function(
err,
data
) {
if (err) {
console.log(err, err.stack);
callback(null, "error fetching security group");
} else {
var cutuff = Date.now() - 24 * 7 * 60 * 60 * 1000;
var ips = data.SecurityGroups[0].IpPermissions[0].IpRanges;
var ipsToRemove = [];
for (var i = 0; i < ips.length; i++) {
var d = ips[i].Description;
if (d.startsWith("Added: ")) {
d = d.replace("Added: ", "");
var addedDate = Date.parse(d);
if (addedDate < cutuff) {
ipsToRemove.push(ips[i]);
}
}
}
if (ipsToRemove.length) {
console.log("Removing ips:" + ipsToRemove);
var params = {
GroupId: securityGroup,
IpPermissions: [
{
FromPort: 443,
ToPort: 443,
IpProtocol: "tcp",
IpRanges: ipsToRemove
}
]
};
ec2.revokeSecurityGroupIngress(params, function(err, data) {
if (err) {
console.log(err, err.stack);
callback(null, "error removing ips");
} else {
console.log("success removing ips");
callback(null, "Removed " + ipsToRemove.length + " ips");
}
});
} else {
callback(null, "Nothing to remove");
}
}
});
};
"use strict";
var AWS = require("aws-sdk");
var ec2 = new AWS.EC2();
var securityGroup = "sg-XXXXX";
module.exports.knocker = (event, context, callback) => {
var ip = event.requestContext.identity.sourceIp;
addId(ip, callback);
};
function addId(ip, callback) {
var d = new Date();
var params = {
DryRun: false,
GroupId: securityGroup,
IpPermissions: [
{
FromPort: 443,
IpProtocol: "tcp",
IpRanges: [
{
CidrIp: ip + "/32",
Description: "Added: " + d.toJSON()
}
],
ToPort: 443
}
]
};
ec2.authorizeSecurityGroupIngress(params, function(err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
if (err.code == "InvalidPermission.Duplicate") {
callback(null, {
statusCode: 200,
headers: {},
body: JSON.stringify({
alreadyAdded: ip
})
});
} else {
callback(null, {
statusCode: 500,
headers: {},
body: JSON.stringify({
error: err
})
});
}
} else {
console.log("Added ip: " + ip);
callback(null, {
statusCode: 200,
headers: {},
body: JSON.stringify({
added: ip
})
});
}
});
}
# Welcome to serverless. Read the docs
# https://serverless.com/framework/docs/
# Serverless.yml is the configuration the CLI
# uses to deploy your code to your provider of choice
# The `service` block is the name of the service
service: FirewallKnocker
# The `provider` block defines where your service will be deployed
provider:
name: aws
runtime: nodejs6.10
role: arn:aws:iam::XXX:role/iam-role-firewall-knocker
# The `functions` block defines what code to deploy
functions:
firewallknocker:
handler: handler.knocker
events:
- http:
path: firewallknocker
method: get
cors: true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment