Skip to content

Latest commit

 

History

History
237 lines (195 loc) · 12.1 KB

20-3.Multi-Master-PKI-Tutorial-With-Failover-给合使用PKI和failover的Multimaster架构.md

File metadata and controls

237 lines (195 loc) · 12.1 KB

Multi-Master-PKI Tutorial With Failover - 给合使用PKI和failover的Multimaster架构

本教程将解释如何运行一套salt-environment,其中单个minion可以拥有多个master服务器,并且如果当前master服务器失败了,则在它们之间进行故障转移。

配置步骤是:

  • 配置master(s),签署其auth-reply
  • 设置minion(s),以验证master-public-keys
  • 在minion(s)上启用对多masters的支持
  • 在minion(s)上启用master-check功能

请注意,建议你事先对salt身份验证和通信过程进行了解,以理解本教程的内容。 此处描述的所有设置都在salt默认的身份验证/通信过程之上实现的。

起因

salt-minion的默认行为是连接到一个master服务器并接受master服务器的公钥。 随着每个发布管理命令,master发送他的public-key供minion检查,如果这个public-key发生了变化,则minion会报错并退出。 实际上,这意味着在任何给定时间只能有一个master。

如果当前的master因网络或硬件故障而失联了,但minion可以拥有任意数量的masters(1:n),那么会不会更好?

注意

另外还有一个MultiMaster-Tutorial的部署方案,它具有与此不同的方法和拓扑,显然也更加简单,可能也能满足你的需求,甚至可能更适合,请参见Multi-Master Tutorial

我们还希望在一个minion从master那里收到的第一个公钥信息的过程中添加一些真实性检查。 目前,minion将接受第一个master的公钥视为理所当然的行为。

目标

设置master设备以签署它发送给minions的公钥,并使minions能够验证此签名的真实性。

配置master以签署公钥

要使用签名功能,master和minion都必须启用签名和/或验证的设置。 如果master签署了公钥但是minion没有核实,那么minion就会报错并退出。 同样的情况也发生在,当master没有签名但是minion试图验证时。

让master签名其公钥的最简单方法是设置:

master_sign_pubkey: True

在重新启动salt-master服务后,master服务器将自动生成新的用于签名服务的密钥对:

master_sign.pem
master_sign.pub

可以指定一个自定义的密钥对的名称:

master_sign_key_name: <name_without_suffix>

然后,master服务器将在重新启动时生成该密钥对,并使用它来创建附加到auth-reply的公钥签名。

这种计算是针对一个minion的每个auth-request完成的。 如果有许多minions频繁做授权,建议使用下面描述的conf_master:master_pubkey_signature和conf_master:master_use_pubkey_signature设置。

如果正在使用多个masters服务器且启用了签署其auth-reply的功能,则必须将用于签名的密钥对master_sign.*文件复制到每一个master服务器上。 否则,当连接到不同的master时,minion将会因为公钥签名是使用不同的签名密钥对创建的,而无法验证master的公钥信息。

配置minion来验证收到的公钥

Minion需要拥有签名使用的公钥(并且只能是正确的那个!)才能验证它收到的签名。 我们需要将该公钥(默认为master_sign.pub)从master服务器复制到minions节点的pki-directory中一份。

/etc/salt/pki/minion/master_sign.pub

千万不要把 master_sign.pem文件也复制走了,这个私钥文件只能存放在master上

当准备好上面的公钥文件后,在minions的配置中启动签名检查的功能:

verify_master_pubkey_sign: True

以debug模式重启下salt minion服务,这样便于观察下上面配置的功能是否正常:

salt-minion -l debug

启动后,你应该能看到类似下面这样的debug日志信息:

[DEBUG   ] Attempting to authenticate with the Salt Master at 172.16.0.10
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] salt.crypt.verify_signature: Loading public key
[DEBUG   ] salt.crypt.verify_signature: Verifying signature
[DEBUG   ] Successfully verified signature of master public key with verification public key master_sign.pub
[INFO    ] Received signed and verified master pubkey from master 172.16.0.10
[DEBUG   ] Decrypting the current master AES key

或者,运气不好的话,也许看到的是类似下面这样的报错信息:

[DEBUG   ] Attempting to authenticate with the Salt Master at 172.16.0.10
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] salt.crypt.verify_signature: Loading public key
[DEBUG   ] salt.crypt.verify_signature: Verifying signature
[DEBUG   ] Failed to verify signature of public key
[CRITICAL] The Salt Master server's public key did not authenticate!

在这种情况下,应该检查,minion上的验证pubkey(master_sign.pub)与master上的验证pubkey(master_sign.pub)是否相同。

确认可以验证成功后,再把minion改为使用守护进程模式启动。

对于信息安全有近乎偏执得严格要求的人,也可以配置为对从master收到的所有数据做签名校验。

always_verify_signature: True

配置minion(s)启用对多masters的支持

通过设置以下两个参数的来完成在minion上配置多个master服务器:

  • 指定一个masters服务器的列表
  • 定义master的类型
master:
    - 172.16.0.10
    - 172.16.0.11
    - 172.16.0.12
master_type: failover

这告诉minion上面的所有master都可以连接。 使用此配置启动minion服务时,它将按照定义的顺序尝试连接master服务器。

如果希望minion随机连接到上面列表中的某一个master,请设置:

master_shuffle: True

于是,在minion第一次连接尝试之前会先对master列表的内容打乱原有的顺序。

接受minion的第一个master会被minion所使用。

为了使minion能够检测它是否仍然连接到其当前的master设备,可以启用它的健康检查功能:

master_alive_interval: <seconds>

如果检测到连接已经丢失了,则minion将临时从列表中删除失败的master服务器并尝试连接到其他已经定义了的一个master服务器上(如果启用了shuffle参数,则还会再次对master列表内容进行洗牌)。

测试设置

至少需要准备好两个masters来测试多masters的故障转移功能。

两个salt masters都需要运行起来,然后为了便于观察测试数据,我们使用debug模式运行salt minion:

salt-minion -l debug

启动minion后,会连接至master列表中的第一个master服务器上面:

[DEBUG   ] Attempting to authenticate with the Salt Master at 172.16.0.10
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] salt.crypt.verify_signature: Loading public key
[DEBUG   ] salt.crypt.verify_signature: Verifying signature
[DEBUG   ] Successfully verified signature of master public key with verification public key master_sign.pub
[INFO    ] Received signed and verified master pubkey from master 172.16.0.10
[DEBUG   ] Decrypting the current master AES key

我们可以登录到master列表中的第一个master服务器上,执行下test.ping命令,来验证测试下这个minion访问master服务的连通性。

如果上面的测试通过了,那我们可以把minion连接上的这个master服务先关闭掉,或者通过系统防火墙屏蔽下服务端口的访问。然后观测下salt多masters架构的故障转移功能。

根据在minion配置文件中设置的master_alive_interval参数所指定的健康检查时间间隔,minion会探测到自己已经不能再正常连接到当前的salt master服务,它会把这个信息也在日志中写入一份,像下面这样。

[INFO    ] Connection to master 172.16.0.10 lost
[INFO    ] Trying to tune in to next master from master-list

然后,minion将从列表中删除当前的master,并尝试连接到下一个master

[INFO    ] Removing possibly failed master 172.16.0.10 from list of masters
[WARNING ] Master ip address changed from 172.16.0.10 to 172.16.0.11
[DEBUG   ] Attempting to authenticate with the Salt Master at 172.16.0.11

如果一切配置正确,将成功验证新的master的密钥公钥:

[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] salt.crypt.verify_signature: Loading public key
[DEBUG   ] salt.crypt.verify_signature: Verifying signature
[DEBUG   ] Successfully verified signature of master public key with verification public key master_sign.pub

使用新master服务器身份验证成功:

[INFO    ] Received signed and verified master pubkey from master 172.16.0.11
[DEBUG   ] Decrypting the current master AES key
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[INFO    ] Authentication with master successful!

这时,在新的master服务器上执行针对这个minion的test.ping测试,可以成功返回结果。

性能调优

通过上述设置,master设备会为每个minion的auth-request请求计算签名。 在有许多minions和频繁的auth请求时,这可以消耗掉master服务器上相当多的CPU资源。

为了避免这种情况,master设备可以使用其公钥预先创建好一个签名。 将签名保存为base64编码的字符串,由master服务在启动时读取一次,并仅将该字符串附加到auth-reply中。

可以使用下面的命令创建该签名:

salt-key --gen-signature

这将在master的 pki-directory目录中创建一个默认的签名文件。

/etc/salt/pki/master/master_pubkey_signature

它是一个简单的文本文件,内容是二进制签名转换为base64格式。

如果在此之前还没有生成过签名密钥对,则可以在同一次的调用中自动创建签名密钥对和签名文件:

salt-key --gen-signature --auto-create

设置下面的参数告诉master服务使用预先创建的签名文件:

master_use_pubkey_signature: True

注意这要求'master_pubkey_signature'文件已经放在master服务器的pki目录中,且具有正确的签名信息。

可以使用下面的参数自定义签名文件的文件名:

master_pubkey_signature: <filename>

对于同时部署和使用了很多master服务器的情况,会有多个公钥(默认和签名),建议使用salt-masters的主机名作为签名的文件名。 因为签名很容易混淆,单单从这个文件的内容上看不出任何有关创建签名的密钥的信息。

在使用这些功能时,请验证你配置的服务是否一切正常,且是按照与上面相同的方式完成的。

签名和验证是如何运作的

salt-master的默认密钥对是:

/etc/salt/pki/master/master.pem
/etc/salt/pki/master/master.pub

为了能够创建对消息的签名(在这种情况下主要是指的公钥),必须将另一个密钥对添加到salt master服务的设置中。 它的默认名称是:

master_sign.pem
master_sign.pub

master.*和master_sign.*密钥对的组合使用,提供了生成(公钥)签名的可能性。 如果签名密钥对所使用的公钥对接收者(minion)是可用的,则给定消息的签名就可以确定是唯一并且可以被验证的。

使用下面的方法计算master服务器公钥master.pub的签名:

master_sign.pem
master.pub
M2Crypto.EVP.sign_update()

这会导致把二进制签名转换为base64格式并附加到aution-reply中发送给minion。

minion因为是可以使用本地存放好的签名对公钥文件的,所以可以用下面的方法对签名的真实性做验证:

master_sign.pub
master.pub
M2Crypto.EVP.verify_update()

在运行了多个master服务器时,必须在所有master服务器上都存放好用于签名的密钥对,或者必须为每个master服务器单独预先计算master_pubkey_signature(因为它们都具有不同的公钥)。