ssh 免密登录_技术漫谈 |非交互式大规模主机群信任登录认证及其容器化实现

d5d2642c93b33bc43950a4f8bb91ed6f.png

原创作者: 清如许

导 读

阅读本文您将了解到:配置免密信任登录会极大地便利Ansible/Breeze 工具管理主机群;应用非交互式方法安全便捷地建立主机间 SSH 信任登录关系;应用多并发技术快速信任登录到1 万台规模的主机群;二步法快速构建容器镜像的方法,速度快到以秒为单位。

一、前 言

一个跨境旅行的例子

开头先举个例子:有内地居民想到去香港旅行,旅客从北京南站或者深圳北站出发,坐上直达香港西九龙站的高铁列车。如果在越过深港边界线时,边检人员对每一位旅客都查验港澳通行证或者护照,那将是不可想象的,工作量巨大而且时间很短,验证工作几乎无法完成。实际的入港通关是在旅客到达香港西九龙站后,在西九龙站入境大厅查验旅行证件、办理通关。

IT 运维自动化场景

在 IT 运维中,也有类似的需求场景。例如,在管理主机上运行 IT 运维工具 Ansible,通过 SSH 在一组被管理主机上远程运行命令,可以复制文件、新建目录和查看进程状态等。这里的登录请求就是一次跨境旅行,管理主机相当于出发车站,被管理主机是到达车站(香港九龙西站)。

主机的账号和密码是保护主机不受非法入侵的安全钥匙,因此账号和密码被严格地保护起来,以免主机安全受到威胁。同一类型的操作系统,一般都有共同的基本账号,例如 root, 广为公众所知悉。相对于保护公开的账号,保护登录密码受到 IT 管理人员的更多重视。

虽然主机的密码安全很重要,但在某些情况下,登录主机的安全入口也会对受到信任的主机门户大开,不需要输入账号和密码就能直接登录,就像开通了直达主机内部的直通快车。

在用 Ansible 管理远程主机时,如果还需要管理员输入账号和密码,那会非常地麻烦。先不说复杂的密码很难记住,Ansible 是自动化 IT 运维工具,在执行自动化任务管理大批量的主机时,如果还需要逐个输入主机密码,自动化任务将降级为半自动任务甚至手动任务, 效率极其低下。如果把主机的账号和密码存为配置文件,自动化程序在运行时读入密码,这样可以免去管理员输入密码的烦恼,但也存在密码泄露的风险,反而把主机安全变为不安全。

睿云智合(wise2c.com)的 Breeze 是经过 CNCF 认证过的 Kubernetes 官方安装工具软件。Breeze 安装部署 Kubernetes 时就用到了 Ansible 在远程主机批量执行命令的能力。Breeze 是开 源 项 目 , 源 代 码 托 管 在 Github 源 码 仓 库 , 地 址 是 :https://github.com/wise2c-devops/breeze 。

信任登录认证,就是解决免密登陆的一个办法。一次信任认证,多次免密登录。

大规模主机群的需求

虽然免密登录能便利运维工作,但是面对集群内的主机群,动辄几十台上百台主机,初次信任认证时手工输入一百次密码工作量也不少。

本文作者的小目标是轻松管理一百台主机,大目标是管理一万台主机也不毫不费力。输入一万次密码对管理员来说,无异于暗无天日的苦力活。

写作本文的目的是自动化完成信任认证工作,把管理员从繁重的体力活中解救出来,这样留出时间从事有价值的工作,或者从事不可被机器替代的工作。

每个地方都改进一点,自动化多一点,IT 世界将变得轻松而有乐趣。

把程序装进容器里

本文开发的程序,也需要运行在一个操作系统环境,对不同运行环境的适应将不得不面对大量的技术细节。作者打算把程序放在容器内运行,这样只需要适应唯一一个容器镜像操作系统,会大大简化开发和维护工作量。

编写本文程序的初衷是缘起于开发一个面向主机、网络、存储、K8s、Docker 和各类服务软件的故障诊断系统,而本文程序是为了在诊断主机和被诊断主机群之间建立免密信任登录,是故障诊断系统的一个子功能。本文程序最先运行,一次建立信任,多次运行诊断。故障诊断程序拟部署在容器内运行,作为先行功能,在容器内运行建信程序(建立信任程序),是自然而然的,也是必须要优先解决的。

让容器镜像构建更快一些

用户与故障诊断系统之间有少量的交互,容器镜像应当预先安装交互操作所必须的系统组件,容器镜像规模达到 700MB。如果每次制作镜像都从零开始,从互联网公共仓库安装系统组件会比较耗时,本文尝试将镜像制作过程拆分为两步,引入中间镜像,把镜像制作时间从十几分钟缩短到几秒钟。

源代码分享

文章末尾有彩蛋喔。本文的源代码已经上传到 git 源代码仓库,项目网址和下载方法在文章的末尾。

二、信任登录原理

信任登录,或者说免密登陆,就是比较好的解决办法。

预先在管理主机和被管理主机之间建立信任关系,以后来自管理主机的 SSH 登录请求, 都将免输入密码直接放行。在这里,管理主机是被信任的,称作被信任主机,被管理主机是信任关系的主体,称作信任主机。管理和被管理,被信任和信任,管理主机是被信任的,被管理主机是发起信任的,正好相反,是一组反对称关系。

信任和被信任的关系并不是基于源 IP 地址的。因为 IP 地址可以被伪装,入侵主机很容伪装成被信任的主机 IP 而获得信任,所以基于源 IP 地址的方案不可行。

SSH 通信是以 RSA 公钥密码体制为基础实现的,私钥和公钥互为对称,秘钥的主人持有私钥和公钥,公钥对外公开。RSA 密钥的主人用私钥给明文加密,接收方用公钥解密,得到原始明文。利用这一原理,RSA 也可以用于数字签名,秘钥的主人用私钥给信息片段签名, 接收方用公钥验证签名后的信息片段,确定是否从密钥主人发出。验证数字签名可以排除伪造的签名,因为伪造者不持有私钥。

数字签名可以用于单向验证 SSH 信任关系。其原理是:主机 A(被信任主机)持有私钥, 向主机 B(信任主机)发起登录请求,发送签名信息给主机 B(信任主机),主机 B 用公钥验证签名信息。只有用主机 A 私钥签过名的信息片段才能通过主机 B(信任主机)的验证(主机信任登录认证)。主机 A(被信任主机)通过信任登录认证,允许免密登录,而其他没有被信任的主机不能免密登录。

主机 B 会把主机 A(被信任主机)的公钥信息添加到主机 B 本地的~/.ssh/authorized_keys 文件末尾。只有主机 B 上的 root 用户才有权限读写 authorized_keys 文件,其他用户无访问权限。

查看主机 B 本地授权文件的命令和输出结果如下:

[root@dev-10 ~]# [root@dev-10 ~]# ls -ltr ~/.ssh/authorized_keys -rw------ 1 root root 19712 Aug 30 00:26 /root/.ssh/authorized_keys[root@dev-10 ~]# tail -1 ~/.ssh/authorized_keys ssh-rsaAAAAB3NzaC1yc2EAAAADAQABAAABAQCh3rFcy99QJI2+rlwhA68H/H1KOY3yMAv1/pxyM7pbLj/ m0EO1QrsiL8eQVbxeiiKPm4E+V5hQiMWSXgiwZ/53y2+153TyhmUtnnCEyg/Mxx6544yKeDPq8OeX cWw7SVcVSHfvp6/C/p+P/rTPBH7+7ydDCCr4o0mFzMxdjsdndzdGvMqeuyQxiq8vdoLivk4Ke6opcf7+jG5otxr4wzAaSp1DXNOSAy/ZT2F/yvTudaDTt85aJeYf6HxPjQ1IArdZrbTxJJd5h7YPgBwK+XADkLbrX 10HcBcodtd6+24lCJlmUqRkrSWli/Q3dx/Virb3m8aYTARon5SPVq1VgnwN root@30ffac589d2f

持有了对方主机的公钥就可以允许对方免密登录进来,那会不会造成免密登录的滥用呢?应该不会,因为对方主机的公钥不是想进就能进来的,对方主机发起复制公钥 ID 到本主机的请求,必须输入正确密码并且通过认证才能复制成功。

初次建立信任登录关系时必须输入密码。一次建立信任,多次免密登录。

信任主机和被信任主机是多对多的关系。一台主机的公钥允许被复制到多台主机,也就是可以免密登录到多台信任主机,这也就为管理大规模集群奠定了基础。一台信任主机也可以接收多台被信任主机的秘钥,可以被多台主机免密登录进来,被多台管理主机所管理。

交互式流程

几个步骤:生成 RSA 密钥对、复制公钥到信任主机。

建立信任关系后,免密登录到主机,即使修改了登录密码也不影响已建立信任关系主机的正常免密登录。先设立统一密码,建立信任关系后,再修改密码(对各主机各不相同的密码,或者自动生成的动态密码),防止因密码失窃而遭受损失。

公钥已存在信任主机的本地文件。私钥存在被信任主机的本地文件。

三、信任登录实现

主机认证配置文件

本程序的主机认证配置文件由两段组成:第一段是默认配置,只有一行;第二段是目标主机配置,允许多行。

默认配置格式:

默认配置以 default 开头,分别是默认的登录用户、默认的登录密码和默认的端口。

## IP user password port default root mypassword 22

目标主机配置格式:

主机配置行的格式与默认配置行格式相同,不同之处是以主机 IP 或者域名开头,主机IP 是必填项。其余三项属性可以省略,省略的属性自动以默认配置行的对应项填充。省略的属性如果位于一行的中间,必须以一对长度为空的双引号或单引号占位。

## IP user password port192.168.1.11 “” mypassword 22

配置主机的几个场景

所有主机的登录账号、账号密码相同。配置方法是默认配置完整,目标主机行只保留主 机 IP 或者域名。在新建集群时,可以把所有主机的 root 密码设为相同的静态值,便于批量建立信任登录,之后,管理员可以修改密码,或者使用动态密码。

对于不同的场景,具体配置方法如下:

主机的登录用户相同、密码各不相同。配置方法是默认配置完整(也可能有些主机密码 相同),目标主机行配置主机 IP、密码,登录用户以占位符替代,SSH 端口不填。

主机的登录用户、登录密码和端口各不相同。可以不配置默认行,主机行的主机 IP、登录用户、登录密码和 SSH 端口填写完整。这种情况比较少见,要么是对安全性要求高,不便于使用默认端口,要么是主机有特殊要求。

对目标主机群完成信任登录认证后,不再需要密码属性,可以从配置文件删除密码属性,或者以占位符代替,或者删除整个主机认证配置文件。

信任登录实现流程

信任登录主流程:

S1、生成 RSA 密钥对和证书,在本地主机安装必须的软件包 ssh-clients 和 expect 等。对软件包自动检查、自动安装。

S2、主进程读主机列表文件 hosts-auth.txt。

S3、从主机行解析出主机 IP、登录用户、登录密码和 SSH 端口等属性。对于属性值为空的属性,以默认值填充。

S4、调用 expect 类型脚本 expect-ssh-copy-id.sh,进入非交互式子流程。子流程将完成一个具体主机的信任登录认证。

S5、跳转到 S3 步继续处理,直到处理完列表中的所有主机。

S6、输出统计信息,结束退出。

非交互式 expect 子流程:

S1、expect 脚本从命令行获得主机 IP、登录用户、登录密码和端口等参数。

S2、spawn 孵化子进程调用 ssh-copy-id 执行信任登录。

S3、进入 expect 期待/应答模式,对对方主机给与提示信息,自动识别,并自动应答。例如,当收到提示"password:"时,输出应答"${SSH_PASS}"。

S4、完成单次信任登录认证,结束。

信任登录源代码

主流程源代码:

# ssh.sh## enable trusting on this local host by remote hosts function ssh_remote_trust(){ ## generate rsa-key locally  ssh_gen_rsakey; ## check and install packages  ssh_local_check_install "expect" "expect" ssh_local_check_install "ssh-copy-id" "openssh-clients" ## get ssh default params ssh_default=$(cat ${HOSTS_AUTH_FILE} | grep default)  ssh_default_user=$(echo ${ssh_default} | awk '{print $2}')  ssh_default_pass=$(echo ${ssh_default} | awk '{print $3}')  ssh_default_port=$(echo ${ssh_default} | awk '{print $4}') ssh_default_user=${ssh_default_user:-root}  ssh_default_port=${ssh_default_port:-${SSH_PORT_DEFAULT}}  ## echo and log default ssh connect's param logger_debug "ssh_default=${ssh_default}" logger_debug "ssh_default_pass=${ssh_default_pass}" logger_info "ssh_default_user=${ssh_default_user}, ssh_default_pass=***, ssh_default_port=${ssh_default_port}" ## loop for hosts list _count=0 _hosts_auth=$(cat ${HOSTS_AUTH_FILE} | grep -v "default" | grep -v "[" | grep -v "]" | grep -v "#" | awk 'BEGIN{OFS=
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值