Ansible: Raw vs Command vs Shell Module
Recently I started to work on a topic but I stumbled upon these modules. I did a decent search, but unfortunately I could not find the answer I wanted. Most of answers were generic and copy paste with no details and it bugged me more. I like solving problems with help of wireshark which is quite good at decrypting protocols. I thought it would be great to be able to decrypt shh packets and analyzing what is going through the tunnel. After some search I noticed it was not possible so I changed my focus to debugging ssh which gave me everthing I wanted.
Ssh is the secure channel for Ansible to connect to the cilent and run all the commands and scripts. When someone connects an ssh server (openssh), it creates a sub process which handles that connecction and gives a shell.
For sake of simplicity, I am going to make an ssh connection and show you some outputs. As seen below, from system monitor tool, we can get process id of the sshd and the shell it gives.
Below output shows process tree for the ssh connection.
Before comparing the modules, we need to enable low level debugging for ssh and sftp server which is heavily used by Ansible. I changed some parameters in the /etc/ssh/sshd_config file like below to get more verbosity.
LogLevel DEBUG3
Subsystem sftp /usr/lib/openssh/sftp-server -l DEBUG3
The logs will be collected in /var/log/auth.log
Ansible: Raw Module
I will make remote node ping another node, using raw module with “ansible all -m raw -a “ping 192.168.1.50 -c 4000” — ask-pass” command.
As we see below, raw module connects to the sshd sub process(3317) and make it create a sub ping process(3318) with -c 4000 parameter. Simply you connect server and it creates a ping process, that is all raw module does. It is as simple as a pure ssh connection without a shell.
Since raw module does not push any python script to the sftp server, I did not see any logs in the /var/log/auth.log file but only shh ping command. For better understanding here is another output below.
Ansible: Command Module
After applying “ansible all -m command -a “ping 192.168.1.50 -c 4000” — ask-pass”, There were some logs in the file related both sftp and ssh. For simplicity, below output summaries what’s happening at the background.
Command module uses ssh(sftp) to push a python file to the node. The details about python file and it’s location is in the log file like below.
So far sshd process (3116) was created and python file stored on the remote server. Next step, Ansible makes this file run on the node. When I filtered the file for ssh command with cat /var/log/auth.log | grep “entering command” I got the result below.
entering command /bin/sh -c ‘/usr/bin/python3 /home/osboxes/.ansible/tmp/ansible-tmp-1640793262.3616188–8166–160488554275701/AnsiballZ_command.py && sleep 0’
In short, sshd process(3116) created a shell(3137), telling it to make python(3138) run stored python file which created ping process(3140).
The process tree is below.
Ansible: Shell Module
I think you have understand the logic I will follow for Shell module too. The steps are almost identical with a little bit change in the result. Shell module is pretty similar to executing commands as if you are on the terminal.
I applied the Ad-Hoc command: “ansible all -m shell -a “ping 192.168.1.50 -c 4000” — ask-pass” and monitored the processes creation from System Monitor tool.
Log file output for sftp and ssh:
SSH command sent from Ansible to the remote node is below:
entering command /bin/sh -c ‘/usr/bin/python3 /home/osboxes/.ansible/tmp/ansible-tmp-1640793708.8731627–8196–38272766545634/AnsiballZ_command.py && sleep 0’
After running python script, the processes tree became like below.
Conclusion
Raw module is completely different from the other two modules and it does not push any python script to the remote node. It runs ping process through sshd process, as above. It could be used on devices like IoT or networking devices. Shell module runs the command(ping) inside a shell, providing piping(“|”), redirection(“>”) and operators(“&&”, “||”) . Shell module is susceptible to command injection/shell injection. In contrast to shell module, command module runs the command(ping) directly with python script. Unlike shell module, running commands can not use pipes and redirections. It can be said that command module is more secure than shell module.