Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding VPN restriction capability to MCR #11588

Merged
merged 25 commits into from
Feb 27, 2024
Merged

Adding VPN restriction capability to MCR #11588

merged 25 commits into from
Feb 27, 2024

Conversation

dwhitestratiform
Copy link
Contributor

@dwhitestratiform dwhitestratiform commented Feb 16, 2024

Description

This pull request is to lock down non production environments for MCR to be only accessible behind CMS VPN. In addition to locking down the environments to be accessible behind VPN changes were required to temporarily enable access for GitHub Actions to access the environment to run tests.

Because the serverless environment uses AWS Cloudfront we cannot place Cloudfront inside of a private subnet. Therefore, to restrict traffic the AWS WAF is being utilized to lock down access. To accomplish this we're beginning to utilize the CMS WAF Serverless plugin to apply standard rule sets and extend that by applying custom IP sets.

This PR was also needed
#11602

This pull request does the following:

Implements the CMS WAF Plugin for both the cloudfront distro as well as the api
Creates a prioritized rule set for the WAF
Creates a custom IP set per stack
Associates a manually created global IP (for both ipv4 and ipv6) set that houses all CMS VPN IP addresses to the stacks WAF
Looks up GitHub Runner IP's and adds them to the stacks custom IP set (that is only applied to that stack)
Upon successful run of all tests clears out the GitHub Runner IP's from the stacks custom IP set

Related ticket(s)

https://jiraent.cms.gov/browse/CMDCT-3242)

How to test

To test locally connect to Zscaler or Cisco Any Connect:
In an incognito window navigate to the endpoint of the environment and you should see the login page for MCR and should be able to login and use the app as expected
Disconnect from Zscaler and navigate to the same endpoint in a new incognito window and you should receive a 403.

Important updates

When creating new projects or migrating this work to other products we will need to manually create the CMS VPN IP set for both ipv4 and ipv6. In addition SSM parameters will need to be created containing the arn of each IP set so that they can be pulled into the serverless.yml at deploy time.

  • Worth noting: when creating an ipset the ip set gets created by going Into the aws console and going to the waf service -> ipsets -> change region to cloudfront -> create ip set

Additional Details

The script that registers IPs against the IP set assigned to the WAF for the application stack, is designed to be able to be run concurrently while managing race and optimistic concurrency control locks. The new implementation of the web application firewall (version 2) requires setting the entirety of the array in each operation, and does not support append. To avoid concurrency write contention, AWS requires a lock token be supplied in the update operation, such that a read must occur before a write. Console actions will also invalidate a token. Read operations are also throttled, so this script implements an exponential backoff strategy with jitter, such that a random time between min, and the lesser of min^try or max, is used to sleep between each each read, each write, and the entirety of the loop, with short circuits should the number of attempts of any operation exceed the circuit breaker number of attempts. This allows for a relatively high level of concurrency, at the cost of performance with creating the registry. For other implementation patterns, the not fully realized branch, skipci-whitelist-gha-cidrs can be used an example.

Also worth noting the reason that a global vpn ip set and a per stack GitHub runner ip set was chosen was to allow a single place with ideally few updates to control VPN access. Then, for the individual stacks IP set we can simply add the GitHub runner ip's, run tests, then clear out those IP's at the end of the run ensuring that we only apply this to one stack and ensure security across all the stacks.

The script is called as follows:
./waf-controller.sh [set|append] [ip_set name] [ip_set id] [space delimited list of ips or CIDRs]


Author checklist

  • I have performed a self-review of my code
  • I have added thorough tests, if necessary
  • I have updated relevant documentation, if necessary

convert to a different template: test → val | val → prod

Copy link
Contributor

@gmrabian gmrabian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't fully read the code changes but I know they are being ported.
branch url didn't work in incognito for me while on zscaler
https://d33o8hg6uk6hv9.cloudfront.net/

services/ui/serverless.yml Show resolved Hide resolved
@dwhitestratiform
Copy link
Contributor Author

Today @BearHanded and I met with the CMS networking/zscaler team. They let us know that ipv6 is not currently turned on for Zscaler which is why we're seeing our ISP IP come into the waf when having an IPV6 IP. Merging these changes will enable both IPV4 and IPV6 IP whitelisting for MCR. This only affects ephemeral environments for the time being. When the networking team turns on ipv6 for Zscaler we would anticipate this just working .

gmrabian
gmrabian previously approved these changes Feb 23, 2024
Copy link
Contributor

@gmrabian gmrabian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approving knowing that this will be re-verified later

Copy link

codeclimate bot commented Feb 26, 2024

Code Climate has analyzed commit ba53a02 and detected 0 issues on this pull request.

The test coverage on the diff in this pull request is 100.0% (90% is the threshold).

This pull request will bring the total coverage in the repository to 96.8% (0.0% change).

View more on Code Climate.

@dwhitestratiform dwhitestratiform merged commit b56d949 into main Feb 27, 2024
18 checks passed
@dwhitestratiform dwhitestratiform deleted the waf-changes branch February 27, 2024 12:40
@dwhitestratiform dwhitestratiform changed the title Adding VPN restriction to MCR dev environments Adding VPN restriction capability to MCR Feb 27, 2024
@dwhitestratiform dwhitestratiform removed the ready for review Ready for all the reviews! label Feb 27, 2024
@gmrabian gmrabian mentioned this pull request Feb 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants