记录一下Consul开启 ACL方法和遇到的小坑
一、Consul的ACL是什么

ACL:访问策略控制

Consul的ACL用来控制访问API和Key/Value文档,做到访问控制。

二、达成目标

启动Consul ACL后,可以对服务注册和调用、Key/Value文档的访问控制,进行授权访问。

三、使用方法
一、开启ACL
1、添加consul配置文件,开启ACL。

创建config-dir目录,将以下配置文件放在此目录下,命名为acl.json

{
    "acl": {
        "enabled": true,        //是否开启ACLToken
        "default_policy": "deny",  //allow和deny两个值。allow模式下,ACL是黑名单,允许任何未明确禁止的操作。deny模式下,ACL是白名单,阻止任何未明确允许的操作。
		"enable_token_persistence": true //值为true时,API使用的令牌集合将被保存到磁盘,并且当代理重新启动时会重新加载。
    }
}

启动consul

启动命令:

consul.exe agent -server -bootstrap -advertise 127.0.0.1 -data-dir ./data -ui -config-dir ./config-dir/acl.json

2、使用Postman调用API,获取超级管理员token。

localhost:8500/v1/acl/bootstrap
在这里插入图片描述

将AccessorID添加到配置文件中,重新启动Consul

{
    "acl": {
        "enabled": true,        
        "default_policy": "deny",  
		"enable_token_persistence": true,
		"tokens": {
			"master": "d90be899-26c6-7fb7-84c3-68ba051611a8"
		}
    }
}

具有全局管理的权限,也就是最大的权限。它允许操作员使用令牌密钥ID来引导ACL系统。需要在所有的server agent上设置同一个值,可以设置为一个随机的UUID。这个值权限最大,注意保管好。

3、使用Postman调用API,创建客户端token。

localhost:8500/v1/acl/create

在Headers中填写

keyvalue
X-Consul-Token上一步获取的master token
Content-Typeapplication/json

在这里插入图片描述

将获得的token添入到配置文件中,重新启动。

{
    "acl": {
        "enabled": true,        
        "default_policy": "deny",  
		"enable_token_persistence": true,
		"tokens": {
			"master": "d90be899-26c6-7fb7-84c3-68ba051611a8",
			"agent": "a7744c70-9aab-a190-9ff6-e935a87c117f"
		}
    }
}

如果不配置控制台会报

[WARN] agent: Coordinate update blocked by ACLs

4、复制master的token,输入

在这里插入图片描述

在这里插入图片描述

5、在bootstrap.yml配置文件中加入如下属性

服务的注册和获取

spring:
  cloud:
    consul:
      discovery:
        acl-token: 输入创建的token

配置文件Key/Value获取

spring:
  cloud:
    consul:
      config:
        acl-token: 输入创建的token
二、自定义策略
1、首先进行策略设置

在这里插入图片描述

在这里插入图片描述

2、创建token并且添加策略

在这里插入图片描述

查看权限列表选择权限并且保存。

在这里插入图片描述

保存完成后可以在token列表看到刚才添加的token。

在这里插入图片描述

点击进去后查看token进行使用。

三、配置策略信息

在这里插入图片描述

https://learn.hashicorp.com/tutorials/consul/access-control-manage-policies(官方文档)

示例格式:

用于服务注册

service_prefix ""{
	policy = "write"
}

用于key/value获取

key_prefix "" {
	policy = "read"
}

官方文档给出,调用服务的ACL需要节点可读,服务可读。(只给了单独服务的可读权限会获取不到),策略如下:

# 安全性低, 所有节点和服务名都可以暴露,基本等同于Master Token
node_prefix "" { policy = "read" }
service_prefix "" { policy = "read" }

# 仅开放相关node和service的可读权限
node "xxxxx" { policy = "read" }
service "xxxxx" { policy = "read" }
四、注意

在开启ACL后,要重写心跳检测(在consulACL项目consul包下已重写)

https://my.oschina.net/u/4227761/blog/3114951(心跳检测方法重写资料)

五、开启心跳检测与consul自己的健康检查会发生互斥

源码:

public static NewService.Check createCheck(Integer port,
      HeartbeatProperties ttlConfig, ConsulDiscoveryProperties properties) {
   NewService.Check check = new NewService.Check();
   if (StringUtils.hasText(properties.getHealthCheckCriticalTimeout())) {
      check.setDeregisterCriticalServiceAfter(
            properties.getHealthCheckCriticalTimeout());
   }
    //如果开启就会设置为心跳检查。
   if (ttlConfig.isEnabled()) {
      check.setTtl(ttlConfig.getTtl());
      return check;
   }

   Assert.notNull(port, "createCheck port must not be null");
   Assert.isTrue(port > 0, "createCheck port must be greater than 0");

   if (properties.getHealthCheckUrl() != null) {
      check.setHttp(properties.getHealthCheckUrl());
   }
   else {
      check.setHttp(String.format("%s://%s:%s%s", properties.getScheme(),
            properties.getHostname(), port, properties.getHealthCheckPath()));
   }
   check.setHeader(properties.getHealthCheckHeaders());
   check.setInterval(properties.getHealthCheckInterval());
   check.setTimeout(properties.getHealthCheckTimeout());
   check.setTlsSkipVerify(properties.getHealthCheckTlsSkipVerify());
   return check;
}

如果要开启ACL权限访问控制,就需要关闭心跳检测,让consul使用自己的健康检测机制。主要因为:

@Override
public void run() {
   TtlScheduler.this.client.agentCheckPass(this.checkId);
   if (log.isDebugEnabled()) {
      log.debug("Sending consul heartbeat for: " + this.checkId);
   }
}

心跳检测调用的方法没有token,所以会一直403过不去权限检测。

六、更改配置文件

spring官方文档配置:

在这里插入图片描述

在bootstrap.yml中 更改健康检查路径的地址为 /actuator/health

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐