2016-01-19 44 views
9

我正在使用默認URL(如https://***.amazonaws.com/***)工作視頻應用程序並將文件存儲在AWS S3上,但我已決定使用更快速的內容交付CloudFront 。加載AWS CloudFront文件時獲取403(禁止)

使用CF,我不斷得到403 (Forbidden)使用此URL https://***.cloudfront.net/***。我錯過了什麼嗎?

一切工作正常,直到我決定從CloudFront加載指向我的存儲桶的內容。

任何解決方案,請?

+0

你還沒有給我們太多去。您使用的是預先簽名的網址嗎?您的存儲桶策略是否根據某些請求參數拒絕請求? –

+0

@ Michael-sqlbot我沒有使用預先簽名的URL,只是標準配置。我設置的策略是隻接受我的URL來加載文件。 – Shina

+0

因此,您正在使用類似'「Condition」的桶策略:{ 「StringLike」:{「aws:Referer」:[「http://www.example.com/*」]} }? –

回答

8

當使用檢查傳入Referer:標頭的存儲桶策略限制對S3內容的訪問時,您需要執行一些自定義配置以「替代」CloudFront。

瞭解CloudFront旨在成爲一個行爲良好的緩存很重要。通過「良好行爲」,我的意思是CloudFront旨在永不返回與源服務器返回的響應不同的響應。我相信你可以看到這是一個重要的因素。

比方說,我有一個web服務器(未S3)背後CloudFront的,和我的網站設計,使其返回基於Referer:頭的檢查......或任何其他HTTP請求頭中的不同內容,如User-Agent:例如。根據您的瀏覽器,我可能會返回不同的內容。 CloudFront如何知道這一點,以避免向用戶提供某個頁面的錯誤版本?

答案是,它無法分辨 - 它不知道這一點。因此,CloudFront的解決方案根本不是將大多數請求標頭轉發給我的服務器。我的Web服務器無法看到,它無法響應,所以我返回的內容不能根據我沒有收到的標頭而有所不同,這會阻止CloudFront根據這些標頭緩存並返回錯誤的響應。 Web緩存有義務避免爲給定頁面返回錯誤的緩存內容。

「但等等,」你反對。 「我的網站取決於某個標題的價值,以確定如何迴應。」正確,這是有道理的...所以我們必須告訴CloudFront:

而不是根據請求的路徑緩存我的頁面,我需要你也轉發Referer:User-Agent:或其他幾個標頭之一發送通過瀏覽器,並緩存在其他請求上使用的響應,這些請求不僅包含相同的路徑,而且還包含與您轉發給我的額外頭部相同的值

但是,當原始服務器是S3時,CloudFront不支持轉發大多數請求標頭,因爲假設由於靜態內容不太可能發生變化,這些標頭只會導致它不必要地緩存多個相同的響應。

您的解決方案不是告訴CloudFront您使用S3作爲原點。相反,請將您的分發配置爲使用「自定義」來源,並將其分配給要用作原始服務器主機名的存儲分區的主機名。

然後,您可以配置CloudFront以將Referer:標頭轉發到原點,並且拒絕/允許基於該標頭的請求的S3存儲桶策略將按預期工作。

好吧,幾乎和預期的一樣。這會稍微降低緩存命中率,因爲現在緩存的頁面將基於路徑+引用頁面進行緩存。它的一個S3對象被多個站點的頁面引用,CloudFront將緩存每個唯一請求的副本。這聽起來像是一種限制,但實際上,它只是適當緩存行爲的產物 - 無論轉發到後端,幾乎所有的後端都必須用於確定該特定響應是否可用於爲將來的請求提供服務。

請參閱http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesForwardHeaders,以便將CloudFront配置爲將特定標頭白名單發送到您的原始服務器。

重要提示:不要轉發任何不需要的標題,因爲每個變體請求都會進一步降低命中率。特別是當使用S3作爲自定義起源的後端時,不要轉發Host:標頭,因爲這可能不會達到您的預期。在這裏選擇Referer:標題,並進行測試。 S3應該開始看到標題並作出相應的反應。

請注意,當您刪除存儲桶策略以進行測試時,CloudFront將繼續提供緩存的錯誤頁面,除非您通過發送無效請求刷新緩存,這將導致CloudFront清除與指定的路徑模式相匹配的所有緩存頁面,歷時約15分鐘。實驗時最簡單的事情就是使用新配置創建新的CloudFront分配,因爲分發本身不收取任何費用。

查看CloudFront的響應標頭時,請注意X-Cache:(命中/未命中)和Age:(此特定頁面已緩存多久)響應。這些對於故障排除也很有用。


更新:@alexjs做出了一個重要的觀察:不是這樣用水桶政策和轉發Referer:頭S3進行分析 - 這會傷害你的緩存比例,與變化的程度資源在引薦頁面上的傳播 - 您可以使用新的AWS Web應用防火牆服務,該服務允許您對傳入的CloudFront請求實施過濾規則,以允許或阻止基於string matching in request headers的請求。

爲此,您需要將分配連接到S3,如S3原點(正常配置,與上面解決方案中的「自定義」原點相反),並使用內置CloudFront能夠對S3的後端請求進行身份驗證(因此,如果惡意角色直接從S3請求,則不能直接訪問存儲桶內容)。

有關此選項的更多信息,請參閱https://www.alexjs.eu/preventing-hotlinking-using-cloudfront-waf-and-referer-checking/

2

另外,它可能很簡單。當您第一次上傳文件到S3存儲桶時,即使該存儲桶中的其他文件是公開的,即使存儲桶本身是公開的也是非公開的。

要在AWS控制檯中更改此設置,請選中要公開的文件夾(剛上傳的文件夾)旁邊的框,然後從菜單中選擇「公開」。

該文件夾(和任何子文件夾)中的文件將被公開,您將可以從S3提供文件。

對於AWS CLI,添加「--acl公衆閱讀」選項,在你的命令,像這樣:

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