¿Cómo manejar los cambios de puerto SSH con Ansible?
27
Estoy tratando de usar Ansible para automatizar el proceso de configuración de nuevas instancias de servidor. Una de las tareas de configuración cambia el puerto SSH predeterminado, por lo que me exige actualizar la lista de hosts.
¿Es posible automatizar esto al tener una respuesta alternativa a un puerto específico si la conexión no se puede establecer en el puerto SSH predeterminado?
Puede probar una acción local en los hosts para ver si puede conectarse a los puertos respectivos y registrar el que tiene éxito y configurarlo como un hecho. Desea desactivar la recopilación de datos porque, de lo contrario, el módulo de configuración fallará cuando intente conectarse con los hosts que ya se han reconfigurado. Una vez que hayas hecho esta jugada, solo agrega otros a continuación con collect_facts y todo lo demás.
- name: determine ssh port
hosts: all
gather_facts: false
vars:
custom_ssh_port: 222
tasks:
- name: test default ssh port
local_action: wait_for port=22 timeout=5 host={{inventory_hostname}}
register: default_ssh
ignore_errors: true
- name: set ansible_ssh_port to default
set_fact: ansible_ssh_port=22
when: default_ssh.elapsed < 5
- name: test ssh on high port
local_action: wait_for port={{custom_ssh_port}} timeout=5 host={{inventory_hostname}}
register: high_ssh
when: default_ssh.elapsed >= 5
ignore_errors: true
- name: set ansible_ssh_port high
set_fact: ansible_ssh_port={{custom_ssh_port}}
when: default_ssh.elapsed >= 5 and high_ssh.elapsed < 5
Se me señaló que esto hará que se acabe el tiempo para los libros de jugadas donde usas esto. También puede establecer ansible_ssh_port en la sección vars de las reproducciones que solo se deben ejecutar en hosts con puerto ssh reconfigurado. p.ej
Su estrategia de pruebas de puerto junto con la configuración de hechos parece un enfoque ideal para estos casos. ¡¡¡Gracias!!!
Jay Taylor
10
@ RichardSalts gracias por ayudarme a comenzar con esto. Utilicé nc para verificar los puertos, que deberían ser mucho más rápidos. Este es mi bootstrap.xml:
Probado con ansible 1.5 (desarrollo 3b8fd62ff9) última actualización 28/01/2014 20:26:03
---
# Be sure to set the following variables for all hosts:
# vars:
# oldsshport: 22
# sshport: 555
# Might fail without setting remote_tmp = /tmp/ansible/$USER in your ansible.cfg. Also fix for directly below.
# Once host is setup most of the checks are skipped and works very quickly.
# Also, be sure to set non-standard shells in a different playbook later. Stick with /bin/bash until you can run apt install.
# Assumes root user has sshkey setup already. Not sure how to utilize the --ask-pass option. For now, use ssh-copy-id prior to running playbook on new host for root user (if needed).
# Test new ssh port
- name: ssh test nc {{ sshport }}
local_action: shell nc -z -w5 {{ inventory_hostname }} {{ sshport }}
register: nc_ssh_port
failed_when: nc_ssh_port.stdout.find('failed') != -1
changed_when: nc_ssh_port.stdout == ""
ignore_errors: yes
# Set port to new port if connection success
- name: set ansible_ssh_port
set_fact: ansible_ssh_port={{ sshport }}
when: nc_ssh_port|success
# Fail back to old port if new ssh port fails
- name: ssh test nc port {{ oldsshport }}
local_action: shell nc -z -w5 {{ inventory_hostname }} {{ oldsshport }}
register: nc_ssh_default
changed_when: nc_ssh_default.stdout == ""
ignore_errors: yes
when: nc_ssh_port|changed
# Set ansible to old port since new failed
- name: set ansible_ssh_port to {{ oldsshport }}
set_fact: ansible_ssh_port={{ oldsshport }}
when: nc_ssh_default|success and nc_ssh_port|changed
# Check if root user can ssh
- name: find user
local_action: shell ssh -o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=5 -p {{ ansible_ssh_port }} root@{{ inventory_hostname }} exit
register: ssh_as_root
failed_when: ssh_as_root.stdout.find('failed') != -1
changed_when: ssh_as_root.stderr.find('Permission denied') == -1
# If root user success, set this up to change later
- name: first user
set_fact: first_user={{ ansible_ssh_user }}
when: ssh_as_root|changed
# Set ssh user to root
- name: root user
set_fact: ansible_ssh_user=root
when: ssh_as_root|changed
# ANSIBLE FIX: /tmp/ansible isn't world-writable for setting remote_tmp = /tmp/ansible/$USER in ansible.cfg
- name: /tmp/ansible/ directory exists with 0777 permission
file: path=/tmp/ansible/ owner=root group=root mode=0777 recurse=no state=directory
changed_when: False
sudo: yes
# Setup user accounts
- include: users.yml
# Set ssh user back to default user (that was setup in users.yml)
- name: ansible_ssh_user back to default
set_fact: ansible_ssh_user={{ first_user }}
when: ssh_as_root|changed
# Reconfigure ssh with new port (also disables non-ssh key logins and disable root logins)
- name: sshd.conf
template: src=sshd_config.j2 dest=/etc/ssh/sshd_config owner=root group=root mode=0644
register: sshd_config
sudo: yes
# Force changes immediately to ssh
- name: restart ssh
service: name=ssh state=restarted
when: sshd_config|changed
sudo: yes
# Use updated ssh port
- name: set ansible_ssh_port
set_fact: ansible_ssh_port={{ sshport }}
when: nc_ssh_port|changed
Dado que probablemente implemente su configuración ssh temprano, realmente debería mantener esto simple. Simplemente configure su inventario con el objetivo ansible_ssh_porty -eúselo cuando implemente su configuración ssh por primera vez:
¿Es posible automatizar esto al tener una respuesta alternativa a un puerto específico si la conexión no se puede establecer en el puerto SSH predeterminado?
También necesitaba una funcionalidad similar, así que bifurqué y parcheé el complemento Ansible ssh con la esperanza de que Ansible Inc. lo adoptara; ellos no lo hicieron. Prueba las especificaciones de puerto ssh no estándar para ver si están abiertas y, de lo contrario, vuelve al puerto ssh predeterminado. Es un parche muy pequeño, disponible en https://github.com/crlb/ansible .
Si tiene una lista de puertos y desea verificarlos todos y usar uno que funcione, puede usar esto en su libro de jugadas:
- name: just test
hosts: server
gather_facts: false
vars:
list_of_ssh_ports: [22, 222, 234]
tasks:
- name: test ssh on port
sudo: no
local_action: wait_for port={{item}} timeout=5 host={{inventory_hostname}}
register: ssh_checks
with_items: "{{list_of_ssh_ports}}"
ignore_errors: true
- debug: msg = "{{item}}"
with_items: "{{ssh_checks.results}}"
- name: set available ansible_ssh_port
sudo: no
set_fact: ansible_ssh_port={{item.item}}
when: ssh_checks is defined and {{item.elapsed}} < 5
with_items: "{{ssh_checks.results}}"
Se me ocurrió una lista de tareas idempotentes robustas para cambiar el puerto SSH y manejar la conexión al puerto correcto sin tener que cambiar su archivo de inventario. He publicado los detalles en mi blog: https://dmsimard.com/2016/03/15/changing-the-ssh-port-with-ansible/
@ RichardSalts gracias por ayudarme a comenzar con esto. Utilicé nc para verificar los puertos, que deberían ser mucho más rápidos. Este es mi bootstrap.xml:
Probado con ansible 1.5 (desarrollo 3b8fd62ff9) última actualización 28/01/2014 20:26:03
fuente
Dado que probablemente implemente su configuración ssh temprano, realmente debería mantener esto simple. Simplemente configure su inventario con el objetivo
ansible_ssh_port
y-e
úselo cuando implemente su configuración ssh por primera vez:Tenga en cuenta que
ansible_ssh_port
está en desuso en 2.0 (reemplazado poransible_port
)fuente
También necesitaba una funcionalidad similar, así que bifurqué y parcheé el complemento Ansible ssh con la esperanza de que Ansible Inc. lo adoptara; ellos no lo hicieron. Prueba las especificaciones de puerto ssh no estándar para ver si están abiertas y, de lo contrario, vuelve al puerto ssh predeterminado. Es un parche muy pequeño, disponible en https://github.com/crlb/ansible .
fuente
Si tiene una lista de puertos y desea verificarlos todos y usar uno que funcione, puede usar esto en su libro de jugadas:
fuente
Se me ocurrió una lista de tareas idempotentes robustas para cambiar el puerto SSH y manejar la conexión al puerto correcto sin tener que cambiar su archivo de inventario. He publicado los detalles en mi blog: https://dmsimard.com/2016/03/15/changing-the-ssh-port-with-ansible/
fuente
'dict object' has no attribute 'state'