问题
使用最新的,稳定的Ansible构建,我遇到了一个奇怪的问题,即我的剧本在“ Gathering_Facts”期间挂在一台服务器上,但是在使用Sudo时在其他类似服务器上可以正常工作。在Ansible服务器上,我以用户(NIS用户)身份运行,并在远程服务器上使用sudo(以root 用户身份)进行更改。如果我从此设置中删除Sudo,则一切正常。
设定
软件版本
- 作业系统:RHEL 6.4
- Ansible版本:Ansible 1.8.2
- 须藤版本:
Sudo版本1.8.6p3 Sudoers策略插件版本1.8.6p3 Sudoers文件语法版本42 Sudoers I / O插件版本1.8.6p3
- SSH版本:OpenSSH_5.3p1,OpenSSL 1.0.0-fips 2010年3月29日
服务器映射
-------- User1 @ Server1:sudo -H -S -p(挂在Gathering_Facts上) / User1 @ Ansible ---- \ -------- User1 @ Server2:sudo -H -S -p(工作正常)
用户数
- User1:Server1和Server2上的NIS可访问用户。
- root:每个服务器的本地root用户。
Ansible配置
我的ansible.cfg的相关部分。
ansible.cfg
sudo = true
sudo_user = root
ask_sudo_pass = True
ask_pass = True
...
gathering = smart
....
# change this for alternative sudo implementations
sudo_exe = sudo
# what flags to pass to sudo
#sudo_flags = -H
...
# remote_user = ansible
这是一个简单的测试手册,可以触摸一个空文件,然后将其删除。真的,我只是想测试是否可以让Ansible在远程服务器上正确使用sudo。如果这本剧本能正常运行,那么我的状态就很好。
测试文件
---
- hosts: Server1:Server2
vars:
- test_file: '/tmp/ansible_test_file.txt'
sudo: yes
tasks:
- name: create empty file to test connectivity and sudo access
file: dest={{ test_file }}
state=touch
owner=root group=root mode=0600
notify:
- clean
handlers:
- name: clean
file: dest={{ test_file }}
state=absent
Sudo配置
/ etc / sudoers
Host_Alias SRV = Server1, Server2
User_Alias SUPPORT = User1, User2, User3
SUPPORT SRV=(root) ALL
这种sudo配置在两台服务器上都可以正常工作。sudo本身没有问题。
我如何运作
很简单:
$ ansible-playbook test.yml SSH密码: sudo password [默认为SSH密码]: 播放[Server1:Server2] ************************************************ ** 汇总事实**************************************************** *************** 好的:[Server2] 失败:[Server1] => {“失败”:true,“已分析”:false} 抱歉,请再试一次。 [通过ansudo的sudo,密钥= mxxiqyvztlfnbctwixzmgvhwfdarumtq]密码: sudo:1次错误的密码尝试 任务:[创建空文件以测试连接性和sudo访问] **************** 更改为:[Server2] 通知:[干净] ************************************************* **************** 更改为:[Server2] PLAY RECAP ************************************************ ******************** 要重试,请使用:--limit @ / home / User1 / test.retry 服务器1:确定= 0更改= 0 =无法访问= 0失败= 1 Server2:ok = 3更改= 2无法访问= 0失败= 0
无论我是否显式输入SSH / Sudo密码以及隐式输入(将sudo pass默认设置为SSH)都失败。
远程服务器日志
Server1(失败)
/ var / log / secure
12月31日15:21:10 Server1 sshd [27093]:从xxxx端口51446 ssh2接受的User1密码 12月31日15:21:10 Server1 sshd [27093]:pam_unix(sshd:session):通过(uid = 0)为用户User1打开了会话 12月31日15:21:11 Server1 sshd [27095]:SFTP的子系统请求 12月31日15:21:11 Server1 sudo:pam_unix(sudo:auth):身份验证失败; logname = User1 uid = 187 euid = 0 tty = / dev / pts / 1 ruser = User1 rhost = user = User1 12月31日15:26:13 Server1 sudo:pam_unix(sudo:auth):对话失败 12月31日15:26:13 Server1 sudo:pam_unix(sudo:auth):auth无法识别[User1]的密码 12月31日15:26:13 Server1 sudo:User1:1次错误的密码尝试;TTY = pts / 1; PWD = / home / User1; USER = root; COMMAND = / bin / sh -c echo SUDO-SUCCESS-mxxiqyvztlfnbctwixzmgvhwfdarumtq; LANG = C LC_CTYPE = C / usr / bin / python /tmp/.ansible/tmp/ansible-tmp-1420039272.66-164754043073536/setup; rm -rf /tmp/.ansible/tmp/ansible-tmp-1420039272.66-164754043073536/> / dev / null 2>&1 12月31日15:26:13 Server1 sshd [27093]:pam_unix(sshd:session):用户User1的会话已关闭
Server2(运行正常)
/ var / log / secure
12月31日15:21:12 Server2 sshd [31447]:从xxxx端口60346 ssh2接受的User1密码 12月31日15:21:12 Server2 sshd [31447]:pam_unix(sshd:session):通过(uid = 0)为用户User1打开了会话 12月31日15:21:12 Server2 sshd [31449]:sftp的子系统请求 12月31日15:21:12 Server2 sudo:User1:TTY = pts / 2; PWD = / home / User1; USER = root; COMMAND = / bin / sh -c echo SUDO-SUCCESS-vjaypzeocvrdlqalxflgcrcoezhnbibs; LANG = C LC_CTYPE = C / usr / bin / python /tmp/.ansible/tmp/ansible-tmp-1420039272.68-243930711246149/setup; rm -rf /tmp/.ansible/tmp/ansible-tmp-1420039272.68-243930711246149/> / dev / null 2>&1 12月31日15:21:14 Server2 sshd [31447]:pam_unix(sshd:session):用户User1的会话已关闭
轨迹输出
这是针对root用户的ansible命令时strace的输出。命令:
while [[ -z $(ps -fu root|grep [a]nsible|awk '{print $2}') ]]; do
continue
done
strace -vfp $(ps -fu root|grep [a]nsible|awk '{print $2}') -o /root/strace.out`
服务器1
23650 select(0,NULL,NULL,NULL,{1,508055})= 0(超时) 23650套接字(PF_NETLINK,SOCK_RAW,9)= 10 23650 fcntl(10,F_SETFD,FD_CLOEXEC)= 0 23650 readlink(“ / proc / self / exe”,“ / usr / bin / sudo”,4096)= 13 23650 sendto(10,“ | \ 0 \ 0 \ 0L \ 4 \ 5 \ 0 \ 1 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0op = PAM:authentic” ...,124,0,{sa_family = AF_NETLINK,pid = 0,groups = 00000000},12)= 124 23650 poll([{fd = 10,events = POLLIN}],1,500)= 1([{fd = 10,revents = POLLIN}]) 23650 recvfrom(10,“ $ \ 0 \ 0 \ 0 \ 2 \ 0 \ 0 \ 0 \ 1 \ 0 \ 0 \ 0b \\\ 0 \ 0 \ 0 \ 0 \ 0 \ 0 | \ 0 \ 0 \ 0L \ 4 \ 5 \ 0 \ 1 \ 0 \ 0 \ 0“ ...,8988,MSG_PEEK | MSG_DONTWAIT,{sa_family = AF_NETLINK,pid = 0,groups = 00000000},[12])= 36 23650 recvfrom(10,“ $ \ 0 \ 0 \ 0 \ 2 \ 0 \ 0 \ 0 \ 1 \ 0 \ 0 \ 0b \\\ 0 \ 0 \ 0 \ 0 \ 0 \ 0 | \ 0 \ 0 \ 0L \ 4 \ 5 \ 0 \ 1 \ 0 \ 0 \ 0“ ...,8988,MSG_DONTWAIT,{sa_family = AF_NETLINK,pid = 0,groups = 00000000},[12])= 36 23650关闭(10)= 0 23650 write(2,“对不起,再试一次。\ n”,18)= 18 23650 gettimeofday({1420050850,238344},NULL)= 0 23650套接字(PF_FILE,SOCK_STREAM,0)= 10 23650 connect(10,{sa_family = AF_FILE,path =“ / var / run / dbus / system_bus_socket”},33)= 0
服务器2
6625 select(8,[5 7],[],NULL,NULL)=?ERESTARTNOHAND(要重新启动) 6625-SIGCHLD(孩子退出)@ 0(0)- 6625 write(8,“ \ 21”,1)= 1 6625 rt_sigreturn(0x8)= -1 EINTR(系统调用中断) 6625 select(8,[5 7],[],NULL,NULL)= 1(在[7]中) 6625读取(7,“ \ 21”,1)= 1 6625 wait4(6636,[{WIFEXITED(s)&& WEXITSTATUS(s)== 0}],WNOHANG | WSTOPPED,NULL)= 6636 6625 rt_sigprocmask(SIG_BLOCK,NULL,[],8)= 0 6625套接字(PF_NETLINK,SOCK_RAW,9)= 6 6625 fcntl(6,F_SETFD,FD_CLOEXEC)= 0 6625 readlink(“ / proc / self / exe”,“ / usr / bin / sudo”,4096)= 13 6625 sendto(6,“ x \ 0 \ 0 \ 0R \ 4 \ 5 \ 0 \ 6 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0op = PAM:session_c” ...,120,0,{sa_family = AF_NETLINK,pid = 0,groups = 00000000},12)= 120 6625 poll([{fd = 6,events = POLLIN}],1,500)= 1([{fd = 6,revents = POLLIN}]) 6625 recvfrom(6,“ $ \ 0 \ 0 \ 0 \ 2 \ 0 \ 0 \ 0 \ 6 \ 0 \ 0 \ 0 \ 330 \ 355 \ 355 \ 377 \ 377 \ 0 \ 0 \ 0 \ 0x \ 0 \ 0 \ 0R \ 4 \ 5 \ 0 \ 6 \ 0 \ 0 \ 0“ ...,8988,MSG_PEEK | MSG_DONTWAIT,{sa_family = AF_NETLINK,pid = 0,groups = 00000000},[12])= 36 6625 recvfrom(6,“ $ \ 0 \ 0 \ 0 \ 2 \ 0 \ 0 \ 0 \ 6 \ 0 \ 0 \ 0 \ 330 \ 355 \ 355 \ 377 \ 377 \ 0 \ 0 \ 0 \ 0x \ 0 \ 0 \ 0R \ 4 \ 5 \ 0 \ 6 \ 0 \ 0 \ 0“ ...,8988,MSG_DONTWAIT,{sa_family = AF_NETLINK,pid = 0,groups = 00000000},[12])= 36 6625关闭(6)= 0 6625打开(“ /etc/security/pam_env.conf”,O_RDONLY)= 6 6625 fstat(6,{st_dev = makedev(253,1),st_ino = 521434,st_mode = S_IFREG | 0644,st_nlink = 1,st_uid = 0,st_gid = 0,st_blksize = 4096,st_blocks = 8,st_size = 2980,st_atime = 2014/12 / 31-16:10:01,st_mtime = 2012/10 / 15-08:23:52,st_ctime = 2014/06 / 16-15:45:35})= 0 6625 mmap(NULL,4096,PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_ANONYMOUS,-1,0)= 0x7fbc3a59a000 6625 read(6,“#\ n#这是配置fi” ...,4096)= 2980 6625读取(6,“”,4096)= 0 6625关闭(6)= 0 6625 munmap(0x7fbc3a59a000,4096)= 0 6625打开(“ / etc / environment”,O_RDONLY)= 6
我猜
Server1无法正确获取密码,或者错误地要求/等待密码。这看起来好像不是Sudo或Ansible问题(单独,它们都可以正常工作),但是Server1似乎没有以类似于Server2的方式接收凭据(或坚持使用它们)。Server1和2具有不同的用途,因此它们可能在身份验证或程序包版本方面有所不同,但它们都是从同一存储库构建的;因此,它们应该没什么不同。
PAM验证
我认为系统可能具有不同的PAM配置,从而导致密码处理方式有所不同。我比较了/etc/pam.d/文件(使用md5sum [file]
),它们在两个系统之间是相同的。
测验
须藤STDIN
测试了另一个问题,即sudo无法从STDIN读取密码,但是在两台服务器上都可以正常工作。
测试Sudo Ad-Hoc
-bash-4.1 $ ansible Server1 -m文件-a“ dest = / tmp / ansible_test.txt state = touch” -sK SSH密码: sudo password [默认为SSH密码]: 服务器1 | 成功>> { “已更改”:是, “ dest”:“ /tmp/ansible_test.txt”, “ gid”:0, “ group”:“ root”, “ mode”:“ 0644”, “ owner”:“ root”, “大小”:0, “ state”:“文件”, “ uid”:0 }
成功!但为什么?!
TL; DR
- Server1看起来很好,而Server1似乎正在等待sudo密码提示。
ansible
在Server1上运行“临时”工作正常。将其作为剧本运行失败。
问题
- 是什么导致我的Ansible Sudo配置在一台服务器上正常工作而在另一台服务器上被拒绝?
- 当运行临时脚本和剧本时,Ansible从本地计算机到远程计算机的密码“传递”是否不同?我以为他们会是一样的。
我认为这接近于仅向GitHub页面提交错误报告,纯粹是基于sudo访问具有不同的结果,这取决于我是否临时运行。