searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

通过Ansible控制主机异常的案例解析

2024-06-21 09:38:24
32
0

背景

Ansible

是一个开源的自动化平台,它允许系统管理员自动化云服务、配置管理、应用部署、任务执行等任务。Ansible使用YAML语言编写的剧本(Playbooks),这些剧本描述了如何配置系统或应用程序。

SSH

即安全外壳协议(Secure Shell Protocol),是一种加密的网络协议,用于在不安全的网络上安全地访问远程计算机。SSH提供了一个安全的通道,允许用户执行远程命令、传输文件以及进行端口转发等操作。

案例

问题描述

在日常持续集成与持续部署的开发中,会使用Ansible工具来实现自动化的主机部署。

1项目结构

我们会有这样的Ansible配置结构:

|--hosts
|--site.yml
|--roles
    |--install
        |--tasks
            |--main.yml

2任务配置

具体的,会配置这样的一个Ansible任务,实现登陆到目标主机执行命令:

- name: Check package_storage_path
  file:
    path: "{{ package_storage_path }}"
    state: directory
    mode: 0777
    owner: "{{ ansible_user }}"
    group: "{{ ansible_user }}"
  tags: create_package_storage_path

另外,主要的hosts文件配置为:

目标ip ansible_host=目标ip ansible_ssh_port=目标端口 ansible_user=目标主机用户名 ansible_ssh_pass=目标主机密码 ansible_ssh_common_args='-o StrictHostKeyChecking=no'

3任务运行

执行该启动命令:ansible-playbook -i hosts site.yml

4常见问题

但是,经常会遇到问题,导致执行命令失败:

5问题排查

我们到目标主机上通过 journalctl -u sshd 命令查看日志,会发现网络是通的,有收到请求;

但是ssh连接,发现客户端的公钥不正确之后,就没有下文了:

Jun 21 10:34:03 cc-rqh-gztest63-x86-controller-1 sshd[1134801]: Connection from 请求ip port 请求端口 on 目标ip port 目标端口

Jun 21 10:34:03 cc-rqh-gztest63-x86-controller-1 sshd[1134801]: Failed publickey for root from请求ip port 请求端口 ssh2: RSA SHA256:6GGbGKD/9nYZSb0yS7pSRKxRBUiUQnwOBpI55PIYuir

Jun 21 10:34:03 cc-rqh-gztest63-x86-controller-1 sshd[1134801]: Connection closed by authenticating user 用户账号 请求ip port 请求端口 [preauth]

解决方案

1调整执行命令

改为:ansible-playbook -i hosts site.yml --timeout 60 --ssh-extra-args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'

2任务成功

3日志查看

  • 在目标主机上通过 journalctl -u sshd 命令查看日志:

Jun 21 10:45:53 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Connection from 请求ip port 请求端口 on 目标ip port 目标端口

Jun 21 10:45:53 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Failed publickey for root from 请求ip port 请求端口 ssh2: RSA SHA256:6GGbGKD/9nYZSb0yS7pSRKxRBUiUQnwOBpI55PIYuir

Jun 21 10:45:53 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Accepted password for 目标主机用户名 from 请求ip port 请求端口 ssh2

Jun 21 10:45:53 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: pam_unix(sshd:session): session opened for user 目标主机用户名(uid=0) by (uid=0)

Jun 21 10:45:53 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Starting session: command on pts/9 for 目标主机用户名 from 请求ip port 请求端口 id 0

Jun 21 10:45:54 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Close session: user root from 请求ip port 请求端口 id 0

Jun 21 10:45:54 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Connection closed by 请求ip port 请求端口

Jun 21 10:45:54 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: pam_unix(sshd:session): session closed for user root

Jun 21 10:45:54 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Transferred: sent 2608, received 2548 bytes

Jun 21 10:45:54 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Closing connection to 请求ip port 请求端口

 

  • 发现在客户端的公钥校验失败后,客户端主动使用账号、通过密码连接上了,可以成功在主机执行命令。

原理解析

问题原因

  • 网络抖动

  • 目标主机的密钥变化

解决方式

给 ansible-playbook -i hosts site.yml 命令添加参数解决问题:

--timeout 60 --ssh-extra-args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'

参数意义

  • --timeout 60:该选项设置了连接到远程主机的超时时间,单位是秒;加大超时时间,可避免网络抖动。

  • --ssh-extra-args:该选项可传递额外的SSH参数给Ansible。

  • -o StrictHostKeyChecking=no:该参数告诉SSH不要进行严格的主机密钥检查。通常,SSH客户端会检查服务器的公钥是否在known_hosts文件中,以防止中间人攻击。使用这个选项会禁用这个检查,使得SSH连接不会因未知的主机密钥而失败。

  • -o UserKnownHostsFile=/dev/null:该参数指定SSH不使用用户的known_hosts文件,而是写入到/dev/null,即黑洞设备。这意味着SSH不会记录任何主机密钥信息,也不会检查现有的记录。在自动化脚本中,可避免因known_hosts文件中的数据变化而导致的问题。

中间人攻击

是一种网络攻击技术,攻击者在通信双方之间插入自己,截获并可能篡改双方的通信数据。

为防止中间人攻击,SSH客户端在首次连接到服务器时,会要求用户确认服务器的公钥指纹,以防止攻击者使用伪造的公钥,如:

The authenticity of host '目标ip (目标ip)' can't be established.

ECDSA key fingerprint is SHA256:AOEUgBJnuTpZVLTMLNcBht0XDYyamkgDXZpeeyhfuil.

Are you sure you want to continue connecting (yes/no)?

总结

这种解决方式通过避免主机密钥检查,解决目标主机因为主机IP变化、重装系统等原因导致无法控制的问题,通常用于自动化环境或持续集成/持续部署流程中,但在生产环境中,考虑到中间人攻击,应该谨慎使用该方式。

0条评论
0 / 1000
g****n
3文章数
0粉丝数
g****n
3 文章 | 0 粉丝
g****n
3文章数
0粉丝数
g****n
3 文章 | 0 粉丝
原创

通过Ansible控制主机异常的案例解析

2024-06-21 09:38:24
32
0

背景

Ansible

是一个开源的自动化平台,它允许系统管理员自动化云服务、配置管理、应用部署、任务执行等任务。Ansible使用YAML语言编写的剧本(Playbooks),这些剧本描述了如何配置系统或应用程序。

SSH

即安全外壳协议(Secure Shell Protocol),是一种加密的网络协议,用于在不安全的网络上安全地访问远程计算机。SSH提供了一个安全的通道,允许用户执行远程命令、传输文件以及进行端口转发等操作。

案例

问题描述

在日常持续集成与持续部署的开发中,会使用Ansible工具来实现自动化的主机部署。

1项目结构

我们会有这样的Ansible配置结构:

|--hosts
|--site.yml
|--roles
    |--install
        |--tasks
            |--main.yml

2任务配置

具体的,会配置这样的一个Ansible任务,实现登陆到目标主机执行命令:

- name: Check package_storage_path
  file:
    path: "{{ package_storage_path }}"
    state: directory
    mode: 0777
    owner: "{{ ansible_user }}"
    group: "{{ ansible_user }}"
  tags: create_package_storage_path

另外,主要的hosts文件配置为:

目标ip ansible_host=目标ip ansible_ssh_port=目标端口 ansible_user=目标主机用户名 ansible_ssh_pass=目标主机密码 ansible_ssh_common_args='-o StrictHostKeyChecking=no'

3任务运行

执行该启动命令:ansible-playbook -i hosts site.yml

4常见问题

但是,经常会遇到问题,导致执行命令失败:

5问题排查

我们到目标主机上通过 journalctl -u sshd 命令查看日志,会发现网络是通的,有收到请求;

但是ssh连接,发现客户端的公钥不正确之后,就没有下文了:

Jun 21 10:34:03 cc-rqh-gztest63-x86-controller-1 sshd[1134801]: Connection from 请求ip port 请求端口 on 目标ip port 目标端口

Jun 21 10:34:03 cc-rqh-gztest63-x86-controller-1 sshd[1134801]: Failed publickey for root from请求ip port 请求端口 ssh2: RSA SHA256:6GGbGKD/9nYZSb0yS7pSRKxRBUiUQnwOBpI55PIYuir

Jun 21 10:34:03 cc-rqh-gztest63-x86-controller-1 sshd[1134801]: Connection closed by authenticating user 用户账号 请求ip port 请求端口 [preauth]

解决方案

1调整执行命令

改为:ansible-playbook -i hosts site.yml --timeout 60 --ssh-extra-args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'

2任务成功

3日志查看

  • 在目标主机上通过 journalctl -u sshd 命令查看日志:

Jun 21 10:45:53 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Connection from 请求ip port 请求端口 on 目标ip port 目标端口

Jun 21 10:45:53 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Failed publickey for root from 请求ip port 请求端口 ssh2: RSA SHA256:6GGbGKD/9nYZSb0yS7pSRKxRBUiUQnwOBpI55PIYuir

Jun 21 10:45:53 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Accepted password for 目标主机用户名 from 请求ip port 请求端口 ssh2

Jun 21 10:45:53 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: pam_unix(sshd:session): session opened for user 目标主机用户名(uid=0) by (uid=0)

Jun 21 10:45:53 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Starting session: command on pts/9 for 目标主机用户名 from 请求ip port 请求端口 id 0

Jun 21 10:45:54 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Close session: user root from 请求ip port 请求端口 id 0

Jun 21 10:45:54 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Connection closed by 请求ip port 请求端口

Jun 21 10:45:54 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: pam_unix(sshd:session): session closed for user root

Jun 21 10:45:54 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Transferred: sent 2608, received 2548 bytes

Jun 21 10:45:54 cc-rqh-gztest63-x86-controller-1 sshd[1227554]: Closing connection to 请求ip port 请求端口

 

  • 发现在客户端的公钥校验失败后,客户端主动使用账号、通过密码连接上了,可以成功在主机执行命令。

原理解析

问题原因

  • 网络抖动

  • 目标主机的密钥变化

解决方式

给 ansible-playbook -i hosts site.yml 命令添加参数解决问题:

--timeout 60 --ssh-extra-args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'

参数意义

  • --timeout 60:该选项设置了连接到远程主机的超时时间,单位是秒;加大超时时间,可避免网络抖动。

  • --ssh-extra-args:该选项可传递额外的SSH参数给Ansible。

  • -o StrictHostKeyChecking=no:该参数告诉SSH不要进行严格的主机密钥检查。通常,SSH客户端会检查服务器的公钥是否在known_hosts文件中,以防止中间人攻击。使用这个选项会禁用这个检查,使得SSH连接不会因未知的主机密钥而失败。

  • -o UserKnownHostsFile=/dev/null:该参数指定SSH不使用用户的known_hosts文件,而是写入到/dev/null,即黑洞设备。这意味着SSH不会记录任何主机密钥信息,也不会检查现有的记录。在自动化脚本中,可避免因known_hosts文件中的数据变化而导致的问题。

中间人攻击

是一种网络攻击技术,攻击者在通信双方之间插入自己,截获并可能篡改双方的通信数据。

为防止中间人攻击,SSH客户端在首次连接到服务器时,会要求用户确认服务器的公钥指纹,以防止攻击者使用伪造的公钥,如:

The authenticity of host '目标ip (目标ip)' can't be established.

ECDSA key fingerprint is SHA256:AOEUgBJnuTpZVLTMLNcBht0XDYyamkgDXZpeeyhfuil.

Are you sure you want to continue connecting (yes/no)?

总结

这种解决方式通过避免主机密钥检查,解决目标主机因为主机IP变化、重装系统等原因导致无法控制的问题,通常用于自动化环境或持续集成/持续部署流程中,但在生产环境中,考虑到中间人攻击,应该谨慎使用该方式。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0