介绍
Consul是一种服务发现工具,可用于轻松发现和跟踪整个基础架构中各种服务的健康状况。 您可以使用consul管理您的服务并维护分布式检查系统,以确保在应用程序或服务器出现故障时可以进行响应。
在过去的指导 ,我们专注于得到一个生产就绪的环境和准备。 这包括创建将在启动时读取的配置文件和upstart脚本以实际启动服务。
这使我们大部分的方式到我们的最终基本配置,但我们还没有完全保护我们的配置。 我们实现了一个简单的共享秘密解决方案,它很容易加密我们的gossip协议。
但是,此时RPC通信仍然完全未加密。 为了解决这个问题,安全地支持TLS加密,我们将在本指南中关注。 要实现这一点,我们必须创建一个证书颁发机构,并签署并分发密钥到我们的节点。
先决条件和目标
在填写本指南,您应该已经建立了,因为我们给他们留下我们的最后指南在领事服务器系统建立一个生产就绪的基础设施领事 。
我们用于该指南的服务器具有以下属性:
主机名 | IP地址 | 角色 |
---|---|---|
server1.example.com | 192.0.2.1 | 引导consul服务器 |
server2.example.com | 192.0.2.2 | consul服务器 |
server3.example.com | 192.0.2.3 | consul服务器 |
agent1.example.com | 192.0.2.50 | 领事客户 |
这些是64位Ubuntu 14.04服务器。 请注意,这些服务器都位于同一个域中。 这对我们在本指南中实现的配置很重要,因为我们将利用将匹配域中任何主机的通配符证书。
在本指南中,我们将重点介绍创建TLS证书颁发机构,以便为我们的每台服务器签发证书。 这将允许consul组件验证身份和加密流量。 然后我们将稍微修改配置文件,以强制我们的节点加密流量。
创建SSL结构
为了开始,我们将设置一些基本文件和目录,我们将用它们来管理我们的密钥。
同样,我们将在根shell中执行本指南中的所有过程。 无论以root身份登录,或使用sudo -i
作为使用sudo权限的用户。
在每个领事成员,创建一个ssl
的内部目录/etc/consul.d
目录。 这是我们将保存加密RPC流量所需的文件:
mkdir /etc/consul.d/ssl
在计划用作证书授权的服务器上,我们将在此目录中创建一个子目录,以容纳创建和签名证书所需的所有文件。 我们可以选择我们的任何服务器来容纳证书颁发机构的,但我们的目的,我们将使用server1
是还设有引导配置。
在此服务器上,创建一个名为的子目录CA
我们刚刚创建的目录下:
mkdir /etc/consul.d/ssl/CA
这将包含一些我们可能不希望其他人访问的敏感数据,所以让我们锁定权限:
chmod 0700 /etc/consul.d/ssl/CA
移动到CA服务器上的此目录。
cd /etc/consul.d/ssl/CA
在这里,我们将创建一些基本文件,需要出现在我们的证书签名。 首先,我们需要创建一个文件,该文件将使用下一个可用的证书序列号递增。 我们需要用一个值预种。
要做到这一点,echo的价值000a
串行文件:
echo "000a" > serial
我们还需要提供一个文件,其中我们的证书颁发机构可以记录它签名的证书。 我们称这个文件certindex
:
touch certindex
创建自签名根证书
要开始使用我们的证书颁发机构,我们需要做的第一步是创建自签名根证书。 我们可以做到这一点与openssl
是默认情况下在Ubuntu机器上安装命令。
我们将用来创建证书的命令是:
openssl req -x509 -newkey rsa:2048 -days 3650 -nodes -out ca.cert
让我们来看看这意味着什么:
- REQ:这个参数告诉OpenSSL的,你有兴趣在一个工作PKCS#10证书,通过创建或处理请求。
- -x509:该参数指定你想一个自签名证书,而不是一个证书请求。 这通常对根CA证书执行。
- -newkey RSA:2048:这告诉OpenSSL生成一个新的证书请求和私钥。 我们传递一个参数,指定我们想要一个2048位的RSA密钥。
- -days 3650:在这里,我们指定的天证书被认为是有效的数量。 我们使用的一个值
3650
,它是10年。 - -nodes:指定生成的私钥将不使用DES加密,这将需要一个口令。 这避免了这个要求。
- -out ca.cert:设置要被用于生成证书文件的文件名。
在证书创建过程中,系统将提示您输入有关要验证的主机的信息。 您可以填写您想要的关于服务器的任何相关信息:
. . .
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:ConsulCA
Email Address []:admin@example.com
对于Common Name
,这将是在我们的其他证书重要的是,你可以把你想要什么。
当你完成,你应该有一个ca.cert
证书文件,以及相关联的密钥称为privkey.pem
。
创建通配符证书签名请求
现在我们有根CA证书,我们可以为我们的客户端计算机生成证书签名请求。
在这种情况下,我们的所有领事成员都是客户,包括我们现在运行的服务器。 不是为每个服务器生成唯一的证书并使用我们的CA签名,我们将创建一个通配符证书,该证书对我们域中的任何主机都有效。
命令的一般格式将是相同的,有一些细微的差别:
openssl req -newkey rsa:1024 -nodes -out consul.csr -keyout consul.key
我们创建的自签名根CA证书请求和我们现在生成的新证书签名请求之间的区别在这里:
- 没有-x509标志 :我们已经移除了
-x509
以生成证书签名请求,而不是自签名证书标志。 - 退房手续consul.csr:该输出的文件不是证书本身,而是一个证书签名请求。
- -keyout consul.key:我们已经指定了与该证书签名请求相关联的密钥的名称。
同样,我们将提示我们对证书签名请求(CSR)的响应。 这比我们为自签名根CA证书提供的答案更重要。 在这里,我们将需要使用通配符Common Name
,以便我们的证书来检查为有效我们每个主机:
. . .
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:*.example.com
Email Address []:admin@example.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
正如你在这里可以看到的,我们使用我们的域,用星号作为主机,表示证书应该被认为对域内的任何主机有效。 您可以安全地跳过末尾添加的质询密码和可选的公司名称提示。
创建证书颁发机构配置文件
现在,我们有自签名的根CA证书文件和通配符证书签名请求,匹配我们域中的所有主机。 在我们使用我们的CA证书签署签名请求之前,我们需要创建一个将控制这种情况的配置文件。
我们称我们正在创建的文件myca.conf
,将举行我们的CA信息。 立即打开此文件:
nano /etc/consul.d/ssl/CA/myca.conf
此文件使用INI格式被划分为几个部分。 第一部分,我们将定义为ca
一节。 我们在这里唯一要做的是指向具有实际CA信息的用户定义部分:
[ ca ]
default_ca = myca
接下来,我们将创建刚刚引用的部分。 这将包含大量的CA配置详细信息。
我们将指定输入到cert提示中的信息不必是唯一的。 然后我们将给出我们创建的签名过程所需的所有文件的位置。 我们会告诉openssl
当前目录来放置新的证书。
我们还要选择一些默认值,以便在命令行上没有指定替代项时使用。 我们将选择签名的证书是有效期为10年,并且将使用sha1
算法。 最后,我们将指向我们将要创建的一些其他部分来定义附加信息:
[ myca ]
unique_subject = no
new_certs_dir = .
certificate = ca.cert
database = certindex
private_key = privkey.pem
serial = serial
default_days = 3650
default_md = sha1
policy = myca_policy
x509_extensions = myca_extensions
现在,让我们关注我们刚刚引用的第一个用户定义部分,它用于决定需要为要接受的CSR提供哪些信息。 我们将标记一些字段为必填字段,其他字段为可选字段。 我们将为通常的提示做一些非常标准的选择:
[ myca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = supplied
emailAddress = optional
organizationName = supplied
organizationalUnitName = optional
最后一节将定义我们在签署证书时要使用的x509扩展。
首先,我们需要告诉它,我们将要签名的证书不是CA证书。 我们将使用主键标识符的“hash”的标准值作为十六进制字符串(备选)。
我们将权限密钥标识符设置为“keyid”以从父证书复制主题密钥标识符。 我们还将指定密钥可以用作签名或使用加密密钥的协议。 我们将指定密钥的扩展使用可以用于服务器和客户端认证:
[ myca_extensions ]
basicConstraints = CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth,clientAuth
在一起,文件看起来像这样:
[ ca ]
default_ca = myca
[ myca ]
unique_subject = no
new_certs_dir = .
certificate = ca.cert
database = certindex
private_key = privkey.pem
serial = serial
default_days = 3650
default_md = sha1
policy = myca_policy
x509_extensions = myca_extensions
[ myca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = supplied
emailAddress = optional
organizationName = supplied
organizationalUnitName = optional
[ myca_extensions ]
basicConstraints = CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth,clientAuth
保存并在完成后关闭文件。 我们现在有一个重要的配置文件,可以用来签署我们之前生成的证书签名请求。
签署证书签名请求以生成证书
现在,我们拥有签署CSR并生成证书所需的所有组件。 我们只需要引用刚才创建的配置文件,并传入我们生成的CSR。
我们将使用的命令是:
openssl ca -batch -config myca.conf -notext -in consul.csr -out consul.cert
我们使用的选项是:
- CA:使用OpenSSL的证书权限管理功能。
- -batch:指定它应该进入批处理模式。 批处理模式自动验证传入的任何CSR,而不提示。
- -config myca.conf:通过我们创建的配置文件英寸
- -notext:不输出证书的文本形式。
其余选项指定输入和输出文件。
这将产生一个名为consul.cert
在当前目录。 它还将创造新版本serial
和certindex
文件,移动旧版本备份文件。 一个.pem
文件也将基于序列号创建serial
文件。
将文件移动到正确的位置
现在,我们拥有所有我们所需要的内部组件/etc/consul.d/ssl/CA
目录。 我们希望,我们需要将三个文件复制/etc/consul.d/ssl
目录中,我们会引用它们:
cp ca.cert consul.key consul.cert ..
我们的server1
,现在持有CA机器在正确的位置,必要的证书和密钥文件。
把它们放到你的基础设施的其他机器, scp
是一个不错的选择。 从/etc/consul.d/ssl
在目录server1
,您可以通过键入推到其他服务器所需的文件:
cd /etc/consul.d/ssl
scp ca.cert consul.key consul.cert root@192.0.2.2:/etc/consul.d/ssl
scp ca.cert consul.key consul.cert root@192.0.2.3:/etc/consul.d/ssl
scp ca.cert consul.key consul.cert root@192.0.2.50:/etc/consul.d/ssl
更改IP地址以引用基础架构中的每台计算机。
修改领事配置文件
现在我们有我们的根证书文件和一个证书/密钥对为我们的领事成员,我们可以修改我们的consul配置文件引用这些文件。
打开服务器上的每个consul配置文件。 对于我们server1
机器,我们将与引导配置文件启动:
nano /etc/consul.d/bootstrap/config.json
该文件应该如下所示:
{
"bootstrap": true,
"server": true,
"datacenter": "nyc2",
"data_dir": "/var/consul",
"encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",
"log_level": "INFO",
"enable_syslog": true
}
我们应该做的第一件事是使用consul参数来标识我们的每个新文件。 该ca_file
参数引用CA证书文件的位置。 在cert_file
和key_file
参数分别引用客户端的证书和密钥文件。
因为这些都与加密,以及,我们将添加下面的encrypt
为清楚起见参数:
{
"bootstrap": true,
"server": true,
"datacenter": "nyc2",
"data_dir": "/var/consul",
"encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",
"ca_file": "/etc/consul.d/ssl/ca.cert",
"cert_file": "/etc/consul.d/ssl/consul.cert",
"key_file": "/etc/consul.d/ssl/consul.key",
"log_level": "INFO",
"enable_syslog": true
}
现在,我们已经定义了这些文件的位置,但我们没有告诉consul我们要验证使用这些文件的每个主机的真实性。 我们现在可以通过告诉consul验证传入和传出连接:
{
"bootstrap": true,
"server": true,
"datacenter": "nyc2",
"data_dir": "/var/consul",
"encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",
"ca_file": "/etc/consul.d/ssl/ca.cert",
"cert_file": "/etc/consul.d/ssl/consul.cert",
"key_file": "/etc/consul.d/ssl/consul.key",
"verify_incoming": true,
"verify_outgoing": true,
"log_level": "INFO",
"enable_syslog": true
}
保存并在完成后关闭文件。
对您的领事成员使用的每个配置文件进行相同的更改。
在server1
,你需要做这些更改/etc/consul.d/bootstrap/config.json
和/etc/consul.d/server/config.json
。
在您的其他服务器,你只需要修改/etc/consul.d/server/config.json
。 在您的客户端机器上,你将不得不修改/etc/consul.d/client/config.json
。
重新启动服务器
要实现我们的加密流量,您必须依次重新启动每个领事会员的领事会议。
在基础架构中的每台计算机上,暂时停止,然后再启动consul:
stop consul && sleep 5 && start consul
这将停止进程,并立即重新启动。
如果你依次对每个领事成员这样做,他们将切换到使用SSL来加密它们之间的RPC流量。 当仅切换其中的一些时,一些通信问题可能短暂存在,因为一些业务由于未被加密而被拒绝。
当所有成员重新启动时,RPC流量应该完全加密。
结论
在这一点上,您应该为您的基础架构建立一个相当安全的服务发现系统。 我们利用了领事提供的所有本地安全系统来锁定访问并防止欺骗我们的不同机器。