it-swarm.com.de

403 (Verboten) beim Laden der AWS CloudFront-Datei

Ich arbeite an einer Video-App und speichere die Dateien in AWS S3. Die Standard-URL wie https://***.amazonaws.com/*** funktioniert einwandfrei, aber ich habe mich für CloudFront entschieden, das schneller für die Bereitstellung von Inhalten ist.

Bei Verwendung von CF erhalte ich ständig 403 (Forbidden) mit dieser URL https://***.cloudfront.net/***. Habe ich etwas vergessen?

Alles funktioniert gut, bis ich beschließe, den Inhalt von CloudFront zu laden, der auf meinen Bucket verweist.

Irgendwelche Lösung bitte?

13
Shina

Wenn Sie den Zugriff auf S3-Inhalt mithilfe einer Bucket-Richtlinie einschränken, die den eingehenden Referer:-Header untersucht, müssen Sie ein wenig benutzerdefinierte Konfiguration vornehmen, um CloudFront zu übertreffen.

Es ist wichtig zu verstehen, dass CloudFront als Cache mit gutem Verhalten entwickelt wurde. Mit "gut benommen" meine ich, dass CloudFront niemals eine Antwort zurückgibt, die sich von der des Origin-Servers unterscheidet. Ich bin sicher, Sie können sehen, dass dies ein wichtiger Faktor ist.

Nehmen wir an, ich habe einen Webserver (nicht S3) hinter CloudFront, und meine Website ist so ausgelegt, dass unterschiedliche Inhalte basierend auf einer Überprüfung des Referer:-Headers ... oder eines anderen http-Request-Headers wie User-Agent: zurückgegeben werden. Abhängig von Ihrem Browser kann ich andere Inhalte zurückgeben. Wie würde CloudFront das wissen, um zu vermeiden, dass einem Benutzer die falsche Version einer bestimmten Seite angezeigt wird?

Die Antwort ist, es würde es nicht sagen - das kann es nicht wissen. Die Lösung von CloudFront besteht also darin, die meisten Anforderungsheader überhaupt nicht an meinen Server weiterzuleiten. Was mein Webserver nicht sehen kann, kann er nicht reagieren. Daher kann der von mir zurückgegebene Inhalt nicht auf der Grundlage von Kopfzeilen variieren, die ich nicht erhalten habe. Dadurch wird verhindert, dass CloudFront aufgrund dieser Kopfzeilen die falschen Antworten zurückgibt. Web-Caches müssen verhindern, dass für eine bestimmte Seite der falsche zwischengespeicherte Inhalt zurückgegeben wird.

"Aber warte", widersprichst du. "Meine Site hängt vom Wert eines bestimmten Headers ab, um zu bestimmen, wie sie reagieren sollen." Richtig, das macht Sinn ... also müssen wir CloudFront folgendes sagen:

Anstatt meine Seiten nur anhand des angeforderten Pfads zu cachen, müssen Sie auch Referer: oder User-Agent: oder einen von mehreren anderen Headern, wie vom Browser gesendet, weiterleiten und die Antwort zur Verwendung für andere Anforderungen zwischenspeichern, die nicht nur den derselbe Pfad, aber auch die gleichen Werte für die zusätzlichen Header, die Sie an mich weiterleiten.

Wenn der Origin-Server jedoch S3 ist, unterstützt CloudFront die Weiterleitung der meisten Anforderungsheader nicht. Wenn davon ausgegangen wird, dass sich statischer Inhalt kaum ändert, würden diese Header nur dazu führen, dass mehrere identische Antworten unnötig zwischengespeichert werden.

Ihre Lösung besteht nicht darin, CloudFront nicht mitzuteilen, dass Sie S3 als Origin verwenden. Konfigurieren Sie stattdessen Ihre Distribution so, dass sie ein "benutzerdefiniertes" Origin verwendet, und geben Sie den Hostnamen des Buckets an, der als Origin-Hostname verwendet werden soll.

Anschließend können Sie CloudFront so konfigurieren, dass der Referer:-Header an den Origin weitergeleitet wird. Die S3-Bucket-Richtlinie, die Anforderungen, die auf diesem Header basieren, ablehnt oder zulässt, funktioniert erwartungsgemäß.

Nun, fast wie erwartet. Dadurch wird die Cachetrefferquote etwas verringert, da nun die zwischengespeicherten Seiten basierend auf Pfad + verweisender Seite zwischengespeichert werden. Wenn ein S3-Objekt von mehreren Seiten Ihrer Site referenziert wird, speichert CloudFront eine Kopie für jede eindeutige Anforderung. Es klingt wie eine Einschränkung, aber im Grunde ist es nur ein Artefakt des richtigen Cache-Verhaltens. Was immer an das Back-End weitergeleitet wird, muss fast alles sein, um zu bestimmen, ob diese bestimmte Antwort für die Bearbeitung zukünftiger Anforderungen geeignet ist.

Siehe http://docs.aws.Amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesForwardHeaders , um CloudFront so zu konfigurieren, dass bestimmte Header an Ihren Origin-Server gesendet werden.

Wichtig: Leiten Sie keine Kopfzeilen weiter, die Sie nicht benötigen, da durch jede Variantenanfrage die Trefferquote weiter reduziert wird. Wenn Sie S3 als Back-End für ein benutzerdefiniertes Origin verwenden, leiten Sie den Host:-Header nicht weiter, da dies wahrscheinlich nicht das tut, was Sie erwarten. Wählen Sie hier den Header Referer: aus und testen Sie. S3 sollte beginnen, den Header zu sehen und entsprechend zu reagieren.

Wenn Sie Ihre Bucket-Richtlinie zu Testzwecken entfernt haben, hätte CloudFront die zwischengespeicherte Fehlerseite weiterhin bereitgestellt, es sei denn, Sie haben den Cache durch Senden einer Invalidierungsanforderung geleert. In diesem Fall löscht CloudFront alle zwischengespeicherten Seiten, die dem von Ihnen angegebenen Pfadmuster entsprechen von etwa 15 Minuten. Am einfachsten ist es beim Experimentieren, eine neue CloudFront-Distribution mit der neuen Konfiguration zu erstellen, da für die Distributionen selbst keine Kosten anfallen.

Beachten Sie bei der Anzeige der Antwortheader in CloudFront die Antworten X-Cache: (Treffer/Fehler) und Age: (wie lange diese bestimmte Seite im Cache war). Diese sind auch bei der Problembehandlung hilfreich. 


Update: _ ​​ @alexjs hat eine wichtige Beobachtung gemacht: Verwenden Sie stattdessen die Bucket-Richtlinie und leiten Sie den Referer:-Header zur Analyse an S3 weiter. Dies beeinträchtigt die Cache-Rate in unterschiedlichem Maße bei der Verteilung von Ressourcen auf verweisende Seiten - Sie können den neuen AWS Web Application Firewall-Dienst verwenden, mit dem Sie Filterregeln für eingehende Anforderungen an CloudFront festlegen können, um Anforderungen basierend auf Zeichenfolgenübereinstimmung in Anforderungsheadern) zuzulassen oder zu blockieren. } _.Dazu müssten Sie die Distribution mit S3 als S3 Origin (der normalen Konfiguration, anders als in der obigen Lösung vorgeschlagen, mit einem "benutzerdefinierten" Origin) verbinden und die eingebaute Funktion von CloudFront verwenden Back-End-Anforderungen bei S3 authentifizieren (der Bucket-Inhalt kann daher nicht direkt aufgerufen werden, wenn er direkt von einem böswilligen Akteur angefordert wird).

Weitere Informationen zu dieser Option finden Sie unter _ {(https://www.alexjs.eu/preventing-hotlinking-using-cloudfront-waf-and-referer-checking/ .

See https://www.alexjs.eu/preventing-hotlinking-using-cloudfront-waf-and-referer-checking/ for more on this option.

10

Ich habe einen weiteren Grund gefunden, warum CloudFront eine 403 (Bad request) zurückgeben kann. Vielleicht ist das ein Edge-Fall, aber ich möchte mit Ihnen teilen.

CloudFront implementiert einen Forward-Loop-Erkennungsmechanismus, um Forwarding-Loop-Angriffe zu verhindern.
Sie können laut AWS-Unterstützung nicht mehr als 2 CloudFront-Distributionen als Ursprünge kaskadieren.

Nehmen wir an, Sie haben CloudFront A mit CloudFront B als Ursprung konfiguriert und von CloudFront B aus haben Sie CloudFront C als Ursprung konfiguriert und von CloudFront C aus haben Sie einen S3-Bucket als Ursprung.

A --> B --> C --> S3 bucket (can return a 403 error)

Wenn Sie eine Datei von CloudFront A anfordern, die sich am Ende der Kaskade im S3-Bucket befindet, gibt CloudFront C eine 403 zurück (ungültige Anforderung).

Wenn Ihre Kaskade nur aus 2 CloudFront-Distributionen und einem S3-Bucket am Ende besteht, funktioniert die Anforderung einer Datei von S3 Origin.

A --> B --> S3 bucket (works)

5
Stefan Rode

Es kann auch etwas einfaches sein. Wenn Sie eine Datei zum ersten Mal in einen S3-Bucket hochladen, ist sie nicht öffentlich, auch wenn andere Dateien in diesem Bucket öffentlich sind und der Bucket selbst öffentlich ist. 

Um dies in der AWS Console zu ändern, aktivieren Sie das Kontrollkästchen neben dem Ordner, den Sie öffentlich machen möchten (den Ordner, den Sie gerade hochgeladen haben), und wählen Sie "Make public" aus dem Menü. 

Die Dateien in diesem Ordner (und in allen Unterordnern) werden veröffentlicht, und Sie können die Dateien von S3 aus bereitstellen.

Fügen Sie für die AWS-CLI die Option "--acl public-read" in Ihren Befehl ein.

aws s3 cp index.html s3://your.remote.bucket --acl public-read
4
Patrick Chu

Für mich hatte ich CodePipeline Zugriff auf S3 erteilt, wodurch meine s3-Bucket-Richtlinie überschrieben wurde. Zum Beispiel so etwas: 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::mys3bucket/*"
        }
    ]
}
0
Jghorton14