为AWS Transfer用户添加含逻辑目录的策略后出现权限拒绝的原因
问题原因及解决方案
核心问题分析
你添加的IAM策略仅授权了s3:ListBucket操作针对桶根目录(arn:aws:s3:::amzn-s3-demo-bucket),但当你通过SFTP访问/types目录并执行ls时,对应的S3操作是要列出桶内somedir/前缀下的内容(因为你的逻辑目录映射将/types/emptytype指向/bucket/somedir/empty_dir,/types/standardevent指向/bucket/somedir/users/${transfer:UserName})。原策略没有覆盖这个前缀的ListBucket权限,所以触发了"Permission denied"。
另外,当使用AWS Transfer Family的逻辑目录映射时,IAM策略必须明确匹配映射后的S3实际路径,不能仅授权桶根权限——因为逻辑目录的导航操作会被转换为对应S3前缀的List操作。
修正后的策略示例
以下策略实现你的需求:允许上传/下载,禁止删除(除了OUT目录),同时支持逻辑目录的正常访问:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": "arn:aws:s3:::amzn-s3-demo-bucket", "Condition": { "StringLike": { "s3:prefix": [ "somedir/empty_dir/*", "somedir/empty_dir/", "somedir/users/${transfer:UserName}/*", "somedir/users/${transfer:UserName}/", "somedir/users/${transfer:UserName}/OUT/*", "somedir/users/${transfer:UserName}/OUT/" ] } } }, { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::amzn-s3-demo-bucket/somedir/empty_dir/*", "arn:aws:s3:::amzn-s3-demo-bucket/somedir/users/${transfer:UserName}/*" ] }, { "Effect": "Allow", "Action": "s3:DeleteObject", "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/somedir/users/${transfer:UserName}/OUT/*" }, { "Effect": "Deny", "Action": "s3:DeleteObject", "Resource": [ "arn:aws:s3:::amzn-s3-demo-bucket/somedir/empty_dir/*", "arn:aws:s3:::amzn-s3-demo-bucket/somedir/users/${transfer:UserName}/*" ], "Condition": { "StringNotLike": { "s3:prefix": "somedir/users/${transfer:UserName}/OUT/*" } } } ] }
关键说明
- ListBucket权限:通过
s3:prefix条件限制仅允许列出映射后的S3前缀,确保逻辑目录的ls操作正常。注意要同时包含带/*和不带/*的前缀(前者匹配目录下的对象,后者匹配目录本身)。 - 上传/下载权限:授权
s3:GetObject和s3:PutObject针对所有映射后的对象路径。 - 删除权限控制:先允许OUT目录的
DeleteObject,再拒绝其他路径的删除操作,实现仅OUT目录可删除的需求。 - 变量使用:
${transfer:UserName}会自动替换为当前登录的用户名(这里是test1),确保策略的通用性。
应用策略的命令
将上述策略替换到--policy参数中执行:
aws transfer --region us-east-1 update-user --user-name test1 \ --server-id "s-12345" \ --policy '{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Action": ["s3:ListBucket"],"Resource": "arn:aws:s3:::amzn-s3-demo-bucket","Condition": {"StringLike": {"s3:prefix": ["somedir/empty_dir/*","somedir/empty_dir/","somedir/users/${transfer:UserName}/*","somedir/users/${transfer:UserName}/","somedir/users/${transfer:UserName}/OUT/*","somedir/users/${transfer:UserName}/OUT/"]}}},{"Effect": "Allow","Action": ["s3:GetObject","s3:PutObject"],"Resource": ["arn:aws:s3:::amzn-s3-demo-bucket/somedir/empty_dir/*","arn:aws:s3:::amzn-s3-demo-bucket/somedir/users/${transfer:UserName}/*"]},{"Effect": "Allow","Action": "s3:DeleteObject","Resource": "arn:aws:s3:::amzn-s3-demo-bucket/somedir/users/${transfer:UserName}/OUT/*"},{"Effect": "Deny","Action": "s3:DeleteObject","Resource": ["arn:aws:s3:::amzn-s3-demo-bucket/somedir/empty_dir/*","arn:aws:s3:::amzn-s3-demo-bucket/somedir/users/${transfer:UserName}/*"],"Condition": {"StringNotLike": {"s3:prefix": "somedir/users/${transfer:UserName}/OUT/*"}}]}' \ --home-directory-type LOGICAL --home-directory-mappings '[{"Entry":"/types/emptytype", "Target":"/amzn-s3-demo-bucket/somedir/empty_dir"},{"Entry":"/types/standardevent", "Target":"/amzn-s3-demo-bucket/somedir/users/${transfer:UserName}"}]'
注意:确保逻辑目录映射中的Target路径里的桶名和策略中的桶名一致(示例中统一为amzn-s3-demo-bucket)。
内容的提问来源于stack exchange,提问作者lopass
相关产品推荐
相关产品推荐

