批量修改主机密码并发送到邮箱

会哭的雨 2019-12-13

1. 前言

需求:一批云主机,要求每周修改一次密码。

2. 实践

使用 ansible + sendmail 即可实现。

主机信息:

批量修改主机密码并发送到邮箱

(1)安装 sendmail

wget http://caspian.dotconf.net/menu/Software/SendEmail/sendEmail-v1.56.tar.gz
tar zxf sendEmail-v1.56.tar.gz -C /usr/src/
cd /usr/src/sendEmail-v1.56/
cp -a sendEmail /usr/local/bin/
yum install perl-Net-SSLeay perl-IO-Socket-SSL -y
wget http://www.cpan.org/src/5.0/perl-5.10.0.tar.gz
tar zxf perl-5.10.0.tar.gz
cd perl-5.10.0
./configure.gnu -des -Dprefix=/usr/local/perl
make
make install
mv /usr/bin/perl /usr/bin/perl.bak
ln -s /usr/local/perl/bin/perl /usr/bin/perl

测试:

/usr/local/bin/sendEmail -f 发送方邮箱地址 -t 接收方邮件地址 -s 发送方SMTP服务器 -u "test" -xu 发送方邮箱登录用户名 -xp 发送方邮件服务器登录密码 -m "test-1234567890" -l /var/log/sendmail.log

邮件查收

批量修改主机密码并发送到邮箱

(2)配置 ansible

建立ssh互信登录

#yum install -y ansible expect
#ssh-keygen -t rsa -P ‘‘  # 两下回车
#mkdir copy_key
#cd copy_key/
#cat ip.txt   # 所有要做 ssh 互信的主机ip列表
192.168.118.12
192.168.118.13
#cat copykey.sh     # 通过 expect 批量进行 ssh 互信操作,这样可以节省很多时间
#!/bin/bash
# Author:hukey
while read line
do
    expect <<EOF
      set timeout 10
      spawn ssh-copy-id $line
      expect {
        "yes/no" {send "yes\n"; exp_continue}
        "password" {send "123123\n"}    # 发送ssh密码
  }
  expect "password" {send "123123\n"}   # 发送ssh密码
EOF
done < ip.txt
#sh copykey.sh  # 执行脚本建立ssh互信登录

配置 ansible

#cd /etc/ansible/
#mv hosts hosts_bak
#vim hosts
[nodes]
192.168.118.12 ansible_ssh_user=root
192.168.118.13 ansible_ssh_user=root
测试ssh 互信是否完成
#ansible all -m ping
192.168.118.13 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
192.168.118.12 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
ok, 以上信息没有报错就说明ssh互信完成。

编写 playbook 实现批量修改主机密码

#mkdir change_passwd
#cd change_passwd/
通过 user 模块很容易修改主机密码
#cat change_passwd.yaml 
- hosts: all  # 主机组为 ansible hosts 中的所有主机
  gather_facts: false
  tasks:
  - name: Change password
    user: name={{ name1 }}  password={{ chpass | password_hash(‘sha512‘) }}  update_password=always # 需要传递2个变量 name1 和 chpass
测试执行:
#ansible-playbook change_passwd.yaml -e "name1=root chpass=123456"
PLAY [all] ********************************************
TASK [Change password] ********************************
changed: [192.168.118.12]
changed: [192.168.118.13]
PLAY RECAP ********************************************
192.168.118.12             : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.118.13             : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
通过结果,可以判断是执行成功的,也就是 ansible hosts 中的主机 root 密码已经修改为 123456

 

(3)编写脚本

这是做主机 root 密码的修改,脚本必须谨慎谨慎再谨慎,如下:

#!/bin/bash
# Author:hukey
sendMail(){
    to=$1
    subject=$2
    body=$3
    user=‘‘  # 邮件发送者,这里如果没有,建议 126注册一个
    smtp_server=‘smtp.126.com‘ # 邮箱 smtp 服务器
    password=‘xxx‘  # smtp 密码
    /usr/local/bin/sendEmail  -f $user -t "$to" -s $smtp_server -u "$subject" -o tls=no -o message-content-type=html  -o message-charset=utf8 -xu $user -xp $password -m "$body" >> /var/log/sendmail.log
}
USERMAIL=‘xxx,xxx‘ # 邮件接收者,多人接收格式 ‘,‘
USER=root
PASSWD=$(tr -dc _A-Z-a-z#$%^*_0-9 </dev/urandom | head -c20)    # 随机生成密码
ansible all -m ping &> /tmp/ansible_ping.log    # 首先通过 ping 模块检测主机存活和连接情况
if [ $? -ne 0 ];then    # 一旦有一台主机无法连接则发送错误邮件后退出脚本执行
    sendMail $USERMAIL ‘xxx主机- 批处理错误‘ "
    <table border="1" bordercolor="black" cellspacing="0px" cellpadding="4px">
    <tr>
        <td colspan="2" align="center" bgcolor="\#FF3333">电信云 - 批处理错误</td>
    </tr>
    <tr>
        <td>主机</td>
        <td>192.168.1.222</td>
    </tr>
    <tr>
        <td>错误日志</td>
        <td>/tmp/ansible_ping.log</td>
    </tr>
    </table>
    "
    exit 1
fi
# 执行 playbook 批量修改密码
ansible-playbook /root/change_password/change_passwd.yaml -e "name1=${USER} chpass=${PASSWD}" &> /tmp/ansible_update.log
# 密码全部修改成功发送邮件
if [ $? -eq 0 ];then
    sendMail $USERMAIL ‘xxx主机信息‘ "
    <table border="1" bordercolor="black" cellspacing="0px" cellpadding="4px">
    <tr>
        <td align="center" bgcolor="\#00FF00" colspan="2">电信云主机信息</td>
    </tr>
    <tr>
        <td>用户名</td>
        <td>${USER}</td>
    </tr>
    <tr>
        <td>密码</td>
        <td>${PASSWD}</td>
    </table>
    "
    echo $PASSWD > /tmp/tmp.log
# 一旦脚本执行失败,则发送错误日志+登录密码
#(这里的 else 很少会出现,因为上面 ping 模块的检测已经挡掉了,除非在检测完后,突然中断,脚本才会走到这里)
else
    echo "密码:$PASSWD" >> /tmp/ansible_update.log
    for i in {1..3};do
        sendMail $USERMAIL ‘电信云主机密码修改失败 - 日志‘ < /tmp/ansible_update.log
        sleep 300
    done
fi

测试下脚本执行:

批量修改主机密码并发送到邮箱

主机批量修改成功,root 用户密码修改为上面的随机串。随后就可以加入到 crontab 中。

3. 总结

其实,这是一个需要很严谨的操作,通过脚本来执行有些欠妥,但是对于大批量的主机操作,这也算比较好的方式吧。目前,以上脚本已经在生产环境中使用,但是 批量管理主机 不在修改密码的行列。这样,就算出现bug,也能及时补救。

相关推荐