Update get_vpn.py
This commit is contained in:
+95
-28
@@ -3,62 +3,129 @@ import sys
|
|||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
def fetch_clash_config():
|
def fetch_and_prepare_configs():
|
||||||
# Получаем ссылку-подписку из секретов Gitea/GitHub
|
# Забираем ссылку из секретов Gitea/GitHub
|
||||||
sub_url = os.getenv("VPN_SUB_URL")
|
sub_url = os.getenv("VPN_SUB_URL")
|
||||||
|
|
||||||
if not sub_url:
|
if not sub_url:
|
||||||
print("Ошибка: Переменная окружения VPN_SUB_URL не задана!")
|
print("Ошибка: Переменная окружения VPN_SUB_URL не задана!")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Имитируем заголовки оригинального клиента OpenClash / Mihomo
|
# Имитируем заголовки оригинального ядра Mihomo (Clash.Meta) для OpenClash
|
||||||
headers = {
|
headers = {
|
||||||
"User-Agent": "Clash.meta; mihomo; OpenClash",
|
"User-Agent": "Mihomo/1.18.3 Clash.Meta OpenClash",
|
||||||
"Accept": "*/*",
|
"Accept": "application/yaml, text/yaml, */*",
|
||||||
|
"Connection": "keep-alive",
|
||||||
}
|
}
|
||||||
|
|
||||||
# На всякий случай проверяем, есть ли уже в ссылке флаг клиента.
|
# Принудительно заставляем панель выдать мета-конфиг
|
||||||
# Если нет — панель может проигнорировать User-Agent, поэтому добавляем флаг принудительно.
|
|
||||||
if "flag=" not in sub_url:
|
if "flag=" not in sub_url:
|
||||||
separator = "&" if "?" in sub_url else "?"
|
separator = "&" if "?" in sub_url else "?"
|
||||||
sub_url += f"{separator}flag=clash"
|
sub_url += f"{separator}flag=meta"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print("Отправка запроса к серверу VPN с заголовками Clash...")
|
print("Отправка запроса к серверу VPN...")
|
||||||
response = requests.get(sub_url, headers=headers, timeout=20)
|
response = requests.get(sub_url, headers=headers, timeout=20)
|
||||||
|
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
print(
|
print(
|
||||||
f"Ошибка сервера: Статус {response.status_code}. Проверьте ссылку."
|
f"Ошибка сервера: Статус {response.status_code}. Проверьте ссылку-подписку."
|
||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
content = response.text.strip()
|
raw_content = response.text.strip()
|
||||||
|
|
||||||
# Проверяем, что сервер вернул именно YAML-подобную структуру, а не ошибку JSON
|
# Проверяем, что в ответе реально есть сервера
|
||||||
if "proxies:" in content or "proxy-groups:" in content:
|
if "proxies:" not in raw_content:
|
||||||
print("Успешно получен готовый Clash-конфиг от сервера!")
|
print(
|
||||||
|
"Ошибка: Сервер вернул YAML, но в нём отсутствует блок нод 'proxies:'."
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# Сохраняем результат в файл
|
# ФАЙЛ 1: Сохраняем оригинальный чистый конфиг от провайдера
|
||||||
output_file = "clash.yaml"
|
with open("clash.yaml", "w", encoding="utf-8") as f:
|
||||||
with open(output_file, "w", encoding="utf-8") as f:
|
f.write(raw_content)
|
||||||
f.write(content)
|
print("Оригинальный конфиг успешно сохранен в clash.yaml")
|
||||||
|
|
||||||
print(f"Конфигурация сохранена в файл: {output_file}")
|
# ФАЙЛ 2: Создаем модифицированный конфиг для раздельного обхода
|
||||||
|
# Переводим режим работы в rule (по правилам) вместо global (весь трафик)
|
||||||
|
split_content = raw_content.replace("mode: global", "mode: rule")
|
||||||
|
|
||||||
|
if "rules:" in split_content:
|
||||||
|
# Отрезаем старые правила провайдера (всё, что после 'rules:')
|
||||||
|
base_part = split_content.split("rules:")[0]
|
||||||
|
|
||||||
|
# Формируем огромный расширенный список правил с разделением трафика
|
||||||
|
advanced_rules = """rules:
|
||||||
|
# 1. Локальные адреса и домашняя сеть (в обход VPN)
|
||||||
|
- DOMAIN-SUFFIX,local,DIRECT
|
||||||
|
- IP-CIDR,127.0.0.0/8,DIRECT
|
||||||
|
- IP-CIDR,172.16.0.0/12,DIRECT
|
||||||
|
- IP-CIDR,192.168.0.0/16,DIRECT
|
||||||
|
- IP-CIDR,10.0.0.0/8,DIRECT
|
||||||
|
- IP-CIDR,198.18.0.0/16,DIRECT
|
||||||
|
|
||||||
|
# 2. Популярные заблокированные ресурсы и сервисы (через VPN)
|
||||||
|
- GEOSITE,onion,→ Remnawave
|
||||||
|
- GEOSITE,twitter,→ Remnawave
|
||||||
|
- GEOSITE,instagram,→ Remnawave
|
||||||
|
- GEOSITE,facebook,→ Remnawave
|
||||||
|
- GEOSITE,meta,→ Remnawave
|
||||||
|
- GEOSITE,youtube,→ Remnawave
|
||||||
|
- GEOSITE,netflix,→ Remnawave
|
||||||
|
- GEOSITE,openai,→ Remnawave
|
||||||
|
- GEOSITE,chatgpt,→ Remnawave
|
||||||
|
- GEOSITE,discord,→ Remnawave
|
||||||
|
- GEOSITE,protonmail,→ Remnawave
|
||||||
|
- GEOSITE,intel,→ Remnawave
|
||||||
|
- GEOSITE,amd,→ Remnawave
|
||||||
|
- GEOSITE,nvidia,→ Remnawave
|
||||||
|
- GEOSITE,spotify,→ Remnawave
|
||||||
|
- GEOSITE,linkedin,→ Remnawave
|
||||||
|
- GEOSITE,rutracker,→ Remnawave
|
||||||
|
- GEOSITE,notion,→ Remnawave
|
||||||
|
- GEOSITE,docker,→ Remnawave
|
||||||
|
- GEOSITE,medium,→ Remnawave
|
||||||
|
- GEOSITE,behance,→ Remnawave
|
||||||
|
- GEOSITE,pinterest,→ Remnawave
|
||||||
|
- GEOSITE,canva,→ Remnawave
|
||||||
|
- GEOSITE,epicgames,→ Remnawave
|
||||||
|
|
||||||
|
# 3. Весь остальной зарубежный контент (по желанию, через VPN)
|
||||||
|
- GEOSITE,geolocation-!cn,→ Remnawave
|
||||||
|
|
||||||
|
# 4. Российские государственные сайты, банки и крупные ресурсы (напрямую, без VPN)
|
||||||
|
- GEOSITE,win-russia,DIRECT
|
||||||
|
- GEOSITE,category-gov-ru,DIRECT
|
||||||
|
- GEOSITE,ru,DIRECT
|
||||||
|
- GEOSITE,yandex,DIRECT
|
||||||
|
- GEOSITE,vk,DIRECT
|
||||||
|
- GEOSITE,mailru,DIRECT
|
||||||
|
- GEOSITE,sberbank,DIRECT
|
||||||
|
- GEOSITE,tinkoff,DIRECT
|
||||||
|
- GEOSITE,kinopoisk,DIRECT
|
||||||
|
- GEOSITE,avito,DIRECT
|
||||||
|
- GEOIP,RU,DIRECT
|
||||||
|
|
||||||
|
# 5. Финальное замыкающее правило: всё, что не подошло под списки выше, идет НАПРЯМУЮ
|
||||||
|
- MATCH,DIRECT
|
||||||
|
"""
|
||||||
|
# Склеиваем настройки и новые правила
|
||||||
|
full_split_yaml = base_part + advanced_rules
|
||||||
|
|
||||||
|
with open("clash_split.yaml", "w", encoding="utf-8") as f:
|
||||||
|
f.write(full_split_yaml)
|
||||||
|
print("Раздельный конфиг успешно сохранен в clash_split.yaml")
|
||||||
else:
|
else:
|
||||||
print("Предупреждение: Сервер вернул ответ, но он не похож на Clash YAML.")
|
print(
|
||||||
print("Первые 200 символов ответа для отладки:")
|
"Ошибка: В исходном конфиге не найдена секция rules: для замены!"
|
||||||
print(content[:200])
|
)
|
||||||
|
|
||||||
# Сохраняем как есть, чтобы вы могли посмотреть, что пришло
|
|
||||||
with open("response_debug.txt", "w", encoding="utf-8") as f:
|
|
||||||
f.write(content)
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Критическая ошибка при запросе: {e}")
|
print(f"Критическая ошибка во время выполнения: {e}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
fetch_clash_config()
|
fetch_and_prepare_configs()
|
||||||
|
|||||||
Reference in New Issue
Block a user