- PVSM.RU - https://www.pvsm.ru -
Актуальные proxy-клиенты на старых Mac часто ведут себя одинаково: если устанавливаются, импортируют профиль, и даже показывают список серверов, не доводят дело до рабочего подключения. На практике это особенно заметно на macOS Catalina 10.15.8. Текущий Happ [1] для Mac официально требует macOS 12.0 или новее, а значит для Catalina уже не подходит как штатный путь. IRBox [2] в релизах заявляет поддержку macOS 10.15+, но в моём тесте на Catalina встроенный core упёрся в несовместимость с системой. Рабочий результат в итоге дал V2RayXS [3] 1.5.9 для x86_64: не через обычный импорт подписки, а через ручную сборку VLESS + Reality outbound.
Дисклеймер
Я не сетевой инженер и не специалист по обходу блокировок. Я написал эту инструкцию как пользователь для таких же пользователей, которые столкнулись с задачей, и не смогли найти в одном месте понятную пошаговую инструкцию. Для тех, кто просто хочет последовательно добиться рабочего результата на старом Mac.
Эта статья рассчитана на ситуацию, когда у вас старый Intel Mac, macOS Catalina 10.15.x, подписка с VLESS-узлами и обычный импорт подписки в клиенте либо не работает, либо создаёт пустой конфиг.
Это важный шаг, который легко пропустить. На старом macOS нельзя просто скачать «самую новую» версию клиента и ожидать, что она будет работать.
Логика выбора для Intel Mac с Catalina 10.15.x была такой:
сначала нужно смотреть не только на название приложения, но и на архитектуру сборки — в нашем случае нужна именно x86_64, а не arm64;
затем нужно проверить release notes старых версий на странице релизов V2RayXS;
если в релизе разработчик сам предупреждает о проблеме именно в x86_64-сборке, такую версию для Catalina лучше не брать;
если в более раннем релизе есть правка, связанная с realitySettings или импортом VLESS, такая версия становится приоритетной.
В моём случае это привело к такому выводу:
V2RayXS 1.5.9 x86_64 — лучший кандидат для Catalina;
V2RayXS 1.5.10 x86_64 — нежелателен, потому что сам разработчик предупреждает, что в этой сборке встроен неправильный bundled xray core package;
более новые версии на старом Intel Mac стоит проверять только после явного изучения release notes.
Практическое правило простое: для Catalina сначала искать последнюю стабильную x86_64-сборку до проблемного релиза, а уже потом экспериментировать с более новыми.
Искать старые версии лучше в двух местах:
Основной источник — страница релизов проекта V2RayXS [4]. Там можно проверить историю версий, changelog и названия файлов.
Для старых сборок V2RayXS есть удобное зеркало на SourceForge [5]. Это полезно, когда GitHub-asset неудобно скачивать напрямую или нужна конкретная старая версия.
Важный нюанс: старые версии V2RayXS обычно распространяются не как DMG, а как ZIP-архив с .app внутри. То есть для Catalina не стоит искать именно DMG любой ценой: для V2RayXS рабочий формат старых релизов — это чаще V2RayXS_x86_64.app.zip.
Схема загрузки такая:
открыть релизы проекта;
найти нужную версию;
выбрать x86_64-сборку;
скачать ZIP-архив;
распаковать его и перенести .app в Applications.
Как основной клиент для Catalina его лучше не брать: текущая версия в Mac App Store [1] требует macOS 12.0 or later. То есть для Catalina этот путь закрыт официально.
В релизах IRBox [2] прямо указаны сборки для macOS Intel и Apple Silicon, а в описании релиза сказано, что приложение включает sing-box и xray-core. Формально это выглядит перспективно для Catalina. Но в реальном тесте на 10.15.8 bundled core может оказаться несовместимым с системой.
Рабочая схема выглядела так:
отсеять клиенты, которые не подходят по macOS или реально не запускаются;
установить V2RayXS 1.5.9 x86_64;
не полагаться на auto-import подписки, если он создаёт пустой config.json;
локально декодировать подписку на самом Mac;
собрать отдельный JSON-outbound для каждого VLESS/Reality-узла;
добавить нужные узлы через Advanced -> Outbounds;
загрузить core и включить Global Mode;
отдельно настроить Telegram Desktop на локальный SOCKS5.
V2RayXS [3] — это GUI для xray-core на macOS. Приложение поднимает локальный SOCKS5 на 127.0.0.1:1081 и HTTP proxy на 127.0.0.1:8001, а также работает в режимах Global Mode, PAC Mode и Manual Mode.
У V2RayXS на Catalina может возникнуть типичная проблема: подписка подтягивается, пункты в меню появляются, но итоговый config.json содержит не реальный узел, а пустую заготовку, например:
address: ""
port: 0
нулевой UUID
security: "none"
пустой realitySettings
Если вы видите такую картину, значит клиент не собрал полноценный outbound из подписки, и дальше нужно идти через ручной JSON.
"outbounds": [
{
"protocol": "vless",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "",
"users": [
{
"flow": "",
"id": "00000000-0000-0000-0000-000000000000",
"encryption": "none"
}
],
"port": 0
}
]
},
"tag": "VLESS",
"streamSettings": {
"security": "none",
"realitySettings": {},
"network": "tcp"
}
}
]
Признаки сломанного импорта: пустой address, port=0, нулевой UUID, security=none и пустой realitySettings.
Если у вас есть только subscription URL, не публикуйте его и не отправляйте в онлайн-конвертеры. Всё можно сделать локально на самом Mac.
Откройте Terminal и выполните:
curl -L '<SUBSCRIPTION_URL>' | tr -d 'rn' | base64 -D | nl -ba > ~/Desktop/vless-list.txt
open ~/Desktop/vless-list.txt
Что делает эта команда:
скачивает подписку;
декодирует base64;
нумерует все строки;
сохраняет их в ~/Desktop/vless-list.txt.
В итоге вы получаете локальный список всех vless://...-ссылок без публикации URL и без передачи содержимого на сторонние сервисы.
vless-list.txt без использования сторонних сервисовЕсли взять один такой vless://...-линк и разобрать его на части, в нём обычно есть:
адрес сервера и порт;
UUID;
security=reality;
flow=xtls-rprx-vision;
sni, pbk, sid, fp, иногда spx.
Это нужно превратить в JSON-outbound для Xray. Базовый шаблон выглядит так:
{
"protocol": "vless",
"tag": "node-001",
"settings": {
"vnext": [
{
"address": "example.com",
"port": 443,
"users": [
{
"id": "UUID-HERE",
"encryption": "none",
"flow": "xtls-rprx-vision"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"serverName": "SNI-HERE",
"fingerprint": "firefox",
"publicKey": "PUBLIC-KEY-HERE",
"shortId": "SHORTID-HERE",
"spiderX": "/PATH-HERE"
}
}
}
Важно: tag должен быть уникальным. Не используйте main: в V2RayXS это служебный тег.
Откройте Configure... -> Advanced... -> Outbounds.
Дальше:
нажмите +;
вставьте JSON одного узла;
нажмите Finish;
вернитесь в основное окно Configure...;
обязательно нажмите OK.
Advanced -> OutboundsЕсли после Finish вы не нажмёте OK в основном окне Configure, правка может не сохраниться.
Configure... должны появиться реальные параметры узла, а не пустая заглушкаНажмите Load core, затем откройте View current config.json....
После этого в итоговом config.json должно быть видно:
routing.rules[].outboundTag указывает на ваш тег;
в outbounds указан реальный address;
указан реальный port;
streamSettings.security [6] равно "reality";
realitySettings заполнен.
Если всё это есть, значит вы получили не пустой шаблон, а настоящий рабочий Xray-конфиг.
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "example-server.com",
"users": [
{
"flow": "xtls-rprx-vision",
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"encryption": "none"
}
],
"port": 443
}
]
},
"tag": "reality 1",
"streamSettings": {
"network": "tcp",
"realitySettings": {
"publicKey": "PUBLIC_KEY_HERE",
"serverName": "example-sni.com",
"shortId": "SHORT_ID_HERE",
"spiderX": "/example-path",
"fingerprint": "firefox"
},
"security": "reality"
}
}
]
Признак правильного импорта: заполнены address, port, UUID, flow, security=reality и блок realitySettings
Когда ручной узел уже сохранён и виден в config.json:
выберите нужный сервер в меню V2RayXS;
нажмите Load core;
затем включите Global Mode.
Если интернет заработал — схема рабочая.
Если интернет пропал:
вернитесь в Manual Mode;
проверьте config.json;
убедитесь, что выбран именно ваш ручной узел, а не пустой шаблон.
Global ModeДаже если в браузере уже открываются и обычные, и заблокированные сайты, Telegram Desktop может не заработать автоматически. В таком случае проблема обычно не в VLESS и не в сервере, а в том, что Telegram не использует системный proxy V2RayXS так же, как браузер.
Решение:
тип proxy: SOCKS5;
host: 127.0.0.1;
port: 1081;
логин и пароль: пусто.
После этого Telegram начинает работать через локальный SOCKS5 V2RayXS.
Если подключение уже работает, но скорость заметно ниже, это не обязательно ошибка настройки. На старом iMac типичные причины такие:
выбран перегруженный узел;
более слабый Intel CPU;
iMac сидит в диапазоне 2.4 GHz, а не 5 GHz;
на другом компьютере используется другой клиент или другой сетевой маршрут.
На практике переход на 5 GHz может дать очень заметный прирост скорости.
Если узлов много, вручную собирать JSON для каждого неудобно. Ниже — локальный Python-скрипт, который:
скачивает подписку по URL;
декодирует её;
находит все vless://...-ссылки;
превращает каждый узел в отдельный JSON-файл для V2RayXS;
ничего не отправляет на сторонние сервисы.
Сохраните файл как ~/Desktop/convert_subscription.py:
#!/usr/bin/env python3
import base64
import json
import os
import re
import sys
import urllib.request
from urllib.parse import urlparse, parse_qs, unquote
def safe_name(s: str) -> str:
s = unquote(s).strip()
s = re.sub(r'[\/:*?"<>|]+', "_", s)
s = re.sub(r"s+", " ", s)
return s[:80] if s else "node"
def first(params, key, default=""):
values = params.get(key, [])
return values[0] if values else default
def vless_to_outbound(link: str, index: int) -> dict:
p = urlparse(link.strip())
if p.scheme.lower() != "vless":
raise ValueError("Not a vless link")
params = parse_qs(p.query)
tag = f"node-{index:03d} {safe_name(p.fragment)}".strip()
user = {
"id": p.username or "",
"encryption": first(params, "encryption", "none"),
}
flow = first(params, "flow", "")
if flow:
user["flow"] = flow
outbound = {
"protocol": "vless",
"tag": tag,
"settings": {
"vnext": [
{
"address": p.hostname or "",
"port": p.port or 443,
"users": [user]
}
]
},
"streamSettings": {
"network": first(params, "type", "tcp"),
"security": first(params, "security", "none")
}
}
if outbound["streamSettings"]["security"] == "reality":
reality = {
"serverName": first(params, "sni", ""),
"fingerprint": first(params, "fp", ""),
"publicKey": first(params, "pbk", ""),
"shortId": first(params, "sid", ""),
"spiderX": unquote(first(params, "spx", "")),
}
reality = {k: v for k, v in reality.items() if v}
outbound["streamSettings"]["realitySettings"] = reality
return outbound
def main():
if len(sys.argv) != 2:
print("Usage: python3 convert_subscription.py '<SUBSCRIPTION_URL>'")
sys.exit(1)
sub_url = sys.argv[1]
with urllib.request.urlopen(sub_url) as r:
raw = r.read().decode("utf-8", errors="ignore").strip()
decoded = base64.b64decode(raw).decode("utf-8", errors="ignore")
links = [line.strip() for line in decoded.splitlines() if line.strip().lower().startswith("vless://")]
if not links:
print("No VLESS links found.")
sys.exit(2)
out_dir = os.path.expanduser("~/Desktop/v2rayxs-outbounds")
os.makedirs(out_dir, exist_ok=True)
index_lines = []
for i, link in enumerate(links, start=1):
outbound = vless_to_outbound(link, i)
filename = f"{i:03d} - {safe_name(outbound['tag'])}.json"
filepath = os.path.join(out_dir, filename)
with open(filepath, "w", encoding="utf-8") as f:
json.dump(outbound, f, ensure_ascii=False, indent=2)
index_lines.append(f"{i:03d} -> {outbound['tag']}")
with open(os.path.join(out_dir, "INDEX.txt"), "w", encoding="utf-8") as f:
f.write("n".join(index_lines))
print(f"Done. Files saved to: {out_dir}")
if __name__ == "__main__":
main()
Запуск:
python3 ~/Desktop/convert_subscription.py '<SUBSCRIPTION_URL>'
open ~/Desktop/v2rayxs-outbounds
После этого на рабочем столе появится папка v2rayxs-outbounds с JSON-файлами.

Скрипт раскладывает подписку на отдельные JSON-файлы.

Каждый такой файл можно открывать, копировать код и вставлять в Advanced -> Outbounds
Сработало:
отказаться от Happ как от основного сценария для Catalina;
не переоценивать формальную совместимость IRBox с macOS 10.15;
использовать V2RayXS как GUI над Xray;
не доверять auto-import, если он создаёт пустой конфиг;
собирать VLESS + Reality вручную через Advanced -> Outbounds;
подключить Telegram Desktop отдельно через SOCKS5 127.0.0.1:1081;
проверить диапазон Wi-Fi и перейти на 5 GHz.
Не сработало:
ожидание, что «подписка импортировалась — значит всё готово»;
попытка работать с пустыми VLESS-пунктами из кривого импорта;
надежда, что браузер и Telegram поведут себя одинаково;
попытка использовать неподходящий клиент просто потому, что он хорошо работает на других устройствах.
Главный вывод из этой истории простой: на старом Intel Mac с macOS Catalina рабочее подключение зависит не столько от формальной поддержки протокола VLESS/Reality, сколько от того, насколько конкретный клиент и его bundled core реально совместимы с системой. Happ сейчас требует macOS 12+ и для Catalina отпадает официально. IRBox формально поддерживает macOS 10.15+, но на практике оказалось что это не так. А V2RayXS оказался рабочим именно потому, что позволил обойти кривой импорт и вручную собрать нормальный Xray-конфиг.
Автор: OKTHEOK
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/json/450338
Ссылки в тексте:
[1] Happ: https://apps.apple.com/us/app/happ-proxy-utility/id6504287215
[2] IRBox: https://github.com/frank-vpl/IRBox/releases
[3] V2RayXS: https://github.com/tzmax/V2RayXS
[4] страница релизов проекта V2RayXS: https://github.com/tzmax/v2rayXS/releases
[5] зеркало на SourceForge: https://sourceforge.net/projects/v2rayxs.mirror/files/
[6] streamSettings.security: http://streamSettings.security
[7] Источник: https://habr.com/ru/articles/1027620/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1027620
Нажмите здесь для печати.