使用Project Policy管理日志服务资源访问权限

Project Policy是日志服务推出的针对Project的授权策略,通过Project Policy授权指定网络或IP访问日志服务资源的权限。

背景介绍

SLSProject默认可以从任意IP写入数据,当通过LoongCollector(原Logtail)向SLS写数据时,非预期来源数据也可能被写入。因此需要Project Policy做一层安全拦截,指定可以写入数据的IP段。例如线上已有稳定运行的生产集群A,日志写入Project A,并配置了告警等自动化运维策略,为了防止测试集群或新集群的日志误写入Project A对日常运维造成干扰,就可以使用Project Policy。

使用前须知

  • Project Policy仅支持通过SDK配置,暂无控制台入口。

  • 了解Action、Resource以及Condition授权信息

  • 配置Project Policy时,若授权用户选择了匿名账号(*):

    • 不包含Condition的情况下,则Project Policy仅对Project Owner以外的所有用户生效。

    • 包含Condition的情况下,则Project Policy会对包含Project Owner在内的所有用户生效。

使用示例

Java SDK为例展示设置Project Policy的流程,更多语言参考SDK概述

  1. 下载Java SDK开发包

  2. 创建src/main/java/com/aliyun/openservices/log/sample/ProjectPolicyDemo.java。

  3. 根据场景使用如下示例代码,根据注释修改参数值。

    重要
    • 执行setProjectPolicy方法的效果是覆盖原有配置,暂不支持追加。

    • 启动程序后Policy生效大约需要1分钟。

仅允许指定VPC访问某个Project资源

示例代码

权限策略

代码中参数获取方式参考如下:

  • accessKeyIdaccessKey获取参考创建AccessKey

  • endPoint获取方式:

    1. 登录日志服务控制台,在Project列表中,单击目标Project。

    2. 单击Project名称右侧的image进入项目概览页面,在访问域名中复制公网域名。

package com.aliyun.openservices.log.sample;

import com.aliyun.openservices.log.Client;
import com.aliyun.openservices.log.exception.LogException;
import org.junit.Assert;

public class ProjectPolicyDemo {
	// 本示例从环境变量中获取AccessKey IDAccessKey Secret
	static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
	static String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
	static String endPoint = "your-endpoint"; // 修改为日志服务Project的地域对应的endPoint。
        static String projectName = "example-project";// 修改为日志服务Project的名称。
	static Client client = new Client(endPoint, accessKeyId, accessKey);

	public static void main(String[] args) throws LogException {
		try {
			client.GetProject(projectName);
		} catch (LogException e) {
			Assert.fail("should not fail : " + e.GetErrorCode());
		}
		String policyText="{\"Version\":\"1\",\"Statement\":[{\"Action\":[\"log:*\"],\"Principal\": [\"*\"],\"Resource\":\"acs:log:*:*:project/" + projectName + "/*\",\"Condition\": {\"StringNotEquals\": {\"acs:SourceVpc\": [\"vpc-t4nlw426y44rd3iq4****\"]}},\"Effect\":\"Deny\"}]}";
		client.setProjectPolicy(projectName, policyText); 
		client.getProjectPolicy(projectName);
		Assert.assertEquals(policyText, client.getProjectPolicy(projectName).getPolicyText());
	}
}

示例代码中policyText使用的权限策略如下,表示仅允许来自VPC IDt4nlw426y44rd3iq4****的请求访问名为example-projectProject 。

{
    "Version": "1",
    "Statement": [
        {
            "Action": [
                "log:*"
            ],
            "Principal": [
                "*"
            ],
            "Resource": "acs:log:*:*:project/example-project/*",
            "Condition": {
                "StringNotEquals": {
                    "acs:SourceVpc": [
                        "vpc-t4nlw426y44rd3iq4****"
                    ]
                }
            },
            "Effect": "Deny"
        }
    ]
}

禁止特定IP访问

示例代码

权限策略

代码中参数获取方式参考如下:

  • accessKeyIdaccessKey获取参考创建AccessKey

  • endPoint获取方式:

    1. 登录日志服务控制台,在Project列表中,单击目标Project。

    2. 单击Project名称右侧的image进入项目概览页面,在访问域名中复制公网域名。

package com.aliyun.openservices.log.sample;

import com.aliyun.openservices.log.Client;
import com.aliyun.openservices.log.exception.LogException;
import org.junit.Assert;

public class ProjectPolicyDemo {
	// 本示例从环境变量中获取AccessKey IDAccessKey Secret
	static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
	static String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
	static String endPoint = "your-endpoint"; // 修改为日志服务Project的地域对应的endPoint。
        static String projectName = "example-project";// 修改为日志服务Project的名称。
	static Client client = new Client(endPoint, accessKeyId, accessKey);

	public static void main(String[] args) throws LogException {
		try {
			client.GetProject(projectName);
		} catch (LogException e) {
			Assert.fail("should not fail : " + e.GetErrorCode());
		}
		String policyText="{\"Version\":\"1\",\"Statement\":[{\"Action\":[\"*\"],\"Principal\": [\"*\"],\"Resource\":\"acs:log:*:*:project/" + projectName + "/*\",\"Condition\": {\"IpAddress\":{\"acs:SourceIp\":[\"192.168.0.0\",\"172.16.215.218\"]}},\"Effect\":\"Deny\"}]}";
		client.setProjectPolicy(projectName, policyText);
		client.getProjectPolicy(projectName);
		Assert.assertEquals(policyText, client.getProjectPolicy(projectName).getPolicyText());
	}
}

下述权限策略表示192.168.0.0172.16.215.218这两个IP地址不能访问名为example-projectProject。

{
    "Version":"1",
    "Statement":[
        {
            "Effect":"Deny",
            "Action":[
                "*"
            ],
            "Principal":[
                "*"
            ],
            "Resource":"acs:log:*:*:project/example-project/*",
            "Condition":{
                "IpAddress":{
                    "acs:SourceIp":[
                        "192.168.0.0",
                        "172.16.215.218"
                    ]
                }
            }
        }
    ]
}

禁止外网IP写入

示例代码

权限策略

代码中参数获取方式参考如下:

  • accessKeyIdaccessKey获取参考创建AccessKey

  • endPoint获取方式:

    1. 登录日志服务控制台,在Project列表中,单击目标Project。

    2. 单击Project名称右侧的image进入项目概览页面,在访问域名中复制公网域名。

package com.aliyun.openservices.log.sample;

import com.aliyun.openservices.log.Client;
import com.aliyun.openservices.log.exception.LogException;
import org.junit.Assert;

public class ProjectPolicyDemo {
	// 本示例从环境变量中获取AccessKey IDAccessKey Secret
	static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
	static String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
	static String endPoint = "your-endpoint"; // 修改为日志服务Project的地域对应的endPoint。
        static String projectName = "example-project";// 修改为日志服务Project的名称。
	static Client client = new Client(endPoint, accessKeyId, accessKey);

	public static void main(String[] args) throws LogException {
		try {
			client.GetProject(projectName);
		} catch (LogException e) {
			Assert.fail("should not fail : " + e.GetErrorCode());
		}
		String policyText="{\"Version\":\"1\",\"Statement\":[{\"Action\":[\"log:PostLogStoreLogs\"],\"Principal\": [\"*\"],\"Resource\":\"acs:log:*:*:project/" + projectName + "/*\",\"Condition\":{\"StringNotLike\": {\"acs:SourceVpc\":[\"vpc-*\"]}},\"Effect\":\"Deny\"}]}";
		client.setProjectPolicy(projectName, policyText);
		client.getProjectPolicy(projectName);
		Assert.assertEquals(policyText, client.getProjectPolicy(projectName).getPolicyText());
	}
}

下述权限策略表示拒绝使用外网写入日志到名为example-projectProject。

{
    "Version": "1",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": [
                "log:PostLogStoreLogs"
            ],
            "Principal": [
                "*"
            ],
            "Resource": "acs:log:*:*:project/example-project/*",
            "Condition": {
                "StringNotLike": {
                    "acs:SourceVpc": [
                        "vpc-*"
                    ]
                }
            }
        }
    ]
}

删除Project Policy

如果后续不需要访问控制,可删除Project Policy。

package com.aliyun.openservices.log.sample;

import com.aliyun.openservices.log.Client;
import com.aliyun.openservices.log.exception.LogException;
import org.junit.Assert;

public class ProjectPolicyDemo {
	// 本示例从环境变量中获取AccessKey ID和AccessKey Secret
	static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
	static String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
	static String endPoint = "your-endpoint"; // 修改为日志服务Project的地域对应的endPoint。
        static String projectName = "example-project";// 修改为日志服务Project的名称。
	static Client client = new Client(endPoint, accessKeyId, accessKey);

	public static void main(String[] args) throws LogException {
		client.deleteProjectPolicy(projectName);
		Assert.assertEquals("", client.getProjectPolicy(projectName).getPolicyText());
	}
}