Jak obsługiwać zmiany portów SSH za pomocą Ansible?
27
Próbuję użyć Ansible do automatyzacji procesu instalacji nowych instancji serwera. Jedno z zadań instalacyjnych zmienia domyślny port SSH, dlatego wymaga ode mnie aktualizacji listy hostów.
Czy można to zautomatyzować, korzystając z opcji Ansible fallback do określonego portu, jeśli nie można nawiązać połączenia z domyślnym portem SSH?
Możesz spróbować działania lokalnego na hostach, aby sprawdzić, czy możesz połączyć się z odpowiednimi portami i zarejestrować ten, który się powiedzie, i ustawić to jako fakt. Chcesz wyłączyć zbieranie faktów, ponieważ w przeciwnym razie moduł konfiguracji zawiedzie, gdy spróbuje połączyć się z hostami, które zostały już ponownie skonfigurowane. Po zakończeniu tej gry po prostu dodaj inne osoby poniżej z parametrami gather_facts i całą resztą.
- 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
Zwrócono mi uwagę, że to wydłuży czas na poradniki, w których tego używasz. Możesz także ustawić ansible_ssh_port w sekcji vars gier, które powinny być uruchamiane tylko na hostach ze zrekonfigurowanym portem ssh. na przykład
Twoja strategia testowania portów w połączeniu z ustalaniem faktów wydaje się idealnym rozwiązaniem dla tych przypadków. Dzięki!!!
Jay Taylor
10
@RichardSalts dzięki za rozpoczęcie od tego. Użyłem nc do sprawdzenia portów, które powinny być znacznie szybsze. To jest mój bootstrap.xml:
Testowane przy użyciu ansible 1.5 (devel 3b8fd62ff9) ostatnia aktualizacja 2014/01/28 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
Ponieważ prawdopodobnie wdrożyłeś konfigurację ssh wcześnie, naprawdę powinieneś zachować to proste. Po prostu skonfiguruj swój ekwipunek z celem ansible_ssh_porti użyj go -epodczas wdrażania konfiguracji ssh po raz pierwszy:
Czy można to zautomatyzować, korzystając z opcji Ansible fallback do określonego portu, jeśli nie można nawiązać połączenia z domyślnym portem SSH?
Potrzebowałem również podobnej funkcjonalności, więc rozwidliłem i załatałem wtyczkę Ansible ssh, mając nadzieję, że Ansible Inc. ją zastosuje; nie zrobili tego. Testuje specyfikacje nietypowego portu ssh, aby sprawdzić, czy są otwarte, a jeśli nie, powraca do domyślnego portu ssh. To bardzo mała łatka, dostępna na https://github.com/crlb/ansible .
Jeśli masz listę portów i chcesz sprawdzić je wszystkie i użyć jednego działającego, możesz użyć tego w swoim poradniku:
- 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}}"
Wymyśliłem solidną idempotentną listę zadań, która ma za zadanie zmienić port SSH i obsłużyć połączenie z odpowiednim portem bez konieczności zmiany pliku inwentarza. Opublikowałem szczegóły na moim blogu: https://dmsimard.com/2016/03/15/changing-the-ssh-port-with-ansible/
@RichardSalts dzięki za rozpoczęcie od tego. Użyłem nc do sprawdzenia portów, które powinny być znacznie szybsze. To jest mój bootstrap.xml:
Testowane przy użyciu ansible 1.5 (devel 3b8fd62ff9) ostatnia aktualizacja 2014/01/28 20:26:03
źródło
Ponieważ prawdopodobnie wdrożyłeś konfigurację ssh wcześnie, naprawdę powinieneś zachować to proste. Po prostu skonfiguruj swój ekwipunek z celem
ansible_ssh_port
i użyj go-e
podczas wdrażania konfiguracji ssh po raz pierwszy:Uwaga:
ansible_ssh_port
przestarzała w wersji 2.0 (zastąpiona przezansible_port
)źródło
Potrzebowałem również podobnej funkcjonalności, więc rozwidliłem i załatałem wtyczkę Ansible ssh, mając nadzieję, że Ansible Inc. ją zastosuje; nie zrobili tego. Testuje specyfikacje nietypowego portu ssh, aby sprawdzić, czy są otwarte, a jeśli nie, powraca do domyślnego portu ssh. To bardzo mała łatka, dostępna na https://github.com/crlb/ansible .
źródło
Jeśli masz listę portów i chcesz sprawdzić je wszystkie i użyć jednego działającego, możesz użyć tego w swoim poradniku:
źródło
Wymyśliłem solidną idempotentną listę zadań, która ma za zadanie zmienić port SSH i obsłużyć połączenie z odpowiednim portem bez konieczności zmiany pliku inwentarza. Opublikowałem szczegóły na moim blogu: https://dmsimard.com/2016/03/15/changing-the-ssh-port-with-ansible/
źródło
'dict object' has no attribute 'state'