如何利用TLS/SSL与防火墙规则保护CoreOS集群
2017-02-14 09:28
316 查看
提供:ZStack云计算
幸运的是,etcd支持对等TLS/SSL连接,这意味着集群中各成员节点皆经过验证,且全部通信皆经过加密。在本教程中,我们将配置一套三节点集群,而后在各设备上配置HTTPS端点与基础防火墙。
大家应当熟悉etcd、fleetctl、cloud-config文件并生成一条发现URL。
为了在集群中创建并访问各设备,大家需要使用与DigitalOcean账户相关联的SSH公钥。欲了解更多与之相关的信息,请参阅本篇教程。
如果大家希望使用DigitalOcean构建自己的CoreOS集群,可参阅此教程以了解如何通过写入权限生成并使用个人访问令牌。大家也可以选择使用API,从长远角度看,这种作法有助于在大规模集群内节约管理时间。
curl -w “\n” “https://discovery.etcd.io/new?size=3”
保存返回的URL,我们将在后面的cloud-config中加以使用。
在本地设备上打开终端,确保位于主目录下,使用nano创建并打开~/cloud-config.yml文件:
cd ~
nano cloud-config.yml
粘贴以下内容,而后将etcd2部分内的https://discovery.etcd.io/token变更为大家在上一部分中声明的发现URL。
如果不需要防火墙,大家也可以移除iptables-restore部分。
请注意粘贴时保留缩进。由于cloud-config由YAML写成,其中的空格数非常重要。查看文件内的注释以了解各行含义,我们将强调其中的部分内容。
作为可选步骤,大家也可以将cloud-config粘贴至官方官方CoreOS云配置验证当中,而后按下Validate Cloud-Config。
保存并退出。
下面来看cloud-init.yml文件中的重要部分。首先是fleet值:
注意,etcd_servers被设定为一条https URL。对于普通HTTP操作,此值不需要额外设置。不过如果不经特别调整,HTTPS将无法实现。($private_ipv4是一条CoreOS初始化流程中的变量,这里不需要变更。)
下面,我们来看write_files部分。其值被拆分为一条文件系统路径、权限掩码以及文件内容。在这里,我们为etcd2与fleet服务指定systemd单元文件,从而设置其环境变量以指定我们生成的TLS/SSL证书:
尽管我们已经声明了证书文件的位置,但文件本身尚未生成。因此,我们需要了解每台CoreOS设备的专有IP地址,而此地址在设备创建时即可用。
请注意:在CoreOS Droplets上,cloud-config内容无法在Droplet创建完成后再行改动,因此需要重新引导方可重新执行该文件。大家应当避免在集群构建完成后在任何配置当中使用write-files部分,因为其需要在Droplet下次启动方可起效。
coreos-1
coreos-2
coreos-3
在User Data字段内,粘贴之前的cloud-config.yml内容,确保在discovery字段中插入discovery URL。
cd ~
nano makecoreos.sh
粘贴并保存以下脚本,调整region与size字段(默认为nyc3与512mb):
现在将环境变量DOSSHKEYFINGERPRINT与TOKEN分别设置至与DigitalOcean账户与API个人访问令牌相关联的SSH密钥指纹。
关于更多与个人访问令牌与其API使用相关的信息,请参阅此教程。
为了找到与账户相关联的密钥指纹,请参阅账户设置的安全部分。公钥指纹,的一般形式为43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8。
我们可以使用export,确保该shell的子进程(例如makecoureos.sh)访问各变量。二者必须在脚本使用时的当前shell内设置,否则API调用将无法成功:
export DO_SSH_KEY_FINGERPRINT=”ssh_key_fingerprint”
export TOKEN=”your_personal_access_token”
注意:如果大家已经为该API生成了个人访问令牌,请记得保持其便利性与安全性。我们无法在其创建完成后再行检索,而且 任何拥有该令牌的用户都能够控制大家的DigitalOcean账户。
在为各必要凭证设置了环境变量后,我们可以运行该脚本以创建必要的Droplet。
利用其首条参数填充指向该API的调用中的name字段:
bash makecoreos.sh coreos-1
bash makecoreos.sh coreos-2
bash makecoreos.sh coreos-3
可以看到,每套新Droplet都以JSON输出结果进行描述,且三者全部显示在控制面板中的Droplets列表当中。整个引导过程可能需要数秒钟。
下面测试Droplet。确保我们的SSH密钥被添加至本地SSH代理当中:
eval $(ssh-agent)
ssh-add
在控制面板中找到coreos-1的公共IP地址,接入SSH代理:
ssh -A core@coreos-1_public_ip
在首次登录任何集群成员时,我们可能会收集来自systemd的错误信息:
可以看到,防火墙还没有进行配置。现在我们直接忽略即可。
在防火墙之前,我们首先保证各集群成员上的etcd2实例能够彼此通信。
确保我们的GOPATH得到正确设置并被添加至PATH当中,而后使用go以安装cfssl命令:
export GOPATH=~/gocode
export PATH=PATH:GOPATH/bin
go get -u github.com/cloudflare/cfssl/cmd/cfssl
go get -u github.com/cloudflare/cfssl/…
作为备选方案,我们也可以从pkg.cfssl.org检索预置二进制代码。首先确保路径中已经存在~/bin:
mkdir -p ~/bin
export PATH=$PATH:~/bin
而后使用curl检索cfssl与cfssljson的最新版本:
curl -s -L -o ~/bin/cfssl https://pkg.cfssl.org/R1.1/cfssl_linux-amd64
curl -s -L -o ~/bin/cfssljson https://pkg.cfssl.org/R1.1/cfssljson_linux-amd64
确保cfssl二进制代码拥有执行权限:
chmod +x ~/bin/cfssl
chmod +x ~/bin/cfssljson
mkdir ~/coreos_certs
cd ~/coreos_certs
现在创建并打开ca-config.json文件:
nano ca-config.json
复制以下内容后保存,其负责配置cfssl的签名方式:
请注意这里的expiry,目前其设定为43800 hours(相当于5年),而client-server配置文件中则同时包含server auth与client auth使用情况。我们需要保留二者以实现对等TLS。
下面创建并打开ca-csr.json。
nano ca-csr.json
粘贴以下内容,将CN与names部分调整为必要的位置与组织。这里可以使用虚构的hosts条目位置与组织名称:
如果大家希望将其与ca-config.json与ca-csr.json的默认值进行比较,则可使用cfssl输出默认值。在ca-config.json中,使用:
cfssl print-defaults config
对于ca-csr.json,使用:
cfssl print-defaults csr
在ca-csr.json与ca-config.json就绪后,生成证书中心:
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
创建并打开coreos-1.json:
nano coreos-1.json
粘贴并保存以下内容,将其调整为coreos-1的专有IP地址:
这里最重要的部分是CN,将其设定为我们的主机名称,而后是hosts部分,其中必须包含全部:
各本地主机名称
127.0.0.1
CoreOS设备的专有IP地址(而非公共IP)
这些内容都应作为subjectAltNames被添加至生成的证书内。
etcd连接(包含127.0.0.1上的本地回环设备)要求使用证书以获取与该连接主机名称匹配的SAN。
大家也可以变更name数组以反映必要位置。再次强调,这里我们可以使用虚构的位置名称值。
在各设备上重复以上流程,利用对应的hosts条目匹配coreos-2.json与coreos-3.json。
注意:如果大家希望查看coreos-1.json的默认值,可以使用cfssl:
cfssl print-defaults csr
现在,为各CoreOS设备生成签名证书,并将其上传至正确的设备:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client-server coreos-1.json | cfssljson -bare coreos
chmod 0644 coreos-key.pem
scp ca.pem coreos-key.pem coreos.pem core@coreos-1_public_ip:
这将创建三个文件(ca.pem、coreos-key.pem以及coreos.pem),确保keyfile拥有正确的权限,而后通过scp将其复制至coreos-1上core的主目录中。
重复以上步骤,请注意每次命令调用都会覆盖之前的证书文件:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client-server coreos-2.json | cfssljson -bare coreos
chmod 0644 coreos-key.pem
scp ca.pem coreos-key.pem coreos.pem core@coreos-2_public_ip:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client-server coreos-3.json | cfssljson -bare coreos
chmod 0644 coreos-key.pem
scp ca.pem coreos-key.pem coreos.pem core@coreos-3_public_ip:
ssh -A core@coreos-1_public_ip
接下来,列出集群内的全部设备:
fleetctl list-machines
大家应当会看到各设备的标识符及其专有IP地址:
如果fleetctl无限挂起,我们可能需要重启集群。退出当前设备:
exit
使用SSH将reboot命令发送至各CoreOS设备:
ssh core@coreos-1_public_ip ‘sudo reboot’
ssh core@coreos-2_public_ip ‘sudo reboot’
ssh core@coreos-3_public_ip ‘sudo reboot’
等待几分钟,重新接入coreos-1,再次尝试fleetctl。
请注意,如果我们在cloud-config中启用iptables-restore服务,则会在首次登录CoreOS设备时看到以下错误信息:
其提示我们尽管服务已经启用,但iptables-restore未能正确加载。使用systemctl将其忽略:
systemctl status -l iptables-restore
Output
● iptables-restore.service - Restore iptables firewall rules
Loaded: loaded (/usr/lib64/systemd/system/iptables-restore.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Wed 2015-11-25 00:01:24 UTC; 27min ago
Process: 689 ExecStart=/sbin/iptables-restore /var/lib/iptables/rules-save (code=exited, status=1/FAILURE)
Main PID: 689 (code=exited, status=1/FAILURE)
Nov 25 00:01:24 coreos-2 systemd[1]: Starting Restore iptables firewall rules…
Nov 25 00:01:24 coreos-2 systemd[1]: iptables-restore.service: Main process exited, code=exited, status=1/FAILURE
Nov 25 00:01:24 coreos-2 systemd[1]: Failed to start Restore iptables firewall rules.
Nov 25 00:01:24 coreos-2 iptables-restore[689]: Can’t open /var/lib/iptables/rules-save: No such file or directory
Nov 25 00:01:24 coreos-2 systemd[1]: iptables-restore.service: Unit entered failed state.
Nov 25 00:01:24 coreos-2 systemd[1]: iptables-restore.service: Failed with result ‘exit-code’.
这里包含大量信息,不过最重要的在于iptables-restore[689]这行,其代表的是systemd尝试与其进程id共同运行的进程名称。在这里,我们通常会发现失效服务的错误信息。
防火墙之所以未能成功加载,是因为尽管我们已经在cloud-config中启用了iptables-restore,但还没有为其提供容纳有必要规则的文件。由于已经了解了各集群成员的专有IP,因此我们可以在这里编写规则集。
在编辑器中打开新文件,粘贴以下内容,注意将其中的coreos-1_private_ip,coreos-2_private_ip与coreos-3_private_ip替换为各CoreOS设备的专有IP地址。大家可能还需要调整Accept all TCP/IP traffic…以反映由集群提供的公共服务。
将以上内容复制到剪贴板,登录至coreos-1,而后利用Vim打开rules-save文件:
ssh -A core@coreos-1_public_ip
sudo vim /var/lib/iptables/rules-save
在编辑器内,输入:set进行粘贴,而后按下回车以确保自动缩进功能被关闭。按下Esc键离开插入模式,而后:wq以写入该文件并退出。
注意:确保该文件的最后一行上存在尾部新行,否则即使文件内的全部命令皆为正确,IPTables仍然会出现语法错误。
最后,确保该文件拥有正确的权限:
sudo chmod 0644 /var/lib/iptables/rules-save
现在我们可以再次尝试此服务了:
sudo systemctl start iptables-restore
如果成功,systemctl会静默退出。我们可以通过两种方式检查防火墙状态。首先,使用systemctl status:
sudo systemctl status -l iptables-restore
而后列出全部现有iptables规则:
sudo iptables -v -L
我们使用-v选项以获取详细输出结果,这将告知我们特定规则应用于哪个接口。
确定coreos-1上的防火墙配置完成后,进行登出:
exit
接下来,重复以上步骤在coreos-2与coreos-3上安装/var/lib/iptables/rules-save。
以此为基础,大家也可以参阅CoreOS上手指南以了解更多也出服务定义及管理相关的内容。
本文来源自DigitalOcean Community。英文原文:How To Secure Your CoreOS Cluster with TLS/SSL and Firewall Rules By Brennen Bearnes
翻译:diradw
系列教程
本教程为CoreOS上手指南系列九篇中的第九篇。内容介绍
如果大家需要在控制外网络环境中运行CoreOS集群,例如立足于共享数据中心或者公共互联网,则需要注意一点——etcd利用未加密HTTP请求进行通信。我们可以在集群内对每个节点进行IPTables防火墙配置,从而消除这一风险。但更为彻底的解决手段则是使用加密传输层。幸运的是,etcd支持对等TLS/SSL连接,这意味着集群中各成员节点皆经过验证,且全部通信皆经过加密。在本教程中,我们将配置一套三节点集群,而后在各设备上配置HTTPS端点与基础防火墙。
先决条件
本教程会涉及大量CoreOS系统组件概念,大家可能也需要参阅如何在DigitalOcean上设置CoreOS集群。大家应当熟悉etcd、fleetctl、cloud-config文件并生成一条发现URL。
为了在集群中创建并访问各设备,大家需要使用与DigitalOcean账户相关联的SSH公钥。欲了解更多与之相关的信息,请参阅本篇教程。
如果大家希望使用DigitalOcean构建自己的CoreOS集群,可参阅此教程以了解如何通过写入权限生成并使用个人访问令牌。大家也可以选择使用API,从长远角度看,这种作法有助于在大规模集群内节约管理时间。
生成一条新的发现URL
大家可以在浏览器内访问https://discovery.etcd.io/new?size=3以检索新的discovery URL,复制显示的URL或者直接在本地设备上使用curl命令:curl -w “\n” “https://discovery.etcd.io/new?size=3”
保存返回的URL,我们将在后面的cloud-config中加以使用。
编写包含HTTPS配置的Cloud-Config文件
首先从编写cloud-config开始。此文件在服务器初始化时作为用户数据使用,负责定义集群的各重要配置细节。文件内容较长,但却并不复杂。具体请参阅基础集群指南。我们将要求fleet明确使用HTTPS端点,同时启用imptables-restore服务作为防火墙,而后编写配置文件以告知etcd与fleet在哪里找到SSL证书。在本地设备上打开终端,确保位于主目录下,使用nano创建并打开~/cloud-config.yml文件:
cd ~
nano cloud-config.yml
粘贴以下内容,而后将etcd2部分内的https://discovery.etcd.io/token变更为大家在上一部分中声明的发现URL。
如果不需要防火墙,大家也可以移除iptables-restore部分。
请注意粘贴时保留缩进。由于cloud-config由YAML写成,其中的空格数非常重要。查看文件内的注释以了解各行含义,我们将强调其中的部分内容。
~/cloud-config.yml #cloud-config coreos: etcd2: # generate a new token for each unique cluster from https://discovery.etcd.io/new: discovery: https://discovery.etcd.io/token # multi-region deployments, multi-cloud deployments, and Droplets without # private networking need to use $public_ipv4: advertise-client-urls: https://$private_ipv4:2379,https://$private_ipv4:4001 initial-advertise-peer-urls: https://$private_ipv4:2380 # listen on the official ports 2379, 2380 and one legacy port 4001: listen-client-urls: https://0.0.0.0:2379,https://0.0.0.0:4001 listen-peer-urls: https://$private_ipv4:2380 fleet: # fleet defaults to plain HTTP - explicitly tell it to use HTTPS on port 4001: etcd_servers: https://$private_ipv4:4001 public-ip: $private_ipv4 # used for fleetctl ssh command units: - name: etcd2.service command: start - name: fleet.service command: start # enable and start iptables-restore- name: iptables-restore.serviceenable: truecommand: start write_files: # tell etcd2 and fleet where our certificates are going to live: - path: /run/systemd/system/etcd2.service.d/30-certificates.conf permissions: 0644 content: | [Service] # client environment variables Environment=ETCD_CA_FILE=/home/core/ca.pem Environment=ETCD_CERT_FILE=/home/core/coreos.pem Environment=ETCD_KEY_FILE=/home/core/coreos-key.pem # peer environment variables Environment=ETCD_PEER_CA_FILE=/home/core/ca.pem Environment=ETCD_PEER_CERT_FILE=/home/core/coreos.pem Environment=ETCD_PEER_KEY_FILE=/home/core/coreos-key.pem - path: /run/systemd/system/fleet.service.d/30-certificates.conf permissions: 0644 content: | [Service] # client auth certs Environment=FLEET_ETCD_CAFILE=/home/core/ca.pem Environment=FLEET_ETCD_CERTFILE=/home/core/coreos.pem Environment=FLEET_ETCD_KEYFILE=/home/core/coreos-key.pem
作为可选步骤,大家也可以将cloud-config粘贴至官方官方CoreOS云配置验证当中,而后按下Validate Cloud-Config。
保存并退出。
下面来看cloud-init.yml文件中的重要部分。首先是fleet值:
fleet: # fleet defaults to plain HTTP - explicitly tell it to use HTTPS: etcd_servers: https://$private_ipv4:4001 public-ip: $private_ipv4 # used for fleetctl ssh command
注意,etcd_servers被设定为一条https URL。对于普通HTTP操作,此值不需要额外设置。不过如果不经特别调整,HTTPS将无法实现。($private_ipv4是一条CoreOS初始化流程中的变量,这里不需要变更。)
下面,我们来看write_files部分。其值被拆分为一条文件系统路径、权限掩码以及文件内容。在这里,我们为etcd2与fleet服务指定systemd单元文件,从而设置其环境变量以指定我们生成的TLS/SSL证书:
write_files: # tell etcd2 and fleet where our certificates are going to live: - path: /run/systemd/system/etcd2.service.d/30-certificates.conf permissions: 0644 content: | [Service] # client environment variables Environment=ETCD_CA_FILE=/home/core/ca.pem ... - path: /run/systemd/system/fleet.service.d/30-certificates.conf permissions: 0644 content: | [Service] # client auth certs Environment=FLEET_ETCD_CAFILE=/home/core/ca.pem ...
尽管我们已经声明了证书文件的位置,但文件本身尚未生成。因此,我们需要了解每台CoreOS设备的专有IP地址,而此地址在设备创建时即可用。
请注意:在CoreOS Droplets上,cloud-config内容无法在Droplet创建完成后再行改动,因此需要重新引导方可重新执行该文件。大家应当避免在集群构建完成后在任何配置当中使用write-files部分,因为其需要在Droplet下次启动方可起效。
配置Droplets
现在我们已经定义了cloud-config.yml,下面利用其配置各集群成员。在DigitalOcean上,我们可以选择两种实现方案:通过基于Web的控制面板,或者利用cURL在命令行中调用DigitalOcean API。使用DigitalOcean控制面板
在同一数据中心服务区内创建新的CoreOS Droplets。确保每次创建时检查专有网络并启用User Data。coreos-1
coreos-2
coreos-3
在User Data字段内,粘贴之前的cloud-config.yml内容,确保在discovery字段中插入discovery URL。
使用DigitalOcean API
作为备选方案,我们也可以编写一套简短的Bash脚本,利用curl从DIgitalOcean API请求创建新的Droplet。首先利用nano打开makecoreos.sh新文件:cd ~
nano makecoreos.sh
粘贴并保存以下脚本,调整region与size字段(默认为nyc3与512mb):
~/makecoreos.sh #!/usr/bin/env bash # A basic Droplet create request. curl -X POST "https://api.digitalocean.com/v2/droplets" \ -d'{"name":"'"$1"'","region":"nyc3","size":"512mb","private_networking":true,"image":"coreos-stable","user_data": "'"$(cat ~/cloud-config.yml)"'", "ssh_keys":[ "'$DO_SSH_KEY_FINGERPRINT'" ]}' \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json"
现在将环境变量DOSSHKEYFINGERPRINT与TOKEN分别设置至与DigitalOcean账户与API个人访问令牌相关联的SSH密钥指纹。
关于更多与个人访问令牌与其API使用相关的信息,请参阅此教程。
为了找到与账户相关联的密钥指纹,请参阅账户设置的安全部分。公钥指纹,的一般形式为43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8。
我们可以使用export,确保该shell的子进程(例如makecoureos.sh)访问各变量。二者必须在脚本使用时的当前shell内设置,否则API调用将无法成功:
export DO_SSH_KEY_FINGERPRINT=”ssh_key_fingerprint”
export TOKEN=”your_personal_access_token”
注意:如果大家已经为该API生成了个人访问令牌,请记得保持其便利性与安全性。我们无法在其创建完成后再行检索,而且 任何拥有该令牌的用户都能够控制大家的DigitalOcean账户。
在为各必要凭证设置了环境变量后,我们可以运行该脚本以创建必要的Droplet。
利用其首条参数填充指向该API的调用中的name字段:
bash makecoreos.sh coreos-1
bash makecoreos.sh coreos-2
bash makecoreos.sh coreos-3
可以看到,每套新Droplet都以JSON输出结果进行描述,且三者全部显示在控制面板中的Droplets列表当中。整个引导过程可能需要数秒钟。
登录至coreos-1
无论大家是使用控制面板还是API,应该都已经构建起了三套Droplets。现在点击控制面板内各Droplet、再点击设置链接,查看其公共与专有IP。各Droplet的专有IP地址需要用于生成证书及配置防火墙。下面测试Droplet。确保我们的SSH密钥被添加至本地SSH代理当中:
eval $(ssh-agent)
ssh-add
在控制面板中找到coreos-1的公共IP地址,接入SSH代理:
ssh -A core@coreos-1_public_ip
在首次登录任何集群成员时,我们可能会收集来自systemd的错误信息:
Output CoreOS stable (766.5.0) Failed Units: 1 iptables-restore.service
可以看到,防火墙还没有进行配置。现在我们直接忽略即可。
在防火墙之前,我们首先保证各集群成员上的etcd2实例能够彼此通信。
使用CFSSL以生成自签名证书
CFSSL是一款工具套件,用于处理TLS/SSL证书,由CloudFlare发布。目前其已经成为CoreOS维护方的指定工具,用于生成自签名证书。这里不推荐使用etcd-ca。在本地设备上安装CFSSL
CFSSL要求安装Go以获取代码源。具体请参阅Go安装指南。确保我们的GOPATH得到正确设置并被添加至PATH当中,而后使用go以安装cfssl命令:
export GOPATH=~/gocode
export PATH=PATH:GOPATH/bin
go get -u github.com/cloudflare/cfssl/cmd/cfssl
go get -u github.com/cloudflare/cfssl/…
作为备选方案,我们也可以从pkg.cfssl.org检索预置二进制代码。首先确保路径中已经存在~/bin:
mkdir -p ~/bin
export PATH=$PATH:~/bin
而后使用curl检索cfssl与cfssljson的最新版本:
curl -s -L -o ~/bin/cfssl https://pkg.cfssl.org/R1.1/cfssl_linux-amd64
curl -s -L -o ~/bin/cfssljson https://pkg.cfssl.org/R1.1/cfssljson_linux-amd64
确保cfssl二进制代码拥有执行权限:
chmod +x ~/bin/cfssl
chmod +x ~/bin/cfssljson
生成证书中心
现在cfssl命令已经安装完成,我们可以利用其生成定制化证书中心,从而为各COreOS设备签署证书。首先创建并前往新建目录,用于容纳这些文件:mkdir ~/coreos_certs
cd ~/coreos_certs
现在创建并打开ca-config.json文件:
nano ca-config.json
复制以下内容后保存,其负责配置cfssl的签名方式:
~/coreos_certs/ca-config.json { "signing": { "default": { "expiry": "43800h" }, "profiles": { "client-server": { "expiry": "43800h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] } } } }
请注意这里的expiry,目前其设定为43800 hours(相当于5年),而client-server配置文件中则同时包含server auth与client auth使用情况。我们需要保留二者以实现对等TLS。
下面创建并打开ca-csr.json。
nano ca-csr.json
粘贴以下内容,将CN与names部分调整为必要的位置与组织。这里可以使用虚构的hosts条目位置与组织名称:
~/coreos_certs/ca-csr.json { "CN": "My Fake CA", "hosts": [ "example.net", "www.example.net" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "CO", "O": "My Company", "ST": "Lyons", "OU": "Some Org Unit" } ] }
如果大家希望将其与ca-config.json与ca-csr.json的默认值进行比较,则可使用cfssl输出默认值。在ca-config.json中,使用:
cfssl print-defaults config
对于ca-csr.json,使用:
cfssl print-defaults csr
在ca-csr.json与ca-config.json就绪后,生成证书中心:
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
为CoreOS设备生成并签署证书
现在我们的证书中心已经就绪,我们可以为CoreOS设备编写默认值:创建并打开coreos-1.json:
nano coreos-1.json
粘贴并保存以下内容,将其调整为coreos-1的专有IP地址:
~/coreos_certs/coreos-1.json { "CN": "coreos-1", "hosts": [ "coreos-1", "coreos-1.local", "127.0.0.1", "coreos-1_private_ip" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "Lyons", "ST": "Colorado" } ] }
这里最重要的部分是CN,将其设定为我们的主机名称,而后是hosts部分,其中必须包含全部:
各本地主机名称
127.0.0.1
CoreOS设备的专有IP地址(而非公共IP)
这些内容都应作为subjectAltNames被添加至生成的证书内。
etcd连接(包含127.0.0.1上的本地回环设备)要求使用证书以获取与该连接主机名称匹配的SAN。
大家也可以变更name数组以反映必要位置。再次强调,这里我们可以使用虚构的位置名称值。
在各设备上重复以上流程,利用对应的hosts条目匹配coreos-2.json与coreos-3.json。
注意:如果大家希望查看coreos-1.json的默认值,可以使用cfssl:
cfssl print-defaults csr
现在,为各CoreOS设备生成签名证书,并将其上传至正确的设备:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client-server coreos-1.json | cfssljson -bare coreos
chmod 0644 coreos-key.pem
scp ca.pem coreos-key.pem coreos.pem core@coreos-1_public_ip:
这将创建三个文件(ca.pem、coreos-key.pem以及coreos.pem),确保keyfile拥有正确的权限,而后通过scp将其复制至coreos-1上core的主目录中。
重复以上步骤,请注意每次命令调用都会覆盖之前的证书文件:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client-server coreos-2.json | cfssljson -bare coreos
chmod 0644 coreos-key.pem
scp ca.pem coreos-key.pem coreos.pem core@coreos-2_public_ip:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client-server coreos-3.json | cfssljson -bare coreos
chmod 0644 coreos-key.pem
scp ca.pem coreos-key.pem coreos.pem core@coreos-3_public_ip:
在coreos-1上检查etcd2功能
证书准备好后,我们可以在coreos-1上运行fleetctl了。首先通过SSH进行登录:ssh -A core@coreos-1_public_ip
接下来,列出集群内的全部设备:
fleetctl list-machines
大家应当会看到各设备的标识符及其专有IP地址:
Output MACHINE IP METADATA 7cb57440... 10.132.130.187 - d91381d4... 10.132.87.87 - eeb8726f... 10.132.32.222 -
如果fleetctl无限挂起,我们可能需要重启集群。退出当前设备:
exit
使用SSH将reboot命令发送至各CoreOS设备:
ssh core@coreos-1_public_ip ‘sudo reboot’
ssh core@coreos-2_public_ip ‘sudo reboot’
ssh core@coreos-3_public_ip ‘sudo reboot’
等待几分钟,重新接入coreos-1,再次尝试fleetctl。
在集群成本上配置IPTables防火墙
证书就绪后,本地网络中的其它设备将无法控制集群或者从etcd2中提取值。然而,尽可能降低攻击面仍然有其必要。为了限制网络公开性,我们可以在各设备上添加简单的防火墙规则,从而阻断集群之外的大部分网络流量。请注意,如果我们在cloud-config中启用iptables-restore服务,则会在首次登录CoreOS设备时看到以下错误信息:
Output CoreOS stable (766.5.0) Failed Units: 1 iptables-restore.service
其提示我们尽管服务已经启用,但iptables-restore未能正确加载。使用systemctl将其忽略:
systemctl status -l iptables-restore
Output
● iptables-restore.service - Restore iptables firewall rules
Loaded: loaded (/usr/lib64/systemd/system/iptables-restore.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Wed 2015-11-25 00:01:24 UTC; 27min ago
Process: 689 ExecStart=/sbin/iptables-restore /var/lib/iptables/rules-save (code=exited, status=1/FAILURE)
Main PID: 689 (code=exited, status=1/FAILURE)
Nov 25 00:01:24 coreos-2 systemd[1]: Starting Restore iptables firewall rules…
Nov 25 00:01:24 coreos-2 systemd[1]: iptables-restore.service: Main process exited, code=exited, status=1/FAILURE
Nov 25 00:01:24 coreos-2 systemd[1]: Failed to start Restore iptables firewall rules.
Nov 25 00:01:24 coreos-2 iptables-restore[689]: Can’t open /var/lib/iptables/rules-save: No such file or directory
Nov 25 00:01:24 coreos-2 systemd[1]: iptables-restore.service: Unit entered failed state.
Nov 25 00:01:24 coreos-2 systemd[1]: iptables-restore.service: Failed with result ‘exit-code’.
这里包含大量信息,不过最重要的在于iptables-restore[689]这行,其代表的是systemd尝试与其进程id共同运行的进程名称。在这里,我们通常会发现失效服务的错误信息。
防火墙之所以未能成功加载,是因为尽管我们已经在cloud-config中启用了iptables-restore,但还没有为其提供容纳有必要规则的文件。由于已经了解了各集群成员的专有IP,因此我们可以在这里编写规则集。
在编辑器中打开新文件,粘贴以下内容,注意将其中的coreos-1_private_ip,coreos-2_private_ip与coreos-3_private_ip替换为各CoreOS设备的专有IP地址。大家可能还需要调整Accept all TCP/IP traffic…以反映由集群提供的公共服务。
/var/lib/iptables/rules-save - *filter - :INPUT DROP [0:0] - :FORWARD DROP [0:0] - :OUTPUT ACCEPT [0:0] - # Accept all loopback (local) traffic: - -A INPUT -i lo -j ACCEPT - # Accept all traffic on the local network from other members of - # our CoreOS cluster: - -A INPUT -i eth1 -p tcp -s coreos-1_private_ip -j ACCEPT - -A INPUT -i eth1 -p tcp -s coreos-2_private_ip -j ACCEPT - -A INPUT -i eth1 -p tcp -s coreos-3_private_ip -j ACCEPT - # Keep existing connections (like our SSH session) alive: - -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - # Accept all TCP/IP traffic to SSH, HTTP, and HTTPS ports - this should - # be customized for your application: - -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT - -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT - -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT - # Accept pings: - -A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT - -A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT - -A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT - COMMIT
将以上内容复制到剪贴板,登录至coreos-1,而后利用Vim打开rules-save文件:
ssh -A core@coreos-1_public_ip
sudo vim /var/lib/iptables/rules-save
在编辑器内,输入:set进行粘贴,而后按下回车以确保自动缩进功能被关闭。按下Esc键离开插入模式,而后:wq以写入该文件并退出。
注意:确保该文件的最后一行上存在尾部新行,否则即使文件内的全部命令皆为正确,IPTables仍然会出现语法错误。
最后,确保该文件拥有正确的权限:
sudo chmod 0644 /var/lib/iptables/rules-save
现在我们可以再次尝试此服务了:
sudo systemctl start iptables-restore
如果成功,systemctl会静默退出。我们可以通过两种方式检查防火墙状态。首先,使用systemctl status:
sudo systemctl status -l iptables-restore
而后列出全部现有iptables规则:
sudo iptables -v -L
我们使用-v选项以获取详细输出结果,这将告知我们特定规则应用于哪个接口。
确定coreos-1上的防火墙配置完成后,进行登出:
exit
接下来,重复以上步骤在coreos-2与coreos-3上安装/var/lib/iptables/rules-save。
总结
在本教程中,我们已经定义了三个基础CoreOS集群成员,为其各自提供了TLS/SSL证书以实现验证及传输安全,而后利用防火墙屏蔽一切来自本地数据中心网络的其它Droplets的连接。以此为基础,大家也可以参阅CoreOS上手指南以了解更多也出服务定义及管理相关的内容。
本文来源自DigitalOcean Community。英文原文:How To Secure Your CoreOS Cluster with TLS/SSL and Firewall Rules By Brennen Bearnes
翻译:diradw
相关文章推荐
- 如何利用fleet单元文件为CoreOS集群创建高灵活性服务
- 如何利用MBSA扫描受防火墙保护的电脑
- 如何利用MySQL加密函数保护Web网站敏感数据
- 如何利用DES加密的算法保护Java源代码
- 经典技术文章转载:如何利用 SSL 调用 Web 服务
- https/ssl原理,如何保护数据不被窃听
- 如何利用 SSL 调用 Web 服务
- 如何在 Web 发布规则中使用证书进行 SSL 身份验证
- 如何设置Windows 7防火墙来保护系统安全
- Flex中如何利用setInterval()和clearInterval()函数按照一定时间有规则的执行函数的例子
- 如何利用openssl为iis生成ssl服务器证书
- 9.3.2 保护内部客户机的防火墙规则
- 如何利用C++ Builder 5.0 实现屏幕保护程序的开发
- 如何利用openssl为iis生成ssl服务器证书!
- 利用iptables防火墙保护Oracle数据库
- 如何利用MySQL加密函数保护Web网站敏感数据
- 如何利用Windows自带功能保护私密信息
- jsp如何利用SSL进行双向认证
- 如何通过iptables防火墙保护oracle数据库
- 如何定义防火墙的规则iptables