-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #84 from AlibabaCloudLandingZone/solution-access-a…
…nalyzer-external-access/0.0.1 solution-access-analyzer-external-access/0.0.1
- Loading branch information
Showing
8 changed files
with
377 additions
and
0 deletions.
There are no files selected for viewing
23 changes: 23 additions & 0 deletions
23
solution/solution-access-analyzer-external-access/.gitignore
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
target/ | ||
!.mvn/wrapper/maven-wrapper.jar | ||
!**/src/main/**/target/ | ||
!**/src/test/**/target/ | ||
dependency-reduced-pom.xml | ||
|
||
### IntelliJ IDEA ### | ||
.idea/ | ||
|
||
### Eclipse ### | ||
.apt_generated | ||
.classpath | ||
.factorypath | ||
.project | ||
.settings | ||
.springBeans | ||
.sts4-cache | ||
|
||
### VS Code ### | ||
.vscode/ | ||
|
||
### Mac OS ### | ||
.DS_Store |
25 changes: 25 additions & 0 deletions
25
solution/solution-access-analyzer-external-access/README.md
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# 通过访问分析识别和收敛外部访问 | ||
|
||
企业在日常用云的过程中,为保证业务的灵活性,通常会出现外部访问授权的情形,如账号A会将部分云资源授权给账号B乃至多个账号使用,运维团队对此难以及时跟踪,存在安全风险。为了既不影响业务协同的灵活性,又保障企业账号的安全,本方案介绍如何通过Access Analyzer访问分析服务来帮助企业及时发现存在跨账号访问权限的资源,从而判断该访问的合理性并收敛非必要的外部访问权限。 | ||
|
||
访问分析通过和事件总线集成,支持您使用事件总线接收访问分析的分析结果事件,并执行您自己的自动化程序,实现访问分析结果的自动修复和处理。这里针对最常见的OSS Bucket非预期公开访问的场景,通过访问分析、事件总线配合函数计算,实现自动化阻止OSS Bucket公开访问,避免非预期的公开访问,导致企业数据泄露,及时保证数据安全。 | ||
|
||
本方案提供基于Terraform的自动化模板,为资源目录下的目标账号批量创建RAM角色并提供函数计算示例代码。 | ||
|
||
## 使用步骤 | ||
|
||
### 自动化部署代码 | ||
|
||
本方案提供了基于ROS的批量跨账号创建角色的Terraform自动化代码,模版代码所在目录为`ros/create-role-cross-account`,其模版入参输入: | ||
|
||
| **参数名称** | **参数值示例** | **描述** | | ||
| --- | --- | --- | | ||
| role_name | CentralizedOperationRole | 批量创建的角色的名称 | | ||
| policy_name | CentralizedOperationRolePolicy | 绑定到该角色的权限策略的名称 | | ||
| policy_document | {"Version":"1","Statement":[{"Action":"ecs:*","Resource":"*","Effect":"Allow"}]} | 绑定到该角色的权限策略内容。既跨账号资源操作的所有权限。| | ||
| assume_role_principal_account | 1254004******** | 角色的可信账号,既允许扮演到该新建角色的账号,不填默认为当前账号| | ||
| assume_role_principal_role | AssumeRoleName | 允许可信账号下扮演到该角色的角色名称。请确保该角色在可信账号下已经存在,否则会创建失败。 | | ||
|
||
### 函数计算代码示例 | ||
|
||
本方案提供了基于函数计算自动阻止OSS Bucket公共访问的示例代码,代码所在目录为`fc/java`。您可以使用命令`mvn -U clean package`将代码构建为JAR包,然后上传至阿里云函数计算。 |
93 changes: 93 additions & 0 deletions
93
solution/solution-access-analyzer-external-access/fc/java/pom.xml
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>org.example</groupId> | ||
<artifactId>fc-java</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
<packaging>jar</packaging> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<maven.compiler.source>1.8</maven.compiler.source> | ||
<maven.compiler.target>1.8</maven.compiler.target> | ||
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> | ||
<exec.cleanupDaemonThreads>false</exec.cleanupDaemonThreads> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.aliyun</groupId> | ||
<artifactId>aliyun-java-sdk-sts</artifactId> | ||
<version>3.1.2</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>com.aliyun</groupId> | ||
<artifactId>aliyun-java-sdk-core</artifactId> | ||
<version>[4.0.0,5.0.0)</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>com.aliyun.oss</groupId> | ||
<artifactId>aliyun-sdk-oss</artifactId> | ||
<version>3.18.1</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>com.aliyun.fc.runtime</groupId> | ||
<artifactId>fc-java-core</artifactId> | ||
<version>1.4.1</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>com.aliyun.fc.runtime</groupId> | ||
<artifactId>fc-java-event</artifactId> | ||
<version>1.2.0</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>com.alibaba.fastjson2</groupId> | ||
<artifactId>fastjson2</artifactId> | ||
<version>2.0.51</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.projectlombok</groupId> | ||
<artifactId>lombok</artifactId> | ||
<version>1.18.6</version> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-shade-plugin</artifactId> | ||
<version>3.2.1</version> | ||
<executions> | ||
<execution> | ||
<phase>package</phase> | ||
<goals> | ||
<goal>shade</goal> | ||
</goals> | ||
<configuration> | ||
<filters> | ||
<filter> | ||
<artifact>*:*</artifact> | ||
<excludes> | ||
<exclude>META-INF/*.SF</exclude> | ||
<exclude>META-INF/*.DSA</exclude> | ||
<exclude>META-INF/*.RSA</exclude> | ||
</excludes> | ||
</filter> | ||
</filters> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
88 changes: 88 additions & 0 deletions
88
...tion/solution-access-analyzer-external-access/fc/java/src/main/java/org/example/Main.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package org.example; | ||
|
||
import com.alibaba.fastjson2.JSON; | ||
import com.aliyun.fc.runtime.Context; | ||
import com.aliyun.fc.runtime.FunctionComputeLogger; | ||
import com.aliyun.fc.runtime.StreamRequestHandler; | ||
import com.aliyun.oss.ClientBuilderConfiguration; | ||
import com.aliyun.oss.OSS; | ||
import com.aliyun.oss.OSSClientBuilder; | ||
import com.aliyun.oss.common.auth.DefaultCredentialProvider; | ||
import com.aliyun.oss.common.comm.SignVersion; | ||
import com.aliyun.oss.model.PutBucketPublicAccessBlockRequest; | ||
import com.aliyuncs.DefaultAcsClient; | ||
import com.aliyuncs.IAcsClient; | ||
import com.aliyuncs.profile.DefaultProfile; | ||
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest; | ||
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse; | ||
import lombok.Data; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
import java.nio.charset.StandardCharsets; | ||
|
||
public class Main implements StreamRequestHandler { | ||
|
||
@Override | ||
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { | ||
FunctionComputeLogger logger = context.getLogger(); | ||
ByteArrayOutputStream result = new ByteArrayOutputStream(); | ||
byte[] buffer = new byte[1024]; | ||
for (int length; (length = inputStream.read(buffer)) != -1; ) { | ||
result.write(buffer, 0, length); | ||
} | ||
String event = result.toString(StandardCharsets.UTF_8.name()); | ||
logger.error(event); | ||
MessageData messageData = JSON.parseObject(event, MessageData.class); | ||
|
||
// get credentials from context | ||
com.aliyun.fc.runtime.Credentials creds = context.getExecutionCredentials(); | ||
|
||
// cross account | ||
DefaultProfile profile = DefaultProfile.getProfile(System.getenv("REGION"), creds.getAccessKeyId(), | ||
creds.getAccessKeySecret(), creds.getSecurityToken()); | ||
IAcsClient client = new DefaultAcsClient(profile); | ||
AssumeRoleRequest request = new AssumeRoleRequest(); | ||
request.setRoleArn(String.format("acs:ram::%s:role/%s", messageData.getResourceOwnerAccountId(), System.getenv("ASSUME_ROLE_NAME"))); | ||
request.setRoleSessionName("AccessAnalyzer"); | ||
|
||
try { | ||
AssumeRoleResponse response = client.getAcsResponse(request); | ||
|
||
ClientBuilderConfiguration configuration = new ClientBuilderConfiguration(); | ||
configuration.setSignatureVersion(SignVersion.V4); | ||
|
||
String[] resourceArns = messageData.getResourceArn().split(":"); | ||
String ossRegion = resourceArns[2]; | ||
String ossBucket = resourceArns[4]; | ||
|
||
OSS ossClient = OSSClientBuilder.create() | ||
.endpoint(String.format("https://%s.aliyuncs.com", ossRegion)) | ||
.credentialsProvider(new DefaultCredentialProvider(response.getCredentials().getAccessKeyId(), response.getCredentials().getAccessKeySecret(), response.getCredentials().getSecurityToken())) | ||
.clientConfiguration(configuration) | ||
.region(ossRegion.replace("oss-", "")) | ||
.build(); | ||
ossClient.putBucketPublicAccessBlock(new PutBucketPublicAccessBlockRequest(ossBucket, true)); | ||
} catch (Exception e) { | ||
logger.error(e.getMessage()); | ||
} | ||
} | ||
|
||
@Data | ||
class MessageData { | ||
|
||
String resourceOwnerAccountId; | ||
|
||
String resourceType; | ||
|
||
String isPublic; | ||
|
||
String status; | ||
|
||
Boolean isDeleted; | ||
|
||
String resourceArn; | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
solution/solution-access-analyzer-external-access/ros/create-role-cross-account/main.tf
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
resource "alicloud_ram_role" "role" { | ||
name = var.role_name | ||
document = <<EOF | ||
{ | ||
"Statement": [ | ||
{ | ||
"Action": "sts:AssumeRole", | ||
"Effect": "Allow", | ||
"Principal": { | ||
"RAM": [ | ||
"acs:ram::${var.assume_role_principal_account == "" ? var.ALIYUN__AccountId : var.assume_role_principal_account}:role/${var.assume_role_principal_role}" | ||
] | ||
} | ||
} | ||
], | ||
"Version": "1" | ||
} | ||
EOF | ||
} | ||
|
||
resource "alicloud_ram_policy" "policy" { | ||
policy_name = var.policy_name | ||
policy_document = jsonencode(var.policy_document) | ||
} | ||
|
||
resource "alicloud_ram_role_policy_attachment" "attach" { | ||
policy_name = alicloud_ram_policy.policy.name | ||
policy_type = alicloud_ram_policy.policy.type | ||
role_name = alicloud_ram_role.role.name | ||
|
||
depends_on = [alicloud_ram_policy.policy, alicloud_ram_role.role] | ||
} |
3 changes: 3 additions & 0 deletions
3
solution/solution-access-analyzer-external-access/ros/create-role-cross-account/outputs.tf
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
output "role_arn" { | ||
value = alicloud_ram_role.role.arn | ||
} |
104 changes: 104 additions & 0 deletions
104
solution/solution-access-analyzer-external-access/ros/create-role-cross-account/variables.tf
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
variable "ALIYUN__AccountId" { | ||
type = string | ||
} | ||
|
||
variable "role_name" { | ||
type = string | ||
description = <<EOT | ||
{ | ||
"ConstraintDescription": { | ||
"zh-cn": "不得超过 64 个字符、英文字母、数字或'-'。", | ||
"en": "No more than 64 characters,English letters, Numbers, or '-' are allowed." | ||
}, | ||
"Description": { | ||
"zh-cn": "角色的名称,如果已经存在,请更改名称,<br>由英文字母、数字或'-'组成,不超过64个字符。", | ||
"en": "The name of role, Change the name if it already exists,<br>Consist of english letters, numbers or '-',not more than 64 characters." | ||
}, | ||
"MinLength": 1, | ||
"Label": { | ||
"zh-cn": "角色的名称", | ||
"en": "Role Name" | ||
}, | ||
"AllowedPattern": "^[a-zA-Z0-9\\-]+$", | ||
"MaxLength": 64, | ||
"Type": "String" | ||
} | ||
EOT | ||
} | ||
|
||
variable "policy_name" { | ||
type = string | ||
description = <<EOT | ||
{ | ||
"Type": "String", | ||
"Description": { | ||
"zh-cn": "策略名,改变名称如果它已经存在,<br>由英文字母,数字或'-',5-128个字符组成。", | ||
"en": "The policy name, Change the name if it already exists,<br>Consist of english letters, numbers or '-', 5-128 characters." | ||
}, | ||
"MinLength": 5, | ||
"Label": { | ||
"zh-cn": "策略名", | ||
"en": "Policy Name" | ||
}, | ||
"AllowedPattern": "^[a-zA-Z0-9\\-]+$", | ||
"MaxLength": 128, | ||
"ConstraintDescription": { | ||
"zh-cn": "由英文字母、数字或'-',5-128个字符组成。", | ||
"en": "Consist of english letters, numbers or '-',5-128 characters." | ||
} | ||
} | ||
EOT | ||
} | ||
|
||
variable "policy_document" { | ||
type = any | ||
description = <<EOT | ||
{ | ||
"Type": "Json", | ||
"Description": { | ||
"zh-cn": "策略内容。其中 Action 和 Resource 必须配置为数组格式。", | ||
"en": "The policy document. Action and Resource must be configured in array format." | ||
}, | ||
"Label": { | ||
"zh-cn": "策略内容", | ||
"en": "Policy Document" | ||
} | ||
} | ||
EOT | ||
} | ||
|
||
variable "assume_role_principal_account" { | ||
type = string | ||
default = "" | ||
description = <<EOT | ||
{ | ||
"Default": "", | ||
"Type": "String", | ||
"Description": { | ||
"zh-cn": "该角色可信的账号。置空,则默认为当前账号。", | ||
"en": "The trusted account for this role. Default is current account while empty." | ||
}, | ||
"Label": { | ||
"zh-cn": "角色可信的账号", | ||
"en": "Principal Account" | ||
} | ||
} | ||
EOT | ||
} | ||
|
||
variable "assume_role_principal_role" { | ||
type = string | ||
description = <<EOT | ||
{ | ||
"Type": "String", | ||
"Description": { | ||
"zh-cn": "允许扮演该角色的可信账号下的角色。请确保该角色在可信账号下已经存在,否则会创建失败。", | ||
"en": "Role of trusted account that are allowed to assume this role." | ||
}, | ||
"Label": { | ||
"zh-cn": "可信账号下允许扮演的角色", | ||
"en": "Principal Role" | ||
} | ||
} | ||
EOT | ||
} |
9 changes: 9 additions & 0 deletions
9
solution/solution-access-analyzer-external-access/ros/create-role-cross-account/versions.tf
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
terraform { | ||
required_providers { | ||
alicloud = { | ||
source = "aliyun/alicloud" | ||
version = ">=1.213.1" | ||
} | ||
} | ||
required_version = ">=0.13" | ||
} |