如何在 Ubuntu 14.04 上使用 TLS 加密保护 Consul

介绍

Consul 是一个服务发现工具,可以用来轻松发现并跟踪整个基础设施中各种服务的健康状况. 您可以使用领事来管理您的服务,并维护分布式检查系统,以确保您在应用程序或服务器故障时能够响应。

最后的指南中,我们专注于制作准备的环境,包括创建配置文件,这些文件会在启动和升级脚本时读取,以便实际启动服务。

这需要我们大部分时间来完成我们的最终基层配置,但我们还没有完全保护我们的配置,我们实施了一个简单的共享秘密解决方案,该解决方案非常容易加密我们的语协议。

然而,RPC通信目前仍然完全未加密. 为了解决这个问题,领事本地支持TLS加密,我们将在本指南中专注于此。

前提和目标

在完成本指南之前,您应该建立一个领事服务器系统,正如我们在 设置生产准备的领事基础设施上最后的指南中所描述的那样。

我们为该指南所拥有的服务器具有以下属性:

HostnameIP AddressRole
server1.example.com192.0.2.1bootstrap consul server
server2.example.com192.0.2.2consul server
server3.example.com192.0.2.3consul server
agent1.example.com192.0.2.50consul 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的文件,还会创建serialcertindex文件的新版本,将旧版本移动到备份文件中。

将文件移动到正确的位置

现在,我们有我们需要的所有组件在 /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流量应该完全加密。

结论

在此时,您应该为您的基础设施提供一个相当安全的服务发现系统,我们已经利用了领事处可用的所有本地安全系统,以阻止访问并防止我们不同的机器被欺骗。

Published At
Categories with 技术
comments powered by Disqus