This repository contains the code for a Lambda function that can scan a set
of AWS accounts and publish files (to an S3 bucket) containing the public IP
addresses of EC2 instances or Elastic IPs that have been properly tagged.
Refer to the Lambda inputs section below, specifically the
publish_egress_tag
, for more information about how to tag an instance
or EIP for publication.
The base Lambda image can be built with the following command:
docker compose build
This base image is used both to build a deployment package and to run the Lambda locally.
You can build a deployment zip file to use when creating a new AWS Lambda function with the following command:
docker compose up build_deployment_package
This will output the deployment zip file in the root directory.
To customize the name of the deployment file, you can override the
BUILD_FILE_NAME
environment variable. For example:
BUILD_FILE_NAME="publish_egress_ip_lambda.zip" docker compose up build_deployment_package
The Python dependencies are maintained using a Pipenv
configuration for each supported Python version. Changes to requirements
should be made to the respective src/py<Python version>/Pipfile
. More
information about the Pipfile
format can be found here.
The accompanying Pipfile.lock
files contain the specific dependency versions
that will be installed. These files can be updated like so (using the Python
3.9 configuration as an example):
cd src/py3.9
pipenv lock
Name | Description | Type | Default | Required |
---|---|---|---|---|
account_ids | The list of AWS accounts to query for egress IPs to publish. | list(string) |
n/a | yes |
application_tag | The name of the AWS tag whose value represents the application associated with an IP address. | string |
"Application" |
no |
bucket_name | The name of the S3 bucket to publish egress IP address information to. | string |
n/a | yes |
domain | The fully qualified domain hosting the published file(s) containing egress IPs. | string |
"egress.ips.example.gov" |
no |
ec2_read_role_name | The name of the IAM role that allows read access to the necessary EC2 attributes. Note that this role must exist in each account that you want to query and it must be assumable by Lambda. For an example policy, see cisagov/cool-accounts . |
string |
"EC2ReadOnly" |
no |
file_configs | A list of dictionaries that define the files to be published. "app_regex" specifies a regular expression that is matched against the value of the application_tag to determine if the address should be included in the file. "description" is the description of the published file. "filename" is the name to assign the published file. "static_ips" is the list of CIDR blocks that will always be included in the published file. | list(dict({ app_regex = string, description = string, filename = string, static_ips = list(string) })) |
n/a | yes |
file_header | The header template for each published file, comprised of a list of strings. When the file is published, newline characters are automatically added between each item in the list. The following variables are available within the template: {domain} - the domain where the published files are located, {filename} - the name of the published file, {timestamp} - the timestamp when the file was published, {description} - the description of the published file. |
list(string) |
["###", "# https://{domain}/{filename}", "# {timestamp}", "# {description}", "###"] |
no |
publish_egress_tag | The name of the AWS tag whose value represents whether the EC2 instance or elastic IP should have its public IP address published. | string |
"Publish Egress" |
no |
region_filters | A list of AWS EC2 region filters to use when querying for IP addresses to publish. If a filter is not specified, the query will be performed in all regions. An example filter to restrict to US regions looks like this: [{ "Name" : "endpoint", "Values" : ["*.us-*"] }] . For more information, refer to the AWS EC2 CLI documentation. |
list(dict({ Name = string, Values = list(string) })) |
[] |
no |
task | The name of the Lambda task to perform. Currently, the only valid value is "publish" . |
string |
n/a | yes |
The following is an example of the JSON input event that is expected by the Lambda:
{
"account_ids": [
"123456789012",
"234567890123"
],
"bucket_name": "my-egress-ip-bucket",
"domain": "egress.ips.example.gov",
"file_configs": [
{
"app_regex": ".*",
"description": "This file contains a list of all IP public addresses to be published.",
"filename": "all.txt",
"static_ips": []
},
{
"app_regex": "^Vulnerability Scanning$",
"description": "This file contains a list of all IPs used for Vulnerability Scanning.",
"filename": "vs.txt",
"static_ips": [
"192.168.1.1/32",
"192.168.2.2/32"
]
}
],
"region_filters": [{
"Name": "endpoint",
"Values": ["*.us-*"]
}],
"task": "publish"
}
The easiest way to deploy the Lambda and related resources is to use the cisagov/publish-egress-ip-terraform repository. Refer to the documentation in that project for more information.
We welcome contributions! Please see CONTRIBUTING.md
for
details.
This project is in the worldwide public domain.
This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the CC0 1.0 Universal public domain dedication.
All contributions to this project will be released under the CC0 dedication. By submitting a pull request, you are agreeing to comply with this waiver of copyright interest.