← Все руководства
Onboarding нового сервера через Ansible
Каждый новый сервер требует стандартизации: обновления, настройки 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-пароля. Иначе потеряете доступ к серверу.