Làm cách nào để xử lý các thay đổi cổng SSH với Ansible?


27

Tôi đang cố gắng sử dụng Ansible để tự động hóa quá trình thiết lập các phiên bản máy chủ mới. Một trong những tác vụ thiết lập thay đổi cổng SSH mặc định, do đó yêu cầu tôi cập nhật danh sách máy chủ.

Có thể tự động hóa việc này bằng cách chuyển dự phòng Ansible sang một cổng được chỉ định nếu kết nối không thể được thiết lập với cổng SSH mặc định?

Câu trả lời:


15

Bạn có thể thử local_action trên máy chủ để xem liệu bạn có thể kết nối với các cổng tương ứng hay không và đăng ký cổng thành công và đặt điều đó thành sự thật. Bạn muốn tắt thu thập dữ kiện vì nếu không mô-đun thiết lập sẽ thất bại khi nó cố gắng kết nối với các máy chủ đã được cấu hình lại. Khi bạn đã thực hiện trò chơi này, chỉ cần thêm những người khác bên dưới với tập hợp_facts và tất cả phần còn lại.

- 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

Nó đã được chỉ ra cho tôi rằng điều này sẽ thổi bay thời gian cho các vở kịch mà bạn sử dụng nó. Bạn cũng có thể đặt ansible_ssh_port trong phần vars của các lần phát chỉ nên chạy trên máy chủ có cổng ssh được cấu hình lại. ví dụ

- 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:
    ...

Chiến lược kiểm tra cổng của bạn kết hợp với thiết lập các sự kiện có vẻ như là một cách tiếp cận lý tưởng cho những trường hợp này. Cảm ơn!!!
Jay Taylor

10

@RichardSalts cảm ơn vì đã giúp tôi bắt đầu với điều này. Tôi đã sử dụng nc để kiểm tra các cổng sẽ nhanh hơn rất nhiều. Đây là bootstrap.xml của tôi:

Đã thử nghiệm bằng cách sử dụng ansible 1.5 (devel 3b8fd62ff9) được cập nhật lần cuối 2014/01/11 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

Vì bạn có thể triển khai cấu hình ssh sớm, nên bạn thực sự nên giữ đơn giản. Chỉ cần định cấu hình khoảng không quảng cáo của bạn với mục tiêu ansible_ssh_portvà sử dụng -ekhi triển khai cấu hình ssh của bạn lần đầu tiên:

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

Lưu ý rằng ansible_ssh_portkhông được chấp nhận trong 2.0 (thay thế bởi ansible_port)


3

Có thể tự động hóa việc này bằng cách chuyển dự phòng Ansible sang một cổng được chỉ định nếu kết nối không thể được thiết lập với cổng SSH mặc định?

Tôi cũng cần chức năng tương tự, vì vậy tôi đã rẽ nhánh và vá plugin Ansible ssh với hy vọng rằng Ansible Inc. sẽ áp dụng nó; họ đã không làm thế. Nó kiểm tra các thông số kỹ thuật của cổng ssh không std để xem chúng có mở không và hoàn nguyên về cổng ssh mặc định nếu không. Đó là một bản vá rất nhỏ, có sẵn tại https://github.com/crlb/ansible .


1

Nếu bạn có danh sách các cổng và bạn muốn kiểm tra tất cả các cổng và sử dụng một cổng hoạt động, bạn có thể sử dụng cổng này trong sổ chơi của mình:

- 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

Tôi đã đưa ra một danh sách nhiệm vụ idempotent mạnh mẽ để đóng vai trò thay đổi cổng SSH và xử lý kết nối với cổng bên phải mà không phải thay đổi tệp kiểm kê của bạn. Tôi đã đăng chi tiết trên blog của mình: https://dmsimard.com/2016/03/15/changing-the-ssh-port-with-ansible/


3
Chúng tôi thực sự thích câu trả lời để chứa nội dung không phải con trỏ đến nội dung có thể dễ dàng bị mất.
user9517 hỗ trợ GoFundMonica

Ngoài ra, tập lệnh của bạn không thành công, default_ssh.state đưa ra một ngoại lệ'dict object' has no attribute 'state'
sandre89
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.