Установщик 3X-UI: 12 протоколов и единая подписка одной командой

- REALITY, Hysteria2, XHTTP, VLESS/VMess WS, Trojan gRPC, Shadowsocks 2022, TUIC,
  WireGuard, AmneziaWG (классика и 3.1, обфускация генерируется), MTProto
- Все подключения пользователя с общим subId — 3X-UI собирает одну подписку;
  Clash/Mihomo-клиенты получают готовый конфиг, остальные — ссылки
- Свой сертификат: --cert/--key; без Let's Encrypt — самоподписанный, отпечаток в ссылках (pcs)
- --protocols для выбора протоколов, повторный запуск досоздаёт недостающее
- Генератор Mihomo: AmneziaWG 3.1 с правильными именами параметров и version: 3
- Инструкция и матрица обновлены: подписка проверена на Xray, Mihomo и sing-box
This commit is contained in:
itsnotkubrick
2026-09-27 17:19:33 +03:00
parent 78935727be
commit 5958eceefb
9 changed files with 428 additions and 123 deletions
+2 -1
View File
@@ -245,7 +245,8 @@
if (!i.privatekey || !p.publickey || !p.endpoint) throw new Error('конфиг WireGuard неполный');
const ep = /^\[?([^\]]+?)\]?:(\d+)$/.exec(p.endpoint);
if (!ep) throw new Error('в конфиге WireGuard неверный Endpoint');
const awgKeys = ['jc', 'jmin', 'jmax', 's1', 's2', 's3', 's4', 'h1', 'h2', 'h3', 'h4', 'i1', 'i2', 'i3', 'i4', 'i5'];
const awgKeys = ['jc', 'jmin', 'jmax', 's1', 's2', 's3', 's4', 'h1', 'h2', 'h3', 'h4', 'i1', 'i2', 'i3', 'i4', 'i5',
'headerprotectionkey', 'contentpaddingaddition', 'rekeyaftertime', 'rejectaftertime', 'rekeytimeout', 'keepalivetimeout', 'maxhandshakeattempts'];
const awg = {};
awgKeys.forEach((k) => { if (i[k] !== undefined && i[k] !== '') awg[k] = /^\d+$/.test(i[k]) ? Number(i[k]) : i[k]; });
const isAwg = Object.keys(awg).length > 0;
+14 -1
View File
@@ -141,7 +141,20 @@
o['private-key'] = p.privateKey; o['public-key'] = p.publicKey;
o['pre-shared-key'] = p.preSharedKey || undefined; o.mtu = p.mtu;
o.reserved = p.reserved || undefined;
if (p.awg) o['amnezia-wg-option'] = p.awg;
// Параметры AmneziaWG в именах Mihomo. Для 3.1 (есть ключ защиты заголовков)
// обязателен version: 3 — без него Mihomo не подключается к такому серверу.
if (p.awg) {
const names = { headerprotectionkey: 'header-protection-key', contentpaddingaddition: 'content-padding-addition',
rekeyaftertime: 'rekey-after-time', rejectaftertime: 'reject-after-time', rekeytimeout: 'rekey-timeout',
keepalivetimeout: 'keepalive-timeout', maxhandshakeattempts: 'max-handshake-attempts' };
const c = {};
Object.keys(p.awg).forEach((k) => {
const v = p.awg[k];
c[names[k] || k] = /^h[1-4]$/.test(k) ? String(v) : v;
});
if (c['header-protection-key']) c.version = 3;
o['amnezia-wg-option'] = c;
}
break;
case 'hysteria2':
o.password = p.password; o.sni = p.sni; o.alpn = p.alpn;
+10
View File
@@ -119,6 +119,16 @@ test('Xray 26: вместо allowInsecure — отпечаток или пред
assert.equal(pinned.warnings.length, 0);
});
test('Mihomo: AmneziaWG 3.1 — имена параметров Mihomo и version: 3', () => {
const conf = '[Interface]\nPrivateKey = cHJpdg==\nAddress = 10.8.2.2/32\nJc = 3\nJmin = 49\nJmax = 139\nS1 = 141\nS2 = 92\nS3 = 22\nS4 = 18\nH1 = 5\nH2 = 6\nH3 = 7\nH4 = 8\nI1 = <r 89>\nHeaderProtectionKey = a2V5\nRekeyTimeout = 5-6\n[Peer]\nPublicKey = cHVi\nEndpoint = a.example.com:51822\n';
const r = buildMihomo(parseText('vpn://' + Buffer.from(conf).toString('base64')).proxies, { secret: 'x' });
const o = r.config.proxies[0]['amnezia-wg-option'];
assert.equal(o['header-protection-key'], 'a2V5');
assert.equal(o['rekey-timeout'], '5-6');
assert.equal(o.version, 3);
assert.equal(o.h1, '5');
});
test('Mihomo: порты XKeen и прокси', () => {
const r = buildMihomo(parseText([REALITY, HY2, SS_2022].join('\n')).proxies, { secret: 'x' });
assert.equal(r.config['redir-port'], 5000);