Ansible fails to connect with SSH (banner exchange) - ssh

Sorry in advance if the question is not clear and/or if i am not askin where i should.
I have issues with connecting to hosts with ansible via SSH. It worked few days ago but i have been having the same message error for several days :
camille#ubuntu:~$ ansible all -m ping -u remote
192.xxx.xxx.xxx | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Connection timed out during banner exchange\r\n",
"unreachable": true
}
SSH connection (without ansible) with working nicely so i don't really understand the issue. I'm running Ansible on a Ubuntu 16.04 VM and the host i want to reach is a CentOS 7 VM.
My hosts file is the following :
[test]
192.xxx.xxx.xxx ansible_ssh_user=remote ansible_ssh_pass=password ansible_sudo_pass='password' #VM CentOS
I tried the solution explained here but it didn't fix the problem.
Edit 1: After trying Ripper Tops solution and testing some other things, my inventory now looks like this :
[test]
192.xxx.xxx.xxx ansible_connection=ssh ansible_user=remote ansible_password='password'
[test:vars]
proxy=my_proxy:8080
I also tried increasing timeout to 25, i still have the same issue.
Edit 2 :
After changing my ansible.cfg file, the error message has changed :
192.xxx.xxx.xxx | UNREACHABLE! => {
"changed": false,
"msg": "SSH Error: data could not be sent to remote host \"192.xxx.xxx.xxx\". Make sure this host can be reached over ssh",
"unreachable": true }
I test ssh connection again, it is still working nicely.
My config file is now :
[defaults]
timeout = 25
host_key_checking = False
roles_path = roles/
gathering = smart
[ssh_connection]
ssh_args = -o
ControlMaster=auto -o
ControlPersist=600s
control_path = %(directory)s/%%h-%%r
pipelining = True
Do you have any clue about this ?

Try to use ansible_user instead ansible_ssh_user and ansible_password instead ansible_ssh_pass. It depends of your ansible version.
Also you may need to place [group:vars] after [group] section in the inventory file.
There is simple way to check difference
ansible 192.168.15.29 -i your_hosts_file -m ping -e "ansible_ssh_user=remote ansible_ssh_pass=password"
or
ansible 192.168.15.29 -i your_hosts_file -m ping -e "ansible_user=remote ansible_password=password"

I finally fixed my issue ! :D
I apply the suggestions of Ripper Tops (thanks again) : change the ansible.cfg (see the 1st message)
I changed my hosts file to the following :
[test]
192.xxx.xxx.xxx ansible_user=remote ansible_password=remote_password ansible_ssh_user=remote ansible_ssh_pass=remote_password
[test:vars]
proxy=my_proxy:8080
I pinged my hosts using the -c paramiko option
Thanks again Ripper Tops for your time & help :)

Just want to add my two cents to this problem resolution:
Had the same issue and tried everything above, but that didn't work as my case wasn't exactly the same:
When i tried to do some playbooks towards multiple dozens of hosts, i received this error randomly on various hosts.
To fix this, i had to reduce the concurrency level from "serial: no" to "serial: 4". The number of concurrent executions depends on the network throughput and should be figured out experimentally or thorough digging and calculating your OS and hardware specifics.
It also definitely involves network and possible fork number on your bastion host if you use one.
I hope this might help someone with the situation like mine.

Related

Ansible issue with ssh authentication

i have searched around this problem for a while now but didnt find anything that helps.
We are using ansible to automate our Juniper devices and therefore use the ansible juniper modules. When i try to use "junos_facts" for example, i can execute it without problems on host1, but on host2 i get either a PasswordRequiredException or an AuthenticationException when i add -k in the cli
TASK [proact-junos-test : Gather JunOS facts] ***************************************************************************************************************************************************
fatal: [host2]: FAILED! => {"changed": false, "msg": "PasswordRequiredException('Private key file is encrypted')"}
ok: [host1]
i tried every possible combination of parameters in cli, in ansible.cfg, in the playbook itself. For some reason it works on one host but not the other. I have deployed the same key on both host and have it stored in my ssh-agent. I can ssh to both hosts without a problem.
Can anyone help me with this? Thanks
For anyone having the same issue, the problem was that the remote host didn't accept my SSH key algorithm, because, since Paramiko 2.9, it was deprecated.
So, I installed Paramike 2.8.1 and it worked
As far as I can understand, the problem is that ssh key is encrypted. Try to add ssh key to ssh agent (if you have it).
If you don't have, there is a simple trick:
eval $(ssh-agent)
ssh-add path/to/private/ssh/key
ansible ...
If you are running this in CI/CD environment you'll need to fight with ssh-add about the way to ask password, but that's a different story.

Running Automation on Google Cloud Virtual Instances using Ansible

I'm trying to automate google cloud virtual instances remotely only using external ip addresses of virtual machines. I can ssh into the virtual machines using command line with user name shishir9159_gmail_com . But If I use any ansible commands like this:
ansible -i hosts -u shishir9159_gmail_com --private-key=~/.ssh/google_compute_engine -m ping all
and it results in this following error:
"msg": "Failed to connect to the host via ssh: shishir9159#35.202.219.6: Permission denied (publickey,gssapi-keyex,gssapi-with-mic)."
I've added some parameters in my ansible.cfg:
host_key_checking = False
ssh_args = -o ControlMaster=no
But I don't think they do much of a help according to this post:
https://serverfault.com/questions/929222/ansible-where-do-preferredauthentications-ssh-settings-come-from
And I tried many methods and recommendations. I have a service account but it doesn't seem to me necessary for this simple ping command.
The problem is in the underscores of the user name. Try to add a username without underscore or try using quote.
I solved the problem by adding ansible_ssh_user and ansible_ssh_pass at the hosts file. This post contain the solution.
ansible SSH connection fail

Ansible command fails with 'Failed to connect to the host via ssh' but succeeds after doing 'ansible all -m ping' - why?

This is on an Ubuntu 16.10 Linux VM (host) going to an EC2 Ubuntu instance (client).
I do this command:
sudo ansible-playbook deploy.yml -vvv
And get:
fatal: [web1]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh.", "unreachable": true}
Yet if I do this immediately (seconds) afterward:
ansible all -m ping
The previous command works!
Is it something to do with ControlPersist=60s, like no more commands can be issued? Confusing.
Seems like this may be a known Ansible bug where SSH connections intermittently fail, and give a poor error message. I'm on Ansible 2.1.1, the same version that so many people in this bug report are on too:
https://github.com/ansible/ansible/issues/15706
So upgrading Ansible would probably get around the error. Or use the workaround I discovered of pinging ansible <your hosts> -m ping.

Ansible: "sudo: a password is required\r\n" [duplicate]

This question already has an answer here:
How can a user with SSH keys authentication have sudo powers in Ansible? [duplicate]
(1 answer)
Closed 5 years ago.
quick question
I have setup an Ubuntu server with a user named test. I copy the authorized_keys to it, I can ssh no problem.
If I do $ ansible -m ping ubu1, no problem I get a response
<i><p>ubu1 | SUCCESS => {
<br>"changed": false,
<br>"ping": "pong"
<br>}</i>
What I dont get is this, If I do
$ ansible-playbook -vvvv Playbooks/htopInstall.yml
fatal: [ubu1]: FAILED! => {"changed": false, "failed": true, "invocation": {"module_name": "setup"}, "module_stderr": "OpenSSH_7.2p2 Ubuntu-4ubuntu2.1, OpenSSL 1.0.2g-fips 1 Mar 2016\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 19: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 6109\r\ndebug3: mux_client_request_session: session request sent\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 1\r\nShared connection to 192.168.1.112 closed.\r\n", "module_stdout": "sudo: a password is required\r\n", "msg": "MODULE FAILURE", "parsed": false}
If I do $ ansible-playbook --ask-sudo-pass Playbooks/htopInstall.yml, then it ask my user password and the play is a success.
If I rename the authorized_keys it tells me I "Failed to connect to the host via ssh." which is ok.
What I dont understand is why is it asking for a sudo password. I definetly missed something along the way.
my ansible.cfg file looks like this
[defaults]
nocows = 1
inventory = ./Playbooks/hosts
remote_user = test
private_key_file = /home/test/.ssh/id_ubu
host_key_checking = false
my hosts file looks like this
[servers]
ubu1 ansible_ssh_host=192.168.1.112 ansible_ssh_user=test
What I dont understand is why is it asking for a sudo password.
We can't say for certain without seeing your playbook, but it's almost certainly because a) your playbook asks Ansible to run a particular command with sudo (via the sudo or become directives) and b) the test user does not have password-less sudo enabled.
It sounds like you are aware of (a) but are confused about (b); specifically, what I'm picking up is that you don't understand the difference between ssh authentication and sudo authentication. Again, without more information I can't confirm if this is the case, but I'll take a stab at explaining it in case I guessed correctly.
When you connect to a machine via ssh, there are two primary ways in which sshd authenticates you and allows you to log in as a particular user. The first is to ask for the account's password, which is hands off to the system, and allows a login if it was correct. The second is through public-key cryptography, in which you prove that you have access to a private key that corresponds to a public key fingerprint in ~/.ssh/authorized_keys. Passing sshd's authentication checks gives you a shell on the machine.
When you invoke a command with sudo, you're asking sudo to elevate your privileges beyond what the account normally gets. This is an entirely different system, with rules defined in /etc/sudoers (which you should edit using sudo visudo) that control which users are allowed to use sudo, what commands they should be able to run, whether they need to re-enter their password or not when using the command, and a variety of other configuration options.
When you run the playbook normally, Ansible is presented with a sudo prompt and doesn't know how to continue - it doesn't know the account password. That's why --ask-sudo-pass exists: you're giving the password to Ansible so that it can pass it on to sudo when prompted. If you don't want to have to type this every time and you've decided it's within your security parameters to allow anyone logged in as the test user to perform any action as root, then you can consult man sudoers on how to set passwordless sudo for that account.
I solved this exact error sudo: a password is required\n which I got when running my playbook with become: true but somewhere in a task delegating to localhost, something like this:
uri:
url: "{{ some_url }}"
return_content: yes
status_code: 200
delegate_to: 127.0.0.1
If I understood correctly, the become: true causes Ansible to log into the remote host as my user and then use sudo in order to execute all commands on the remote host as root. Now when delegating to 127.0.0.1, sudo is also executed and as it happens that on my localhost a password is expected when using sudo.
For me the solution was simply to remove the delegate_to, which was not actually needed in that particular use case.

Write failed : broken pipe

I have a headless Ubuntu server. I ran a command on the server (snapraid sync) over SSH from my Mac. The command said it would take about 6 hrs, so I left it over night.
When I came down this morning, the Terminal on the Mac said: "Write failed: broken pipe"
I'm not sure if the command executed fully. Is this a timeout issue? If so, how can I keep the SSH connection alive overnight?
This should resolve the problem for Mac osX version: 10.8.2
add:
ServerAliveInterval 120
TCPKeepAlive no
to this file:
~/.ssh/config
Or, if you want it to be a global change in the SSH client, to this file
/private/etc/ssh_config
"ServerAliveInterval 120" basically says to "ping" the server with a NULL packet every 120s, and "TCPKeepAlive no" means to not set the SO_KEEPALIVE socket option (since you shouldn't need it with ServerAliveInterval already set, and apparently it's "spoofable" or some odd).
The servers similarly have something they could set for the same effect (ClientKeepAliveInterval) but typically you don't have control over those settings as much.
You can use "screen" util for that. Just connect to the server over SSH, start screen session by "screen" command execution, start your command there and disconnect (don't exit screen session). When you think your command already done you can connect to the server and attach to your screen session where you can see the command execution result/progress (in case one should be).
See "man screen" for more details.
This should resolve the problem for ubuntu and linux mint
add:
ServerAliveInterval 120
TCPKeepAlive yes
to
/etc/ssh/ssh_config file
Instead of screen I'd recommend tmux, an (arguably) better competitor to screen
tmux new-session -s {name}
That command creates a session. Any time after that you want to connect:
tmux a -t {name}
there are two solutions
To update server and restart server sshd
echo "ClientAliveInterval 60" | sudo tee -a /etc/ssh/sshd_config
To update client
echo "ServerAliveInterval 60" >> ~/.ssh/config
After having tried to change many of above parameters in sshd_config (ClientAliveInterval, ClientMaxCount,TCPKeepAlive...) nothing had changed. I have spend hours and days to look for a solution on forums and blogs...
It appears that the problem of broken pipe which forbids to connect with ssh/sftp came from permissions settings on ChrootDirectory.
the ChrootDirectory has to be owned by root/root with 755 permision
lower permissions 765/766/775... won't work but strongers do (eg 700)
if you need to give a write permission to connected user, you can give it in sub-directories.
if chroot is owned by sftpUser:sftpGroup, it won't work neither...
chroot-> root:root 755
|
---subdirectories-> sftpUser:sftpGroup 700 up to 770
hope it would help
If you're still having problem after editing /etc/ssh/sshd_config or if ~/.ssh/config
simply does not exist on your machine then I highly recommend reinstalling ssh. This solution took about a minute to fig both "Broken pipe" errors and "closed by remote host" errors.
sudo apt-get purge openssh-server
sudo apt update
sudo apt install openssh-server
jeremyforan's answer is correct, however I've found that if you are trying to use scp it is necessary to explicitly point it to a config file configured as described, it seems to not obey the normal hierarchy of config. For example:
scp -F ~/.ssh/config myfile joe#myserver.com:~
works, while omitting the -F still results in the broken pipe error.
Ubuntu :
ssh -o ServerAliveInterval=5 -o ServerAliveCountMax=1 user#x.x.x.x
I use an ASUS router with two internet input lines. I appoint my IP to a certain line, and it works.