将expect和tcl的软件包下载放到 /usr/local/src 目录下,解压tcl,进入tcl解压目录,然后进入unix目录进行编译安装 [root@server-202 ~] # cd /usr/local/src/ [root@server-202 src] # tar -zvxf tcl8.4.11-src.tar.gz [root@server-202 src] # cd tcl8.4.11/unix [root@server-202 unix] # ./configure [root@server-202 unix] # make && make install 安装expect [root@server-202 src] # tar -zvxf expect-5.43.0.tar.gz [root@server-202 src] # cd expect-5.43.0 [root@server-202 expect-5.43.0] # ./configure --with-tclinclude=/usr/local/src/tcl8.4.11/generic --with-tclconfig=/usr/local/lib/ [root@server-202 expect-5.43.0] # make && make install 安装完成后进行测试 [root@server-202 ~] # expect expect1.1> [root@server-202 ~] # which expect /usr/local/bin/expect 做个expect执行文件的软件 [root@server-202 ~] # ln -s /usr/local/bin/expect /usr/bin/expect [root@server-202 ~] # ll /usr/bin/expect 批量实现信任关系的脚本如下: [root@server-202 ~] # vim /opt/ssh_auth.sh #!/bin/sh DEST_USER=$1 PASSWORD=$2 HOSTS_FILE=$3 if [ $ # -ne 3 ]; then echo "Usage:" echo "$0 remoteUser remotePassword hostsFile" exit 1 fi SSH_DIR=~/. ssh SCRIPT_PREFIX=. /tmp echo =========================== # 1. prepare directory .ssh mkdir $SSH_DIR chmod 700 $SSH_DIR # 2. generat ssh key TMP_SCRIPT=$SCRIPT_PREFIX.sh echo "#!/usr/bin/expect" >$TMP_SCRIPT echo "spawn ssh-keygen -b 1024 -t rsa" >>$TMP_SCRIPT echo "expect *key*" >>$TMP_SCRIPT echo "send \r" >>$TMP_SCRIPT if [ -f $SSH_DIR /id_rsa ]; then echo "expect *verwrite*" >>$TMP_SCRIPT echo "send y\r" >>$TMP_SCRIPT fi echo "expect *passphrase*" >>$TMP_SCRIPT echo "send \r" >>$TMP_SCRIPT echo "expect *again:" >>$TMP_SCRIPT echo "send \r" >>$TMP_SCRIPT echo "interact" >>$TMP_SCRIPT chmod +x $TMP_SCRIPT /usr/bin/expect $TMP_SCRIPT rm $TMP_SCRIPT # 3. generat file authorized_keys cat $SSH_DIR /id_rsa .pub>>$SSH_DIR /authorized_keys # 4. chmod 600 for file authorized_keys chmod 600 $SSH_DIR /authorized_keys echo =========================== # 5. copy all files to other hosts for ip in $( cat $HOSTS_FILE) do if [ "x$ip" != "x" ]; then echo ------------------------- TMP_SCRIPT=${SCRIPT_PREFIX}.$ip.sh # check known_hosts val=` ssh -keygen -F $ip` if [ "x$val" == "x" ]; then echo "$ip not in $SSH_DIR/known_hosts, need to add" val=` ssh -keyscan $ip 2> /dev/null ` if [ "x$val" == "x" ]; then echo "ssh-keyscan $ip failed!" else echo $val>>$SSH_DIR /known_hosts fi fi echo "copy $SSH_DIR to $ip" echo "#!/usr/bin/expect" >$TMP_SCRIPT echo "spawn scp -r $SSH_DIR $DEST_USER@$ip:~/" >>$TMP_SCRIPT echo "expect *assword*" >>$TMP_SCRIPT echo "send $PASSWORD\r" >>$TMP_SCRIPT echo "interact" >>$TMP_SCRIPT chmod +x $TMP_SCRIPT #echo "/usr/bin/expect $TMP_SCRIPT" >$TMP_SCRIPT.do #sh $TMP_SCRIPT.do& /usr/bin/expect $TMP_SCRIPT rm $TMP_SCRIPT echo "copy done." fi done echo done . 在上面脚本文件的同目录下新建名为host的文件,将要建立 ssh 互信的机器名或ip地址添加到该文件中,每个机器名或ip占一行,如: [root@server-202 ~] # vim /opt/host 192.168.10.202 192.168.10.203 192.168.10.205 192.168.10.206 192.168.10.207 192.168.10.208 最后就可以运行这个脚本ssh_auth.sh文件,ssh_auth.sh接受三个参数,远程机器用户名、密码和host文件名(相对路径或绝对路径均可)。 [root@server-202 ~] # sh /opt/ssh_auth.sh root kevin123456 /opt/host 然后查看下其他服务器,发现. ssh 目录下的文件和192.168.10.202机器的. ssh 目录下的文件一致。 最后就可以在这些机器之间进行相互信任的 ssh 无密码跳转登录了! ========================================================================== 注意:上面脚本针对的是服务器 ssh 端口是22的情况,如果 ssh 是非22端口,比如是22222端口。 则只需要在ssh_auth.sh脚本中修改下面两行内容: [root@server-202 ~] # cp /opt/ssh_auth.sh /opt/ssh_auth.sh.bak [root@server-202 ~] # vim /opt/ssh_auth.sh #注意下面一个小写p,一个大写P ....... val=` ssh -keyscan $ip 2> /dev/null ` 修改为 val=` ssh -keyscan -p 22222 $ip 2> /dev/null ` ....... echo "spawn scp -r $SSH_DIR $DEST_USER@$ip:~/" >>$TMP_SCRIPT 修改为 echo "spawn scp -P 22222 -r $SSH_DIR $DEST_USER@$ip:~/" >>$TMP_SCRIPT [root@server-202 ~] # diff /opt/ssh_auth.sh /opt/ssh_auth.sh.bak 57c57 < val=` ssh -keyscan -p 22222 $ip 2> /dev/null ` --- > val=` ssh -keyscan $ip 2> /dev/null ` 67c67 < echo "spawn scp -P 22222 -r $SSH_DIR $DEST_USER@$ip:~/" >>$TMP_SCRIPT --- > echo "spawn scp -r $SSH_DIR $DEST_USER@$ip:~/" >>$TMP_SCRIPT 最后执行脚本,进行相互信任关系批量部署即可 [root@server-202 ~] # sh /opt/ssh_auth.sh root kevin123456 /opt/host 原文地址:https://www.cnblogs.com/kevingrace/p/10601309.html 按照集团运维信息安全制度, 需要每3或6个月对线上服务器密码进行一次变更,通过shell脚本部署比较繁琐,所以决定采用ansible脚本对远程主机root密码进行批量重置,该脚本已经在稳定运行在正式环境下。具体方法如下: 1) 在服务端安装ansible
1 | [root@ansible-server ~] # yum install -y ansible |
2) 配置ansible到远程主机的ssh无密码登录的信任关系 (authoried_keys 模块)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 首先采用Ansible批量建立 ssh 无密码登录的信任关系!! [root@ansible-server ~] # ssh-keygen -t rsa #一路回车 [root@ansible-server ~] # ls /root/.ssh/ id_rsa id_rsa.pub #################################################################################################### 需要注意 ssh 建立互信的命令格式: # ssh-copy-id -i ~/.ssh/id_rsa.pub username@ip或hostname #################################################################################################### 在客户机比较多的情况下,使用 ssh -copy- id 命令的方法显然是有些费时,使用ansible-playbook 推送 ymal进行批量创建 ssh 互信关系就显得省事多了, 这里就使用到了ansible的authoried_keys 模块: 首先要配置ansible清单 (远程主机的密码这里为 "123456" ) [root@ansible-server ~] # vim /etc/ansible/hosts ................ ................ [ ssh -host] 172.16.60.204 172.16.60.205 172.16.60.206 172.16.60.207 [ ssh -host:vars] ansible_ssh_pass= "123456" #################################################################################################### 发送公钥到目标机器命令格式如下: # ansible ssh-host -m copy -a "src=/root/.ssh/id_rsa.pub dest=/root/.ssh/authorized_keys mode=600" #################################################################################################### 在上面分发密钥中,如果清单文件 /etc/ansible/hosts 里没有使用ansible_ssh_pass变量指明密码,则可以使用下面命令: 这里默认 ssh -host组下的机器root密码都一样,使用-k 参数,回车输入root密码即可: # ansible ssh-host -m authorized_key -a "user=root state=present key=\"{{ lookup('file', '/root/.ssh/id_rsa.pub') }} \"" -k #################################################################################################### 编写playbook文件 [root@ansible-server ~] # vim /opt/ssh_key.yaml --- - hosts: ssh -host user: root tasks: - name: ssh -copy authorized_key: user=root key= "{{ lookup('file', '/root/.ssh/id_rsa.pub') }}" 注意上面yaml脚本中的 "ssh-key-host" 是在 /etc/ansible/hosts 清单文件里配置的远程客户机列表 这里做的是基于远程主机root用户的 ssh 互信 执行批量互信 [root@ansible-server ~] # ansible-playbook /opt/ssh_key.yaml PLAY [ ssh -host] ************************************************************************************************************************ TASK [Gathering Facts] ***************************************************************************************************************** ok: [172.16.60.204] ok: [172.16.60.205] ok: [172.16.60.206] ok: [172.16.60.207] TASK [ ssh -copy] ************************************************************************************************************************ changed: [172.16.60.205] changed: [172.16.60.204] changed: [172.16.60.206] changed: [172.16.60.207] PLAY RECAP ***************************************************************************************************************************** 172.16.60.204 : ok=2 changed=1 unreachable=0 failed=0 172.16.60.205 : ok=2 changed=1 unreachable=0 failed=0 172.16.60.206 : ok=2 changed=1 unreachable=0 failed=0 172.16.60.207 : ok=2 changed=1 unreachable=0 failed=0 最后验证下 ssh 互信 [root@ansible-server ~] # ansible -i /etc/ansible/hosts ssh-host -m shell -a "whoami" 172.16.60.204 | SUCCESS | rc=0 >> root 172.16.60.205 | SUCCESS | rc=0 >> root 172.16.60.207 | SUCCESS | rc=0 >> root 172.16.60.206 | SUCCESS | rc=0 >> root 这样,ansible批量创建到远程客户机的 ssh 信任关系已经实现了! |
3) Ansible批量更新远程主机用户密码方法 方法一: 使用Ansible的user模块批量修改远程客户机的用户密码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 由于在使用ansible修改用户密码的时候不能使用明文的方式,需要先加密,所以就需要使用一个方法对输入的明文的密码进行加密. 废话不多说了. 下面直接记录下操作方法: [root@ansible-server ~] # vim /opt/root_passwd.yaml --- - hosts: ssh -host gather_facts: false tasks: - name: change user passwd user: name={{ item.name }} password={{ item.chpass | password_hash( 'sha512' ) }} update_password=always with_items: - { name: 'root' , chpass: 'kevin@123' } - { name: 'app' , chpass: 'bjop123' } 注意上面在yaml文件中修改了远程客户机的root用户密码, app用户密码. 如果还想要修改其他用户密码, 则继续按照上面规则添加即可! 执行ansible-play [root@ansible-server ~] # ansible-playbook /opt/root_passwd.yaml PLAY [ ssh -host] ************************************************************************************************************************ TASK [change user passwd ] ************************************************************************************************************** changed: [172.16.60.204] => (item={u 'chpass' : u 'kevin@123' , u 'name' : u 'root' }) changed: [172.16.60.205] => (item={u 'chpass' : u 'kevin@123' , u 'name' : u 'root' }) changed: [172.16.60.204] => (item={u 'chpass' : u 'bjop123' , u 'name' : u 'app' }) changed: [172.16.60.205] => (item={u 'chpass' : u 'bjop123' , u 'name' : u 'app' }) changed: [172.16.60.206] => (item={u 'chpass' : u 'kevin@123' , u 'name' : u 'root' }) changed: [172.16.60.206] => (item={u 'chpass' : u 'bjop123' , u 'name' : u 'app' }) changed: [172.16.60.207] => (item={u 'chpass' : u 'kevin@123' , u 'name' : u 'root' }) changed: [172.16.60.207] => (item={u 'chpass' : u 'bjop123' , u 'name' : u 'app' }) PLAY RECAP ***************************************************************************************************************************** 172.16.60.204 : ok=1 changed=1 unreachable=0 failed=0 172.16.60.205 : ok=1 changed=1 unreachable=0 failed=0 172.16.60.206 : ok=1 changed=1 unreachable=0 failed=0 172.16.60.207 : ok=1 changed=1 unreachable=0 failed=0 |
方法二: 修改远程主机的单个用户密码使用此方法比较方便
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 编写playbook文件 [root@ansible-server ~] # vim /opt/root_passwd2.yaml --- - hosts: ssh -host gather_facts: false tasks: - name: Change password user: name={{ name1 }} password={{ chpass | password_hash( 'sha512' ) }} update_password=always 执行ansible-playbook, 使用-e参数传递用户名和密码给剧本,其中root为用户名,admin #123就是修改后的root密码 [root@ansible-server ~] # ansible-playbook /opt/root_passwd2.yaml -e "name1=root chpass=admin#123" PLAY [ ssh -host] ************************************************************************************************************************ TASK [Change password] ***************************************************************************************************************** changed: [172.16.60.204] changed: [172.16.60.205] changed: [172.16.60.206] changed: [172.16.60.207] PLAY RECAP ***************************************************************************************************************************** 172.16.60.204 : ok=1 changed=1 unreachable=0 failed=0 172.16.60.205 : ok=1 changed=1 unreachable=0 failed=0 172.16.60.206 : ok=1 changed=1 unreachable=0 failed=0 172.16.60.207 : ok=1 changed=1 unreachable=0 failed=0 |
方法三: 使用如下Ansible脚本, 适用于修改清单中部分远程主机的用户密码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 编写ansible-playbook脚本 (需要注意下面脚本中 "ens192" 是客户机ip所在的网卡设备名称, 这个要根据自己实际环境去配置, 比如eth0, eth1等) [root@ansible-server ~] # cat /opt/root_passwd4.yaml - hosts: test -host remote_user: root tasks: - name: change password for root shell: echo '{{ item.password }}' | passwd --stdin root when: ansible_ens192.ipv4.address == '{{ item.ip }}' with_items: - { ip: "172.16.60.220" , password: 'haha@123' } - { ip: "172.16.60.221" , password: 'kevin@123' } - { ip: "172.16.60.222" , password: 'bobo@123' } 执行ansible-playbook: [root@ansible-server ansible] # ansible-playbook /opt/root_passwd3.yaml PLAY [ ssh -host] ************************************************************************************************************************ TASK [Gathering Facts] ***************************************************************************************************************** ok: [172.16.60.204] ok: [172.16.60.205] ok: [172.16.60.206] ok: [172.16.60.207] TASK [change password for root] ******************************************************************************************************** [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: ansible_eth0.ipv4.address == '{{ item.ip }}' [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: ansible_eth0.ipv4.address == '{{ item.ip }}' skipping: [172.16.60.205] => (item={u 'ip' : u '172.16.60.204' , u 'password' : u 'haha@123' }) [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: ansible_eth0.ipv4.address == '{{ item.ip }}' skipping: [172.16.60.206] => (item={u 'ip' : u '172.16.60.204' , u 'password' : u 'haha@123' }) skipping: [172.16.60.206] => (item={u 'ip' : u '172.16.60.205' , u 'password' : u 'kevin@123' }) [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: ansible_eth0.ipv4.address == '{{ item.ip }}' skipping: [172.16.60.207] => (item={u 'ip' : u '172.16.60.204' , u 'password' : u 'haha@123' }) skipping: [172.16.60.207] => (item={u 'ip' : u '172.16.60.205' , u 'password' : u 'kevin@123' }) skipping: [172.16.60.207] => (item={u 'ip' : u '172.16.60.206' , u 'password' : u 'bobo@123' }) changed: [172.16.60.205] => (item={u 'ip' : u '172.16.60.205' , u 'password' : u 'kevin@123' }) skipping: [172.16.60.205] => (item={u 'ip' : u '172.16.60.206' , u 'password' : u 'bobo@123' }) changed: [172.16.60.204] => (item={u 'ip' : u '172.16.60.204' , u 'password' : u 'haha@123' }) skipping: [172.16.60.204] => (item={u 'ip' : u '172.16.60.205' , u 'password' : u 'kevin@123' }) skipping: [172.16.60.204] => (item={u 'ip' : u '172.16.60.206' , u 'password' : u 'bobo@123' }) changed: [172.16.60.206] => (item={u 'ip' : u '172.16.60.206' , u 'password' : u 'bobo@123' }) PLAY RECAP ***************************************************************************************************************************** 172.16.60.204 : ok=2 changed=1 unreachable=0 failed=0 172.16.60.205 : ok=2 changed=1 unreachable=0 failed=0 172.16.60.206 : ok=2 changed=1 unreachable=0 failed=0 172.16.60.207 : ok=1 changed=0 unreachable=0 failed=0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 如果ansible服务端没有和远程主机做 ssh 信任关系, 则可以在hosts清单配置里直接指明用户名和密码. 如果使用普通用户, 并且允许 sudo , 则需要提前在客户机里的 /etc/sudoers 文件里配置好该普通用户的 sudo 配置, 即允许该普通用户有 sudo 权限. [root@ansible-server ~] # vim /etc/ansible/hosts ................ [ test -host] 172.16.60.220 ansible_ssh_user=root ansible_ssh_pass=123456 ansible_ssh_port=22 172.16.60.221 ansible_ssh_user=root ansible_ssh_pass=bo@123 ansible_ssh_port=22 172.16.60.222 ansible_ssh_user=app ansible_ssh_pass=bj@123 ansible_ssh_port=22 ansible_sudo_pass=bj@123 即172.16.60.222客户机上要提前配置, 允许app用户具有 sudo 权限. 执行: [root@ansible-server ~] # ansible test-host -m shell -a "hostname" 172.16.60.222 | SUCCESS | rc=0 >> k8s-node02 172.16.60.220 | SUCCESS | rc=0 >> k8s-master01 172.16.60.221 | SUCCESS | rc=0 >> k8s-node01 [root@ansible-server ~] # ansible -i /etc/ansible/hosts test-host -m shell -a "hostname" 172.16.60.222 | SUCCESS | rc=0 >> k8s-node02 172.16.60.220 | SUCCESS | rc=0 >> k8s-master01 172.16.60.221 | SUCCESS | rc=0 >> k8s-node01 |
*************** 当你发现自己的才华撑不起野心时,就请安静下来学习吧!*************** |