Interact with an allocated tty in ansible to login by CyberArk - ssh

I am attempting to use ansible in order to automatize some workflow in Linux Servers. However, I am forced to do the login using CyberArk.
In a normal ssh connection session, you can connect with your credentials and once you are logged, you are prompted to write the reason of the login.
When using ansible, I add my credentials and after using the debug parameters I find out this message:
'PSPSD072E Perform session error occurred. Reason: You are required to specify more information for this operation and no terminal was allocated. Use the [-t] option to force terminal allocation, or connect with SSH through PSMP to the target and then run the command.. (Codes: -1, -1)\n'
Next step, I edit ansible.cfg and I add the -tt parameter for the ssh conecction.
[ssh_connection]
ssh_args = -tt -C -o ControlMaster=auto -o ControlPersist=60s
However, when I run ansible right now, terminal is allocated and I can write text in an allocated terminal but I don't know how to close it. I mean, I am not aware how to submit a text and close this terminal and continue with the run of the playbook.
For example:
ansible-playbook -i inventory.yml playbook.yml --ask-pass -vvvv
SSH password: #here I write my credentials
PLAYBOOK: playbook.yml
TASK [command] #Task of the playbook
(Here I can start to write, but how to submit the text I just wrote?) #Terminal allocated
I tried to press to enter or control+c, but it does not work.
So basically, my question is, once the terminal is allocated in Ansible, how can I submit text and keep going the rest of the playbook?
Thanks.

Related

Prevent rsync from trying to ask for a password

How do I prevent rsync from trying to ask for a password for the remote server login?
Note: I am not asking how to set up public key authenticated SSH. I know how to set up public key authenticated SSH. What I am asking is how to prevent rsync from trying to ask for a password if public key authentication fails, like what scp's -B flag does. I am using rsync in a script here, so if it tries to ask for a password, my script will hang, waiting for input that will never come. I want the rsync command to instead fail, so my script can detect the failure and exit gracefully.
Just pass options to the underlying ssh command used by rsync:
rsync -e 'ssh -oBatchMode=yes [other ssh options]' [rest of rsync command]
From the rsync manual:
-e, --rsh=COMMAND specify the remote shell to use
From the ssh manual:
BatchMode
If set to “yes”, passphrase/password querying will be disabled.
This option is useful in scripts and other batch jobs where no
user is present to supply the password. The argument must be
“yes” or “no”. The default is “no”.
This emulates the bahavior os scp -B.

Ansible percent expand

I have an ansible playbook which connects to a virtual machine via a non-standard ssh port (forwarded to localhost) and a different user than the host user (vagrant).
The ssh port is specified in the ansible inventory:
[vms]
localhost:2222
The username given on the command line to ansible-playbook:
ansible-playbook -i <inventory from above> <some playbook> -u vagrant
The communication with the VM works correctly, however, %p always expands to 22 and %r to the host username.
Consequently, I cannot flush the SSH connection (for the user's changed group membership to take effect) like this:
- name: flush the ssh connection
command: ssh -o ControlPath="~/.ansible/cp/ansible-ssh-%h-%p-%r" -O stop {{inventory_hostname}}
delegate_to: 127.0.0.1
Am I making a silly mistake somewhere? Alternatively, is there a different way to flush the SSH connection?
The percent expand is not expanded by ansible, but by ssh later on.
Sorry, forgot to add the most important part
Using
command: ssh -o ControlPath=[...] -O stop {{inventory_hostname}}
will use default port, because you didn't specify it on the command-line. You would have to specify also the port to "flush" the connection this way:
command: ssh -o ControlPath=[...] -O stop -p {{inventory_port}} {{inventory_hostname}}
But I don't think it is needed. Ansible should clean up the connections when the playbook ends and I don't see any different reason why to do that.

Ansible prompts password when using synchronize

I'm using ansible in the following way:
ansible-playbook -f 1 my-play-book.yaml --ask-pass --ask-sudo-pass
After this I'm asked to enter the ssh & sudo passwords (same password for both).
Inside my playbook file I'm using synchronize task:
synchronize: mode=push src=rel/path/myfolder/ dest=/abs/path/myfolder/
For each host, I'm prompted to enter the ssh password of the remote host (the same that I entered in the beginning of the playbook run)
How can I avoid entering the password when executing synchronize task?
If you have setup the ssh keys correctly on the <host>, then the following should work.
ansible all -m synchronize -a "mode=push src=rel/path/myfolder/ dest=/abs/path/myfolder/" -i <host>, -vvv
I was able to get the above working without any password prompt.

How to do remote ssh non-interactively

I am trying to connect to a remote host from my local host through the below command.But there was a setting in the remote host that soon after we login it will prompt to enter a badge ID,password and reason for logging in, because it was coded like that in profile file on remote-host How can I overcome those steps and login directly non-interactively, without disturbing the code in profile.
jsmith#local-host$ ssh -t -t generic_userID#remote-host
Enter your badgeID, < exit > to abort:
Enter your password for <badgeID> :
Enter a one line justification for your interactive login to generic_userID
Small amendment: to overcome remote server expect approach is required, but in case local script connects to bunch of remote servers, which configuration may be broken, just use SSH options:
ssh -f -q -o BatchMode=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null USER#TARGETSYSTEM
This will omit ask for password in case there is no ssh_key setup, exit silently and continue with script/other hosts.
Puts ssh to background with -f, which is required when calling ssh command from sh (batch) file to remove local console redirect to remote input (implies -n).
Look into setting up a wrapper script around expect. This should do exactly what you're looking for.
Here are a few examples you can work from.
I have upvoted Marvin Pinto's answer because there is every reason to script this, in case there are other features in the profile that you need, such as Message of the Day motd.
However, there is a quick and dirty alternative if you don't want to make a script and you don't want other features from the profile. Depending on your preferred shell on the remote host, you can insist that the shell bypasses the profile files. For example, if bash is available on the remote host, you can invoke it with:
ssh -t -t generic_userID#remote-host bash --noprofile
I tested the above on the macOS 10.13 version of OpenSSH. Normally the command at the end of the ssh invocation is run non-interactively, but the -t flag allows bash to start an interactive shell.
Details are in the Start-up files section of the Bash Reference Manual.

why is the `tcgetattr` error seen when ssh is used for dumping the backup file on another server?

I want to dump a tables backup on another server and I am using ssh for doing it.
when I run the below command, it gives an error but dump file is copied to destination.
mysqldump -u username -ppassword dbname tablename | ssh -t -t servers_username#domain_name 'cat > /tmp/bckp.sql';
tcgetattr: Invalid argument
If I press CTRL+c then it appends error message with Killed by signal 2.
Why is this error?
I've seen this error when forcing pseudo-terminal allocation using ssh -t -t or ssh -tt.
The tcgetattr function is used to look up the attributes of the pseudoterminal represented by a file descriptor; it takes a file descriptor and a pointer to a termios structure to store the terminal metadata in. It looks to me from the stub code in glibc that this error represents a null pointer for the termios struct. I am not sure whether these same error handling semantics are in place for the platform-specific implementations of tcgetattr.
If you want to suppress this error, invoke ssh like so:
ssh 2>/dev/null
This will redirect STDERR to /dev/null; you won't see the error when invoking with this redirection. Note that this will mask other errors with ssh; you may need to remove this for debugging purposes.
In my case, forcing pty allocation on the outer ssh of a two-level ssh invocation fixed the problem.
Details:
When you provide a command for ssh to run ( e.g. ssh some_server "do_some_command" ), then ssh assumes you won't need an interactive session, and it will not allocate a pty as it submits the "do_some_command" job you asked it to.
However, things get interesting if you have two layers of ssh (e.g. let's say you want to ssh into a "gateway" machine first, and from there you ssh into an "inner" machine and run some "inner_command").
The thing is, with a two-layer ssh'ing job, from the perspective of the outer ssh, you are requesting that the outer ssh run a non-interactive command, hence the outer ssh will not allocate a tty.
If the command you are running in the inner ssh is meant to be interactive, it will probably want to query tty attributes and it will (righteously) complain that it is not being run on a tty.
The solution in my case was to force the outer ssh to allocate a pty, by using the -t argument. So it looked like this:
ssh -t <gateway_machine> "ssh <inner_machine> \"<inner_interactive_command>\" "
Greetings to the sysadmins out there