介绍
Consul 是一个服务发现工具,可以用来轻松发现并跟踪整个基础设施中各种服务的健康状况. 您可以使用领事来管理您的服务,并维护分布式检查系统,以确保您在应用程序或服务器故障时能够响应。
在 最后的指南中,我们专注于制作准备的环境,包括创建配置文件,这些文件会在启动和升级脚本时读取,以便实际启动服务。
这需要我们大部分时间来完成我们的最终基层配置,但我们还没有完全保护我们的配置,我们实施了一个简单的共享秘密解决方案,该解决方案非常容易加密我们的语协议。
然而,RPC通信目前仍然完全未加密. 为了解决这个问题,领事本地支持TLS加密,我们将在本指南中专注于此。
前提和目标
在完成本指南之前,您应该建立一个领事服务器系统,正如我们在 设置生产准备的领事基础设施上最后的指南中所描述的那样。
我们为该指南所拥有的服务器具有以下属性:
Hostname | IP Address | Role |
---|---|---|
server1.example.com | 192.0.2.1 | bootstrap consul server |
server2.example.com | 192.0.2.2 | consul server |
server3.example.com | 192.0.2.3 | consul server |
agent1.example.com | 192.0.2.50 | consul client |
这些是 64 位 Ubuntu 14.04 服务器. 请注意,这些服务器中的每个服务器都位于同一个域内. 这对于我们在本指南中实施的配置来说很重要,因为我们将利用一个 wildcard 证书来匹配该域内的任何主机。
在本指南中,我们将专注于创建一个TLS证书授权机构,以便为每个服务器签署证书。这将允许领事组件验证身份并加密流量。
创建SSL结构
要开始,我们将设置一些基本的文件和目录,我们将使用它们来管理我们的密钥。
再次,我们将从根壳内部执行本指南中的所有程序,或者登录为 root,或者使用sudo -i
作为具有 sudo 特权的用户。
在您的每个领事会员中,在/etc/consul.d
目录中创建一个ssl
目录,在这里我们将保留加密RPC流量所需的文件:
1mkdir /etc/consul.d/ssl
在您计划使用作为证书权威的服务器上,我们将在该目录中创建一个子目录,以存储创建和签署证书所需的所有文件。
在这个服务器上,在我们刚刚创建的目录下创建一个名为CA
的子目录:
1mkdir /etc/consul.d/ssl/CA
这将包含一些敏感数据,我们可能不希望其他人访问,所以让我们锁定权限:
1chmod 0700 /etc/consul.d/ssl/CA
在 CA 服务器上移动到此目录。
1cd /etc/consul.d/ssl/CA
在这里,我们将创建一些需要在我们的证书签名时存在的基本文件. 首先,我们需要创建一个文件,该文件将增加到证书的下一个可用的序列号。
要做到这一点,对序列文件响应000a
的值:
1echo "000a" > serial
我们还需要提供一个文件,我们的证书机构可以记录它签署的证书,我们将这个文件称为certindex
:
1touch certindex
创建自签名的根证书
要开始使用我们的证书权限,我们需要做的第一步是创建一个自签名的根证书,我们可以使用openssl
命令,该命令默认安装在Ubuntu机器上。
我们将使用的命令来创建证书是:
1openssl req -x509 -newkey rsa:2048 -days 3650 -nodes -out ca.cert
让我们来看看这意味着什么:
- req: 此论点表示 openssl 表示您有兴趣在 PKCS#10证书上运行,无论是通过创建或处理请求
- -x509: 此论点说明您想要一个自签证书而不是证书请求。 此论点通常用于 root CA 证书
- -newkey rsa:2048: 此论点表示 openssl 生成新证书请求和私钥。 我们传递给它一个说明我们想要 2048 位的 RSA 密钥
- -days 3650: 在这里,我们指定证书被认为有效的日数。 我们使用一个值
3650
,即 10 年(
在创建证书过程中,您将被要求输入有关您正在认证的主机的信息,您可以用您想要的服务器相关信息来填写此信息:
1. . .
2Country Name (2 letter code) [AU]:US
3State or Province Name (full name) [Some-State]:New York
4Locality Name (eg, city) []:New York City
5Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
6Organizational Unit Name (eg, section) []:
7Common Name (e.g. server FQDN or YOUR name) []:ConsulCA
8Email Address []:[email protected]
对于共同名称
,这将在我们的其他证书中很重要,你可以放任何你想要的。
当你完成时,你应该有一个ca.cert
证书文件,以及一个名为privkey.pem
的相关密钥。
创建一个 Wildcard 证书签名请求
现在我们有根 CA 证书,我们可以为我们的客户端机器生成证书签名请求。
在这种情况下,我们所有的领事会员都是客户端,包括我们目前正在运行的服务器,而不是为每个服务器生成一个独特的证书,并与我们的 CA 签署它,我们将创建一个 wildcard 证书,该证书将适用于我们域中的任何主机。
命令的一般格式将是相同的,但有一些小差异:
1openssl req -newkey rsa:1024 -nodes -out consul.csr -keyout consul.key
我们创建的自签名的 root CA 证书请求和我们现在生成的新证书签名请求之间的区别在这里:
- 没有 -x509 旗帜:我们已删除 `-x509 旗帜以生成证书签名请求而不是自签证书
- -out consul.csr:输出的文件不是证书本身,而是证书签名请求
- -keyout consul.key:我们已指定与证书签名请求相关的密钥名称
再次,我们将被要求对证书签名请求(CSR)的回复。这比我们为自签名的根 CA cert 提供的答案更为重要。
1. . .
2Country Name (2 letter code) [AU]:US
3State or Province Name (full name) [Some-State]:New York
4Locality Name (eg, city) []:New York City
5Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
6Organizational Unit Name (eg, section) []:
7Common Name (e.g. server FQDN or YOUR name) []:*.example.com
8Email Address []:[email protected]
9
10Please enter the following 'extra' attributes
11to be sent with your certificate request
12A challenge password []:
13An optional company name []:
正如您可以在这里看到的,我们使用了我们的域名,作为主机的星座表示该证书应该被认为适用于该域内的任何主机,您可以安全地跳过挑战密码和可选的公司名称提示,这些提示被添加到末尾。
创建证书权限配置文件
现在,我们有我们自签名的 root CA 证书文件和一个与我们域内的所有主机相匹配的 wildcard 证书签名请求. 在我们可以使用我们的 CA 证书签署签名请求之前,我们需要创建一个配置文件,以控制这种情况。
我们将将我们正在创建的文件命名为myca.conf
,它将包含我们的CA信息。
1nano /etc/consul.d/ssl/CA/myca.conf
此檔案使用一個 INI 格式,它被分成部分. 我們將定義的第一個部分是「ca」部分. 在這裡,我們唯一要做的就是指向我們用戶定義的部分與實際的 CA 資訊:
1[ ca ]
2default_ca = myca
接下来,我们将创建我们刚刚引用的部分,其中将包含大部分CA配置细节。
我们将指定输入 cert 提示的信息不一定是独一无二的,然后我们将提供为签名过程所需的所有我们创建的文件的位置,我们将告诉 'openssl'在当前目录中放置新的证书。
我们还希望在命令行上没有指定替代品时选择一些默认值,我们将选择签名的证书为10年,并使用sha1
算法。
1[ myca ]
2unique_subject = no
3new_certs_dir = .
4certificate = ca.cert
5database = certindex
6private_key = privkey.pem
7serial = serial
8default_days = 3650
9default_md = sha1
10policy = myca_policy
11x509_extensions = myca_extensions
现在,让我们专注于我们刚刚引用的第一个用户定义部分,该部分用于决定需要提供哪些信息才能接受CSR。
1[ myca_policy ]
2commonName = supplied
3stateOrProvinceName = supplied
4countryName = supplied
5emailAddress = optional
6organizationName = supplied
7organizationalUnitName = optional
最后的部分将定义我们想要在签署证书时使用的x509扩展。
首先,我们需要告诉它,我们将签署的证书不是CA证书,我们将使用主题密钥标识符的哈希
的标准值,因为六字符串(替代)被强烈阻止。
我们将将权威密钥识别符设置为keyid
,以复制主体密钥识别符从主管 cert. 我们还将指定密钥可以作为签名或与加密密钥的协议使用。
1[ myca_extensions ]
2basicConstraints = CA:false
3subjectKeyIdentifier = hash
4authorityKeyIdentifier = keyid:always
5keyUsage = digitalSignature,keyEncipherment
6extendedKeyUsage = serverAuth,clientAuth
总的来说,这个文件看起来像这样的东西:
1[ ca ]
2default_ca = myca
3
4[ myca ]
5unique_subject = no
6new_certs_dir = .
7certificate = ca.cert
8database = certindex
9private_key = privkey.pem
10serial = serial
11default_days = 3650
12default_md = sha1
13policy = myca_policy
14x509_extensions = myca_extensions
15
16[ myca_policy ]
17commonName = supplied
18stateOrProvinceName = supplied
19countryName = supplied
20emailAddress = optional
21organizationName = supplied
22organizationalUnitName = optional
23
24[ myca_extensions ]
25basicConstraints = CA:false
26subjectKeyIdentifier = hash
27authorityKeyIdentifier = keyid:always
28keyUsage = digitalSignature,keyEncipherment
29extendedKeyUsage = serverAuth,clientAuth
保存并关闭文件完成后,我们现在有一个实质性的配置文件,可以用来签署我们之前生成的证书签名请求。
签署证书签名请求生成证书
现在,我们有所有必要的组件来签署CSR并生成证书,我们只需要参考我们刚刚创建的配置文件,并传输我们生成的CSR。
我们将使用的命令是:
1openssl ca -batch -config myca.conf -notext -in consul.csr -out consul.cert
我们使用的选项是:
- ca:使用openssl的证书权限管理功能
- -batch: 指定它应该进入批量模式。 批量模式自动认证任何经过的CSR,而无需提示
- -config myca.conf: 进入我们创建的配置文件
- -xtnote: 不要输出 cert 的文本形式
其他选项指定输入和输出文件。
这将在当前目录中生成一个名为consul.cert
的文件,还会创建serial
和certindex
文件的新版本,将旧版本移动到备份文件中。
将文件移动到正确的位置
现在,我们有我们需要的所有组件在 /etc/consul.d/ssl/CA
目录中. 我们想将我们需要的三个文件复制到 /etc/consul.d/ssl
目录中,在那里我们将引用它们:
1cp ca.cert consul.key consul.cert ..
我們的「伺服器1」機器擁有CA,現在有必要的證書和關鍵檔案在正確的位置。
要将它们带到你的基础设施中的其他机器上,‘scp’是一个很好的选择. 从‘server1’上的‘/etc/consul.d/ssl’目录中,你可以通过键入以下方式将所需的文件推向其他服务器:
1cd /etc/consul.d/ssl
2scp ca.cert consul.key consul.cert [email protected]:/etc/consul.d/ssl
3scp ca.cert consul.key consul.cert [email protected]:/etc/consul.d/ssl
4scp ca.cert consul.key consul.cert [email protected]:/etc/consul.d/ssl
更改 IP 地址以参考您的基础设施中的每个机器。
更改领事配置文件
现在我们有我们的根证书文件和我们的领事会员的证书/钥匙对,我们可以修改我们的领事会员配置文件以参考这些文件。
打开您的服务器上的每一个控制台配置文件. 对于我们的server1
机器,我们将从 bootstrap 配置文件开始:
1nano /etc/consul.d/bootstrap/config.json
文件现在应该是这样的:
1{
2 "bootstrap": true,
3 "server": true,
4 "datacenter": "nyc2",
5 "data_dir": "/var/consul",
6 "encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",
7 "log_level": "INFO",
8 "enable_syslog": true
9}
我们应该做的第一件事是使用领事参数来识别我们每一个新文件。‘ca_file’参数参考CA证书文件的位置。‘cert_file’和‘key_file’参数分别参考客户端的证书和关键文件。
由于这些都与加密有关,我们将在加密
参数下方为清晰度添加:
1{
2 "bootstrap": true,
3 "server": true,
4 "datacenter": "nyc2",
5 "data_dir": "/var/consul",
6 "encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",
7 "ca_file": "/etc/consul.d/ssl/ca.cert",
8 "cert_file": "/etc/consul.d/ssl/consul.cert",
9 "key_file": "/etc/consul.d/ssl/consul.key",
10 "log_level": "INFO",
11 "enable_syslog": true
12}
现在,我们已经定义了这些文件的位置,但我们没有告诉领事,我们希望通过使用这些文件来验证每个主机的真实性。
1{
2 "bootstrap": true,
3 "server": true,
4 "datacenter": "nyc2",
5 "data_dir": "/var/consul",
6 "encrypt": "pmsKacTdVOb4x8/Vtr9PWw==",
7 "ca_file": "/etc/consul.d/ssl/ca.cert",
8 "cert_file": "/etc/consul.d/ssl/consul.cert",
9 "key_file": "/etc/consul.d/ssl/consul.key",
10 "verify_incoming": true,
11 "verify_outgoing": true,
12 "log_level": "INFO",
13 "enable_syslog": true
14}
保存并关闭文件,当你完成。
对您的领事会员使用的每个配置文件进行相同的更改。
在服务器1
中,您需要将这些更改进行到/etc/consul.d/bootstrap/config.json
和/etc/consul.d/server/config.json
。
在您的其他服务器上,您只需要修改 /etc/consul.d/server/config.json
. 在您的客户端机器上,您只需要修改 /etc/consul.d/client/config.json
。
重新启动服务器
要实现我们的加密流量,您必须在每个领事会员中重启领事会话。
在您的基础设施中的每个机器上,暂停一下,然后再次启动控制器:
1stop consul && sleep 5 && start consul
这会阻止这个过程,并立即重新启动它。
如果您在各个领事会员中进行此操作,他们将转换到使用SSL来加密他们之间的RPC流量,当只有其中一些人被切换时,某些通信问题可能会短暂存在,因为某些流量因未加密而被拒绝。
当所有会员重新启动时,RPC流量应该完全加密。
结论
在此时,您应该为您的基础设施提供一个相当安全的服务发现系统,我们已经利用了领事处可用的所有本地安全系统,以阻止访问并防止我们不同的机器被欺骗。