NPV-AM

← Все руководства

Onboarding нового сервера через Ansible

18 июля 2026 · 12 мин чтения · Средний

Каждый новый сервер требует стандартизации: обновления, настройки SSH, файрвола, пользователей и мониторинга. Это руководство превращает этот процесс в воспроизводимый Ansible-плейбук.

Шаг 1: Структура проекта

Создайте типовую структуру Ansible-проекта:

ansible/
├── ansible.cfg
├── inventory/
│   └── hosts.yml
├── group_vars/
│   └── all.yml
├── roles/
│   ├── common/
│   ├── ssh_hardening/
│   ├── firewall/
│   └── monitoring/
└── playbooks/
    └── onboarding.yml
# ansible.cfg
[defaults]
inventory = inventory/hosts.yml
remote_user = root
host_key_checking = False
retry_files_enabled = False

Шаг 2: Инвентори и переменные

# inventory/hosts.yml
all:
  hosts:
    web-01:
      ansible_host: 192.168.1.10
    web-02:
      ansible_host: 192.168.1.11
  vars:
    ansible_user: root
    ansible_port: 22
# group_vars/all.yml
deploy_user: deploy
ssh_port: 22
ufw_rules:
  - { port: "22", proto: "tcp" }
  - { port: "80", proto: "tcp" }
  - { port: "443", proto: "tcp" }

Шаг 3: SSH Hardening

Роль для настройки безопасного SSH:

# roles/ssh_hardening/tasks/main.yml
- name: Disable root login
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#?PermitRootLogin'
    line: 'PermitRootLogin prohibit-password'
  notify: restart sshd

- name: Set SSH port
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#?Port '
    line: "Port {{ ssh_port }}"
  notify: restart sshd

- name: Disable password authentication
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#?PasswordAuthentication'
    line: 'PasswordAuthentication no'
  notify: restart sshd

- name: Disable empty passwords
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#?PermitEmptyPasswords'
    line: 'PermitEmptyPasswords no'
  notify: restart sshd

- name: Set max auth tries
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^#?MaxAuthTries'
    line: 'MaxAuthTries 3'
  notify: restart sshd

- name: Deploy sshd_config
  template:
    src: sshd_config.j2
    dest: /etc/ssh/sshd_config
    validate: '/usr/sbin/sshd -t -f %s'
  notify: restart sshd
# roles/ssh_hardening/handlers/main.yml
- name: restart sshd
  service:
    name: sshd
    state: restarted

Шаг 4: Настройка файрвола (ufw)

# roles/firewall/tasks/main.yml
- name: Install ufw
  apt:
    name: ufw
    state: present
    update_cache: yes

- name: Set default deny incoming
  ufw:
    direction: incoming
    policy: deny

- name: Set default allow outgoing
  ufw:
    direction: outgoing
    policy: allow

- name: Allow SSH
  ufw:
    rule: allow
    port: "{{ ssh_port }}"
    proto: tcp

- name: Allow HTTP
  ufw:
    rule: allow
    port: "80"
    proto: tcp

- name: Allow HTTPS
  ufw:
    rule: allow
    port: "443"
    proto: tcp

- name: Enable ufw
  ufw:
    state: enabled

Шаг 5: Создание пользователей и sudoers

# roles/common/tasks/main.yml
- name: Create deploy user
  user:
    name: "{{ deploy_user }}"
    shell: /bin/bash
    groups: sudo
    create_home: yes
    state: present

- name: Add SSH key for deploy user
  authorized_key:
    user: "{{ deploy_user }}"
    key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
    state: present

- name: Configure sudoers
  lineinfile:
    path: /etc/sudoers.d/{{ deploy_user }}
    line: "{{ deploy_user }} ALL=(ALL) NOPASSWD:ALL"
    create: yes
    mode: '0440'
    validate: '/usr/sbin/visudo -cf %s'

- name: Disable root password
  user:
    name: root
    password_lock: yes

- name: Set timezone
  timezone:
    name: Europe/Moscow

- name: Install essential packages
  apt:
    name:
      - curl
      - wget
      - git
      - htop
      - net-tools
      - unzip
      - vim
      - ufw
      - fail2ban
    state: present
    update_cache: yes

- name: Enable fail2ban
  service:
    name: fail2ban
    state: started
    enabled: yes

Шаг 6: Установка node_exporter

# roles/monitoring/tasks/main.yml
- name: Download node_exporter
  unarchive:
    src: "https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz"
    dest: /usr/local/bin/
    remote_src: yes
    extra_opts:
      - "--strip-components=1"
      - "--wildcards"
      - "*/node_exporter"

- name: Create node_exporter user
  user:
    name: node_exporter
    shell: /sbin/nologin
    system: yes
    create_home: no

- name: Create systemd unit for node_exporter
  template:
    src: node_exporter.service.j2
    dest: /etc/systemd/system/node_exporter.service
  notify: restart node_exporter

- name: Enable node_exporter
  systemd:
    name: node_exporter
    state: started
    enabled: yes
    daemon_reload: yes
# roles/monitoring/handlers/main.yml
- name: restart node_exporter
  systemd:
    name: node_exporter
    state: restarted

Шаг 7: Главный плейбук

# playbooks/onboarding.yml
---
- name: Onboard new server
  hosts: new_servers
  become: yes
  roles:
    - common
    - ssh_hardening
    - firewall
    - monitoring

Запуск:

ansible-playbook playbooks/onboarding.yml --limit web-01

Шаг 8: Проверка

После выполнения проверьте конфигурацию:

# Проверка SSH
ssh -p 22 deploy@192.168.1.10 "sshd -T | grep port"

# Проверка файрвола
ssh -p 22 deploy@192.168.1.10 "sudo ufw status verbose"

# Проверка node_exporter
curl http://192.168.1.10:9100/metrics | head -5
После hardening SSH убедитесь, что у вас есть ключ доступа перед отключением root-пароля. Иначе потеряете доступ к серверу.