在 Ubuntu 系统上安装 Ansible 及相关依赖:
展开代码# 1. 更新软件包索引 sudo apt update -y # 2. 安装 ansible sudo apt install -y ansible # 3. 安装 sshpass(用于密码认证场景) sudo apt install -y sshpass
说明:
sshpass 用于在命令行中传递 SSH 密码,适用于初次配置或无法使用密钥认证的环境当需要批量修改多台服务器的用户密码时,直接使用明文密码存在安全隐患。推荐使用 SHA512 哈希值 进行密码设置,避免密码在剧本中暴露。
展开代码# 交互输入新密码,得到 sha512 哈希 openssl passwd -6 # 输入:NewPass123 # 输出:$6$rounds=5000$abc123...
创建 hosts 文件定义目标主机:
展开代码[gpu-nodes-1] 10.73.103.160 [gpu-nodes-2] 10.73.103.157 [gpu-nodes-1:vars] ansible_user=user ansible_password=userroots [gpu-nodes-2:vars] ansible_user=user ansible_password=1qaz@WSX3edc [all:vars] ansible_port=9922 ansible_ssh_common_args="-o StrictHostKeyChecking=no" ansible_ssh_control_path=/dev/null ansible_ssh_pipelining=no
展开代码--- - name: Batch change user password hosts: all become: yes # 需要 root 权限改 /etc/shadow vars: target_user: user # 要改密码的账号 tasks: - name: Update password for {{ target_user }} ansible.builtin.user: name: "{{ target_user }}" password: "$6$hmFeP8jD4afe0rbQ$cfjKJAMeYA7NiaGLLLVO3sY41l1RRCDXVL.lrpHF0CgR5.eImvk.ImCeq6BnK8I.ZKJvOT9trkV1mwtcqAUyB1" update_password: always notify: restart ssh handlers: - name: restart ssh ansible.builtin.systemd: name: sshd state: restarted
展开代码ansible-playbook change_password.yml -i hosts
定期验证服务器账号密码的有效性,及时发现密码过期、账号锁定等问题。
创建 hosts 文件定义目标主机:
展开代码[gpu-nodes-1] 10.73.103.160 [gpu-nodes-2] 10.73.103.157 [gpu-nodes-1:vars] ansible_user=user ansible_password=userroots [gpu-nodes-2:vars] ansible_user=user ansible_password=1qaz@WSX3edc [all:vars] ansible_port=9922 ansible_ssh_common_args="-o StrictHostKeyChecking=no" ansible_ssh_control_path=/dev/null ansible_ssh_pipelining=no
展开代码--- - name: Batch verify password login hosts: all gather_facts: no # 加快执行 tasks: - name: Ping host with given password ansible.builtin.ping: register: ping_result - name: Print reachability ansible.builtin.debug: msg: "{{ inventory_hostname }} password-login {{ 'SUCCESS' if ping_result.ping == 'pong' else 'FAILED' }}"
展开代码# 使用加密密码文件 ansible-playbook check_password.yml -i hosts --vault-password-file .vault_pass
统一加固 SSH 服务配置,包括禁用 root 登录、修改端口、限制算法等。
创建 hosts 文件定义目标主机:
展开代码;[gpu-nodes-1] ;10.73.103.160 [gpu-nodes-2] 10.73.103.158 ;[gpu-nodes-1:vars] ;ansible_user=user ;ansible_password=userroot [gpu-nodes-2:vars] ansible_user=user ansible_password=userroots [all:vars] ansible_port=22 ansible_ssh_common_args="-o StrictHostKeyChecking=no" ansible_ssh_control_path=/dev/null ansible_ssh_pipelining=no
展开代码--- - name: Memory execute chang_ssh.sh (zero residue) hosts: all become: yes serial: 1 # 逐台,防锁死 vars: script_local: ./chang_ssh.sh # 本地路径 tasks: - name: 1. 内存执行脚本(远程无落盘) ansible.builtin.script: cmd: "{{ script_local }}" register: script_out timeout: 120 changed_when: true - name: 2. 打印脚本返回 ansible.builtin.debug: msg: | {{ inventory_hostname }} 脚本返回: stdout: {{ script_out.stdout }} stderr: {{ script_out.stderr }} rc: {{ script_out.rc }} - name: 3. 语法检查失败 → 立即回滚(内存) ansible.builtin.script: cmd: "{{ script_local }} rollback" # 你的脚本支持 rollback 参数 when: script_out.rc != 0 failed_when: false # 回滚本身失败也不 stop - name: 4. 脚本成功 → 校验新端口连通性 ansible.builtin.wait_for: port: 9922 host: "{{ inventory_hostname }}" delay: 3 timeout: 30 delegate_to: localhost when: script_out.rc == 0 register: wait_result - name: 5. 连通失败 → 内存回滚 ansible.builtin.script: cmd: "{{ script_local }} rollback" delegate_to: localhost when: - script_out.rc == 0 - wait_result is failed
展开代码#!/bin/bash # File: chang_ssh.sh # Usage: sudo bash chang_ssh.sh # sudo bash chang_ssh.sh rollback set -euo pipefail BACKUP="/etc/ssh/sshd_config.bak.$(date +%F_%T)" TEST_CONF="/etc/ssh/sshd_config.d/test.conf" # ========== 正式逻辑 ========== if [[ "${1:-}" != "rollback" ]]; then echo "==== 1. 备份原配置 ====" cp /etc/ssh/sshd_config "$BACKUP" echo "已备份到 $BACKUP" echo "==== 2. 创建 test.conf ====" cat > "$TEST_CONF" <<'EOF' PermitRootLogin no PasswordAuthentication yes Port 9922 EOF echo "==== 3. 修改主配置,仅加载 test.conf ====" sed -i "s|^Include /etc/ssh/sshd_config\\.d/\\*\\.conf$|Include $TEST_CONF|" /etc/ssh/sshd_config echo "==== 4. 语法检查 ====" if ! sshd -t; then echo "❌ 配置有误,未重启 sshd,请检查" exit 1 fi echo "==== 5. 重启 sshd ====" systemctl restart sshd echo "✅ 已切换为仅加载 $TEST_CONF" echo "确认生效值:" sshd -T | grep -E '^(port|permitrootlogin|passwordauthentication)' exit 0 fi # ========== 回滚逻辑 ========== latest_bak=$(ls -t /etc/ssh/sshd_config.bak.* 2>/dev/null | head -n1) if [[ -z "$latest_bak" ]]; then echo "❌ 未找到备份文件,无法回滚" exit 1 fi cp "$latest_bak" /etc/ssh/sshd_config rm -f /etc/ssh/sshd_config.d/test.conf systemctl restart sshd echo "🔙 已回滚到 $latest_bak"
⚠️ 重要:修改 SSH 配置前务必:
sshd -t)ignore_errors: yes 和 serial: 1 分批执行批量创建系统用户并配置 sudo 权限,适用于新员工入职或临时账号场景。
展开代码# 交互输入新密码,得到 sha512 哈希 openssl passwd -6 # 输入:NewPass123 # 输出:$6$rounds=5000$abc123...
创建 hosts 文件定义目标主机:
展开代码[gpu-nodes-1] 10.73.103.160 [gpu-nodes-2] 10.73.103.157 [gpu-nodes-1:vars] ansible_user=user ansible_password=userroots [gpu-nodes-2:vars] ansible_user=user ansible_password=userroots [all:vars] ansible_port=9922 ansible_ssh_common_args="-o StrictHostKeyChecking=no" ansible_ssh_control_path=/dev/null ansible_ssh_pipelining=no
展开代码--- - name: Batch add test account hosts: all become: yes vars: # ← 直接写这里,角色变量可删 test_user: test test_uid: 0 # 0=自动 test_home: /home/test test_shell: /bin/bash test_password: '$6$jqchN5X8WaX2a3DQ$VK9KdfYSLBPiYpaKTulsLPX8ey6sE9iKsbZf1CXdd4lj8/j5SFTk/dohvwQcmpF2mSP0Hsv5A8BEq3K/qKEAb0' # 空=不设置密码 test_pubkey: '' # 空=不注入密钥 test_sudo: yes # yes=放 wheel + NOPASSWD tasks: - name: Create test user ansible.builtin.user: name: "{{ test_user }}" uid: "{{ test_uid if test_uid | int > 0 else omit }}" home: "{{ test_home }}" shell: "{{ test_shell }}" password: "{{ test_password if test_password else omit }}" state: present generate_ssh_key: "{{ 'yes' if not test_pubkey else 'no' }}" - name: Add to sudoers (wheel + NOPASSWD) when: test_sudo | bool ansible.builtin.lineinfile: path: /etc/sudoers line: "{{ test_user }} ALL=(ALL) NOPASSWD:ALL" validate: 'visudo -cf %s' - name: Deploy public key (if provided) when: test_pubkey | length > 0 ansible.posix.authorized_key: user: "{{ test_user }}" state: present key: "{{ test_pubkey }}" - name: Verify account exists ansible.builtin.command: getent passwd {{ test_user }} register: verify changed_when: false - name: Print verification result ansible.builtin.debug: msg: "{{ inventory_hostname }} → {{ test_user }}(UID={{ verify.stdout.split(':')[2] }}) 创建完成"
展开代码ansible-playbook add_user.yml -i hosts
适用于管理机首次配置或少量机器场景:
展开代码# 本地一次性生成密钥对(推荐 ed25519 算法) ssh-keygen -t ed25519 -C "mypc_$(whoami)" -f ~/.ssh/id_ed25519 # 方式一:使用 ssh-copy-id(推荐) ssh-copy-id -i ~/.ssh/id_ed25519.pub user@<IP> # 方式二:手动复制公钥(适用于无 ssh-copy-id 的环境) cat ~/.ssh/id_ed25519.pub | ssh user@<IP> 'mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'
展开代码# 测试连通性 ansible all -i hosts -m ping # 批量执行命令 ansible servers -i hosts -a "uptime" -f 10 # 使用特定用户和密钥 ansible-playbook site.yml -i hosts -u admin --private-key ~/.ssh/ansible_key # 语法检查 ansible-playbook --syntax-check site.yml # 试运行(不实际执行) ansible-playbook --check site.yml # 需配置的机器不能免密使用sudo时 ansible-playbook init.yml -i ./hosts --ask-pass --ask-become-pass
本文作者:zzz
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!