[英]Access Denied to Public S3 Bucket from certain IP addresses
我嘗試使用 PHP SDK 制作一個完全公共的 S3 存儲桶並進行訪問。 當我從本地計算機運行以下訪問代碼時,此方法有效:
require 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$s3 = new S3Client([
'version' => 'latest',
'region' => 'eu-west-2',
'credentials' => [
'key' => "my correct key",
'secret' => "my correct secret"
]
]);
// //publictest2
$bucket = 'mybucketname';
$keyname = 'test_file.txt';
// Upload an object
try {
// Upload data.
$result = $s3->putObject([
'Bucket' => $bucket,
'Key' => $keyname,
'Body' => 'Hello',
'ACL' => 'public-read'
]);
// Print the URL to the object.
echo $result['ObjectURL'] . PHP_EOL;
} catch (S3Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
但是,一旦我從測試服務器(AWS EC2)運行它,我就會收到以下錯誤:
Error executing "PutObject" on "mybucketname"; AWS HTTP error: Client error: `PUT https://mybucketname/test_file.txt` resulted in a `403 Forbidden` response: AccessDeniedAccess DeniedVTJX7V (truncated...) AccessDenied (client): Access Denied - AccessDeniedAccess DeniedVTJX7V4CCKZYG7CRTz+dPA7fsZQnFxTERKxxbP+IpTtMIIsS1uu23fvTruHH3w8KxwGIduCntRBM5u6tIfHdusbCoPw=
我已經實現了以下內容來公開存儲桶:
{
"Version": "2012-10-17",
"Id": "S3BukcetPolicyIPAccess",
"Statement": [
{
"Sid": "DenyIfNotFromAllowedVPC",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"mybucketarn",
"mybucketarn/*"
]
}
]
}
為什么從我的 EC2 服務器運行時這仍然不起作用?
這與 S3 存儲桶無關 - 這里的提示是它可以在您的本地機器上工作,這意味着 S3 存儲桶不應歸咎於實例。
這與您的 EC2 實例承擔(或不承擔)的角色有關 - 創建並分配有權在mybucketname
上執行PutObject
的 IAM 角色。
測試這一點的一種快速方法是使用附加了 AWS 托管策略AmazonS3FullAccess
的角色,該策略提供對所有 S3 存儲桶的完全訪問權限。
然后,您的 EC2 實例將有權訪問 S3 存儲桶。
對於 HTTP 403 禁止錯誤調試以下步驟。
您能否從您的 ec2 實例中檢查此命令
“aws s3 ls s3://doc-example-bucket/abc/”
如果此命令成功,則應用程序代碼中指定的憑據或角色會導致“拒絕訪問”錯誤。 確保實例配置文件角色具有 S3 存儲桶所需的讀取和寫入權限。 例如,以下 IAM 策略中的 S3 操作提供對 S3 存儲桶的所需讀寫訪問權限。
您的問題是在您的 EC2 實例上運行的 PHP 網絡服務器使用 AWS PHP SDK 並且沒有配置文件( IAM 角色主體,AWS),因為您的 EC2 用戶既沒有附加實例,也沒有配置默認角色(AWS)使用aws configure
。
換句話說,您的 AWS API 調用未經過身份驗證,更不用說授權對 S3 執行任何操作了。 即使您在 Bucket 策略中允許所有 Principals 使用s3:*
。 請記住:存儲桶策略需要 AWS 委托人,但您的請求未經過身份驗證(AWS API 無法確定誰在調用)。 因此AccessDenied
。
您的問題有幾種解決方案。 但所有這些都可以歸結為:
使用 IAM 政策(推薦)
使用 S3 存儲桶策略
您可以查看此 AWS 博客文章以了解要遵循的方法,但對於您的特定問題,我會使用 IAM 策略 go。
使用 S3 存儲桶策略
讓我先從第二種解決方案開始。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxx:role/ec2-instance-role"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::yyyyyyyyyyy",
"arn:aws:s3:::yyyyyyyyyyy/*"
]
}
]
}
創建一個名為ec2-instance-role
的新 IAM 角色。 您不需要附加任何 IAM 策略。 留空。
Go 到您的 EC2 實例,單擊Actions -> Security -> Modify IAM role
和 select 在步驟 3 中創建的角色。
無需重啟實例。 為了驗證一切都按預期工作,我正在使用 AWS CLI,但它也應該適用於任何 SDK(例如 PHP)。 從您的 EC2 實例執行:
# Make sure the correct role is assumed
$ aws sts get-caller-identity
{
"Account": "xxxxxxxxxxx",
"UserId": "AROAYGJILC6K4AJRGLZTS:i-0aa422c12359ac00e",
"Arn": "arn:aws:sts::xxxxxxxxxxx:assumed-role/ec2-instance-role/i-0aa422c12359ac00e"
}
# Upload a test file and check the bucket
$ touch test.txt
$ aws s3 cp test.txt s3://yyyyyyyyyyy/test.txt
upload: ./test.txt to s3://yyyyyyyyyyy/test.txt
$ aws s3 ls s3://yyyyyyyyyyy
2021-12-12 11:01:51 0 test.txt
使用 IAM 策略
在這里,除了您不需要任何存儲桶策略之外,一切都保持不變,但您將策略直接附加到 IAM 實例配置文件(角色)。
創建一個存儲桶。 禁用對它的所有公共訪問。 禁用 ACL。
使用以下策略創建一個名為ec2-instance-role
的新 IAM 角色:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::yyyyyyyyyyy",
"arn:aws:s3:::yyyyyyyyyyy/*"
]
}
]
}
Go 到您的 EC2 實例,單擊Actions -> Security -> Modify IAM role
和 select 在上一步中創建的角色。
為了驗證一切都按預期工作,我正在使用 AWS CLI,但它也應該適用於任何 SDK(例如 PHP)。 從您的 EC2 實例執行:
# Make sure the correct role is assumed
$ aws sts get-caller-identity
{
"Account": "xxxxxxxxxxx",
"UserId": "AROAYGJILC6K4AJRGLZTS:i-0aa422c12359ac00e",
"Arn": "arn:aws:sts::xxxxxxxxxxx:assumed-role/ec2-instance-role/i-0aa422c12359ac00e"
}
# Upload a test file and check the bucket
$ touch test.txt
$ aws s3 cp test.txt s3://yyyyyyyyyyy/test.txt
upload: ./test.txt to s3://yyyyyyyyyyy/test.txt
$ aws s3 ls s3://yyyyyyyyyyy
2021-12-12 11:01:51 0 test.txt
最后但並非最不重要的兩種方法:不要使用 ACL(配置您的存儲桶ACLs disabled
),因為 ACL 的存在是為了向后兼容以支持存儲桶策略,請參閱同一篇博文中的詳細信息:
作為一般規則,AWS 建議使用 S3 存儲桶策略或 IAM 策略進行訪問控制。 S3 ACL 是早於 IAM 的傳統訪問控制機制。
在上面的片段中:
xxxxxxxxxxx
是您的 AWS 帳號,例如561262107623
yyyyyyyyyyy
是您的存儲桶名稱,例如mybucket
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.