For security and compliance reasons, you may not be allowed to create INGRESS or EGRESS rules to 0.0.0.0/0 for specific port. Specific to EGRESS rule - If your dependency services are internet facing then you can't simply put current public IP their DNS records on security groups because it may change at any time and when that happens, your system will not able to communicate with the dependency service.
DNS resolver lambda solves this problem. This lambda code is designed to resolve any DNS to its IP and add appropriate security group rule in that regards. While this may sound simple, this approach comes with some native challenges due to few limitations imposed by AWS itself.
-
At the time of writing this document, Security Group can have up to 60 inbound and up to 60 outbound rules. If lambda code is designed to just add new security group rule then at some point in future, it would hit this threshold and solution would stop working. For seemless solution, it is important to identify the inactive security group rules in relation to source DNS record and remove them on timely basis to make a room for new security group rules.
-
At the time of writing this document, Only up to 5 security groups can be attached to EC2 server. Solution should NOT assume performing security group rules changes on dedicated security group. It should identify relevant security group rules associated with source DSN record.
This java 8 based component is developed using Spring Cloud Framework which provides easy abstraction of business logic without having to worry about Cloud Provider specific implementation.
To build this, Simply clone the Git repository and execute below maven command to trigger the build process.
$ mvn clean package
If you don't want to build then grab the binary files from the release section and upload it your lambda.
This lambda code requires you to setup Environment variable FUNCTION_NAME
= DnsResolverFunction
to function properly.
Solution of this stack involves use of Cloud Watch Rule as Scheduled Event
to trigger lambda code, however Cloud Watch Schedule Event shouldn't be passed to the lambda.
Lambda is developed to receive specific custom event which involves following details. Configuring data as part of custom event allows reuse of the lambda for various different DNS records. User is only expected to setup new Cloud Watch rule for new DNS record.
Sr No | Field Name | Required | Default Value | Comments |
---|---|---|---|---|
1 | securityGroupId | Yes | - | Security Group Id |
2 | dnsRecord | Yes | - | Source DNS record for which IP address is required to resolved |
3 | rule | No | EGRESS | Type of Rule. Valid values are 'EGRESS' and 'INGRESS' |
4 | rulePort | No | 443 | Port No |
5 | ruleDescriptionPrefix | Yes | - | Used as rule filter criteria so this has be unique on security group. |
6 | purgeSgRuleCutOff | No | 1440 | In Minutes. Derives how long INACTIVE record can live before it gets deleted. |
If resolve IP address is not part of current security group rule then lambda adds new rule with the rule description in the format as stated in above.
-
Custom event # 1 As fields
rule
,rulePort
andpurgeSgRuleCutOff
are not passed, they will considered asEGRESS
,443
,1440
by lambda.{ "securityGroupId": "sg-04f7feaeaf7908a53", "dnsRecord": "codedeploy.us-east-2.amazonaws.com", "ruleDescriptionPrefix": "Code Deploy US-EAST-2" }
-
Custom event # 2 As field
rule
is not passed, it will be considered asEGRESS
by lambda.{ "securityGroupId": "sg-04f7feaeaf7908a53", "dnsRecord": "codedeploy.us-east-2.amazonaws.com", "rulePort" : 80, "ruleDescriptionPrefix": "Code Deploy US-EAST-2", "purgeSgRuleCutOff": 2880 }
Lambda is not required to be executed in the VPC. Modify this IAM policy to fit into your security requirements.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeSecurityGroups",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress"
],
"Resource": "*"
}
]
}
- Prior to implementing system consuming security group which has dynamic ip requirement, ensure that lambda has executed long enough to have stable set of IP addresses on the security group.
- Schedule lambda to execute more often so security groups stays up to date with changing public ip address for DNS record. Lambda is enforced to flush DNS cache after 1 minute so it would always hit the DNS server to resolve the IP address if scheduled to run after every 2 minutes or more.
- This write up doesn't mention of Cloud Watch Alarm on lambda failure etc. but it is recommended to follow best practices of monitoring solution which allows you to alert whenever action is required.