Last active
November 12, 2024 22:21
-
-
Save gadelkareem/fdcad16caaea205f18a11ab240cc759f to your computer and use it in GitHub Desktop.
Varnish with AWS S3 bucket as backend
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"Version": "2012-10-17", | |
"Id": "S3PolicyId1", | |
"Statement": [ | |
{ | |
"Sid": "IPAllow", | |
"Effect": "Allow", | |
"Principal": "*", | |
"Action": "s3:GetObject", | |
"Resource": "arn:aws:s3:::example.bucket/*", | |
"Condition": { | |
"IpAddress": { | |
"aws:SourceIp": [ | |
"5.6.7.8/32" //varnish ip | |
] | |
} | |
} | |
}, | |
{ | |
"Sid": "Explicit deny to ensure requests are allowed only from specific referer.", | |
"Effect": "Deny", | |
"Principal": "*", | |
"Action": "s3:GetObject", | |
"Resource": "arn:aws:s3:::example.bucket/*", | |
"Condition": { | |
"StringNotLike": { | |
"aws:Referer": [ | |
"https://example.com/*" | |
] | |
} | |
} | |
} | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vcl 4.0; | |
acl cloudflare { | |
"103.21.244.0"/22; | |
"103.22.200.0"/22; | |
"103.31.4.0"/22; | |
"104.16.0.0"/12; | |
"108.162.192.0"/18; | |
"131.0.72.0"/22; | |
"141.101.64.0"/18; | |
"162.158.0.0"/15; | |
"172.64.0.0"/13; | |
"173.245.48.0"/20; | |
"188.114.96.0"/20; | |
"190.93.240.0"/20; | |
"197.234.240.0"/22; | |
"198.41.128.0"/17; | |
"2400:cb00::"/32; | |
"2405:8100::"/32; | |
"2405:b500::"/32; | |
"2606:4700::"/32; | |
"2803:f800::"/32; | |
"2c0f:f248::"/32; | |
"2a06:98c0::"/29; | |
} | |
backend example { | |
.host = "1.2.3.4"; | |
.port = "80"; | |
} | |
backend s3_bucket { | |
.host = "s3.bucket.us-east-1.amazonaws.com"; | |
.port = "80"; | |
} | |
sub vcl_recv { | |
if (req.http.host ~ "bucket.example.com") { | |
if(req.method != "GET" && req.method != "HEAD") { | |
return(synth(900)); //method not allowed | |
} | |
if(req.http.referer !~ "^https://example\.com"){ | |
return(synth(800)); //hotlinking | |
} | |
//clean up for S3 | |
unset req.http.cookie; | |
unset req.http.cache-control; | |
unset req.http.pragma; | |
unset req.http.expires; | |
unset req.http.etag; | |
unset req.http.X-Forwarded-For; | |
unset req.http.CF-Connecting-IP; | |
//set correct backend | |
set req.backend_hint = s3_bucket; | |
set req.http.host = "s3.bucket.us-east-1.amazonaws.com"; | |
//done with this request, forward it to backend | |
return(hash); | |
} | |
//normal request... | |
//pick user IP from Cloudflare request | |
if (client.ip ~ cloudflare && req.http.CF-Connecting-IP) { | |
set req.http.X-Forwarded-For = req.http.CF-Connecting-IP; | |
} | |
if (req.http.host ~ "^(.*\.)?example\.com") { | |
set req.backend_hint = example; | |
} | |
if (req.url ~ "\.(png|gif|jpg|ico|txt|swf|css|js)$") { | |
unset req.http.Cookie; | |
} | |
return(hash); | |
} | |
sub vcl_backend_response { | |
// strip the cookie before the image is inserted into cache | |
if (bereq.url ~ "\.(png|gif|jpg|ico|txt|swf|css|js)$") { | |
unset beresp.http.Set-Cookie; | |
set beresp.ttl = 1d; | |
} | |
} | |
sub vcl_deliver { | |
//clean up for delivery | |
unset resp.http.Via; | |
unset resp.http.X-Whatever; | |
unset resp.http.X-Powered-By; | |
unset resp.http.X-Varnish; | |
unset resp.http.Age; | |
unset resp.http.Server; | |
//s3 stuff | |
unset resp.http.X-Amz-Id-2; | |
unset resp.http.X-Amz-Meta-Group; | |
unset resp.http.X-Amz-Meta-Owner; | |
unset resp.http.X-Amz-Meta-Permissions; | |
unset resp.http.X-Amz-Request-Id; | |
if (req.http.host ~ "s3.bucket.us-east-1.amazonaws.com") { | |
if(resp.status == 404){ | |
return(synth(700)); //not found | |
//convert all other errors from S3 into "520 Unknown Error" | |
}elseif(resp.status != 200){ | |
return(synth(600)); | |
} | |
} | |
} | |
sub vcl_backend_error { | |
set beresp.http.Content-Type = "text/html; charset=utf-8"; | |
synthetic( {"Error! Please retry later.."} ); | |
return(deliver); | |
} | |
sub vcl_synth { | |
if (resp.status > 550) { | |
set resp.http.Content-Type = "text/plain; charset=utf-8"; | |
if (resp.status == 900) { | |
set resp.status = 405; | |
synthetic({"Method Not Allowed"}); | |
}elseif (resp.status == 800) { | |
set resp.status = 403; | |
synthetic({"Hotlinking Not Allowed"}); | |
}elseif (resp.status == 700) { | |
set resp.status = 404; | |
synthetic({"Not Found"}); | |
}elseif (resp.status == 600) { | |
set resp.status = 520; | |
synthetic({"Unknown Error"}); | |
} | |
} | |
return(deliver); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment