it is done

I have completed the respondinator project to my liking, which is rare. I have been able to squash all issues that have come up, protect it against specific types of attacks, and clean up the code to my liking. I added integration tests to make sure I don’t break anything, and I have pushed the changes to a public GitHub repository. You can find the code base at the following location:

Below will be the final instructions moving foward until any changes are made:

Adding routes (POST)

String response route:

$> curl -s -d '{"path": "/hello", "response": "world"}' https://dbag.tech/routes/addme
$> curl -s https://dbag.tech/routes/hello
world

JSON response route:

$> curl -s -d '{"path": "/hello", "response": { "world": { "hello": "world" } }}' https://dbag.tech/routes/addme
$> curl -s https://dbag.tech/routes/hello
{"world":{"hello":"world"}}

Respondinator response:

{
  "path": "/hello",
  "response": "world",
  "key": "b08421d1-4cd5-4668-96d2-bf1467430db5"
}

Updating routes (PUT)

  • Use the key that was provided in the POST or PUT
$> curl -s -XPUT -d '{"path": "/hello", "response": { "world": { "hello": "dbag" } }, "key": "b08421d1-4cd5-4668-96d2-bf1467430db5"}' https://dbag.tech/routes/addme
$> curl -s https://dbag.tech/routes/hello
{"world":{"hello":"dbag"}}

Retrieving route (GET)

$> curl -s https://dbag.tech/routes/hello | jq .
{
  "world": {
    "hello": "dbag"
  }
}

Additional NGINX update

This issue was brought to my attention by a specially crafted Go application that my associate built specifically to take down my application. I was able to prevent further attacks by this application by modifying my base NGINX configuration to rate limit requests. Due to the fact that I use CloudFront in front of my origin, I had one of two choices. Use the binary representation of the IP address in NGINX to block the requests (less memory usage), or block based on X-Forwarded-For address (more memory usage). I chose the former, due to the fact that these applications are running in memory constricted containers.

What happened before adding the set_real_ip_from options was that it was rate limiting each CloudFront edge IP address instead of the true client IP. After setting these options, I no longer see the CloudFront IP address, and all IPs are replaced with the true client IP. I’m still not sure that I want to keep it this way, as it may be useful at some point to know the CloudFront edge IP that’s hitting the site.

NGINX HTTP Context:

    # Rate limiting
    limit_req_zone	$binary_remote_addr zone=mylimit:10m rate=5r/s;

    # Real-IP Module for CloudFront
    real_ip_header	X-Forwarded-For;
    real_ip_recursive	on;

    # CloudFront IP Ranges
    set_real_ip_from	13.32.0.0/15;
    set_real_ip_from	13.54.63.128/26;
    set_real_ip_from	13.59.250.0/26;
    set_real_ip_from	13.113.203.0/24;
    set_real_ip_from	13.124.199.0/24;
    set_real_ip_from	13.228.69.0/24;
    set_real_ip_from	34.195.252.0/24;
    set_real_ip_from	34.226.14.0/24;
    set_real_ip_from	34.232.163.208/29;
    set_real_ip_from	35.158.136.0/24;
    set_real_ip_from	35.162.63.192/26;
    set_real_ip_from	35.167.191.128/26;
    set_real_ip_from	52.15.127.128/26;
    set_real_ip_from	52.46.0.0/18;
    set_real_ip_from	52.47.139.0/24;
    set_real_ip_from	52.52.191.128/26;
    set_real_ip_from	52.56.127.0/25;
    set_real_ip_from	52.57.254.0/24;
    set_real_ip_from	52.66.194.128/26;
    set_real_ip_from	52.78.247.128/26;
    set_real_ip_from	52.84.0.0/15;
    set_real_ip_from	52.199.127.192/26;
    set_real_ip_from	52.212.248.0/26;
    set_real_ip_from	52.220.191.0/26;
    set_real_ip_from	52.222.128.0/17;
    set_real_ip_from	54.182.0.0/16;
    set_real_ip_from	54.192.0.0/16;
    set_real_ip_from	54.230.0.0/16;
    set_real_ip_from	54.233.255.128/26;
    set_real_ip_from	54.239.128.0/18;
    set_real_ip_from	54.239.192.0/19;
    set_real_ip_from	54.240.128.0/18;
    set_real_ip_from	204.246.164.0/22;
    set_real_ip_from	204.246.168.0/22;
    set_real_ip_from	204.246.174.0/23;
    set_real_ip_from	204.246.176.0/20;
    set_real_ip_from	205.251.192.0/19;
    set_real_ip_from	205.251.249.0/24;
    set_real_ip_from	205.251.250.0/23;
    set_real_ip_from	205.251.252.0/23;
    set_real_ip_from	205.251.254.0/24;
    set_real_ip_from	216.137.32.0/19;

NGINX Server Context:

    location /routes/ {
      limit_req				zone=mylimit burst=20 nodelay;
      limit_req_status			429;
      proxy_pass			http://respondinator/;
      proxy_set_header Host		$host;
      proxy_set_header X-Real-IP	$remote_addr;
    }
Ryan Gravlin's Picture

About Ryan Gravlin

Over 25 years experience as a system operator.

Miami, FL https://dbag.tech

Comments