1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
| #!/usr/bin/env node /** * Hysteria2 一键部署脚本 – Pterodactyl 完美运行版 * 支持 amd64 + arm64,永别 EACCES,零语法错误 */
const { execSync, spawn } = require('child_process'); const fs = require('fs'); const https = require('https'); const path = require('path');
// ==================== 配置区 ==================== const HYSTERIA_VERSION = 'v2.6.5'; const DEFAULT_PORT = 25937; const AUTH_PASSWORD = 'abcuser2025'; // 务必改成自己的密码! const SNI = 'www.bing.com'; const ALPN = 'h3'; // ===============================================
const SERVER_PORT = process.argv[2] || DEFAULT_PORT; console.log(`\nHysteria2 将监听端口: ${SERVER_PORT}\n`);
// ---------- 架构检测 ---------- function getArch() { const arch = process.arch; if (arch === 'arm64') return 'arm64'; if (arch === 'x64') return 'amd64'; return ''; } const ARCH = getArch(); if (!ARCH) { console.error('无法识别 CPU 架构:', process.arch); process.exit(1); }
const BIN_NAME = `hysteria-linux-${ARCH}`; const BIN_PATH = path.join(__dirname, BIN_NAME);
// ---------- 检查 openssl ---------- function checkOpenSSL() { try { execSync('openssl version', { stdio: 'ignore' }); } catch { console.error('未检测到 openssl,请执行:apt update && apt install openssl -y'); process.exit(1); } }
// ---------- 下载二进制 ---------- async function downloadBinary() { if (fs.existsSync(BIN_PATH)) { console.log('二进制已存在,跳过下载'); fs.chmodSync(BIN_PATH, 0o755); return; }
const url = `https://gh.nxnow.top/https://github.com/apernet/hysteria/releases/download/app/${HYSTERIA_VERSION}/hysteria-linux-${ARCH}`; console.log(`正在下载 ${ARCH} 版本: ${url}`);
await new Promise((resolve, reject) => { const file = fs.createWriteStream(BIN_PATH); https.get(url, { timeout: 30000 }, res => { if (res.statusCode === 404) { return reject(new Error(`未找到 ${ARCH} 版本,请检查 Hysteria 是否已发布该架构`)); } if (res.statusCode !== 200) { return reject(new Error(`下载失败,状态码: ${res.statusCode}`)); }
res.pipe(file); file.on('finish', () => { file.close(); fs.chmodSync(BIN_PATH, 0o755); console.log('下载完成,已添加执行权限'); resolve(); }); }).on('error', err => { if (fs.existsSync(BIN_PATH)) fs.unlinkSync(BIN_PATH); reject(err); }); }); }
// ---------- 生成证书 ---------- function ensureCert() { if (fs.existsSync('cert.pem') && fs.existsSync('key.pem')) { console.log('已有证书,跳过生成'); return; } console.log('正在生成自签证书(10年)...'); execSync(`openssl req -x509 -nodes -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -days 3650 -keyout key.pem -out cert.pem -subj "/CN=${SNI}"`); console.log('证书生成成功'); }
// ---------- 写配置 ---------- function writeConfig() { const config = ` listen: ":${SERVER_PORT}"
tls: cert: ${path.resolve('cert.pem')} key: ${path.resolve('key.pem')}
auth: type: password password: "${AUTH_PASSWORD}"
alpn: - "${ALPN}"
bandwidth: up: 200 mbps down: 200 mbps
quic: initStreamReceiveWindow: 8388608 maxStreamReceiveWindow: 8388608 initConnReceiveWindow: 20971520 maxConnReceiveWindow: 20971520 maxIdleTimeout: 30s
masquerade: type: proxy proxy: url: https://news.ycombinator.com/ rewriteHost: true `.trim();
fs.writeFileSync('server.yaml', config); console.log('server.yaml 已写入'); }
// ---------- 获取公网IP ---------- async function getIP() { return new Promise(resolve => { https.get('https://api.ipify.org', res => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => resolve(data.trim() || 'YOUR_IP')); }).on('error', () => resolve('YOUR_IP')); }); }
// ---------- 主流程 ---------- (async () => { console.log('开始部署 Hysteria2...\n');
checkOpenSSL(); await downloadBinary(); ensureCert(); writeConfig();
const ip = await getIP();
console.log('\n部署成功!节点信息:\n'); console.log('════════════════════════════════════'); console.log(`IP : ${ip}`); console.log(`端口 : ${SERVER_PORT}`); console.log(`密码 : ${AUTH_PASSWORD}`); console.log(`SNI : ${SNI}`); console.log(`链接 : hysteria2://${AUTH_PASSWORD}@${ip}:${SERVER_PORT}/?sni=${SNI}&alpn=${ALPN}&insecure=1#Hy2-weirdhost`); console.log('════════════════════════════════════\n');
// 最后再加一次权限 fs.chmodSync(BIN_PATH, 0o755);
console.log('启动 Hysteria2 服务端...\n'); spawn(BIN_PATH, ['server', '-c', 'server.yaml'], { stdio: 'inherit' });
// 防止 Node 退出 process.on('SIGINT', () => process.exit()); process.on('SIGTERM', () => process.exit()); })();
|