This commit is contained in:
uristalex
2026-04-20 14:57:38 +03:00
parent 9a3fd011fa
commit b5a00025c2
2 changed files with 212 additions and 0 deletions

73
GITEA_INSTRUCTIONS.md Normal file
View File

@@ -0,0 +1,73 @@
# Инструкция: Удаленный запуск анализатора IP через Gitea Actions
Эта инструкция поможет вам настроить автоматический или ручной запуск скрипта `ip_analyzer.py` на удаленном сервере с использованием встроенного CI/CD Gitea (Gitea Actions).
## Шаг 1: Подготовка репозитория в Gitea
1. Создайте новый репозиторий в вашем инстансе Gitea (или используйте существующий).
2. Загрузите в корень репозитория файл `ip_analyzer.py`.
## Шаг 2: Включение Gitea Actions
1. Перейдите в настройки вашего репозитория в Gitea (`Настройки` -> `Общие`).
2. Найдите раздел **Репозиторий (Repository)** -> **Дополнительные возможности (Advanced Settings)**.
3. Поставьте галочку **Включить действия репозитория (Enable Repository Actions)**.
4. Нажмите `Сохранить`.
*(Примечание: Убедитесь, что администратор Gitea настроил и подключил Gitea Runner для вашего сервера. Без активного раннера (Runner) сценарии выполняться не будут).*
## Шаг 3: Создание Workflow (сценария CI/CD)
Мы создадим сценарий, который позволит запускать скрипт вручную прямо из веб-интерфейса Gitea, передавая нужный IP-адрес как параметр перед запуском.
1. В корне вашего репозитория создайте директорию `.gitea/workflows/` (именно `.gitea`, а не `.github`, хотя Gitea Actions совместимы с синтаксисом GitHub).
2. Внутри этой директории создайте файл `analyze-ip.yaml` (полный путь: `.gitea/workflows/analyze-ip.yaml`).
3. Вставьте в этот файл следующий код:
```yaml
name: IP Analyzer
# Разрешаем ручной запуск (workflow_dispatch) с вводом параметров
on:
workflow_dispatch:
inputs:
ip_address:
description: 'IP-адрес для анализа'
required: true
default: '8.8.8.8'
jobs:
analyze:
runs-on: ubuntu-latest # Укажите здесь метку вашего Gitea Runner (например, ubuntu-latest, debian и т.д.)
steps:
- name: Checkout кода
uses: actions/checkout@v3
- name: Установка Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Запуск анализатора
run: |
echo "Запуск скрипта для IP: ${{ github.event.inputs.ip_address }}"
python ip_analyzer.py ${{ github.event.inputs.ip_address }}
```
4. Закоммитьте и отправьте (push) этот файл в Gitea-репозиторий.
## Шаг 4: Запуск проверки через веб-интерфейс Gitea
1. Откройте ваш репозиторий в Gitea.
2. В верхнем меню перейдите на вкладку **Действия (Actions)**.
3. В левом боковом меню выберите ваш workflow: `IP Analyzer`.
4. В правой части экрана (вверху списка запусков) нажмите кнопку **Запустить процесс (Run Workflow)**.
5. Появится выпадающее меню. В поле `ip_address` введите IP-адрес сервера, который вы хотите проверить (например, `1.1.1.1` или IP нужного сервера).
6. Нажмите зеленую кнопку запуска.
## Шаг 5: Просмотр результатов
1. После запуска появится новая задача в списке с желтым значком "В процессе". Кликните на неё.
2. Нажмите на блок `analyze` (название задачи).
3. Перед вами откроется консоль Gitea Runner'а.
4. Раскройте шаг **Запуск анализатора**. В нем вы увидите подробный текстовый вывод работы вашего скрипта `ip_analyzer.py` со всей собранной информацией об IP-адресе.

139
ip_analyzer.py Normal file
View File

@@ -0,0 +1,139 @@
import argparse
import socket
import subprocess
import platform
import json
import urllib.request
import urllib.error
import concurrent.futures
def get_ip_info(ip):
"""Получает общую информацию об IP через ip-api.com"""
url = f"http://ip-api.com/json/{ip}?fields=status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,query"
try:
# Притворяемся браузером, чтобы избежать блокировок
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req, timeout=10) as response:
data = json.loads(response.read().decode())
return data
except Exception as e:
return {"error": str(e)}
def check_ping(ip, count=4):
"""Измеряет средний пинг до сервера с помощью системной утилиты ping"""
# Выбираем правильный параметр в зависимости от ОС: Windows использует -n, Linux/Mac -c
param = '-n' if platform.system().lower() == 'windows' else '-c'
command = ['ping', param, str(count), ip]
try:
output = subprocess.check_output(command, stderr=subprocess.STDOUT, universal_newlines=True)
return output
except subprocess.CalledProcessError as e:
return e.output
except Exception as e:
return str(e)
def check_port(ip, port, timeout=2):
"""Проверяет доступность определенного TCP-порта"""
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(timeout)
result = sock.connect_ex((ip, port))
return result == 0
except Exception:
return False
def check_dnsbl(ip):
"""Проверяет IP в популярных базах DNSBL (спам-базы и черные списки)"""
dnsbl_lists = [
"zen.spamhaus.org",
"b.barracudacentral.org",
"bl.spamcop.net",
"cbl.abuseat.org",
"dnsbl.sorbs.net"
]
# Разворачиваем IP для DNS-запроса (например: 1.2.3.4 -> 4.3.2.1)
try:
reversed_ip = ".".join(reversed(ip.split(".")))
except Exception:
return {"error": "Неверный формат IP-адреса для проверки в DNSBL"}
results = {}
for dnsbl in dnsbl_lists:
query = f"{reversed_ip}.{dnsbl}"
try:
# Если IP в базе, DNS вернет loopback адрес (обычно 127.0.0.x)
answers = socket.gethostbyname(query)
results[dnsbl] = f"В ЧЕРНОМ СПИСКЕ (ответ: {answers})"
except socket.gaierror:
# Имя не разрешено, значит IP нет в базе, он чист
results[dnsbl] = "Чисто"
except Exception as e:
results[dnsbl] = f"Ошибка проверки: {e}"
return results
def main():
parser = argparse.ArgumentParser(description="Скрипт для подробного анализа IP-адреса сервера.")
parser.add_argument("ip", help="IP-адрес для анализа")
args = parser.parse_args()
ip = args.ip
print(f"{'=' * 50}")
print(f"Анализ IP-адреса: {ip}")
print(f"{'=' * 50}\n")
# 1. Информация о локации и провайдере
print("[*] 1. Получение общей информации и геолокации...")
info = get_ip_info(ip)
if info.get('status') == 'success':
print(f" Страна: {info.get('country')} ({info.get('countryCode')})")
print(f" Регион: {info.get('regionName')}, {info.get('city')} {info.get('zip', '')}")
print(f" Временная: {info.get('timezone')}")
print(f" Координаты: Lat: {info.get('lat')}, Lon: {info.get('lon')}")
print(f" Провайдер: {info.get('isp')}")
print(f" Организация: {info.get('org')}")
print(f" AS: {info.get('as')}")
else:
print(f" Не удалось получить информацию. Ответ: {info}")
# 2. Проверка популярных портов
print("\n[*] 2. Проверка доступности портов (Сервисы)...")
ports_to_check = {'HTTP (80)': 80, 'HTTPS (443)': 443, 'SSH (22)': 22, 'RDP (3389)': 3389, 'FTP (21)': 21}
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
future_to_port = {executor.submit(check_port, ip, port): name for name, port in ports_to_check.items()}
for future in concurrent.futures.as_completed(future_to_port):
port_name = future_to_port[future]
try:
is_open = future.result()
status = "Открыт" if is_open else "Закрыт / Заблокирован Firewall"
print(f" Порт {port_name:12}: {status}")
except Exception as e:
print(f" Порт {port_name:12}: Ошибка проверки ({e})")
# 3. Базы блокировок
print("\n[*] 3. Проверка по базам блокировок (DNSBL / Spamhaus)...")
dnsbl_results = check_dnsbl(ip)
if "error" in dnsbl_results:
print(f" {dnsbl_results['error']}")
else:
for db, res in dnsbl_results.items():
print(f" {db:25}: {res}")
# 4. Проверка пинга
print("\n[*] 4. Измерение пинга до локации (ICMP)...")
ping_result = check_ping(ip)
# Выводим результат пинга с небольшим отступом для красоты
for line in ping_result.splitlines():
if line.strip():
print(f" {line}")
if __name__ == "__main__":
main()