feat: enhance Ansible playbook with security and timezone configurations
- Add fail2ban installation and configuration for SSH, Nginx, and Docker - Implement kernel security parameter adjustments to mitigate DDoS and spoofing attacks - Set timezone to Europe/Moscow - Update SSH configuration to use port 15722 and close the default port 22 - Enhance UFW rules to allow new SSH port and restrict access to essential services - Include checks for fail2ban status and debug output for verification
This commit is contained in:
@@ -52,8 +52,14 @@
|
|||||||
- traceroute
|
- traceroute
|
||||||
- ncdu
|
- ncdu
|
||||||
- prometheus-node-exporter
|
- prometheus-node-exporter
|
||||||
|
- fail2ban
|
||||||
|
- tzdata
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Установить часовой пояс Europe/Moscow
|
||||||
|
timezone:
|
||||||
|
name: Europe/Moscow
|
||||||
|
|
||||||
- name: Проверить существование swap-файла
|
- name: Проверить существование swap-файла
|
||||||
stat:
|
stat:
|
||||||
path: /swapfile
|
path: /swapfile
|
||||||
@@ -99,6 +105,77 @@
|
|||||||
state: present
|
state: present
|
||||||
create: yes
|
create: yes
|
||||||
|
|
||||||
|
# --- НАСТРОЙКА БЕЗОПАСНОСТИ ЯДРА ---
|
||||||
|
- name: Настроить параметры безопасности ядра
|
||||||
|
sysctl:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
value: "{{ item.value }}"
|
||||||
|
state: present
|
||||||
|
reload: yes
|
||||||
|
loop:
|
||||||
|
# Защита от DDoS
|
||||||
|
- { name: "net.ipv4.tcp_syn_retries", value: "2" }
|
||||||
|
- { name: "net.ipv4.tcp_synack_retries", value: "2" }
|
||||||
|
- { name: "net.ipv4.tcp_max_syn_backlog", value: "2048" }
|
||||||
|
- { name: "net.ipv4.tcp_fin_timeout", value: "15" }
|
||||||
|
- { name: "net.ipv4.tcp_keepalive_time", value: "1200" }
|
||||||
|
- { name: "net.ipv4.tcp_keepalive_intvl", value: "15" }
|
||||||
|
- { name: "net.ipv4.tcp_keepalive_probes", value: "5" }
|
||||||
|
- { name: "net.core.netdev_max_backlog", value: "1000" }
|
||||||
|
- { name: "net.core.somaxconn", value: "65535" }
|
||||||
|
# Защита от IP спуфинга
|
||||||
|
- { name: "net.ipv4.conf.all.accept_source_route", value: "0" }
|
||||||
|
- { name: "net.ipv4.conf.default.accept_source_route", value: "0" }
|
||||||
|
- { name: "net.ipv6.conf.all.accept_source_route", value: "0" }
|
||||||
|
- { name: "net.ipv6.conf.default.accept_source_route", value: "0" }
|
||||||
|
# Защита от фрагментации
|
||||||
|
- { name: "net.ipv4.conf.all.log_martians", value: "1" }
|
||||||
|
- { name: "net.ipv4.conf.default.log_martians", value: "1" }
|
||||||
|
- { name: "net.ipv4.icmp_echo_ignore_broadcasts", value: "1" }
|
||||||
|
- { name: "net.ipv4.icmp_ignore_bogus_error_responses", value: "1" }
|
||||||
|
- { name: "net.ipv4.tcp_syncookies", value: "1" }
|
||||||
|
- { name: "net.ipv4.conf.all.rp_filter", value: "1" }
|
||||||
|
- { name: "net.ipv4.conf.default.rp_filter", value: "1" }
|
||||||
|
# Для Docker
|
||||||
|
- { name: "kernel.pid_max", value: "65536" }
|
||||||
|
- { name: "kernel.threads-max", value: "4096" }
|
||||||
|
- { name: "vm.max_map_count", value: "262144" }
|
||||||
|
|
||||||
|
- name: Сохранить параметры безопасности в /etc/sysctl.conf
|
||||||
|
lineinfile:
|
||||||
|
path: /etc/sysctl.conf
|
||||||
|
regexp: "^{{ item.name }}\\s*="
|
||||||
|
line: "{{ item.name }} = {{ item.value }}"
|
||||||
|
state: present
|
||||||
|
loop:
|
||||||
|
# Защита от DDoS
|
||||||
|
- { name: "net.ipv4.tcp_syn_retries", value: "2" }
|
||||||
|
- { name: "net.ipv4.tcp_synack_retries", value: "2" }
|
||||||
|
- { name: "net.ipv4.tcp_max_syn_backlog", value: "2048" }
|
||||||
|
- { name: "net.ipv4.tcp_fin_timeout", value: "15" }
|
||||||
|
- { name: "net.ipv4.tcp_keepalive_time", value: "1200" }
|
||||||
|
- { name: "net.ipv4.tcp_keepalive_intvl", value: "15" }
|
||||||
|
- { name: "net.ipv4.tcp_keepalive_probes", value: "5" }
|
||||||
|
- { name: "net.core.netdev_max_backlog", value: "1000" }
|
||||||
|
- { name: "net.core.somaxconn", value: "65535" }
|
||||||
|
# Защита от IP спуфинга
|
||||||
|
- { name: "net.ipv4.conf.all.accept_source_route", value: "0" }
|
||||||
|
- { name: "net.ipv4.conf.default.accept_source_route", value: "0" }
|
||||||
|
- { name: "net.ipv6.conf.all.accept_source_route", value: "0" }
|
||||||
|
- { name: "net.ipv6.conf.default.accept_source_route", value: "0" }
|
||||||
|
# Защита от фрагментации
|
||||||
|
- { name: "net.ipv4.conf.all.log_martians", value: "1" }
|
||||||
|
- { name: "net.ipv4.conf.default.log_martians", value: "1" }
|
||||||
|
- { name: "net.ipv4.icmp_echo_ignore_broadcasts", value: "1" }
|
||||||
|
- { name: "net.ipv4.icmp_ignore_bogus_error_responses", value: "1" }
|
||||||
|
- { name: "net.ipv4.tcp_syncookies", value: "1" }
|
||||||
|
- { name: "net.ipv4.conf.all.rp_filter", value: "1" }
|
||||||
|
- { name: "net.ipv4.conf.default.rp_filter", value: "1" }
|
||||||
|
# Для Docker
|
||||||
|
- { name: "kernel.pid_max", value: "65536" }
|
||||||
|
- { name: "kernel.threads-max", value: "4096" }
|
||||||
|
- { name: "vm.max_map_count", value: "262144" }
|
||||||
|
|
||||||
- name: Проверить статус swap
|
- name: Проверить статус swap
|
||||||
command: swapon --show
|
command: swapon --show
|
||||||
register: swap_status
|
register: swap_status
|
||||||
@@ -151,6 +228,12 @@
|
|||||||
port: "22"
|
port: "22"
|
||||||
proto: tcp
|
proto: tcp
|
||||||
|
|
||||||
|
- name: Разрешить новый SSH порт (15722) перед включением UFW
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
port: "15722"
|
||||||
|
proto: tcp
|
||||||
|
|
||||||
- name: Настроить политику UFW по умолчанию
|
- name: Настроить политику UFW по умолчанию
|
||||||
ufw:
|
ufw:
|
||||||
policy: deny
|
policy: deny
|
||||||
@@ -171,6 +254,8 @@
|
|||||||
- "9090" # Prometheus
|
- "9090" # Prometheus
|
||||||
- "3000" # Grafana
|
- "3000" # Grafana
|
||||||
- "9100" # Node Exporter
|
- "9100" # Node Exporter
|
||||||
|
- "80" # HTTP
|
||||||
|
- "443" # HTTPS
|
||||||
|
|
||||||
- name: Проверить существование пользователя deploy
|
- name: Проверить существование пользователя deploy
|
||||||
getent:
|
getent:
|
||||||
@@ -216,11 +301,16 @@
|
|||||||
line: "{{ item.line }}"
|
line: "{{ item.line }}"
|
||||||
backup: yes
|
backup: yes
|
||||||
loop:
|
loop:
|
||||||
|
- { regexp: "Port", line: "Port 15722" }
|
||||||
- { regexp: "PermitRootLogin", line: "PermitRootLogin no" }
|
- { regexp: "PermitRootLogin", line: "PermitRootLogin no" }
|
||||||
- { regexp: "PasswordAuthentication", line: "PasswordAuthentication no" }
|
- { regexp: "PasswordAuthentication", line: "PasswordAuthentication no" }
|
||||||
- { regexp: "PubkeyAuthentication", line: "PubkeyAuthentication yes" }
|
- { regexp: "PubkeyAuthentication", line: "PubkeyAuthentication yes" }
|
||||||
|
- { regexp: "AllowUsers", line: "AllowUsers {{ deploy_user }}" }
|
||||||
notify: reload ssh
|
notify: reload ssh
|
||||||
|
|
||||||
|
- name: Переподключиться по новому SSH порту
|
||||||
|
meta: reset_connection
|
||||||
|
|
||||||
- name: Удалить /home/prod, если требуется (чистое развертывание)
|
- name: Удалить /home/prod, если требуется (чистое развертывание)
|
||||||
file:
|
file:
|
||||||
path: "{{ project_root }}"
|
path: "{{ project_root }}"
|
||||||
@@ -483,6 +573,79 @@
|
|||||||
become_user: "{{ deploy_user }}"
|
become_user: "{{ deploy_user }}"
|
||||||
tags: ["start_bots"]
|
tags: ["start_bots"]
|
||||||
|
|
||||||
|
# --- НАСТРОЙКА FAIL2BAN ---
|
||||||
|
- name: Создать конфигурацию Fail2ban для SSH
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
[sshd]
|
||||||
|
enabled = true
|
||||||
|
port = 15722
|
||||||
|
filter = sshd
|
||||||
|
logpath = /var/log/auth.log
|
||||||
|
maxretry = 3
|
||||||
|
bantime = 3600
|
||||||
|
findtime = 600
|
||||||
|
dest: /etc/fail2ban/jail.d/sshd.local
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Создать конфигурацию Fail2ban для Nginx
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
[nginx-http-auth]
|
||||||
|
enabled = true
|
||||||
|
port = http,https
|
||||||
|
filter = nginx-http-auth
|
||||||
|
logpath = /var/log/nginx/error.log
|
||||||
|
maxretry = 3
|
||||||
|
bantime = 3600
|
||||||
|
findtime = 600
|
||||||
|
|
||||||
|
[nginx-limit-req]
|
||||||
|
enabled = true
|
||||||
|
port = http,https
|
||||||
|
filter = nginx-limit-req
|
||||||
|
logpath = /var/log/nginx/error.log
|
||||||
|
maxretry = 3
|
||||||
|
bantime = 3600
|
||||||
|
findtime = 600
|
||||||
|
dest: /etc/fail2ban/jail.d/nginx.local
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Создать конфигурацию Fail2ban для Docker
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
[docker]
|
||||||
|
enabled = true
|
||||||
|
port = 2375,2376
|
||||||
|
filter = docker
|
||||||
|
logpath = /var/log/syslog
|
||||||
|
maxretry = 3
|
||||||
|
bantime = 3600
|
||||||
|
findtime = 600
|
||||||
|
dest: /etc/fail2ban/jail.d/docker.local
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Включить и запустить Fail2ban
|
||||||
|
systemd:
|
||||||
|
name: fail2ban
|
||||||
|
enabled: yes
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: Проверить статус Fail2ban
|
||||||
|
command: fail2ban-client status
|
||||||
|
register: fail2ban_status
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Показать статус Fail2ban
|
||||||
|
debug:
|
||||||
|
var: fail2ban_status.stdout_lines
|
||||||
|
|
||||||
# --- НОВОЕ: Проверка портов ---
|
# --- НОВОЕ: Проверка портов ---
|
||||||
- name: Пауза на 30 секунд — дать контейнерам запуститься
|
- name: Пауза на 30 секунд — дать контейнерам запуститься
|
||||||
pause:
|
pause:
|
||||||
@@ -532,24 +695,16 @@
|
|||||||
retries: 5
|
retries: 5
|
||||||
delay: 10
|
delay: 10
|
||||||
|
|
||||||
- name: Проверить, что дашборд Node Exporter загружен в Grafana
|
|
||||||
uri:
|
|
||||||
url: "http://{{ ansible_host }}:3000/api/search?query=Node%20Exporter%20Full"
|
|
||||||
method: GET
|
|
||||||
user: "{{ grafana_admin_user | default('admin') }}"
|
|
||||||
password: "{{ grafana_admin_password | default('admin') }}"
|
|
||||||
status_code: 200
|
|
||||||
register: dashboard_check
|
|
||||||
retries: 3
|
|
||||||
delay: 5
|
|
||||||
|
|
||||||
- name: Показать информацию о найденных дашбордах
|
- name: Закрыть старый SSH порт 22 в UFW (финальный шаг)
|
||||||
debug:
|
ufw:
|
||||||
var: dashboard_check.json
|
rule: deny
|
||||||
|
port: "22"
|
||||||
|
proto: tcp
|
||||||
|
|
||||||
- name: Проверка запуска ботов завершена — всё работает 🟢
|
- name: Проверка запуска ботов завершена — всё работает 🟢
|
||||||
debug:
|
debug:
|
||||||
msg: "Все сервисы запущены и слушают нужные порты."
|
msg: "Все сервисы запущены и слушают нужные порты. SSH настроен на порт 15722, Fail2ban активен, параметры безопасности ядра применены. Порт 22 закрыт для безопасности."
|
||||||
|
|
||||||
# handlers для перезагрузки сервисов
|
# handlers для перезагрузки сервисов
|
||||||
handlers:
|
handlers:
|
||||||
|
|||||||
Reference in New Issue
Block a user