Skip to content

Commit

Permalink
Merge pull request #43 from GSA-TTS/test-egress-proxy
Browse files Browse the repository at this point in the history
Test egress proxy generator
  • Loading branch information
rahearn authored Oct 3, 2024
2 parents ed83b8c + bdaa4d1 commit f4205d1
Show file tree
Hide file tree
Showing 20 changed files with 223 additions and 32 deletions.
23 changes: 1 addition & 22 deletions .github/actions/deploy-proxy/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,9 @@ runs:
run: |
cf api api.fr.cloud.gov
cf auth
- name: Set restricted space egress
shell: bash
run: ./bin/ops/set_space_egress.sh -t -s ${{ inputs.cf_space }}
- name: Set public space egress
shell: bash
run: ./bin/ops/set_space_egress.sh -p -s ${{ inputs.cf_space }}-egress
- name: Create temp directory
shell: bash
id: create-temp-dir
run: echo "path=$(mktemp -d -t egress-XXXXXXXXXX --tmpdir=$RUNNER_TEMP)" >> $GITHUB_OUTPUT
- name: Clone cg-egress-proxy
shell: bash
run: git clone ${{ inputs.proxy_repo }} ${{ steps.create-temp-dir.outputs.path }}
- name: Switch to deploy ref
shell: bash
working-directory: ${{ steps.create-temp-dir.outputs.path }}
run: git checkout ${{ inputs.proxy_version }}
- name: Copy config files
shell: bash
run: cp ./config/deployment/egress_proxy/${{ inputs.app }}.*.acl ${{ steps.create-temp-dir.outputs.path }}
- name: Target space
shell: bash
run: cf target -o gsa-tts-devtools-prototyping -s ${{ inputs.cf_space }}
- name: Deploy proxy
shell: bash
working-directory: ${{ steps.create-temp-dir.outputs.path }}
run: ./bin/cf-deployproxy -a ${{ inputs.app }} -p egress-proxy -e egress_proxy
run: ./bin/ops/deploy_egress_proxy.rb -a ${{ inputs.app }} -s ${{ inputs.cf_space }} -r ${{ inputs.proxy_repo }} -v ${{ inputs.proxy_version }}
9 changes: 9 additions & 0 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,12 @@ jobs:
cf_org: gsa-tts-devtools-prototyping
cf_space: rahearn
cf_command: push --vars-file config/deployment/production.yml --var rails_master_key="${{ secrets.RAILS_MASTER_KEY }}" --strategy rolling

- name: Deploy egress proxy
uses: ./.github/actions/deploy-proxy
env:
CF_USERNAME: ${{ secrets.CF_USERNAME }}
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
with:
cf_space: rahearn
app: continuous_monitoring-production
2 changes: 1 addition & 1 deletion .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
cf_space: rahearn
cf_command: push --vars-file config/deployment/staging.yml --var rails_master_key="${{ secrets.RAILS_MASTER_KEY }}" --strategy rolling

- name: Deploy proxy
- name: Deploy egress proxy
uses: ./.github/actions/deploy-proxy
env:
CF_USERNAME: ${{ secrets.CF_USERNAME }}
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,18 @@ Otherwise, they are set as a `((variable))` within `manifest.yml` and the variab

Configuration that changes from staging to production, but is public, should be added to `config/deployment/staging.yml` and `config/deployment/production.yml`

### Public Egress Proxy

Traffic to be delivered to the public internet or s3 must be proxied through the [cg-egress-proxy](https://github.com/GSA-TTS/cg-egress-proxy) app.

To deploy the proxy manually:

1. Ensure terraform state is up to date.
1. Update the acl files in `config/deployment/egress_proxy`
1. Deploy the proxy to staging: `bin/ops/deploy_egress_proxy.rb -s rahearn -a continuous_monitoring-staging`
1. Deploy the proxy to production: `bin/ops/deploy_egress_proxy.rb -s rahearn -a continuous_monitoring-production`

See the [ruby troubleshooting doc](https://github.com/GSA-TTS/cg-egress-proxy/blob/main/docs/ruby.md) first if you have any problems making outbound connections through the proxy.
## Documentation

### Auditree Control Validation
Expand Down
2 changes: 1 addition & 1 deletion bin/ops/create_service_account.sh
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ username=`echo $creds | jq -r '.username'`
password=`echo $creds | jq -r '.password'`

if [[ "$org_manager" = "true" ]]; then
cf set-org-role $username $org OrgManager >&2
cf set-org-role $username $org OrgManager 1>&2
fi

cat << EOF
Expand Down
54 changes: 54 additions & 0 deletions bin/ops/deploy_egress_proxy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env ruby

require "tmpdir"
require "optparse"

options = {}
parser = OptionParser.new do |opt|
opt.on("-s", "--space SPACE", "The space apps are running in") { |o| options[:space] = o unless o == "" }
opt.on("-a", "--apps APPLICATION", "Comma-separated list of cloud.gov apps to be proxied") { |o| options[:apps] = o unless o == "" }
opt.on("-r", "--repo PROXY_REPOSITORY", "Address of egress proxy git repo. Default: https://github.com/GSA-TTS/cg-egress-proxy.git") { |o| options[:repo] = o unless o == "" }
opt.on("-v", "--version PROXY_VERSION", "Git ref (sha, tag, branch) to deploy from repo. Default: main") { |o| options[:version] = o unless o == "" }
end
parser.parse!

if options[:space].nil?
warn "--space is a required argument"
puts parser
exit 1
end
if options[:apps].nil?
warn "--apps is a required argument"
puts parser
exit 1
end
proxy_repo = options[:repo].nil? ? "https://github.com/GSA-TTS/cg-egress-proxy.git" : options[:repo]
proxy_version = options[:version].nil? ? "main" : options[:version]

def run(command)
system(command) or exit $?.exitstatus
end

directory = File.dirname(__FILE__)

run "#{File.join(directory, "set_space_egress.sh")} -s #{options[:space]} -t"
run "#{File.join(directory, "set_space_egress.sh")} -s #{options[:space]}-egress -p"

Dir.mktmpdir do |dir|
run "git clone #{proxy_repo} #{dir}"
run "cd #{dir}; git checkout #{proxy_version}"
config_dir = File.join(directory, "../../config/deployment/egress_proxy")
options[:apps].split(",").each do |app|
begin
FileUtils.cp File.join(config_dir, "#{app}.allow.acl"), dir
rescue
warn "config/deployment/egress_proxy/#{app}.allow.acl did not exist. Please create it if you need to customize the app's allow rules"
end
begin
FileUtils.cp File.join(config_dir, "#{app}.deny.acl"), dir
rescue
warn "config/deployment/egress_proxy/#{app}.deny.acl did not exist. Please create it if you need to customize the app's deny rules"
end
end
run "cd #{dir}; bin/cf-deployproxy -a #{options[:apps]} -p ep -e egress_proxy"
end
3 changes: 0 additions & 3 deletions bin/ops/destroy_service_account.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,5 @@ fi

cf target -o $org -s $space

# destroy service key
cf delete-service-key $service service-account-key -f

# destroy service
cf delete-service $service -f
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
raw.githubusercontent.com
*.apps.internal
6 changes: 6 additions & 0 deletions doc/compliance/apps/application.boundary.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ Boundary(aws, "AWS GovCloud") {
Boundary(atob, "ATO boundary") {
Boundary(space, "Restricted-egress cloud.gov space") {
System_Boundary(inventory, "Application") {
Boundary(restricted_space, "Restricted egress space") {
}
Boundary(egress_space, "Public egress space") {
Container(proxy, "<&layers> Egress Proxy", "Caddy, cg-egress-proxy", "Proxy with allow-list of external connections")
}
Container(app, "<&layers> Continuous Monitoring", "Ruby 3.3.4, Rails 7.1.3.4", "TKTK Application Description")
ContainerDb(app_db, "Application DB", "AWS RDS (PostgreSQL)", "Primary data storage")
Container(worker, "<&layers> Sidekiq workers", "Ruby 3.3.4, Sidekiq", "Perform background work and data processing")
Expand Down Expand Up @@ -64,6 +69,7 @@ Rel(egress_proxy, external, "Request file content", "https (443)")
Rel(developer, githuball, "Publish code", "git ssh (22)")
Rel(githuball, cg_api, "Deploy App", "Auth: SpaceDeployer Service Account, https (443)")
Rel(app, proxy, "Proxy outbound connections", "https (443)")
@enduml
```

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"component-definition": {
"uuid": "d2f3e1b7-363a-4c8a-afb9-7cee1e825bdc",
"metadata": {
"title": "cg-egress-proxy Egress Proxy Component Definition.",
"last-modified": "2024-10-03T13:28:05.931086+00:00",
"version": "0.0.1",
"oscal-version": "1.1.2"
},
"components": [
{
"uuid": "1acb8ab7-4191-46c6-b79f-659a2f195b5a",
"type": "software",
"title": "cg-egress-proxy",
"description": "The cg-egress-proxy caddy server with forward_proxy configured",
"props": [
{
"name": "Rule_Id",
"value": "prod-space-restricted",
"remarks": "rule_prod_space_restricted"
},
{
"name": "Rule_Description",
"value": "The production space where the system app is running must not have the public-networks-egress ASG applied to it",
"remarks": "rule_prod_space_restricted"
}
],
"control-implementations": [
{
"uuid": "eba1125b-5fd7-46c3-8edc-bf22d67d98cf",
"source": "https://raw.githubusercontent.com/usnistgov/oscal-content/refs/tags/v1.3.0/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json",
"description": "Controls implemented via use of the cg-egress-proxy outbound connection proxy",
"implemented-requirements": [
{
"uuid": "09de7f16-6339-4daa-b09a-333c5e33185c",
"control-id": "sc-7",
"description": "",
"props": [
{
"name": "implementation-status",
"value": "partial"
}
],
"statements": [
{
"statement-id": "sc-7_smt.c",
"uuid": "b56aa629-2452-4052-a5c0-7d245a8122a2",
"description": "eg-egress-proxy provides a control point for allowing network traffic to specific hostnames or IP addresses. Outbound connections are compared to the following list in order:\n\n1. A `deny_file` list of hostnames and/or IP addresses to deny connections to.\n1. An `allow_file` list of hostnames and/or IP addresses to allow connections to.\n1. A `deny all` rule to deny all connections that did not match one of the first two rules.\n\nThe connection is allowed or denied based on the first matching rule.",
"props": [
{
"name": "Rule_Id",
"value": "prod-space-restricted"
},
{
"name": "implementation-status",
"value": "implemented"
}
]
}
]
}
]
}
]
}
]
}
}
20 changes: 20 additions & 0 deletions doc/compliance/oscal/control-statements/sc/sc-7.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ x-trestle-comp-def-rules:
description: Production spaces should disable ssh access
- name: ssh-access-disabled
description: Production spaces should disable ssh access
cg-egress-proxy:
- name: prod-space-restricted
description: The production space where the system app is running must not have
the public-networks-egress ASG applied to it
x-trestle-rules-params:
DevTools Cloud.gov:
- name: gov.cloud.space-names
Expand Down Expand Up @@ -191,4 +195,20 @@ Application owners are responsible for ensuring their application does not excha

#### Implementation Status: partial

### cg-egress-proxy

eg-egress-proxy provides a control point for allowing network traffic to specific hostnames or IP addresses. Outbound connections are compared to the following list in order:

1. A `deny_file` list of hostnames and/or IP addresses to deny connections to.
1. An `allow_file` list of hostnames and/or IP addresses to allow connections to.
1. A `deny all` rule to deny all connections that did not match one of the first two rules.

The connection is allowed or denied based on the first matching rule.

#### Rules:

- prod-space-restricted

#### Implementation Status: implemented

______________________________________________________________________
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,14 @@
"implementation-status": {
"state": "implemented"
}
},
{
"component-uuid": "1acb8ab7-4191-46c6-b79f-659a2f195b5a",
"uuid": "be70b12c-2fe6-4723-9b2f-16d957c5cf8a",
"description": "eg-egress-proxy provides a control point for allowing network traffic to specific hostnames or IP addresses. Outbound connections are compared to the following list in order:\n\n1. A `deny_file` list of hostnames and/or IP addresses to deny connections to.\n1. An `allow_file` list of hostnames and/or IP addresses to allow connections to.\n1. A `deny all` rule to deny all connections that did not match one of the first two rules.\n\nThe connection is allowed or denied based on the first matching rule.",
"implementation-status": {
"state": "implemented"
}
}
]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"metadata": {
"title": "Continuous Monitoring Proof of Concept SSPP",
"last-modified": "2024-09-26T14:56:30.202245+00:00",
"last-modified": "2024-10-03T17:04:19.631173+00:00",
"version": "0.0.1",
"oscal-version": "1.1.2",
"roles": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,27 @@
"state": "operational"
}
},
{
"uuid": "1acb8ab7-4191-46c6-b79f-659a2f195b5a",
"type": "software",
"title": "cg-egress-proxy",
"description": "The cg-egress-proxy caddy server with forward_proxy configured",
"props": [
{
"name": "Rule_Id",
"value": "prod-space-restricted",
"remarks": "rule_prod_space_restricted"
},
{
"name": "Rule_Description",
"value": "The production space where the system app is running must not have the public-networks-egress ASG applied to it",
"remarks": "rule_prod_space_restricted"
}
],
"status": {
"state": "operational"
}
},
{
"uuid": "3dd05e37-06f1-4f8b-a4b7-7a80f2a0101b",
"type": "this-system",
Expand Down
1 change: 1 addition & 0 deletions doc/compliance/oscal/trestle-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ components:
- cloud_gov
- devtools_cloud_gov
- github_actions
- cg-egress-proxy
6 changes: 4 additions & 2 deletions terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ These steps are run once per project.
A [SpaceDeployer](https://cloud.gov/docs/services/cloud-gov-service-account/) account is required to run terraform or
deploy the application from the CI/CD pipeline. Create a new account by running:
`../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME>`
`../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME> -m`
Passing the `-m` flag to `create_service_account.sh` is required for the account that will run terraform.
## Set up a new environment manually
Expand All @@ -80,7 +82,7 @@ The below steps rely on you first configuring access to the Terraform state in s
# something that communicates the purpose of the deployer
# for example: circleci-deployer for the credentials CircleCI uses to
# deploy the application or <your_name>-terraform for credentials to run terraform manually
../../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME> > secrets.auto.tfvars
../../bin/ops/create_service_account.sh -s <SPACE_NAME> -u <ACCOUNT_NAME> -m > secrets.auto.tfvars
```
The script will output the `username` (as `cf_user`) and `password` (as `cf_password`) for your `<ACCOUNT_NAME>`. Read more in the [cloud.gov service account documentation](https://cloud.gov/docs/services/cloud-gov-service-account/).
Expand Down
11 changes: 11 additions & 0 deletions terraform/production/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,14 @@ module "redis" {
# domain_name = "TKTK-production-domain-name"
# host_name = "TKTK-production-hostname (optional)"
# }

module "egress_space" {
source = "github.com/gsa-tts/terraform-cloudgov//cg_space?ref=v1.0.0"

cf_org_name = local.cf_org_name
cf_space_name = "${local.cf_space_name}-egress"
# deployers should include any user or service account ID that will deploy the egress proxy
deployers = [
var.cf_user
]
}
6 changes: 5 additions & 1 deletion terraform/staging/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,9 @@ module "egress_space" {

cf_org_name = local.cf_org_name
cf_space_name = "${local.cf_space_name}-egress"
deployers = ["[email protected]", var.cf_user]
# deployers should include any user or service account ID that will deploy the egress proxy
deployers = [
"[email protected]",
var.cf_user
]
}

0 comments on commit f4205d1

Please sign in to comment.