搭建consul-1.5.3集群,配置TLS、ACl和Gossip Encryption

内容基于大量官网资料,请耐心阅读

系统及软件版本:consul-1.5.3+CentOS7

docker-compose搭建consul-1.5.3集群

只有一台服务器,我就用docker-compose搭建了
docker-compose.yml配置如下

version: '3.0'
services:
  consul1:
    image: consul:1.5.3
    restart: always
    container_name: consul_1
#-server:表示当前使用的server模式,-node:指定当前节点在集群中的名称,
#-config-dir:指定配置文件路径,定义服务的,缺省值为:/consul/config
#-data-dir: consul存储数据的目录;缺省值为:/consul/data
#-datacenter:数据中心名称,缺省值为dc1
#-ui:使用consul自带的web UI界面 
#-bind: 绑定服务器的ip地址
#-client: 客户端可访问ip,缺省值为:“127.0.0.1”,即仅允许环回连接
#-bootstrap-expect:在一个datacenter中期望的server节点数目,consul启动时会一直等待直到达到这个数目的server才会引导整个集群.这个参数的值在同一个datacenter的所有server节点上必须保持一致
    command: agent -server -client=0.0.0.0 -node=consul_1 -bootstrap-expect=3
    volumes:
      - /usr/local/docker_app/consul/consul_1/config:/consul/config 
      - /usr/local/docker_app/consul/consul_1/data/key:/consul/data/key
  consul2:
    image: consul:1.5.3
    restart: always
    container_name: consul_2
    command: agent -server -client=0.0.0.0 -retry-join=consul_1 -node=consul_2
    volumes:
      - /usr/local/docker_app/consul/consul_2/config:/consul/config
      - /usr/local/docker_app/consul/consul_2/data/key:/consul/data/key 
  consul3:
    image: consul:1.5.3
    restart: always 
    container_name: consul_3
    command: agent -server -client=0.0.0.0 -retry-join=consul_1 -node=consul_3
    volumes:
      - /usr/local/docker_app/consul/consul_3/config:/consul/config 
#证书路径
      - /usr/local/docker_app/consul/consul_3/data/key:/consul/data/key
  consul4: 
    image: consul:1.5.3
    container_name: consul_4
    restart: always 
    ports:
      - 8500:8500
    command: agent -client=0.0.0.0 -retry-join=consul_1 -ui -node=client
    volumes:
      - /usr/local/docker_app/consul/consul_4/config:/consul/config 
      - /usr/local/docker_app/consul/consul_4/data/key:/consul/data/key

docker-compse的语法就不介绍了,consul用的参数都写了注释,consul是C/S结构,配置三台server,一台client,数据卷配置了consul的配置文件,consul数据目录中的证书目录

如果出现下面报错

[root@coen ~] docker-compose up -d
Pulling consul1 (consul:1.5.3)...
ERROR: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)`

编辑/etc/docker/daemon.json,添加

{
  "registry-mirrors": ["https://registry.docker-cn.com","http://hub-mirror.c.163.com"]
}

安装完毕,运行docker exec -i consul_1 consul members,见到下面三台server,一台client就搭建起来了

Node      Address          Status  Type    Build  Protocol  DC   Segment
consul_1  172.19.0.4:8301  alive   server  1.5.3  2         dc1  <all>
consul_2  172.19.0.2:8301  alive   server  1.5.3  2         dc1  <all>
consul_3  172.19.0.5:8301  alive   server  1.5.3  2         dc1  <all>
client    172.19.0.3:8301  alive   client  1.5.3  2         dc1  <default>

访问http://192.168.28.128:8500可以访问client的UI界面

1.png

看上面,“dcl”数据中心(consul能多数据中心,官方推荐一般3-5台性能佳)

“Services”服务列表(默认有consul)
“Ndes”节点列表
“Key / Value”分布式KV
“ACL”Consul用来控制访问API与数据

配置consul的TLS、ACl和Gossip Encryption

consul有三方面的安全保护机制

  • Gossip Encryption:Consul使用Gossip协议来管理集群中的成员关系,以及把消息广播到集群中,通过UDP完成
  • TLS:使用https加密consul的API、GRPC
  • ACl:控制Services、Nodes、KV的读写权限

先配置最简单的Gossip Encryption

先生成Encryption

[root@coen docker_app] docker exec -t consul_1 consul keygen
RAo6b8QwxOTDd8Z0b4/Hiw==

“RAo6b8QwxOTDd8Z0b4/Hiw==”就是Encryption
在数据卷(/usr/local/docker_app/consul/consul_1/config/)下创建encrypt.json,写入Encryption

[root@coen docker_app] cd /usr/local/docker_app/consul/consul_1/config/

[root@coen config] echo '{"encrypt": "gf/aeGk4Ok7Lcpz7p6gCZg=="}' > encrypt.json

[root@coen config] cp encrypt.json ../../consul_2/config/

[root@coen config] cp encrypt.json ../../consul_3/config/

注意:每个server都得写入一样的值,值不一样server怎么交流?client作用是转发,不需要配置Gossip Encryption

配置consul的TLS

consul是基于CA验证的,可以选择官网那种一键生成,但是证书有效期有点短,我选择自己生成
需要安装openssl,这就不演示了,我在windows10上生成

#生成根证书key
openssl genrsa -out ca.key 2048
#生成根证书密钥
openssl req -new -x509 -days 7200 -key ca.key -subj "/CN=consul.com" -out ca.pem

#生成服务端私钥
openssl genrsa -out server.key 2048
#生成客户端私钥
openssl genrsa -out client.key 2048

#生成的服务端的CSR
#CSR 主要作用是 CA 会利用 CSR 文件进行签名使得攻击者无法伪装或篡改原有证书
openssl req -new -key server.key -subj "/CN=consul.com" -out server.csr
 #生成的客户端的CSR
openssl req -new -key client.key -subj "/CN=consul.com" -out client.csr

#服务端自签名的证书
openssl x509 -req -sha256 -CA ca.pem -CAkey ca.key -CAcreateserial -days 3650 -in server.csr -out server.pem
#客户端自签名的证书
openssl x509 -req -sha256 -CA ca.pem -CAkey ca.key -CAcreateserial -days 3650 -in client.csr -out client.pem

可以看到CA有效期7200天!私钥和证书有效期3650天!可以设置小一点,定期更换,更安全;“CN”是只允许某个IP或者域名访问,我这设置成域名“consul.com”,灵活点
整理下


1564391285(1).png

因为是docker搭建的,只能找到docker内部的目录,所以刚刚在docker-compose配置的数据卷上场
把这个目录整到/usr/local/docker_app/consul/consul_3/data/key下,server拷server的,client拷client的
然后开始配置TLS

server端

在数据卷(/usr/local/docker_app/consul/consul_1/config/)下创建tls.json,写入:

{
     "verify_incoming":true,
     "verify_outgoing": true,
     "ca_file": "/consul/data/key/ca.pem",
     "cert_file": "/consul/data/key/server/server.pem",
     "key_file": "/consul/data/key/server/server.key"
   }

  • verify_incoming:所有传入连接都使用TLS
  • verify_outgoing:此代理的所有传出连接都使用TLS
  • ca_file:CA的PEM编码的证书颁发机构的文件路径(docker容器内目录)
  • cert_file:PEM编码证书的文件路径
  • key_file:PEM编码私钥的文件路径

官网说可以使用auto_encrypt自动将证书CA发到客户端,我试了,没成功,怀疑是docker容器的原因,不行就老老实实的配置

#复制到其他server
[root@coen config] cp tls.json ../../consul_2/config/
[root@coen config] cp tls.json ../../consul_3/config/
client端

在数据卷(/usr/local/docker_app/consul/consul_4/config/)下创建tls.json,写入:

{
  "verify_incoming": false,
  "verify_incoming_rpc": true,
  "ports": {
    "http": -1,
    "https": 8500
  }, 
  "ca_file": "/consul/data/key/ca.pem",
  "cert_file": "/consul/data/key/client/client.pem",
  "key_file": "/consul/data/key/client/client.key"
}

verify_incoming配置成false,为啥?官网说,verify_incoming为true的话,在client UI页面要提供有效证书,给不了,就访问不了了,所以为false;verify_incoming_rpc为true,UI能不效验TLS提供服务,但RPC还是验证的,https端口8500
现在搭建好了,我们来试一试,先用http方式请求下数据

#先重启下consul集群
[root@coen docker_app] docker-compose  down
[root@coen docker_app] docker-compose  up -d
#http请求下
[root@coen docker_app] curl http://127.0.0.1:8500/v1/internal/ui/services
Client sent an HTTP request to an HTTPS server.

报错,说客户端发送的是http请求https服务,已经成功!现在用https请求下UI页面

[root@coen docker_app] curl https://localhost:8500/ui/ -k -I
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 6610
Content-Type: text/html; charset=utf-8
Last-Modified: Wed, 31 Jul 2019 01:42:30 GMT
Date: Wed, 31 Jul 2019 01:49:03 GMT

成功!可以在游览器https://192.168.28.128:8500 来访问Ul,游览器信任CA证书就行,“192.168.28.128”是我虚拟机内网地址,写你们自己的

2.png

配置ACL

server端

在数据卷(/usr/local/docker_app/consul/consul_1/config/)下创建acl.json,写入:

{
 "acl":{
   "enabled": true,
   "default_policy": "deny",
   "enable_token_persistence":true,
   "tokens":{
    "master":"saFKyW4CGQP+kv79dWYX6I/LK3iuHrVyuOfS+mxBNyg="
    }
  },
  "datacenter":"dc1",
  "primary_datacenter": "dc1"
}

  • acl-enabled:开启acl
  • acl-default_policy:把自己设置成白名单
  • acl-enable_token_persistence:使用API设置将被保存到磁盘,并且当代理重新启动重新加载
  • tokens-master:令牌密钥ID来引导ACL系统,(可以自定义,除了“master”还有很多种,可以在UI界面设置)
  • datacenter:数据中心,默认“dc1”
  • primary_datacenter:权威性的数据中心,提供它才能启用ACL,和tokens-master配合使用
#复制到其他server
[root@coen config] cp acl.json ../../consul_2/config/
[root@coen config] cp acl.json ../../consul_3/config/
client端

在数据卷(/usr/local/docker_app/consul/consul_4/config/)下创建tls.json,写入:

{
 "acl":{
   "enabled": true,
   "default_policy": "deny",
   "enable_token_persistence":false,
   "tokens":{
    "agent":"saFKyW4CGQP+kv79dWYX6I/LK3iuHrVyuOfS+mxBNyg="
    }
  },
  "datacenter":"dc1",
  "primary_datacenter": "dc1"
}

client端这里要设置tokens-agent,agen作用于客户端和服务器执行内部操作,我这为了图省事直接用sever的master了
线上不能这样,“master”是最高权限,正常流程先配置server的“master”,然后去UI生成权限低的“agent”,配置client端,然后重启client端,不重启server端,数据全部存储在server端,重启就没了
重启consul集群,访问UI,到ACL那

1564452884(1).png

输入sever端配置的“token-agent”

1564452953(1).png

可以看到这样的列表,初始有2个ACL,可以设置其他的,consul把ACL划分成“service_prefix”,“
key_prefix”,“node_prefix”三种"Policy"(策略),每个都有读写权限,配合“role”(角色)可以形成非常细的数据权限控制,查看官网了解
https://www.consul.io/docs/acl/index.html#acl-documentation

https://learn.hashicorp.com/consul/security-networking/production-acls
至此,consul集群搭完,这里只是演示一个数据中心,consul是多数据中心的,需要多数据中心要改一些配置,不要照搬硬套

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,783评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,360评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,942评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,507评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,324评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,299评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,685评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,358评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,652评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,704评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,465评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,318评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,711评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,991评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,265评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,661评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,864评论 2 335

推荐阅读更多精彩内容