diff --git a/bin/cf_deploy.sh b/bin/cf_deploy.sh index aa73fdd..d4cefbc 100755 --- a/bin/cf_deploy.sh +++ b/bin/cf_deploy.sh @@ -50,6 +50,9 @@ fi fi ) +# Call blocklist generator before deploy +./generate_blockips.sh "${app}" "${space}" "${org}" + # Target space cf version cf target -o ${org} -s ${space} diff --git a/blockips.conf b/blockips.conf index a7813d4..48cfd9a 100644 --- a/blockips.conf +++ b/blockips.conf @@ -1,5 +1,5 @@ # The entire if condition is needed to block an IP -# if ($http_x_forwarded_for ~* x.x.x.x) { +# if ($http_x_forwarded_for ~* "(^|,\s*)x\.x\.x\.x(\s*,|$)") { # return 403; # } diff --git a/generate_blockips.sh b/generate_blockips.sh new file mode 100755 index 0000000..f0a7e19 --- /dev/null +++ b/generate_blockips.sh @@ -0,0 +1,32 @@ +#!/bin/bash +set -euo pipefail + +app=${1} +space=${2} +org=${3} + +# Target space +cf target -o ${org} -s ${space} + +echo "Generating blockips.conf from cloud.gov environment variable" +APP_GUID=$(cf app "$app" --guid) +VCAP_SERVICES=$(cf curl "/v3/apps/${APP_GUID}/env" | jq -r '.system_env_json.VCAP_SERVICES') + +BLOCKED_IPS=$(echo "$VCAP_SERVICES" | jq -r ' + .["user-provided"][]? + | select(.credentials.BLOCKED_IPS != null) + | .credentials.BLOCKED_IPS' | head -n 1) + +if [[ -z "$BLOCKED_IPS" || "$BLOCKED_IPS" == "null" ]]; then + echo "No BLOCKED_IPS set in cloud.gov for app '${app}', skipping blockips.conf generation" + echo "# No blocked IPs configured" > blockips.conf +else + echo "# Auto-generated list of blocked IPs" > blockips.conf + IFS=',' read -ra IPS <<< "$BLOCKED_IPS" + for ip in "${IPS[@]}"; do + escaped_ip=$(echo "$ip" | sed 's/\./\\./g') + echo "if (\$http_x_forwarded_for ~* \"(^|,\\s*)${escaped_ip}(\\s*,|$)\") {" >> blockips.conf + echo " return 403;" >> blockips.conf + echo "}" >> blockips.conf + done +fi \ No newline at end of file diff --git a/manifest_dev.yml b/manifest_dev.yml index 6ae60af..14f4237 100644 --- a/manifest_dev.yml +++ b/manifest_dev.yml @@ -4,6 +4,8 @@ applications: instances: 2 memory: 1G disk_quota: 1G + services: + - fecfile-api-creds-dev routes: - route: dev-api.fecfile.fec.gov stack: cflinuxfs4 diff --git a/manifest_prod.yml b/manifest_prod.yml index d339fd2..3cd9a6d 100644 --- a/manifest_prod.yml +++ b/manifest_prod.yml @@ -4,6 +4,8 @@ applications: instances: 2 memory: 1G disk_quota: 1G + services: + - fecfile-api-creds-prod routes: - route: api.fecfile.fec.gov stack: cflinuxfs4 diff --git a/manifest_stage.yml b/manifest_stage.yml index fd9f88b..41e6493 100644 --- a/manifest_stage.yml +++ b/manifest_stage.yml @@ -4,6 +4,8 @@ applications: instances: 2 memory: 1G disk_quota: 1G + services: + - fecfile-api-creds-stage routes: - route: stage-api.fecfile.fec.gov stack: cflinuxfs4 diff --git a/manifest_test.yml b/manifest_test.yml index 993657d..a33d645 100644 --- a/manifest_test.yml +++ b/manifest_test.yml @@ -4,6 +4,8 @@ applications: instances: 2 memory: 1G disk_quota: 1G + services: + - fecfile-api-creds-test routes: - route: test-api.fecfile.fec.gov stack: cflinuxfs4 diff --git a/nginx.conf b/nginx.conf index 13249f2..2aacea0 100644 --- a/nginx.conf +++ b/nginx.conf @@ -37,6 +37,12 @@ http { client_max_body_size 300K; + location = /robots.txt { + default_type text/plain; + return 200 "User-agent: *\nContent-Signal: search=yes, ai-input=no, ai-train=no\nAllow: /api/docs\nAllow: /static/drf_spectacular_sidecar/\nDisallow: /\n"; + + } + location / { resolver {{nameservers}} ipv6=off valid=1s; set $backend "{{env "FECFILE_WEB_API"}}";