What I am trying to do is restrict access to a file to a single IP address.
The bucket policy belows works only when either 0.0.0.0/0
is used instead of the actual IP address or the condition is removed, otherwise a 403 (Forbidden)
error is served.
The IP address is confirmed to be 68.6N.NN1.1N2
.
I recieve a 200
response if I send a curl request via terminal. However, if I include a direct link to the object in index.php
, the response is a 403 (Forbidden)
error…
(I have zero experience with cloud platforms. Any help would be very much appreciated.)
{
"Version": "2012-10-17",
"Id": "Policy17NN310NN0610",
"Statement": [
{
"Sid": "Stmt171NN106NN335",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::testbucket/file.jpg",
"Condition": {
"IpAddress": {
"aws:SourceIp": "68.6N.NN1.1N2"
}
}
}
]
}
Screenshot Confirming the IP Address
Screenshot Showing a 200
Response to a cURL Request
2
Answers
The ‘preferred’ method would be:
This way, access is authenticated rather than relying on the request coming from a specific IP address, especially since that IP address is potentially shared with systems not under your control.
From the comments, there is some confusion about how the S3 bucket policy interacts with the way the file is being accessed.
Expanding on jellycsc‘s comment, the issue could be with the IP address seen by AWS when a user tries to access the file through
index.php
on a website. AWS is seeing the IP address of the user’s browser, not the server’s IP address. Since the bucket policy is set to only allow access from a single IP address (the server’s), requests coming from any other IP address (like a user’s browser) will be denied with a 403 error.The fact that
curl https://icanhazip.com/
returns the expected IP address suggests that your server is using the correct IP. But again, ifindex.php
includes a direct link to the object and the browser tries to fetch it, AWS will see the request as coming from the client’s IP address, not the server’s.If you want the object to be accessible only from the server’s IP, you will need to make sure that the server itself fetches the object and then serves it to the client. That would involve a server-side script that handles the download and then serves the file to the client, rather than the client directly requesting the file from S3 (
S3Client
+S3.getObject()
).Here, when a user requests
index.php
, the server itself requests the object from S3 using its AWS credentials, and then passes it on to the user, without exposing the direct link to S3. The bucket policy IP restriction should work as expected because AWS only sees the server’s IP address.It is true, the above script bypasses IP-based restrictions entirely by using AWS SDK for PHP to access the file with IAM credentials.
If you need to test IP-based access restrictions without involving IAM roles or AWS SDK authentication, you would need to make sure the IP address in the S3 bucket policy is correct and that requests to S3 are actually coming from that IP address.
And… you might already have conducted the test regarding IP-based restrictions through direct links in
index.php
. A403 Forbidden
error when accessing the S3 object through a web page—accurately reflects the situation where the S3 bucket policy restricts access to a specific IP address (presumably the server’s), and the requests come from different client IP addresses through the browser.So that confirms the behavior expected under such a policy configuration: direct access attempts from any IP address other than the one specified in the policy will result in access being denied.