BrM*_*M13 9 sudo rhel6 ansible
使用最新的、稳定的 Ansible 版本,我有一个奇怪的问题,我的剧本在“Gathering_Facts”期间挂在一台服务器上,但在使用 Sudo 时在其他类似服务器上运行良好。在 Ansible 服务器上,我以我的用户(NIS 用户)身份运行,并在远程服务器上使用sudo(以 root 身份)进行更改。如果我从此设置中删除 Sudo,一切正常。
须藤版本 1.8.6p3 Sudoers 策略插件版本 1.8.6p3 sudoers 文件语法版本 42 Sudoers I/O 插件版本 1.8.6p3
-------- User1@Server1: sudo -H -S -p(挂在 Gathering_Facts 上)
/
用户 1@Ansible ----
\
-------- User1@Server2:sudo -H -S -p(工作正常)
我的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
Run Code Online (Sandbox Code Playgroud)
这是一个简单的测试剧本,用于触摸空文件然后将其删除。真的,我只是想测试我是否可以让 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
Run Code Online (Sandbox Code Playgroud)
/etc/sudoers
Host_Alias SRV = Server1, Server2
User_Alias SUPPORT = User1, User2, User3
SUPPORT SRV=(root) ALL
Run Code Online (Sandbox Code Playgroud)
此 sudo 配置在两个服务器上都可以正常工作。sudo 本身没有问题。
很简单:
$ ansible-playbook test.yml
SSH密码:
sudo 密码 [默认为 SSH 密码]:
播放 [Server1:Server2] ******************************************** **
收集事实 **************************************************** ***************
好的:[Server2]
失败:[Server1] => {“失败”:真,“解析”:假}
抱歉,请再试一次。
[sudo 通过 ansible,key=mxxiqyvztlfnbctwixzmgvhwfdarumtq] 密码:
sudo:1 次错误的密码尝试
任务:[创建空文件以测试连通性和 sudo 访问] ****************
更改:[Server2]
通知:[干净] ********************************************* ****************
更改:[Server2]
播放回顾 **************************************************** ********************
要重试,请使用:--limit @/home/User1/test.retry
Server1 : ok=0 已更改=0 无法访问=0 失败=1
Server2 : ok=3 已更改=2 无法访问=0 失败=0
无论我是否明确输入 SSH/Sudo 密码以及隐式输入(让 sudo 默认传递给 SSH),都会失败。
/var/日志/安全
12 月 31 日 15:21:10 Server1 sshd[27093]:接受来自 xxxx 端口 51446 ssh2 的 User1 密码 12 月 31 日 15:21:10 Server1 sshd[27093]: pam_unix(sshd:session): 为用户 User1 打开的会话 (uid=0) 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 ; 密码=/home/User1 ; 用户=根;命令=/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 的会话已关闭
/var/日志/安全
12 月 31 日 15:21:12 Server2 sshd[31447]:接受来自 xxxx 端口 60346 ssh2 的 User1 密码 12 月 31 日 15:21:12 Server2 sshd[31447]: pam_unix(sshd:session): 为用户 User1 打开的会话 (uid=0) 12 月 31 日 15:21:12 Server2 sshd[31449]:子系统请求 sftp 12 月 31 日 15:21:12 Server2 sudo:User1:TTY=pts/2;密码=/home/User1 ; 用户=根;命令=/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`
Run Code Online (Sandbox Code Playgroud)
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, 组=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 连接(10,{sa_family=AF_FILE,路径=“/var/run/dbus/system_bus_socket”},33)= 0
6625 选择(8,[5 7],[],NULL,NULL)=?ERESTARTNOHAND(待重启)
6625 --- SIGCHLD(孩子退出)@ 0 (0) ---
6625 写(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, 组=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\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\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, = 82, st_blocks_size2, =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# 这是配置文件"..., 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 配置,导致密码的处理方式有所不同。我比较了 /etc/pam.d/ 文件(使用md5sum [file]),它们在两个系统之间是相同的。
测试了sudo 无法从 STDIN 读取密码的另一个问题,但这在两台服务器上都运行良好。
-bash-4.1$ ansible Server1 -m 文件 -a "dest=/tmp/ansible_test.txt state=touch" -sK
SSH密码:
sudo 密码 [默认为 SSH 密码]:
服务器 1 | 成功 >> {
“改变”:真的,
"dest": "/tmp/ansible_test.txt",
"gid": 0,
“组”:“根”,
“模式”:“0644”,
"owner": "root",
“大小”:0,
"状态": "文件",
“用户名”:0
}
成功!但为什么?!
ansible在 Server1 上运行“ad-hoc”工作正常。将其作为剧本运行失败。我认为这已经接近于简单地向 GitHub 页面提交错误报告,纯粹是因为 sudo 访问有不同的结果,这取决于我是否正在运行 ad-hoc。
我要做的是使用
strace -vfp `pidof sshd`
Run Code Online (Sandbox Code Playgroud)
并看看哪里失败了。
还要检查帐户,也许它受到限制或其他什么原因,但我敢打赌,您的 /etc/hosts 文件有问题,或者在该过程中它确实发生了更改。
使用 @lulian 作为这个答案的立足点,问题归结为ansible_sudo_pass:group_vars 中定义的流氓,它覆盖了为--ask-sudo-pass.
使用以下内容:
while [[ -z $(ps -eaf|grep 'sshd: [U]ser1@pts/1') ]]; do
continue
done
strace -ff -vfp $(ps -eaf|grep 'sshd: [U]ser1@pts/1'|awk '{print $2}') -o /root/strace_sshd1_2.out
Run Code Online (Sandbox Code Playgroud)
我发现write(4, "{{ password }}\n", 15)正在传递的是密码而不是输入的密码。经过一些快速搜索后,我确实发现ansible_sudo_pass在我的 group_vars 中定义了它,它覆盖了我输入的密码。
仅供其他人参考,该ansible_sudo_pass:定义似乎优先于--ask-sudo-pass乍一看似乎违反直觉的定义。最后,这是用户错误,但@lulian 在调试 SSH 交互以及 和 之间的关系发现方面的方法ansible_sudo_pass应该--ask-sudo-pass对其他人非常有帮助。(希望!)