玩转KVM:TLS安全连接
本次分享的内容是:KVM的安全知识,TLS有什么用。
说TLS安全连接之前,我们需要先聊一下怎么可以远程管理KVM。 目前vmware, xen, kvm, lxc等都支持libvirt, libvirt的强大,然后根本不需要考虑怎么远程的问题。我们只需要考虑怎么更好地远程管理它。
TLS 1.0 (SSL 3.1) | 认证是加密了TCP/IP的套接字,通常监听一个公开段的端口号(默认是16514), 但是使用前需要配置client和server的证书,并放到集群的机器上。 |
unix | 使用unix系统套接字,只允许机器本地操作,无法支持远程。 |
ssh | 最常用的方式, 如同ssh远程登录设备一样,不过建议做ssh-key免密登录,可以使用ssh-agent管理秘钥。 |
tcp | 不加密的TCP/IP套接字, 这个是不安全的,在生产环境应该杜绝 |
简单的逻辑图:
(1)创建临时目录,以将文件和更改保存到其中:
mkdir /opt/cert_files
cd cert_files/
(2)使用 openssl 命令创建 2048 位 RSA 密钥:
openssl genrsa -out cakey.pem 2048
(3)使用该密钥针对本地 CA 创建自签名证书:
这里参数:按需修改:/C=CN/L=GDFS/O=EFLY/CN=EFLY
字段如下:
Country Name (2 letter code) | The two-letter country code where your company is legally located. |
State or Province Name (full name) | The state/province where your company is legally located. |
Locality Name (e.g., city) | The city where your company is legally located. |
Organization Name (e.g., company) | Your company's legally registered name (e.g., YourCompany, Inc.). |
Organizational Unit Name (e.g., section) | The name of your department within the organization. (You can leave this option blank; simply press Enter.) |
Common Name (e.g., server FQDN) | The fully-qualified domain name (FQDN) (e.g., www.example.com). |
Email Address | Your email address. (You can leave this option blank; simply press Enter.) |
A challenge password | Leave this option blank (simply press Enter). |
An optional company name | Leave this option blank (simply press Enter). |
openssl req -new -x509 -days 1095 -key cakey.pem -out cacert.pem -sha256 -subj "/C=CN/L=GDFS/O=EFLY/CN=KVM CA"
(4)检查 CA 证书:
openssl x509 -noout -text -in cacert.pem
client, server
(5)创建密钥:
openssl genrsa -out serverkey.pem 2048
openssl genrsa -out clientkey.pem 2048
(6)为服务器创建证书签名请求。
openssl req -new -key serverkey.pem -out serverkey.csr -subj "/C=CN/O=EFLY/CN=${KVM}/DNS=${KVM}/ip_addres={IP}"
可以使用配置文件形式实现 server.info:
[ req ]
prompt = no
default_bits = 4096
distinguished_name = req_distinguished_name
req_extensions = req_ext
[ req_distinguished_name ]
C=CN
ST=GD
L=FS
O=EFLY
OU=EFLY
CN=EFLY
[ req_ext ]
subjectAltName = @alt_names
[alt_names]
DNS.1 = hostname.domain.tld
DNS.2 = hostname
IP.1 = 10.20.30.40
IP.2 = 10.20.30.40
openssl req -new -key serverkey.pem -out serverkey.csr -config server.info
(7)为客户机创建证书签名请求:
openssl req -new -key clientkey.pem -out clientkey.csr -subj "/C=CN/O=EFLY/OU=virtualization/CN=KVM"
(8)创建客户机和服务器证书
openssl x509 -req -days 3650 -in clientkey.csr -CA cacert.pem -CAkey cakey.pem -set_serial 1 -out clientcert.pem
openssl x509 -req -days 3650 -in serverkey.csr -CA cacert.pem -CAkey cakey.pem -set_serial 94345 -out servercert.pem
(9)检查密钥:
openssl rsa -noout -text -in clientkey.pem
openssl rsa -noout -text -in serverkey.pem
(10)检查证书:
openssl x509 -noout -text -in clientcert.pem
openssl x509 -noout -text -in servercert.pem
路径说明:
路径 | 设备 | 描述 |
/etc/pki/CA/cacert.pem | 客户端和服务端 | 私有CA证书 |
/etc/pki/libvirt/private/serverkey.pem | 服务端 | Server私有秘钥 |
/etc/pki/libvirt/servercert.pem | 服务端 | Server自签证书 (私有CA颁发) |
/etc/pki/libvirt/private/clientkey.pem | 客户端 | Client私有秘钥 |
/etc/pki/libvirt/clientcert.pem | 客户端 | Client自签证书 (私有CA颁发) |
mkdir -p /etc/pki/CA
(1)将认证中心 (CA) 证书 cacert.pem 文件复制到 /etc/pki/CA/cacert.pem
scp [proxy_ip]:/opt/cert_files/cacert.pem /etc/pki/CA/cacert.pem
(2)
*创建 /etc/pki/libvirt 目录。
mkdir /etc/pki/libvirt
*将 servercert.pem 服务器证书文件复制到 /etc/pki/libvirt/servercert.pem。
scp [proxy_ip]:/opt/cert_files/servercert.pem /etc/pki/libvirt/.
*创建 /etc/pki/libvirt/private 目录。
mkdir /etc/pki/libvirt/private
*将 serverkey.pem 服务器密钥文件复制到 /etc/pki/libvirt/private/serverkey.pem 目录。
scp [proxy_ip]:/opt/cert_files/serverkey.pem /etc/pki/libvirt/private/.
*确保只有 root 用户才能够访问专用密钥。
chmod -R o-rwx /etc/pki/libvirt/private
(3)验证这些文件是否已正确放置:
find /etc/pki/CA/*|xargs ls -l
ls -lR /etc/pki/libvirt
配置libvirt
(1)生成 /etc/default/libvirtd 文件和 /etc/libvirt/libvirtd.conf 文件的副本。
(2)编辑 /etc/default/libvirtd 文件
# Start libvirtd to handle qemu/kvm:
start_libvirtd="yes"
# options passed to libvirtd, add "-l" to listen on tcp
修改前
- libvirtd_opts=""
修改后
+ libvirtd_opts="-l"
(3)编辑 /etc/libvirt/libvirtd.conf 文件,并在 libvirtd.conf 文件中使用 tls_allowed_dn_list 伪指令配置一组允许的主题。
以下示例显示原始文件中的更改:
修改前
- #tls_allowed_dn_list = ["DN1", "DN2"]
修改后
+tls_allowed_dn_list = ["C=*,O=EFLY,OU=virtualization,CN=*"]
修改前
- listen_tcp = 0
修改后
+ listen_tls = 1
+ tls_port = "16514"
它将可接受的客户机证书限制为具有 O=IBM,OU=virtualization 值的证书,而系统可能会对国家或地区 (C) 和公共名 (CN) 分配任何值。主题中字段的顺序必须与您创建证书时使用的顺序相同。
(4)重新启动 libvirtd 守护程序服务,以使更改生效:
/etc/init.d/libvirtd restart
Stopping libvirtd daemon: [ OK ]
Starting libvirtd daemon: [ OK ]
(1)将认证中心 (CA) 证书 cacert.pem 从 PowerKVM 主机复制到管理站 /etc/pki/CA/ 目录。请勿变更文件名。
scp [proxy_ip]:/opt/cert_files/cacert.pem /etc/pki/CA/
(2)
*创建 /etc/pki/libvirt 目录。
mkdir -p /etc/pki/libvirt/
*将客户机证书 clientcert.pem 复制到 /etc/pki/libvirt/ 目录。
scp [proxy_ip]:/opt/cert_files/clientcert.pem /etc/pki/libvirt/.
*创建 /etc/pki/libvirt/private 目录。
mkdir -p /etc/pki/libvirt/private
*将客户机密钥 clientkey.pem 从 PowerKVM 主机复制到 /etc/pki/libvirt/private/ 目录。
scp [proxy_ip]:/opt/cert_files/clientkey.pem /etc/pki/libvirt/private/.
*使用缺省文件名称,并确保只有 root 用户才能够访问专用密钥。
chmod -R o-rwx /etc/pki/libvirt/private
(3)验证这些文件是否已正确放置:
ls -lR /etc/pki/libvirt/
可以使用nginx 或者 haproxy等工具
(1)如使用haproxy:
apt-get install haproxy
(2)每一台VM都需要做一个端口代理, 端口号:165+KVM服务器的ip位数
vim /etc/haproxy/haproxy.cfg
listen kvm-proxy-ip位数
bind 0.0.0.0:165ip位数
mode tcp
use_backend kvm-tls-ip位数
backend kvm-tls-ip位数
mode tcp
server kvm-tls-35 10.10.10.35:16514 -一定是16514
如
listen kvm-proxy-35
bind 0.0.0.0:16535
mode tcp
use_backend kvm-tls-35
backend kvm-tls-35
mode tcp
server kvm-tls-35 10.10.10.35:16514 -一定是16514
(3)启动haproxy
service haproxy restart
(4)验证连通
virsh -c qemu+tls://KVM_PROXY:16515/system hostname
ubuntu-kvm35
返回正常, 则完成远程
(1)libvirt sasl配置在/etc/sasl2/libvirt.conf,Tls是tcp的加密传输协议,所以mech_list:需要设置成digest-md5。
vim /etc/sasl2/libvirt.conf
- 修改前, + 修改后
- #sasldb_path: /etc/libvirt/passwd.db
+ sasldb_path: /etc/libvirt/passwd.db
- mech_list: gssapi
# mech_list: gssapi
mech_list: digest-md5 # mandatory for TCP connections
(2)创建用户
/etc/libvirt# saslpasswd2 -a libvirt efly
Ps: 密码123456
Password:
Again (for verification):
(3)指定密码库
/etc/sasl2# sasldblistusers2 -f /etc/libvirt/passwd.db
efly@ubuntu-kvm35: userPassword
(4)修改libvirtd.conf
修改/etc/libvirt/libvirtd.conf
修改前
- #auth_tls = "none"
修改后
+auth_tls = "sasl"
(5)重启libvirtd
systemctl restart libvirtd
(6)centos的客户端需要安装:(否则sasl 校验错误)
yum -y install cyrus-sasl-md5
(7)测试连接
virsh -c qemu+tls://PROXY:16535/system hostname
Please enter your authentication name: efly
Please enter your password:
ubuntu-kvm35
睿江云官网链接:https://www.eflycloud.com/home?from=RJ0032