UNPKG

lightsword

Version:

LightSword Secure SOCKS5 Proxy / iOS VPN Server

123 lines (103 loc) 4.36 kB
#!/usr/bin/env node //----------------------------------- // Copyright(c) 2015 Neko //----------------------------------- import * as program from 'commander'; import { App } from '../app'; import * as ipc from '../../common/ipc'; import * as fs from 'fs'; import * as path from 'path'; import * as child from 'child_process'; import { runAsClusterMode } from '../cluster'; program .version('0.7.0') .option('-p, --port [number]', 'Server Listening Port', Number.parseInt) .option('-k, --password [password]', 'Cipher Password', String) .option('-m, --method [algorithm]', 'Cipher Algorithm', String) .option('-c, --config <path>', 'Configuration File Path', String) .option('-u, --users <path>', 'Mutli-users File Path', String) .option('-t, --timeout [number]', 'Timeout', Number.parseInt) .option('-f, --fork', 'Run as a Daemon') .option('-d, --daemon <command>', 'Daemon Control', String) .option('-r, --cluster', 'Run as Cluster Mode') .option('-a, --management', 'Enable HTTP Management') .option('-x, --user <username>', 'Run Under Specified Privilege') .option('-s, --speed <number>', 'Speed Limitation \(KB\/s\)', Number.parseInt) .option('--disableSelfProtection', 'Disable Self-Protection') .parse(process.argv); var args = <any>program; function parseOptions(path: string) { if (!path) return; if (!fs.existsSync(path)) return; var content = fs.readFileSync(path).toString(); try { var configs = JSON.parse(content); return { port: configs.port, password: configs.password, cipherAlgorithm: configs.method, fork: configs.fork, cluster: configs.cluster, timeout: configs.timeout, management: configs.management, } } catch(ex) { console.warn('Configuration file error'); console.warn(ex.message); } } var fileOptions = parseOptions(args.config) || {}; if (fileOptions) Object.getOwnPropertyNames(fileOptions).forEach(n => args[n] = args[n] === undefined ? fileOptions[n] : args[n]); function parseUsers(path: string): { port: number, password: string, cipherAlgorithm: string, expireDate?: string, disableSelfProtection?: boolean }[] { if (!path) return []; if (!fs.existsSync(path)) return []; var content: string = fs.readFileSync(path).toString(); return content.split('\n').where((l: string) => l.length > 0 && !l.trim().startsWith('#')).select((l: string) => { var info = l.trim().split(' '); return { port: Number(info[0]), password: info[1], cipherAlgorithm: info[2], expireDate: info[3], speed: Number(info[4]), disableSelfProtection: args.disableSelfProtection }; }).toArray(); } var users = parseUsers(args.users); var argsOptions = { port: args.port, password: args.password, cipherAlgorithm: args.method, timeout: args.timeout, disableSelfProtection: args.disableSelfProtection, speed: args.speed } if (fileOptions) Object.getOwnPropertyNames(argsOptions).forEach(n => argsOptions[n] = argsOptions[n] === undefined ? fileOptions[n] : argsOptions[n]); if (!users.length) users.push(argsOptions); users = users.where(u => !Number.isNaN(u.port)).distinct((u1, u2) => u1.port === u2.port).toArray(); if (args.fork && !process.env.__daemon) { console.info('Run as daemon'); process.env.__daemon = true; var cp = child.spawn(process.argv[1], process.argv.skip(2).toArray(), { cwd: process.cwd(), stdio: 'ignore', env: process.env, detached: true }); cp.unref(); console.info('Child PID: ' + cp.pid); process.exit(0); } function listenDaemonCommands() { if (process.env.__daemon) { ipc.IpcServer.start('server'); } } if (args.daemon && !process.env.__daemon) { ipc.sendCommand('server', args.daemon, (code) => process.exit(code)); } else { if (args.cluster) { var clusterOptions = { users, management: args.management, user: args.user }; runAsClusterMode(clusterOptions, listenDaemonCommands); } else { users.forEach(u => new App(u)); listenDaemonCommands(); if (args.management) require('../management/index'); if (args.user) try { process.setuid(args.user); } catch(ex) { console.error(ex.message); } } process.title = process.env.__daemon ? path.basename(process.argv[1]) + 'd' : 'LightSword Server'; process.on('uncaughtException', (err) => { console.error(err); process.exit(1); }); }