Skip to content

Commit

Permalink
init code version
Browse files Browse the repository at this point in the history
  • Loading branch information
askk committed Dec 5, 2017
0 parents commit 2969f52
Show file tree
Hide file tree
Showing 25 changed files with 2,117 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

183 changes: 183 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
[![NPM version][npm-image]][npm-url]
[![npm license][license-image]][download-url]

[npm-image]: https://img.shields.io/npm/v/shadowsocks-manager.svg?style=flat-square
[npm-url]: https://npmjs.org/package/shadowsocks-manager
[download-url]: https://npmjs.org/package/shadowsocks-manager
[license-image]: https://img.shields.io/npm/l/shadowsocks-manager.svg

# shadowsocks-manager

A shadowsocks manager tool for multi user and traffic control.
Base on Node.js and SQLite.

For more details, you can see [the wiki page](https://github.com/shadowsocks/shadowsocks-manager/wiki).

If you want to use the old version, please switch to [this branch](https://github.com/shadowsocks/shadowsocks-manager/tree/version1).

## WebGUI Demo:

[https://wall.gyteng.com](https://wall.gyteng.com)

## Dependencies

Node.js 6.*

## Install

### From source:

```
git clone https://github.com/shadowsocks/shadowsocks-manager.git
cd shadowsocks-manager
npm i
```
use `node server.js` to run this program.

### From npm:
```
npm i -g shadowsocks-manager
```
use `ssmgr` to run this program.

### From docker:
```
docker run --name ssmgr -idt -v ~/.ssmgr:/root/.ssmgr --net=host gyteng/ssmgr [ssmgr params...]
```

### Build docker image:

here is the `Dockerfile`

```
FROM ubuntu:16.04
MAINTAINER gyteng <igyteng@gmail.com>
RUN apt-get update && \
apt-get install tzdata net-tools curl git sudo software-properties-common python-pip -y && \
pip install git+https://github.com/shadowsocks/shadowsocks.git@master && \
add-apt-repository ppa:max-c-lv/shadowsocks-libev -y && \
curl -sL https://deb.nodesource.com/setup_6.x | bash - && \
apt-get install -y nodejs shadowsocks-libev && \
npm i -g shadowsocks-manager && \
echo "Asia/Shanghai" > /etc/timezone && \
rm /etc/localtime && \
dpkg-reconfigure -f noninteractive tzdata
ENTRYPOINT ["/usr/bin/ssmgr"]
```

### Usage
1. Start shadowsocks with [manager API](https://github.com/shadowsocks/shadowsocks/wiki/Manage-Multiple-Users), it supports `shadowsocks-python` and `shadowsocks-libev`.
For example, you can run this command:
`ss-manager -m aes-256-cfb -u --manager-address 127.0.0.1:6001`
2. run ssmgr with type s:

config file:
```
type: s
shadowsocks:
address: 127.0.0.1:6001
manager:
address: 0.0.0.0:4001
password: '123456'
db: 'ss.sqlite'
```

If you want to use MySQL, the `db` must like this:

```
db:
host: '1.1.1.1'
user: 'root'
password: 'abcdefg'
database: 'ssmgr'
```

And you have to close `only_full_group_by` when the version of MySQL is greater than 5.7

command:
`ssmgr -c /your/config/file/path.yml`

3. If you have several servers, you have to run step 1 and step 2 in every server.
The listening address in `--manager-address` of step 1 and in `shadowsocks -> address` of step 2's config file must be same. For security reseon, we recommend you to use `127.0.0.1` instead of `0.0.0.0`.
4. Now you can use the plugins to manage them. You can read the details in plugins readme page.

```
+-------------+ +-------------+ +------+
| Shadowsocks | | Shadowsocks | ... | |
| manager API | | manager API | | |
+-------------+ +-------------+ +------+
| | |
| | |
+-------------+ +-------------+ +------+
| ssmgr | | ssmgr | ... | |
| with type s | | with type s | | |
+-------------+ +-------------+ +------+
| | |
+------------+----+-------- ... ---+
|
|
+---------------+
| ssmgr plugins |
| with type m |
+---------------+
```

### Plugins
[cli](https://github.com/shadowsocks/shadowsocks-manager/blob/master/plugins/cli/README.md)
[telegram](https://github.com/shadowsocks/shadowsocks-manager/blob/master/plugins/telegram/README.md)
[freeAccount](https://github.com/shadowsocks/shadowsocks-manager/blob/master/plugins/freeAccount/README.md)
[webgui](https://github.com/shadowsocks/shadowsocks-manager/blob/master/plugins/webgui/README.md)

### Parameter

`ssmgr --help` will show startup parameters info.

```
Usage: ssmgr [options]
Options:
-h, --help output usage information
-V, --version output the version number
-c, --config [file] config file, default: ~/.ssmgr/default.yml
-d, --db [file] sqlite3 file, sample: ~/.ssmgr/db.sqlite
-t, --type [type] type, s for server side, m for manager side
-s, --shadowsocks [address] ss-manager address, sample: 127.0.0.1:6001
-m, --manager [address] manager address, sample: 0.0.0.0:6002
-p, --password [password] manager password, both server side and manager side must be equals
-r, --run [type] run shadowsocks from child_process, sample: libev / libev:aes-256-cfb / python / python:aes-256-cfb
--debug show debug message
```

First, ssmgr will read the config file in `--config`, and other parameters(`-detsmp`) will replace the config file values.

### Translate

If your want to help to translate it to other languages, please edit files [here](https://github.com/shadowsocks/shadowsocks-manager/tree/dev/plugins/webgui/public/translate) and give me a pull request.

### Telegram
Join the group if you have some problem: [https://t.me/ssmgr](https://t.me/ssmgr)

### VPS recommendation

* [Linode](https://www.linode.com/?r=bbc24323b3adaf3d74f242fd958d91b55cc6fdea)

* [DigitalOcean](https://m.do.co/c/d43891b79a52)

* [Vultr](http://www.vultr.com/?ref=6926595)

* [AlibabaCloud](https://account-intl.aliyun.com/register/intl_register.htm?biz_params=%7B%22intl%22%3A%22%7B%5C%22referralCode%5C%22%3A%5C%22koa26v%5C%22%7D%22%7D)

* [BandwagonHost](https://bandwagonhost.com/aff.php?aff=19999)

* [dediserve](https://manage.dediserve.com/?affid=841)

### Donate
If you find this project helpful, please consider making a donation:

* Alipay
<img src="https://github.com/gyteng/gyteng.github.com/raw/master/media/pic/alipay.jpg" width="160">

* WeChat Pay
<img src="https://github.com/gyteng/gyteng.github.com/raw/master/media/pic/wechat.png" width="160">
8 changes: 8 additions & 0 deletions bin/ssmgr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env node
process.env.NODE_ENV = 'production';
const path = require('path');
const fs = require('fs');
const lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib/');
console.log(lib);
process.chdir(lib);
require(lib + '/server');
17 changes: 17 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
type: s

shadowsocks:
address: 127.0.0.1:6001
#portRange: 50000-51000,55000,55002

manager:
address: 0.0.0.0:6002
password: '123456'

db: 'db.sqlite'

# db:
# host: '1.1.1.1'
# user: 'root'
# password: 'abcdefg'
# database: 'ssmgr'
125 changes: 125 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
const del = require('del');
const gulp = require('gulp');
const path = require('path');
const babel = require('gulp-babel');
const webpack = require('webpack');
const webpackStream = require('webpack-stream');

gulp.task('clean', () => {
return del([
'lib',
'plugins/webgui/libs/bundle.js',
]);
});

gulp.task('freeAccountCopy', ['clean'], () => {
return gulp
.src([
'plugins/freeAccount/libs/**',
'plugins/freeAccount/views/**',
], {
base: './'
})
.pipe(gulp.dest('lib'));
});

gulp.task('webguiBuild', () => {
return gulp.src([
'plugins/webgui/public/**',
])
.pipe(webpackStream({
entry: './plugins/webgui/public/app.js',
output: {
path: path.resolve(__dirname, 'libs'),
filename: 'bundle.js'
},
externals: [
{
window: 'window'
}
],
module: {
loaders: [{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: [
[
'env', {
targets: {
browsers: [
'Chrome >= 52',
'FireFox >= 44',
'Safari >= 7',
'Explorer 11',
'last 4 Edge versions'
]
}
}
]
]
}
}]
},
plugins: [ new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}) ]
}))
.pipe(gulp.dest('plugins/webgui/libs'));
});

gulp.task('webguiCopy', ['webguiBuild'], () => {
return gulp
.src([
'plugins/webgui/libs/**',
'plugins/webgui/public/**',
'plugins/webgui/views/**',
], {
base: './'
})
.pipe(gulp.dest('lib'));
});

gulp.task('babelCopy', ['clean'], () => {
return gulp
.src([
'config/*.yml',
'package.json',
], {
base: './'
})
.pipe(gulp.dest('lib'));
});

gulp.task('babel', ['webguiCopy', 'freeAccountCopy', 'babelCopy'], () => {
return gulp.src([
'**/*.js',
'!node_modules/**',
'!lib/**',
'!plugins/freeAccount/libs/**',
'!plugins/webgui/libs/**',
'!plugins/webgui/public/**',
])
.pipe(babel({
presets: [
[
'env', {
targets: {
node: '6.0'
},
}
]
],
}))
.pipe(gulp.dest('lib'));
});

gulp.task('webguiWatch', function () {
gulp.watch('plugins/webgui/public/**', ['webguiBuild']);
});

gulp.task('default', ['clean', 'babel'], () => {

});
55 changes: 55 additions & 0 deletions init/checkConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const os = require('os');
const path = require('path');
const program = require('commander');
const version = appRequire('package').version;
const log = appRequire('init/log');

const log4js = require('log4js');
const logger = log4js.getLogger('system');

const ssmgrPath = path.resolve(os.homedir(), './.ssmgr/');

program
.version('shadowsocks-manager ' + version)
.option('-c, --config [file]', 'config file, default: ~/.ssmgr/default.yml')
.option('-d, --db [file]', 'sqlite3 file, sample: ~/.ssmgr/db.sqlite')
.option('-t, --type [type]', 'type, s for server side, m for manager side')
.option('-s, --shadowsocks [address]', 'ss-manager address, sample: 127.0.0.1:6001')
.option('-m, --manager [address]', 'manager address, sample: 0.0.0.0:6002')
.option('-p, --password [password]', 'manager password, both server side and manager side must be equals')
.option('-r, --run [type]', 'run shadowsocks from child_process, sample: libev / libev:aes-256-cfb / python / python:aes-256-cfb')
.option('--debug', 'show debug message')
.parse(process.argv);

if(program.config) { global.configFile = program.config; }

if(!program.debug) {
log.setConsoleLevel('ERROR');
}

const config = appRequire('services/config');
let logName = 'uname';

if(program.type) {config.set('type', program.type);}
if(program.shadowsocks) {config.set('shadowsocks.address', program.shadowsocks);}
if(program.manager) {config.set('manager.address', program.manager);}
if(program.password) {config.set('manager.password', program.password);}
if(program.db) {
config.set('db', program.db);
}
if (typeof config.get('db') === 'object') {
logName = config.get('db.database');
} else {
const dbpath = config.get('db');
logName = path.basename(dbpath).split('.')[0];
if (dbpath[0] === '/' || dbpath[0] === '.' || dbpath[0] === '~') {
config.set('db', path.resolve(dbpath));
} else {
config.set('db', path.resolve(ssmgrPath, dbpath));
}
}
log.setFileAppenders(logName);

if(program.run) {
config.set('runShadowsocks', program.run);
}
Loading

0 comments on commit 2969f52

Please sign in to comment.