Cách sử dụng Ansible để tự động thiết lập máy chủ ban đầu trên Ubuntu 22.04

Giới thiệu

Tự động hóa máy chủ hiện đóng một vai trò thiết yếu trong quản trị hệ thống, do tính chất dùng một lần của môi trường ứng dụng hiện đại. Các công cụ quản lý cấu hình như Ansible thường được sử dụng để hợp lý hóa quy trình tự động hóa thiết lập máy chủ bằng cách thiết lập các quy trình chuẩn cho máy chủ mới, đồng thời giảm lỗi do con người liên quan đến thiết lập thủ công.

Ansible cung cấp một kiến trúc đơn giản không yêu cầu cài đặt phần mềm đặc biệt trên các node. Nó cũng cung cấp một bộ tính năng mạnh mẽ và các mô-đun tích hợp giúp tạo điều kiện thuận lợi cho việc viết các tập lệnh tự động hóa.

Điều kiện

Để thực hiện thiết lập tự động do playbook cung cấp trong hướng dẫn này, bạn sẽ cần:

  • Một Ansible control node: một máy Ubuntu 22.04 được cài đặt và định cấu hình Ansible để kết nối với các máy chủ Ansible của bạn bằng các SSH key. Đảm bảo control node có người dùng thông thường với đặc quyền sudo và bật tường lửa, như được giải thích trong hướng dẫn Thiết lập Máy chủ Ban đầu của chúng tôi. Để thiết lập Ansible, vui lòng làm theo hướng dẫn của chúng tôi về Cách cài đặt và định cấu hình Ansible trên Ubuntu 22.04.
  • Một máy chủ từ xa có bản cài đặt Ubuntu 22.04 mới: không yêu cầu thiết lập trước trên máy chủ này, nhưng bạn phải có quyền truy cập SSH vào máy chủ này từ Ansible control node đã đề cập ở trên. Máy chủ này sẽ trở thành một máy chủ lưu trữ từ xa Ansible, được nhắm mục tiêu để cung cấp tự động bởi Ansible control node.

Playbook này làm gì?

Playbook Ansible này cung cấp giải pháp thay thế cho việc chạy thủ công quy trình được nêu trong hướng dẫn thiết lập máy chủ ban đầu Ubuntu 20.04 và hướng dẫn thiết lập SSH key trên Ubuntu 20.04 mỗi khi bạn khởi động máy chủ. Thiết lập playbook của bạn một lần và sử dụng nó cho mọi máy chủ sau đó.

Chạy playbook này sẽ thực hiện các tác vụ sau trên máy chủ Ansible của bạn:

  1. Cài đặt aptitude, được Ansible ưa thích như một giải pháp thay thế cho trình quản lý gói apt.
  2. Tạo người dùng sudo mới và thiết lập sudo không mật khẩu.
  3. Sao chép SSH public key cục bộ và đưa nó vào tệp authorized_keys cho người dùng quản trị mới trên máy chủ từ xa.
  4. Vô hiệu hóa xác thực dựa trên mật khẩu cho root user.
  5. Cài đặt các gói hệ thống.
  6. Định cấu hình tường lửa UFW để chỉ cho phép các kết nối SSH và từ chối mọi yêu cầu khác.

Sau khi playbook chạy xong, bạn sẽ có một người dùng mới mà bạn có thể sử dụng để đăng nhập vào máy chủ.

Để bắt đầu, hãy đăng nhập vào người dùng đã bật sudo trên máy chủ Ansible control node của bạn.

Bước 1 — Chuẩn bị Ansible control node của bạn

Trên máy chủ Ansible control node của bạn, hãy thêm IP của máy chủ lưu trữ từ xa Ansible vào tệp Ansible inventory của bạn. Sử dụng trình soạn thảo văn bản ưa thích của bạn:

sudo nano /etc/ansible/hosts

Thao tác này sẽ mở tệp Ansible inventory của bạn. Thêm IP của máy chủ lưu trữ từ xa Ansible của bạn vào khối [servers]:

/etc/ansible/hosts

[servers]
server1 ansible_host=your_remote_server_ip

. . .

Bây giờ, bạn sẽ kiểm tra và xác thực kết nối SSH giữa Ansible control node này và máy chủ lưu trữ từ xa Ansible của bạn:

ssh root@your_remote_server_ip

Chấp nhận yêu cầu xác thực và nhập mật khẩu của bạn nếu được nhắc. Khi bạn đã xác minh kết nối SSH, hãy nhấn CTRL+D để đóng kết nối và quay lại control node của bạn.

Bước 2 — Chuẩn bị Playbook của bạn

Tệp playbook.yml là nơi xác định tất cả các task của bạn. Task là đơn vị hành động nhỏ nhất mà bạn có thể tự động hóa bằng Playbook Ansible. Nhưng trước tiên, hãy tạo tệp playbook của bạn bằng trình soạn thảo văn bản ưa thích của bạn:

nano playbook.yml

Điều này sẽ mở một tệp YAML trống. Trước khi đi sâu vào việc thêm các tác vụ vào playbook của bạn, hãy bắt đầu bằng cách thêm các mục sau:

playbook.yml

---
- hosts: all
  become: true
  vars:
    created_username: sammy

Vui lòng thay thế tên người dùng bằng một trong những lựa chọn của bạn.

Hầu hết mọi playbook bạn gặp sẽ bắt đầu với các khai báo tương tự như thế này. hosts tuyên bố máy chủ nào mà Ansible control node sẽ nhắm mục tiêu với playbook này. become cho biết liệu tất cả các lệnh sẽ được thực hiện với các đặc quyền gốc được nâng cấp hay không.

vars cho phép bạn lưu trữ dữ liệu trong các biến. Nếu bạn quyết định thay đổi tên người dùng này trong tương lai, bạn sẽ chỉ phải chỉnh sửa một dòng này trong tệp của mình.

Lưu ý: Nếu bạn muốn xem tệp playbook ở trạng thái hoàn thiện cuối cùng, hãy chuyển sang Bước 8. Các tệp YAML có thể đặc biệt với cấu trúc thụt lề của chúng, vì vậy bạn có thể muốn kiểm tra lại playbook của mình sau khi bạn đã thêm tất cả các tác vụ của mình.

Bước 3 — Thêm task cài đặt Aptitude vào Playbook của bạn

Theo mặc định, các task được Ansible thực thi đồng bộ theo thứ tự từ trên xuống dưới trong playbook của bạn. Điều này có nghĩa là thứ tự nhiệm vụ rất quan trọng và bạn có thể yên tâm cho rằng một nhiệm vụ sẽ hoàn thành việc thực thi trước khi nhiệm vụ tiếp theo bắt đầu.

Tất cả các nhiệm vụ trong playbook này có thể độc lập và được sử dụng lại trong các playbook khác của bạn.

Thêm nhiệm vụ đầu tiên của bạn là cài đặt aptitude, một công cụ để giao tiếp với trình quản lý gói Linux:

playbook.yml

tasks:
    - name: Install aptitude
      apt:
        name: aptitude
        state: latest
        update_cache: true

Tại đây, bạn đang sử dụng mô-đun tích hợp apt Ansible để hướng dẫn Ansible cài đặt aptitude. Các mô-đun trong Ansible là các phím tắt để thực thi các thao tác mà bạn sẽ phải chạy dưới dạng các lệnh bash thô. Ansible quay trở lại apt một cách an toàn để cài đặt các gói nếu aptitude không khả dụng. Vì vậy, trong khi bước này là tùy chọn về mặt kỹ thuật, thì Ansible Ansible trước đây đã ưu tiên aptitude.

Bước 4 — Thêm tác vụ thiết lập người dùng Sudo vào Playbook của bạn

Đó là một thực hành tốt để tránh sử dụng rộng rãi root user. Bạn có thể tự động hóa việc tạo người dùng được cấp đặc quyền sudo bằng cách thêm:

playbook.yml

- name: Setup passwordless sudo
      lineinfile:
        path: /etc/sudoers
        state: present
        regexp: '^%sudo'
        line: '%sudo ALL=(ALL) NOPASSWD: ALL'
        validate: '/usr/sbin/visudo -cf %s' 

    - name: Create a new regular user with sudo privileges
      user:
        name: "{{ created_username }}"
        state: present
        groups: sudo
        append: true
        create_home: true

Bạn đang sử dụng mô-đun Ansible lineinfile để nhắm mục tiêu và thay thế một dòng cụ thể trong một tệp. Trong trường hợp này, bạn đang sử dụng regex để nhắm mục tiêu một dòng cụ thể trong tệp sudoers, sau đó sửa đổi nó để cho phép sử dụng sudo không cần mật khẩu. Bạn cũng sử dụng visudo để xác thực các thay đổi của mình nhằm ngăn mọi thứ bị hỏng.

Để tận dụng điều này, bạn sẽ thêm một người dùng mới với mô-đun user. Ansible sẽ đảm bảo người dùng này được tạo nếu chưa tồn tại, rằng người dùng thuộc về nhóm sudo trong khi không bị xóa khỏi các nhóm khác và một thư mục chính được tạo.

Lưu ý: Đảm bảo bạn bao gồm các dấu ngoặc kép xung quanh dấu ngoặc nhọn biểu thị một biến. Việc bỏ qua các trích dẫn này là một lỗi cú pháp Ansible rất phổ biến.

Bước 5 — Thêm thiết lập SSH key và vô hiệu hóa task mật khẩu gốc vào Playbook của bạn

Ansible hoạt động theo giả định rằng bạn đang sử dụng các SSH key. Chúng tôi thực sự khuyên bạn nên kết hợp việc sử dụng SSH key với việc vô hiệu hóa xác thực mật khẩu gốc. Để tự động hóa việc này, hãy thêm:

playbook.yml

- name: Set authorized key for remote user
      ansible.posix.authorized_key:
        user: "{{ created_username }}"
        state: present
        key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"

    - name: Disable password authentication for root
      lineinfile:
        path: /etc/ssh/sshd_config
        state: present
        regexp: '^#?PermitRootLogin'
        line: 'PermitRootLogin prohibit-password'

Mô-đun authorized_key có thể được sử dụng nếu bạn cung cấp tên người dùng và vị trí của key. Tại đây, đường dẫn tới key của bạn được tạo bằng chức năng tra cứu của Ansible.

Mô-đun lineinfile được sử dụng để tìm kiếm và thay thế một dòng trong sshd_config nhằm vô hiệu hóa xác thực mật khẩu cho root, hạn chế quyền truy cập vào các đặc quyền của nó để tăng cường bảo mật.

Bước 6 — Thêm task cài đặt gói vào Playbook của bạn

Ansible có thể đảm bảo các gói nhất định luôn được cài đặt trên máy chủ của bạn. Thay vì gọi apt install trên từng gói riêng lẻ hoặc chia nó thành nhiều tác vụ, bạn có thể liệt kê tất cả các gói mong muốn của mình:

playbook.yml

- name: Update apt and install required system packages
      apt:
        pkg:
          - curl
          - vim
          - git
          - ufw
        state: latest
        update_cache: true}

Bạn có thể thêm bớt các gói theo ý thích của mình. Điều này sẽ đảm bảo tất cả các gói không chỉ hiện diện mà còn trên phiên bản mới nhất và được thực hiện sau khi cập nhật với apt được gọi.

Bước 7 — Thêm Task Thiết lập Tường lửa vào Playbook của bạn

Tường lửa là không thể thiếu đối với bất kỳ máy chủ nào đối mặt với internet. Bạn có thể có Ansible đảm bảo UFW (Uncomplicated Firewall) được định cấu hình đúng bằng cách thêm:

playbook.yml

- name: UFW - Allow SSH connections
      community.general.ufw:
        rule: allow
        name: OpenSSH

    - name: UFW - Enable and deny by default
      community.general.ufw:
        state: enabled
        default: deny

Mô-đun ufw trước tiên đảm bảo quyền truy cập SSH được cho phép thông qua. Sau đó, mô-đun này kích hoạt tường lửa của bạn trong khi mặc định từ chối tất cả lưu lượng truy cập khác đến máy chủ của bạn.

Bước 8 — Xem lại toàn bộ Playbook của bạn

Playbook của bạn sẽ trông giống như sau, với những khác biệt nhỏ tùy thuộc vào các tùy chỉnh của bạn:

playbook.yml

---
- hosts: all
  become: true
  vars:
    created_username: sammy

  tasks:
    - name: Install aptitude
      apt:
        name: aptitude
        state: latest
        update_cache: true

    - name: Setup passwordless sudo
      lineinfile:
        path: /etc/sudoers
        state: present
        regexp: '^%sudo'
        line: '%sudo ALL=(ALL) NOPASSWD: ALL'
        validate: '/usr/sbin/visudo -cf %s'

    - name: Create a new regular user with sudo privileges
      user:
        name: "{{ created_username }}"
        state: present
        groups: sudo
        append: true
        create_home: true

    - name: Set authorized key for remote user
      ansible.posix.authorized_key:
        user: "{{ created_username }}"
        state: present
        key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"

    - name: Disable password authentication for root
      lineinfile:
        path: /etc/ssh/sshd_config
        state: present
        regexp: '^#?PermitRootLogin'
        line: 'PermitRootLogin prohibit-password'

    - name: Update apt and install required system packages
      apt:
        pkg:
          - curl
          - vim
          - git
          - ufw
        state: latest
        update_cache: true

    - name: UFW - Allow SSH connections
      community.general.ufw:
        rule: allow
        name: OpenSSH

    - name: UFW - Enable and deny by default
      community.general.ufw:
        state: enabled
        default: deny

Lưu ý: Đây là một lời nhắc nhở nhẹ nhàng để chú ý đến các vết lõm của bạn. Nếu bạn gặp lỗi, đây rất có thể là thủ phạm. YAML gợi ý sử dụng 2 dấu cách làm thụt lề, như đã được thực hiện trong ví dụ này.

Sau khi hài lòng với playbook của mình, bạn có thể thoát khỏi trình soạn thảo văn bản và lưu lại.

Bước 9 — Chạy Playbook của bạn lần đầu tiên

Bây giờ bạn đã sẵn sàng để chạy cẩm nang này trên một hoặc nhiều máy chủ. Theo mặc định, hầu hết các sách giải trí đều được định cấu hình để thực thi trên mọi máy chủ trong kho của bạn, nhưng lần này bạn sẽ chỉ định máy chủ của mình.

Để chỉ thực thi playbook trên server1, kết nối với quyền root, bạn có thể sử dụng lệnh sau:

ansible-playbook playbook.yml -l server1 -u root -k

Cờ -l chỉ định máy chủ của bạn và cờ -u chỉ định người dùng nào sẽ đăng nhập trên máy chủ từ xa. Vì bạn chưa thiết lập máy chủ từ xa nên root là lựa chọn duy nhất của bạn. Cờ -k rất quan trọng trong lần chạy playbook đầu tiên của bạn, vì nó cho phép bạn nhập mật khẩu SSH của mình.

Bạn sẽ nhận được đầu ra tương tự như thế này:

Output. . .

TASK [UFW - Allow SSH connections] ***************************************************************************************************************************************************************************************************************************
changed: [server1]

TASK [UFW - Enable and deny by default] **********************************************************************************************************************************************************************************************************************
changed: [server1]

PLAY RECAP ***************************************************************************************************************************************************************************************************************************************************
server1                    : ok=9    changed=8    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Điều này cho biết quá trình thiết lập máy chủ của bạn đã hoàn tất! Kết quả đầu ra của bạn không nhất thiết phải giống hệt nhau, nhưng điều quan trọng là bạn không có lỗi nào.

Bây giờ bạn đã thực hiện thiết lập đầu tiên cho playbook của mình, tất cả các cuộc gọi ansible tiếp theo có thể được thực hiện với người dùng sammy và không có cờ -k:

ansible-playbook playbook.yml -l server1 -u sammy

Bạn cũng có thể đăng nhập vào máy chủ bằng:

ssh sammy@your_remote_server_ip

Hãy nhớ thay thế sammy bằng người dùng được xác định bởi biến created_username và server_host_or_IP bằng tên máy chủ hoặc địa chỉ IP của máy chủ của bạn.

Sau khi đăng nhập vào máy chủ, bạn có thể kiểm tra các quy tắc hoạt động của tường lửa UFW để xác nhận rằng nó được cấu hình đúng:

sudo ufw status

Bạn sẽ nhận được đầu ra tương tự như thế này:

OutputStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)

Điều này có nghĩa là tường lửa UFW đã được kích hoạt thành công. Vì đây là task cuối cùng trong playbook, nên nó xác nhận rằng playbook đã được thực hiện đầy đủ trên máy chủ này.

Kết luận

Tự động hóa thiết lập máy chủ ban đầu có thể giúp bạn tiết kiệm thời gian, đồng thời đảm bảo máy chủ của bạn sẽ tuân theo cấu hình tiêu chuẩn có thể được cải thiện và tùy chỉnh theo nhu cầu của bạn. Với bản chất phân tán của các ứng dụng hiện đại và nhu cầu nhất quán hơn giữa các môi trường dàn dựng khác nhau, việc tự động hóa như thế này trở nên cần thiết.

Trong hướng dẫn này, bạn đã trình bày cách sử dụng Ansible để tự động hóa các tác vụ ban đầu sẽ được thực thi trên một máy chủ mới, chẳng hạn như tạo non-root user với quyền truy cập sudo, bật UFW và vô hiệu hóa đăng nhập root dựa trên mật khẩu từ xa.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *