test
This commit is contained in:
73
GITEA_INSTRUCTIONS.md
Normal file
73
GITEA_INSTRUCTIONS.md
Normal 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
139
ip_analyzer.py
Normal 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()
|
||||
Reference in New Issue
Block a user