Answers: <p>You defined multiple <code>ansible_ssh_common_args</code> vars per host. That does'nt work. Ansible will use only one of it (I asume the last). Also you try to reach the bastion host via 10.1.0.49 (but you do not mention that in your question). I think, the second <code>ansible_ssh_common_args</code> in the hostvars of <code>bastion</code> is wrong.</p>
  <p>You could have this vars...</p>
  <pre><code>[bastions:vars]
  ansible_ssh_common_args='-o StrictHostKeyChecking=no'
  ...
  
  [jenkins:vars]
  ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o ProxyCommand=&quot;ssh -o StrictHostKeyChecking=no -W [%h]:%p -q ubuntu@10.1.0.49&quot;'
  </code></pre>
  <p>Also - just a notice - ignoring the host key is not very &quot;secure&quot; - especially when you use a bastion host (which is more or less a man-in-the-middle which you need to trust).</p>
  
Answers: CC BY-SA 4.0
Answers: 2021-02-01T10:30:24.003Z
Answers: 2021-02-01T10:30:24.003Z
Answers: TRW
Body: <p>I am trying to connect to my bastion host and then tunnel that ssh connection to connect to a jenkins host but keep running into the connection timed out error.</p>
  <p>The error message in full is:</p>
  <pre><code>fatal: [&lt;bastion-public-ip&gt;]: UNREACHABLE! =&gt; {
      &quot;changed&quot;: false,
      &quot;msg&quot;: &quot;Failed to connect to the host via ssh: Connection timed out during banner exchange&quot;,
      &quot;unreachable&quot;: true
  }
  </code></pre>
  <p>my inventory file:</p>
  <pre><code>[bastion]
  #ip for bastion host
  &lt;bastion-public-ip&gt;
  
  [bastion:vars]
  ansible_ssh_user=ubuntu
  ansible_python_interpreter=/usr/bin/python3
  ansible_ssh_common_args='-o StrictHostKeyChecking=no'
  ansible_ssh_common_args='-o ProxyCommand=&quot;ssh -W %h:%p -q ubuntu@10.0.1.49&quot;'
  ansible_ssh_private_key_file=~/.ssh/bastion.pem
  
  [jenkins]
  #ip of EC2 instance
  10.0.1.49
  
  [jenkins:vars]
  ansible_user=ubuntu
  ansible_python_interpreter=/usr/bin/python3
  ansible_ssh_common_args='-o StrictHostKeyChecking=no'
  ubuntu@10.0.1.49'
  ansible_ssh_common_args='-o StrictHostKeyChecking=no'
  ansible_ssh_private_key_file=~/j-key.pem
  </code></pre>
  <p>And my playbook file is:</p>
  <pre><code>- hosts: bastion
    become: true
  
  - hosts: jenkins
    # run as the root user on the remote machine
    become: true
    # list of tasks to run on the remote machine
    tasks:
    - name: 'update system'
      apt: name=aptitude state=latest update_cache=yes force_apt_get=yes
  
    - name: 'install docker'
      script: docker.sh
  
    - name: 'install docker-compose'
      script: docker-compose.sh
  
    - name: 'install Jenkins'
      script: jenkins.sh
  </code></pre>
  <p>My ansible version is: ansible 2.9.13</p>
  <p>EDIT: Wanted to add the rules for the security group my bastion server is in</p>
  <p>Port 22 is open to TCP traffic from everywhere currently</p>
  <p>EDIT 2: -vvv flag output</p>
  <pre><code>ansible-playbook 2.9.13
    config file = /etc/ansible/ansible.cfg
    configured module search path = ['/home/qa/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
    ansible python module location = /home/qa/.local/lib/python3.8/site-packages/ansible
    executable location = /home/qa/.local/bin/ansible-playbook
    python version = 3.8.5 (default, Jul 28 2020, 12:59:40) [GCC 9.3.0]
  Using /etc/ansible/ansible.cfg as config file
  host_list declined parsing /home/qa/Projects/Final-Project/ansible/inventory as it did not pass its verify_file() method
  script declined parsing /home/qa/Projects/Final-Project/ansible/inventory as it did not pass its verify_file() method
  auto declined parsing /home/qa/Projects/Final-Project/ansible/inventory as it did not pass its verify_file() method
  Parsed /home/qa/Projects/Final-Project/ansible/inventory inventory source with ini plugin
  
  PLAYBOOK: test-playbook.yml ******************************************************************************************************
  2 plays in test-playbook.yml
  
  PLAY [bastion] *******************************************************************************************************************
  
  TASK [Gathering Facts] ***********************************************************************************************************
  task path: /home/qa/Projects/Final-Project/ansible/test-playbook.yml:1
  &lt;bastion_public_ip&gt; ESTABLISH SSH CONNECTION FOR USER: ubuntu
  &lt;bastion_public_ip&gt; SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'IdentityFile=&quot;/home/qa/.ssh/bastion.pem&quot;' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User=&quot;ubuntu&quot;' -o ConnectTimeout=25 -o 'ProxyCommand=ssh -W %h:%p -q ubuntu@10.0.1.49' -o ControlPath=/home/qa/.ansible/cp/13196dcaf6 bastion_public_ip '/bin/sh -c '&quot;'&quot;'echo ~ubuntu &amp;&amp; sleep 0'&quot;'&quot;''
  &lt;bastion_public_ip&gt; (255, b'', b'Connection timed out during banner exchange\r\n')
  fatal: [bastion_public_ip]: UNREACHABLE! =&gt; {
      &quot;changed&quot;: false,
      &quot;msg&quot;: &quot;Failed to connect to the host via ssh: Connection timed out during banner exchange&quot;,
      &quot;unreachable&quot;: true
  }
  
  PLAY RECAP ***********************************************************************************************************************
  bastion_public_ip                  : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0
  </code></pre>
  
Comments: CC BY-SA 4.0
Comments: 2020-10-25T21:23:34.637Z
Comments: I'm guessing that every occurrence of `bastion_public_ip` on the output was originally the actual IP, which you have removed for putting it on the Internet, is that right?  And that the IP is the correct one?
Comments: caxcaxcoatl
Comments: CC BY-SA 4.0
Comments: 2020-10-25T21:25:15.117Z
Comments: Your `-vvv` output shows the `ssh` command Ansible is trying; try to execute it yourself, perhaps with its own `-vvv`, and see what happens: `ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o 'IdentityFile="/home/qa/.ssh/bastion.pem"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ubuntu"' -o ConnectTimeout=25 -o 'ProxyCommand=ssh -W %h:%p -q ubuntu@10.0.1.49' -o ControlPath=/home/qa/.ansible/cp/13196dcaf6 bastion_public_ip`
Comments: caxcaxcoatl
Tags: <jenkins><amazon-web-services><ansible><amazon-ec2>
Title: Ansible playbook error: "Connection timed out during banner exchange"
UserDisplayName: Imp0sterSyndromeSufferer
ThreadText: # Ansible playbook error: "Connection timed out during banner exchange"
  
  (Asked by: username_0 on 2020-10-23)
  
  I am trying to connect to my bastion host and then tunnel that ssh connection to connect to a jenkins host but keep running into the connection timed out error.
  
  The error message in full is:
  
  ```
  fatal: [<bastion-public-ip>]: UNREACHABLE! => {
      "changed": false,
      "msg": "Failed to connect to the host via ssh: Connection timed out during banner exchange",
      "unreachable": true
  }
  
  ```
  
  my inventory file:
  
  ```
  [bastion]
  #ip for bastion host
  <bastion-public-ip>
  
  [bastion:vars]
  ansible_ssh_user=ubuntu
  ansible_python_interpreter=/usr/bin/python3
  ansible_ssh_common_args='-o StrictHostKeyChecking=no'
  ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p -q ubuntu@10.0.1.49"'
  ansible_ssh_private_key_file=~/.ssh/bastion.pem
  
  [jenkins]
  #ip of EC2 instance
  10.0.1.49
  
  [jenkins:vars]
  ansible_user=ubuntu
  ansible_python_interpreter=/usr/bin/python3
  ansible_ssh_common_args='-o StrictHostKeyChecking=no'
  ubuntu@10.0.1.49'
  ansible_ssh_common_args='-o StrictHostKeyChecking=no'
  ansible_ssh_private_key_file=~/j-key.pem
  
  ```
  
  And my playbook file is:
  
  ```
  - hosts: bastion
    become: true
  
  - hosts: jenkins
    # run as the root user on the remote machine
    become: true
    # list of tasks to run on the remote machine
    tasks:
    - name: 'update system'
      apt: name=aptitude state=latest update_cache=yes force_apt_get=yes
  
    - name: 'install docker'
      script: docker.sh
  
    - name: 'install docker-compose'
      script: docker-compose.sh
  
    - name: 'install Jenkins'
      script: jenkins.sh
  
  ```
  
  My ansible version is: ansible 2.9.13
  
  EDIT: Wanted to add the rules for the security group my bastion server is in
  
  Port 22 is open to TCP traffic from everywhere currently
  
  EDIT 2: -vvv flag output
  
  ```
  ansible-playbook 2.9.13
    config file = /etc/ansible/ansible.cfg
    configured module search path = ['/home/qa/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
    ansible python module location = /home/qa/.local/lib/python3.8/site-packages/ansible
    executable location = /home/qa/.local/bin/ansible-playbook
    python version = 3.8.5 (default, Jul 28 2020, 12:59:40) [GCC 9.3.0]
  Using /etc/ansible/ansible.cfg as config file
  host_list declined parsing /home/qa/Projects/Final-Project/ansible/inventory as it did not pass its verify_file() method
  script declined parsing /home/qa/Projects/Final-Project/ansible/inventory as it did not pass its verify_file() method
  auto declined parsing /home/qa/Projects/Final-Project/ansible/inventory as it did not pass its verify_file() method
  Parsed /home/qa/Projects/Final-Project/ansible/inventory inventory source with ini plugin
  
  PLAYBOOK: test-playbook.yml ******************************************************************************************************
  2 plays in test-playbook.yml
  
  PLAY [bastion] *******************************************************************************************************************
  
  TASK [Gathering Facts] ***********************************************************************************************************
  task path: /home/qa/Projects/Final-Project/ansible/test-playbook.yml:1
  <bastion_public_ip> ESTABLISH SSH CONNECTION FOR USER: ubuntu
  <bastion_public_ip> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'IdentityFile="/home/qa/.ssh/bastion.pem"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ubuntu"' -o ConnectTimeout=25 -o 'ProxyCommand=ssh -W %h:%p -q ubuntu@10.0.1.49' -o ControlPath=/home/qa/.ansible/cp/13196dcaf6 bastion_public_ip '/bin/sh -c '"'"'echo ~ubuntu && sleep 0'"'"''
  <bastion_public_ip> (255, b'', b'Connection timed out during banner exchange\r\n')
  fatal: [bastion_public_ip]: UNREACHABLE! => {
      "changed": false,
      "msg": "Failed to connect to the host via ssh: Connection timed out during banner exchange",
      "unreachable": true
  }
  
  PLAY RECAP ***********************************************************************************************************************
  bastion_public_ip                  : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0
  
  ```
  
  **Tags:** jenkins, amazon-web-services, ansible, amazon-ec2
  
  > **Comments:**
  > **username_1**: I'm guessing that every occurrence of `bastion_public_ip` on the output was originally the actual IP, which you have removed for putting it on the Internet, is that right?  And that the IP is the correct one?  
  > **username_1**: Your `-vvv` output shows the `ssh` command Ansible is trying; try to execute it yourself, perhaps with its own `-vvv`, and see what happens: `ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o 'IdentityFile="/home/qa/.ssh/bastion.pem"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ubuntu"' -o ConnectTimeout=25 -o 'ProxyCommand=ssh -W %h:%p -q ubuntu@10.0.1.49' -o ControlPath=/home/qa/.ansible/cp/13196dcaf6 bastion_public_ip`  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_2 on 2021-02-01. Score: 1
  
  You defined multiple `ansible_ssh_common_args` vars per host. That does'nt work. Ansible will use only one of it (I asume the last). Also you try to reach the bastion host via 10.1.0.49 (but you do not mention that in your question). I think, the second `ansible_ssh_common_args` in the hostvars of `bastion` is wrong.
  
  You could have this vars...
  
  ```
  [bastions:vars]
  ansible_ssh_common_args='-o StrictHostKeyChecking=no'
  ...
  
  [jenkins:vars]
  ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o ProxyCommand="ssh -o StrictHostKeyChecking=no -W [%h]:%p -q ubuntu@10.1.0.49"'
  
  ```
  
  Also - just a notice - ignoring the host key is not very "secure" - especially when you use a bastion host (which is more or less a man-in-the-middle which you need to trust).
  
  
  ---
  
  