Як обробити зміни порту SSH за допомогою Ansible?


27

Я намагаюся використовувати Ansible для автоматизації процесу налаштування нових екземплярів сервера. Одне із завдань налаштування змінює порт SSH за замовчуванням, тому вимагає від мене оновити список хостів.

Чи можливо автоматизувати це, встановивши Ansible backback до вказаного порту, якщо з'єднання не вдалося встановити до SSH-порта за замовчуванням?

Відповіді:


15

Ви можете спробувати локальну перевірку на хостах, щоб побачити, чи можете ви підключитися до відповідних портів і зареєструвати той, що вдається, і встановити це як факт. Ви хочете вимкнути збір фактів, оскільки в іншому випадку модуль налаштування не вдасться, коли він намагається з'єднатися з хостами, які вже були налаштовані. Після того, як ви виконали цю гру, просто додайте інші нижче зі збиранням_фактів та всім іншим.

- 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

Мені вказували, що це вибухне час для ігор, де ви цим користуєтесь. Ви також можете встановити ansible_ssh_port у розділі відтворень, яке слід виконувати лише на хостах із перенастроєним портом ssh. напр

- name: change ssh ports
  tasks:
    - name: edit sshd_config
      lineinfile ..
      notify: restart ssh
   handlers:
     - name: restart ssh
       service: sshd state=restarted
- name: continue setup
  vars:
    - ansible_ssh_port : 5422
  tasks:
    ...

Ваша стратегія тестування портів у поєднанні з встановленням фактів здається ідеальним підходом до цих випадків. Спасибі!!!
Джей Тейлор

10

@RichardSalts дякую, що почав мене з цього. Я використовував nc для перевірки портів, які повинні бути набагато швидшими. Це мій bootstrap.xml:

Тестовано з використанням ansible 1.5 (devel 3b8fd62ff9) востаннє оновлено 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

5

Оскільки ви, ймовірно, рано розгортаєте свій ssh ​​config, вам дійсно слід це робити просто. Просто налаштуйте свій інвентар з цільовим ansible_ssh_portі використовуйте -eпід час першого розгортання конфігурації ssh:

ansible-playbook bootstrap_ssh.yml -e 'ansible_ssh_port=22'

Зауважте, що ansible_ssh_portзастаріле в 2.0 (замінено ansible_port)


3

Чи можливо автоматизувати це, встановивши Ansible backback до вказаного порту, якщо з'єднання не вдалося встановити до SSH-порта за замовчуванням?

Також мені була потрібна аналогічна функціональність, тому я роздрібнив і закріпив плагін Ansible ssh, сподіваючись, що Ansible Inc. прийме його; вони цього не зробили. Він перевіряє не std специфікації порту ssh, щоб побачити, чи вони відкриті, і повертається до стандартного порту ssh, якщо ні. Це дуже маленький патч, доступний на веб- сайті https://github.com/crlb/ansible .


1

Якщо у вас є список портів, і ви хочете перевірити їх усіх і використовувати той, що працює, ви можете використовувати це у своїй програмі:

- 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}}"

0

Я придумав надійний ідентичний список завдань, щоб поставити собі роль змінити порт SSH та обробляти підключення до потрібного порту без зміни файлу інвентаря. Я опублікував деталі у своєму блозі: https://dmsimard.com/2016/03/15/changing-the-ssh-port-with-ansible/


3
Ми дійсно вважаємо за краще відповіді містити вміст, а не покажчики на вміст, який легко втратити.
user9517 підтримує GoFundMonica

Також ваш сценарій не працює, default_ssh.state викликає виняток'dict object' has no attribute 'state'
sandre89
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.