Обновить playbooks/scan_inventory.yml
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
- name: "Сканирование сети через SNMP (Community: public)"
|
- name: "Сканирование сети (Rootless Mode - TCP Only)"
|
||||||
hosts: localhost
|
hosts: localhost
|
||||||
connection: local
|
connection: local
|
||||||
gather_facts: no
|
gather_facts: no
|
||||||
become: yes # МЫ ВЕРНУЛИ ЭТО (нужны права root для nmap -sU / -O)
|
# become: yes <--- УДАЛЕНО: Работаем без прав root
|
||||||
vars:
|
vars:
|
||||||
# --- SEMAPHORE API ---
|
# --- SEMAPHORE API ---
|
||||||
semaphore_url: "http://192.168.0.198:9999"
|
semaphore_url: "http://192.168.0.198:9999"
|
||||||
@@ -33,24 +33,12 @@
|
|||||||
- "172.19.58.0/24"
|
- "172.19.58.0/24"
|
||||||
- "172.19.90.0/24"
|
- "172.19.90.0/24"
|
||||||
|
|
||||||
snmp_community: "public"
|
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
# ТЕСТ ПРАВ: Проверяем, работает ли become после настройки Environment
|
|
||||||
- name: Проверка прав root
|
|
||||||
command: id
|
|
||||||
register: id_check
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Показать пользователя (должен быть root)
|
|
||||||
debug:
|
|
||||||
msg: "Я работаю от имени: {{ id_check.stdout }}"
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
# ШАГ 1: Поиск живых хостов
|
# ШАГ 1: Поиск живых хостов
|
||||||
|
# Используем -sn (обычный пользователь сделает TCP ping, это ок)
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
- name: Ping Sweep (быстрый поиск)
|
- name: Ping Sweep
|
||||||
# УБРАЛИ 'sudo', ОСТАВИЛИ ТОЛЬКО nmap (права дает become: yes выше)
|
|
||||||
command: "nmap -sn -n --min-rate 1000 -T4 -oG - {{ subnets | join(' ') }}"
|
command: "nmap -sn -n --min-rate 1000 -T4 -oG - {{ subnets | join(' ') }}"
|
||||||
register: ping_scan
|
register: ping_scan
|
||||||
changed_when: false
|
changed_when: false
|
||||||
@@ -65,49 +53,58 @@
|
|||||||
when: active_ips | length == 0
|
when: active_ips | length == 0
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
# ШАГ 2: Опрос через SNMP
|
# ШАГ 2: Сканирование портов (TCP Connect)
|
||||||
|
# Используем -sT (не требует root) вместо -sS/-sU
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
- name: SNMP Discovery
|
- name: TCP Port Scan & Name Discovery
|
||||||
# УБРАЛИ 'sudo'
|
|
||||||
shell: |
|
shell: |
|
||||||
nmap -sU -sS -p U:161,T:22,T:445,T:8291,T:9100 \
|
# Сканируем ключевые TCP порты:
|
||||||
--script snmp-sysdescr \
|
# 22 (SSH/Linux), 445 (SMB/Windows), 8291 (Winbox/MikroTik), 9100 (JetDirect/Printer)
|
||||||
--script-args snmpcommunity={{ snmp_community }} \
|
# --script smb-os-discovery пытается узнать имя Windows (работает по TCP, root не нужен)
|
||||||
|
nmap -sT -p 22,445,8291,9100 \
|
||||||
|
--script smb-os-discovery \
|
||||||
-Pn -n -T4 {{ item }}
|
-Pn -n -T4 {{ item }}
|
||||||
loop: "{{ active_ips }}"
|
loop: "{{ active_ips }}"
|
||||||
register: scan_results
|
register: scan_results
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
# ШАГ 3: Классификация
|
# ШАГ 3: Классификация (по открытым портам)
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
- name: Анализ устройств и классификация
|
- name: Анализ результатов
|
||||||
set_fact:
|
set_fact:
|
||||||
classified_hosts: "{{ classified_hosts | default([]) + [ host_data ] }}"
|
classified_hosts: "{{ classified_hosts | default([]) + [ host_data ] }}"
|
||||||
vars:
|
vars:
|
||||||
out: "{{ item.stdout }}"
|
out: "{{ item.stdout }}"
|
||||||
ip: "{{ item.item }}"
|
ip: "{{ item.item }}"
|
||||||
snmp_desc: "{{ out | regex_search('sysDescr\\.0: ([^\\n]+)', '\\1') | first | default('') }}"
|
|
||||||
|
# Пытаемся найти имя компьютера через SMB (для Windows)
|
||||||
|
smb_name: "{{ out | regex_search('Computer name: ([\\w-]+)', '\\1') | first | default('') }}"
|
||||||
|
|
||||||
|
# ЛОГИКА ОПРЕДЕЛЕНИЯ ТИПА (По открытым портам)
|
||||||
detected_type: >-
|
detected_type: >-
|
||||||
{% if 'Windows' in snmp_desc or '445/tcp open' in out %}windows
|
{% if '445/tcp open' in out %}windows
|
||||||
{% elif 'RouterOS' in snmp_desc or 'MikroTik' in snmp_desc or '8291/tcp open' in out %}mikrotik
|
{% elif '8291/tcp open' in out %}mikrotik
|
||||||
{% elif 'Linux' in snmp_desc or 'Ubuntu' in snmp_desc or '22/tcp open' in out %}linux
|
{% elif '9100/tcp open' in out %}printer
|
||||||
{% elif 'JetDirect' in snmp_desc or 'LaserJet' in snmp_desc or 'Samsung' in snmp_desc or 'Kyocera' in snmp_desc or '9100/tcp open' in out %}printer
|
{% elif '22/tcp open' in out %}linux
|
||||||
{% else %}other{% endif %}
|
{% else %}other{% endif %}
|
||||||
|
|
||||||
|
# Формируем имя
|
||||||
|
final_name: >-
|
||||||
|
{% if detected_type == 'windows' and smb_name != '' %}{{ smb_name | lower }}
|
||||||
|
{% else %}{{ detected_type }}_{{ ip | replace('.', '_') }}{% endif %}
|
||||||
|
|
||||||
host_data:
|
host_data:
|
||||||
ip: "{{ ip }}"
|
ip: "{{ ip }}"
|
||||||
type: "{{ detected_type }}"
|
type: "{{ detected_type }}"
|
||||||
desc: "{{ snmp_desc | replace('\"', '') | default('No SNMP info') }}"
|
name: "{{ final_name }}"
|
||||||
name: "{{ detected_type }}_{{ ip | replace('.', '_') }}"
|
|
||||||
loop: "{{ scan_results.results }}"
|
loop: "{{ scan_results.results }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
# ШАГ 4: Группировка
|
# ШАГ 4: Группировка
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
- name: Группировка хостов
|
- name: Группировка списков
|
||||||
set_fact:
|
set_fact:
|
||||||
list_win: "{{ classified_hosts | selectattr('type', 'equalto', 'windows') | list }}"
|
list_win: "{{ classified_hosts | selectattr('type', 'equalto', 'windows') | list }}"
|
||||||
list_lin: "{{ classified_hosts | selectattr('type', 'equalto', 'linux') | list }}"
|
list_lin: "{{ classified_hosts | selectattr('type', 'equalto', 'linux') | list }}"
|
||||||
@@ -118,23 +115,23 @@
|
|||||||
# ШАГ 5: Отправка Windows
|
# ШАГ 5: Отправка Windows
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
- block:
|
- block:
|
||||||
- name: Генерация текста инвентаря Windows
|
- name: Генерация инвентаря Windows
|
||||||
set_fact:
|
set_fact:
|
||||||
content_win: |
|
content_win: |
|
||||||
[windows]
|
[windows]
|
||||||
{% for h in list_win %}
|
{% for h in list_win %}
|
||||||
{{ h.name }} ansible_host={{ h.ip }} # SNMP: {{ h.desc }}
|
{{ h.name }} ansible_host={{ h.ip }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
[windows:vars]
|
[windows:vars]
|
||||||
ansible_connection=ssh
|
ansible_connection=ssh
|
||||||
ansible_shell_type=powershell
|
ansible_shell_type=powershell
|
||||||
ansible_port=22
|
ansible_port=22
|
||||||
|
|
||||||
- name: Сохранение JSON для Windows
|
- name: Сохранение JSON (Windows)
|
||||||
copy:
|
copy:
|
||||||
content: |
|
content: |
|
||||||
{
|
{
|
||||||
"name": "SNMP Windows {{ 1000 | random }}",
|
"name": "Auto Windows {{ 1000 | random }}",
|
||||||
"project_id": {{ semaphore_project_id }},
|
"project_id": {{ semaphore_project_id }},
|
||||||
"type": "static",
|
"type": "static",
|
||||||
"ssh_key_id": {{ key_windows }},
|
"ssh_key_id": {{ key_windows }},
|
||||||
@@ -144,7 +141,7 @@
|
|||||||
}
|
}
|
||||||
dest: /tmp/p_win.json
|
dest: /tmp/p_win.json
|
||||||
|
|
||||||
- name: Отправка Windows API
|
- name: Отправка API (Windows)
|
||||||
command: >
|
command: >
|
||||||
curl -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
|
curl -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
|
||||||
-H "Authorization: Bearer {{ semaphore_api_token }}"
|
-H "Authorization: Bearer {{ semaphore_api_token }}"
|
||||||
@@ -157,22 +154,22 @@
|
|||||||
# ШАГ 6: Отправка MikroTik
|
# ШАГ 6: Отправка MikroTik
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
- block:
|
- block:
|
||||||
- name: Генерация текста инвентаря MikroTik
|
- name: Генерация инвентаря MikroTik
|
||||||
set_fact:
|
set_fact:
|
||||||
content_tik: |
|
content_tik: |
|
||||||
[routers]
|
[routers]
|
||||||
{% for h in list_tik %}
|
{% for h in list_tik %}
|
||||||
{{ h.name }} ansible_host={{ h.ip }} # {{ h.desc }}
|
{{ h.name }} ansible_host={{ h.ip }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
[routers:vars]
|
[routers:vars]
|
||||||
ansible_connection=network_cli
|
ansible_connection=network_cli
|
||||||
ansible_network_os=routeros
|
ansible_network_os=routeros
|
||||||
|
|
||||||
- name: Сохранение JSON для MikroTik
|
- name: Сохранение JSON (MikroTik)
|
||||||
copy:
|
copy:
|
||||||
content: |
|
content: |
|
||||||
{
|
{
|
||||||
"name": "SNMP MikroTik {{ 1000 | random }}",
|
"name": "Auto MikroTik {{ 1000 | random }}",
|
||||||
"project_id": {{ semaphore_project_id }},
|
"project_id": {{ semaphore_project_id }},
|
||||||
"type": "static",
|
"type": "static",
|
||||||
"ssh_key_id": {{ key_mikrotik }},
|
"ssh_key_id": {{ key_mikrotik }},
|
||||||
@@ -182,7 +179,7 @@
|
|||||||
}
|
}
|
||||||
dest: /tmp/p_tik.json
|
dest: /tmp/p_tik.json
|
||||||
|
|
||||||
- name: Отправка MikroTik API
|
- name: Отправка API (MikroTik)
|
||||||
command: >
|
command: >
|
||||||
curl -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
|
curl -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
|
||||||
-H "Authorization: Bearer {{ semaphore_api_token }}"
|
-H "Authorization: Bearer {{ semaphore_api_token }}"
|
||||||
@@ -192,24 +189,24 @@
|
|||||||
when: list_tik | length > 0
|
when: list_tik | length > 0
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
# ШАГ 7: Отправка Принтеров
|
# ШАГ 7: Отправка Принтеров (если нужны)
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
- block:
|
- block:
|
||||||
- name: Генерация текста инвентаря Принтеров
|
- name: Генерация инвентаря Принтеров
|
||||||
set_fact:
|
set_fact:
|
||||||
content_prn: |
|
content_prn: |
|
||||||
[printers]
|
[printers]
|
||||||
{% for h in list_prn %}
|
{% for h in list_prn %}
|
||||||
{{ h.name }} ansible_host={{ h.ip }} # {{ h.desc }}
|
{{ h.name }} ansible_host={{ h.ip }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
[printers:vars]
|
[printers:vars]
|
||||||
ansible_connection=local
|
ansible_connection=local
|
||||||
|
|
||||||
- name: Сохранение JSON для Принтеров
|
- name: Сохранение JSON (Принтеры)
|
||||||
copy:
|
copy:
|
||||||
content: |
|
content: |
|
||||||
{
|
{
|
||||||
"name": "SNMP Printers {{ 1000 | random }}",
|
"name": "Auto Printers {{ 1000 | random }}",
|
||||||
"project_id": {{ semaphore_project_id }},
|
"project_id": {{ semaphore_project_id }},
|
||||||
"type": "static",
|
"type": "static",
|
||||||
"ssh_key_id": {{ key_printers }},
|
"ssh_key_id": {{ key_printers }},
|
||||||
@@ -219,7 +216,7 @@
|
|||||||
}
|
}
|
||||||
dest: /tmp/p_prn.json
|
dest: /tmp/p_prn.json
|
||||||
|
|
||||||
- name: Отправка Принтеров API
|
- name: Отправка API (Принтеры)
|
||||||
command: >
|
command: >
|
||||||
curl -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
|
curl -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
|
||||||
-H "Authorization: Bearer {{ semaphore_api_token }}"
|
-H "Authorization: Bearer {{ semaphore_api_token }}"
|
||||||
@@ -228,5 +225,43 @@
|
|||||||
ignore_errors: yes
|
ignore_errors: yes
|
||||||
when: list_prn | length > 0
|
when: list_prn | length > 0
|
||||||
|
|
||||||
- name: Очистка временных файлов
|
# ----------------------------------------------------------------
|
||||||
|
# ШАГ 8: Отправка Linux
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
- block:
|
||||||
|
- name: Генерация инвентаря Linux
|
||||||
|
set_fact:
|
||||||
|
content_lin: |
|
||||||
|
[linux]
|
||||||
|
{% for h in list_lin %}
|
||||||
|
{{ h.name }} ansible_host={{ h.ip }}
|
||||||
|
{% endfor %}
|
||||||
|
[linux:vars]
|
||||||
|
ansible_connection=ssh
|
||||||
|
ansible_user=root
|
||||||
|
|
||||||
|
- name: Сохранение JSON (Linux)
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
{
|
||||||
|
"name": "Auto Linux {{ 1000 | random }}",
|
||||||
|
"project_id": {{ semaphore_project_id }},
|
||||||
|
"type": "static",
|
||||||
|
"ssh_key_id": {{ key_linux }},
|
||||||
|
"become_key_id": null,
|
||||||
|
"repository_id": null,
|
||||||
|
"inventory": {{ content_lin | to_json }}
|
||||||
|
}
|
||||||
|
dest: /tmp/p_lin.json
|
||||||
|
|
||||||
|
- name: Отправка API (Linux)
|
||||||
|
command: >
|
||||||
|
curl -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
|
||||||
|
-H "Authorization: Bearer {{ semaphore_api_token }}"
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
-d @/tmp/p_lin.json
|
||||||
|
ignore_errors: yes
|
||||||
|
when: list_lin | length > 0
|
||||||
|
|
||||||
|
- name: Очистка
|
||||||
shell: rm -f /tmp/p_*.json
|
shell: rm -f /tmp/p_*.json
|
||||||
Reference in New Issue
Block a user