NixOS / infra

NixOS configurations for nixos.org and its servers
MIT License
229 stars 94 forks source link

terraform: configure authn for fastly<->releases #424

Open mweinelt opened 4 months ago

mweinelt commented 4 months ago

This happens in preparation for enabling requester pays on the S3 bucket.

  # fastly_service_vcl.releases will be updated in-place
  ~ resource "fastly_service_vcl" "releases" {
      ~ active_version     = 55 -> (known after apply)
      ~ cloned_version     = 55 -> (known after apply)
        id                 = "745rWITBeKgJklfVqQ2Sjb"
        name               = "releases.nixos.org"
        # (8 unchanged attributes hidden)

      + snippet {
          + content  = <<-EOT
                # VCL snippet to authenticate Fastly<->S3 requests.
                #
                # https://docs.fastly.com/en/guides/amazon-s3#using-an-amazon-s3-private-bucket

                declare local var.canonicalHeaders STRING;
                declare local var.signedHeaders STRING;
                declare local var.canonicalRequest STRING;
                declare local var.canonicalQuery STRING;
                declare local var.stringToSign STRING;
                declare local var.dateStamp STRING;
                declare local var.signature STRING;
                declare local var.scope STRING;

                if (req.method == "GET" && !req.backend.is_shield) {
                  set bereq.http.x-amz-content-sha256 = digest.hash_sha256("");
                  set bereq.http.x-amz-date = strftime({"%Y%m%dT%H%M%SZ"}, now);
                  set bereq.http.x-amz-request-payer = "requester";
                  set bereq.http.host = "nix-releases.s3.amazonaws.com";
                  set bereq.url = querystring.remove(bereq.url);
                  set bereq.url = regsuball(urlencode(urldecode(bereq.url.path)), {"%2F"}, "/");
                  set var.dateStamp = strftime({"%Y%m%d"}, now);
                  set var.canonicalHeaders = ""
                    "host:" bereq.http.host LF
                    "x-amz-content-sha256:" bereq.http.x-amz-content-sha256 LF
                    "x-amz-date:" bereq.http.x-amz-date LF
                    "x-amz-request-payer:" bereq.http.x-amz-request-payer LF
                  ;
                  set var.canonicalQuery = "";
                  set var.signedHeaders = "host;x-amz-content-sha256;x-amz-date;x-amz-request-payer";
                  set var.canonicalRequest = ""
                    "GET" LF
                    bereq.url.path LF
                    var.canonicalQuery LF
                    var.canonicalHeaders LF
                    var.signedHeaders LF
                    digest.hash_sha256("")
                  ;

                  set var.scope = var.dateStamp "/eu-west-1/s3/aws4_request";

                  set var.stringToSign = ""
                    "AWS4-HMAC-SHA256" LF
                    bereq.http.x-amz-date LF
                    var.scope LF
                    regsub(digest.hash_sha256(var.canonicalRequest),"^0x", "")
                  ;

                  set var.signature = digest.awsv4_hmac(
                    "...",
                    var.dateStamp,
                    "eu-west-1",
                    "s3",
                    var.stringToSign
                  );

                  set bereq.http.Authorization = "AWS4-HMAC-SHA256 "
                    "Credential=.../" var.scope ", "
                    "SignedHeaders=" var.signedHeaders ", "
                    "Signature=" + regsub(var.signature,"^0x", "")
                  ;
                  unset bereq.http.Accept;
                  unset bereq.http.Accept-Language;
                  unset bereq.http.User-Agent;
                  unset bereq.http.Fastly-Client-IP;
                }
            EOT
          + name     = "Authenticate S3 requests"
          + priority = 100
          + type     = "miss"
        }

        # (15 unchanged blocks hidden)
    }
mweinelt commented 4 months ago

Okay, updated.

mweinelt commented 3 months ago

Currently this configuration leads to a 404 from fastly, which is likely a 403 from the S3 bucket.

More context on Matrix