commit
6d394e2756
10 changed files with 441 additions and 0 deletions
@ -0,0 +1 @@ |
|||||
|
/node_modules/ |
||||
@ -0,0 +1 @@ |
|||||
|
# node-panel |
||||
@ -0,0 +1,70 @@ |
|||||
|
var createError = require('http-errors'); |
||||
|
var express = require('express'); |
||||
|
var path = require('path'); |
||||
|
var logger = require('morgan'); |
||||
|
var serveStatic = require('serve-static') |
||||
|
var favicon = require('serve-favicon') |
||||
|
|
||||
|
|
||||
|
|
||||
|
var app = express(); |
||||
|
|
||||
|
// view engine setup
|
||||
|
//app.engine('html', require('express-art-template'));
|
||||
|
|
||||
|
app.set('views', path.join(__dirname, 'views')); |
||||
|
//app.set('view engine', 'html');
|
||||
|
|
||||
|
app.use(logger('dev')); |
||||
|
app.use(express.json()); |
||||
|
app.use(express.urlencoded({ extended: false })); |
||||
|
|
||||
|
// app.use('/static', express.static(path.join(__dirname, 'public')),{
|
||||
|
// etag: false
|
||||
|
// })
|
||||
|
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))) |
||||
|
app.use('/static', serveStatic(path.join(__dirname, 'public'),{ |
||||
|
etag: false |
||||
|
})) |
||||
|
app.use(function(req, res, next) { |
||||
|
req.headers['if-none-match'] = 'no-match-for-this'; |
||||
|
next(); |
||||
|
}); |
||||
|
|
||||
|
//路由,前台
|
||||
|
let indexRouter = require('./routes/index'); |
||||
|
|
||||
|
app.use('/', indexRouter); |
||||
|
|
||||
|
//路由,后台
|
||||
|
let muNodesRouter=require('./routes/mu/nodes.js'); |
||||
|
app.use('/mod_mu/nodes', muNodesRouter); |
||||
|
|
||||
|
let muUsersRouter=require('./routes/mu/users.js'); |
||||
|
app.use('/mod_mu/users', muUsersRouter); |
||||
|
|
||||
|
|
||||
|
let muFuncRouter=require('./routes/mu/func.js'); |
||||
|
app.use('/mod_mu/func', muFuncRouter); |
||||
|
|
||||
|
|
||||
|
// catch 404 and forward to error handler
|
||||
|
app.use(function(req, res, next) { |
||||
|
if (req.path && !req.path.endsWith('.map')){ |
||||
|
next(createError(404)); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// error handler
|
||||
|
app.use(function(err, req, res, next) { |
||||
|
// set locals, only providing error in development
|
||||
|
res.locals.message = err.message; |
||||
|
res.locals.error = req.app.get('env') === 'development' ? err : {}; |
||||
|
console.error(err.stack); |
||||
|
// render the error page
|
||||
|
res.status(err.status || 500); |
||||
|
res.render('error'); |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
module.exports = app; |
||||
@ -0,0 +1,93 @@ |
|||||
|
|
||||
|
const path = require('path'); |
||||
|
let envPath = path.join(__dirname, `../env.${process.env.NODE_ENV}`) |
||||
|
require('dotenv').config({ path: envPath }) |
||||
|
var app = require('../app'); |
||||
|
var debug = require('debug')("mybot:www"); |
||||
|
var http = require('http'); |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Get port from environment and store in Express. |
||||
|
*/ |
||||
|
|
||||
|
var port = normalizePort(process.env.PORT || '3000'); |
||||
|
app.set('port', port); |
||||
|
|
||||
|
/** |
||||
|
* Create HTTP server. |
||||
|
*/ |
||||
|
|
||||
|
var server = http.createServer(app); |
||||
|
|
||||
|
/** |
||||
|
* Listen on provided port, on all network interfaces. |
||||
|
*/ |
||||
|
|
||||
|
server.listen(port); |
||||
|
server.on('error', onError); |
||||
|
server.on('listening', onListening); |
||||
|
|
||||
|
/** |
||||
|
* Normalize a port into a number, string, or false. |
||||
|
*/ |
||||
|
|
||||
|
function normalizePort(val) { |
||||
|
var port = parseInt(val, 10); |
||||
|
|
||||
|
if (isNaN(port)) { |
||||
|
// named pipe |
||||
|
return val; |
||||
|
} |
||||
|
|
||||
|
if (port >= 0) { |
||||
|
// port number |
||||
|
return port; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Event listener for HTTP server "error" event. |
||||
|
*/ |
||||
|
|
||||
|
function onError(error) { |
||||
|
if (error.syscall !== 'listen') { |
||||
|
throw error; |
||||
|
} |
||||
|
|
||||
|
var bind = typeof port === 'string' |
||||
|
? 'Pipe ' + port |
||||
|
: 'Port ' + port; |
||||
|
|
||||
|
// handle specific listen errors with friendly messages |
||||
|
switch (error.code) { |
||||
|
case 'EACCES': |
||||
|
console.error(bind + ' requires elevated privileges'); |
||||
|
process.exit(1); |
||||
|
break; |
||||
|
case 'EADDRINUSE': |
||||
|
console.error(bind + ' is already in use'); |
||||
|
process.exit(1); |
||||
|
break; |
||||
|
default: |
||||
|
throw error; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Event listener for HTTP server "listening" event. |
||||
|
*/ |
||||
|
|
||||
|
function onListening() { |
||||
|
var addr = server.address(); |
||||
|
var bind = typeof addr === 'string' |
||||
|
? 'pipe ' + addr |
||||
|
: 'port ' + addr.port; |
||||
|
debug('Listening on ' + bind); |
||||
|
console.info("项目启动了", port) |
||||
|
//schedule.initSchedule(); |
||||
|
|
||||
|
} |
||||
|
|
||||
@ -0,0 +1,23 @@ |
|||||
|
{ |
||||
|
"name": "node-panel", |
||||
|
"version": "1.0.0", |
||||
|
"description": "", |
||||
|
"main": "index.js", |
||||
|
"scripts": { |
||||
|
"dev": "node ./bin/www NODE_ENV=development", |
||||
|
"start": "set NODE_ENV=development&nodemon --delay 1.5 bin/www ", |
||||
|
"prd": "pm2 start bin/www", |
||||
|
"test": "echo \"Error: no test specified\" && exit 1" |
||||
|
}, |
||||
|
"author": "", |
||||
|
"license": "ISC", |
||||
|
"dependencies": { |
||||
|
"debug": "^4.3.4", |
||||
|
"dotenv": "^16.0.1", |
||||
|
"express": "^4.18.1", |
||||
|
"morgan": "^1.10.0", |
||||
|
"nodemon": "^2.0.16", |
||||
|
"serve-favicon": "^2.5.0", |
||||
|
"serve-static": "^1.15.0" |
||||
|
} |
||||
|
} |
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,23 @@ |
|||||
|
const express = require('express'); |
||||
|
const router = express.Router(); |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
router.get('/', function(req, res, next) { |
||||
|
|
||||
|
res.send({ |
||||
|
title: '自娱自乐', |
||||
|
user: { |
||||
|
name: 'Index', |
||||
|
tags: ['art', 'template', 'nodejs'] |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
router.post('/ding', function(req, res, next) { |
||||
|
res.send({state:'ok', msg:'发送成功'}) |
||||
|
}); |
||||
|
|
||||
|
module.exports = router; |
||||
@ -0,0 +1,40 @@ |
|||||
|
var express = require('express'); |
||||
|
|
||||
|
var router = express.Router(); |
||||
|
|
||||
|
|
||||
|
router.get('/detect_rules', function(req, res, next) { |
||||
|
|
||||
|
console.info('GET /func/detect_rules nodeId:', req.query.node_id) |
||||
|
|
||||
|
let thatData = [ |
||||
|
{"regex":"BitTorrent protocol","id":1}, |
||||
|
{"regex":"(api|ps|sv|offnavi|newvector|ulog\\.imap|newloc)(\\.map|)\\.(baidu|n\\.shifen)\\.com","id":2}, |
||||
|
{"regex":"(.+\\.|^)(360|so)\\.(cn|com)","id":3}, |
||||
|
{"regex":"(Subject|HELO|SMTP)","id":4}, |
||||
|
{"regex":"\\b(dafahao|minghui|dongtaiwang|epochtimes|ntdtv|falundafa|wujieliulan|qxbbs|tuidang|rfi)\\.(org|com|net|fr)","id":5}, |
||||
|
{"regex":"(torrent|\\.torrent|peer_id=|info_hash|get_peers|find_node|BitTorrent|announce_peer|announce\\.php\\?passkey=|Joker)","id":6}, |
||||
|
{"regex":"(^.*\\@)(guerrillamail|guerrillamailblock|sharklasers|grr|pokemail|spam4|bccto|chacuo|027168)\\.(info|biz|com|de|net|org|me|la)","id":7}, |
||||
|
{"regex":"(.?)(sandai0|XLLiveUD0)(.)","id":8}, |
||||
|
{"regex":"(.*\\.||)(guanjia\\.qq\\.com|qqpcmgr|QQPCMGR)","id":9}, |
||||
|
{"regex":"\\b(rising|kingsoft|duba|xindubawukong|jinshanduba)\\.(com|net|org)","id":10}, |
||||
|
{"regex":"(.*\\.||)(fast|cachefly|speedtest)\\.(cn|org|com|net|de)","id":11}, |
||||
|
{"regex":"\\b(pincong|mohu|wujieliulan|epochtimes|voachinese|bbc|nytimes|landofhope)\\.(rocks|com|tv)","id":16}, |
||||
|
{"regex":"netbox\\.ipip\\.net","id":17}, |
||||
|
{"regex":"\\b(paramount|warnermedia|viacomcbs)\\.(rocks|com|tv)","id":18} |
||||
|
] |
||||
|
let result = {ret:1, data: thatData} |
||||
|
|
||||
|
console.info('GET /func/detect_rules result:', result) |
||||
|
res.send(result) |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
// 上送节点状态 负载状态
|
||||
|
router.post('/:nodeId/info', function(req, res, next) { |
||||
|
console.info('POST /func//:nodeId/info nodeId:', req.params.nodeId) |
||||
|
res.send({ret:1, data: "ok"}) |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
module.exports = router;//暴露模块
|
||||
@ -0,0 +1,87 @@ |
|||||
|
var express = require('express'); |
||||
|
|
||||
|
var router = express.Router(); |
||||
|
|
||||
|
|
||||
|
router.get('/:nodeId/info', function(req, res, next) { |
||||
|
console.info('GET /:nodeId/info:', req.params.nodeId) |
||||
|
|
||||
|
let nodeData = {} |
||||
|
|
||||
|
//
|
||||
|
//let ss = {"ret":1,"data":{"node_group":0,"server":"38.106.24.3;58080","node_speedlimit":0,"traffic_rate":1,"sort":1,"node_class":1,"type":"ss-panel-v3-mod_Uim","mu_only":1}}
|
||||
|
// ss
|
||||
|
if(req.params.nodeId == 1){ |
||||
|
let serverData = { |
||||
|
//"offset_port_user": "12345", //前端/订阅中下发的端口
|
||||
|
"offset_port_node": "58080", //节点服务器下发的端口
|
||||
|
//"server_user": "hk.domain.com", //前端/订阅中下发的服务器地址
|
||||
|
"mu_encryption": "aes-256-gcm", // `aes-128-gcm`, `aes-256-gcm`, `chacha20-ietf-poly1305`三者之一
|
||||
|
} |
||||
|
//nodeData = {"ret":1,"data":{"node_group":0,"server":"38.106.24.3;58080","node_speedlimit":0,"traffic_rate":1,"sort":1,"node_class":1,"type":"ss-panel-v3-mod_Uim","mu_only":1}}
|
||||
|
nodeData = { |
||||
|
"node_group":0, |
||||
|
"node_class":1, |
||||
|
"node_speedlimit":0, |
||||
|
"traffic_rate":1, |
||||
|
"mu_only":1, |
||||
|
"sort":1, |
||||
|
"type":"mimi-panel", |
||||
|
"server":"8.106.24.3;58080", |
||||
|
"custom_config": serverData, |
||||
|
"version":"2021.11" |
||||
|
} |
||||
|
} else if (req.params.nodeId == 2){ // v2ray
|
||||
|
let serverData = { |
||||
|
"offset_port_node": "58082", |
||||
|
"alter_id": "0", |
||||
|
"network": "tcp", |
||||
|
"security": "none", |
||||
|
} |
||||
|
//nodeData = {"ret":1,"data":{"node_group":0,"server":"38.106.24.3;58080","node_speedlimit":0,"traffic_rate":1,"sort":1,"node_class":1,"type":"ss-panel-v3-mod_Uim","mu_only":1}}
|
||||
|
nodeData = { |
||||
|
"node_group":0, |
||||
|
"node_class":1, |
||||
|
"node_speedlimit":0, |
||||
|
"traffic_rate":1, |
||||
|
"mu_only":1, |
||||
|
"sort":1, |
||||
|
"type":"mimi-panel", |
||||
|
"server":"141.164.57.1;58082;0;tcp;;", |
||||
|
"custom_config": serverData, |
||||
|
"version":"2021.11" |
||||
|
} |
||||
|
} else if (req.params.nodeId == 3){ // trojan
|
||||
|
let serverData = { |
||||
|
//"offset_port_user": 443,
|
||||
|
"offset_port_node": "58083", |
||||
|
"host": "19.g1cdn.com" |
||||
|
} |
||||
|
nodeData = { |
||||
|
"node_group":0, |
||||
|
"node_class":1, |
||||
|
"node_speedlimit":0, |
||||
|
"traffic_rate":1, |
||||
|
"mu_only":1, |
||||
|
"sort":1, |
||||
|
"type":"mimi-panel", |
||||
|
"server":"38.106.24.200;port=4419|host=19.g1cdn.com", |
||||
|
"custom_config": serverData, |
||||
|
"version":"2021.11" |
||||
|
} |
||||
|
} |
||||
|
let result = {ret:1, data: nodeData} |
||||
|
console.info("GET /:nodeId/info:", result) |
||||
|
res.send(result) |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
// 上送节点状态 负载状态
|
||||
|
router.post('/:nodeId/info', function(req, res, next) { |
||||
|
console.info("POST /:nodeId/info nodeId:", req.params.nodeId) |
||||
|
console.info("POST /:nodeId/info body:", req.body) |
||||
|
res.send({ret:1, data: "ok"}) |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
module.exports = router;//暴露模块
|
||||
@ -0,0 +1,103 @@ |
|||||
|
var express = require('express'); |
||||
|
|
||||
|
var router = express.Router(); |
||||
|
|
||||
|
|
||||
|
router.get('/', function(req, res, next) { |
||||
|
console.info('GET /users/ nodeId:', req.query.node_id) |
||||
|
|
||||
|
let userData = [ |
||||
|
{ |
||||
|
"is_multi_user": 2, |
||||
|
"method": "aes-256-gcm", |
||||
|
"d": 0, |
||||
|
"node_speedlimit": 100, |
||||
|
"node_connector": 2, |
||||
|
"disconnect_ip": "", |
||||
|
"forbidden_ip": "", |
||||
|
"forbidden_port": "", |
||||
|
"protocol_param": "", |
||||
|
"obfs_param": "", |
||||
|
"uuid": "b63abe71-01f9-3ee3-8992-ce16e7bdbf99", |
||||
|
"protocol": "auth_aes128_md5", |
||||
|
"obfs": "tls1.2_ticket_auth", |
||||
|
"port": 58080, |
||||
|
"passwd": "1_www.mimi.ooo", |
||||
|
"u": 0, |
||||
|
"id": 1, |
||||
|
"email": "1_1_www.mimi.ooo" |
||||
|
}, |
||||
|
{ |
||||
|
"is_multi_user": 0, |
||||
|
"method": "aes-256-gcm", |
||||
|
"d": 260605780723, |
||||
|
"node_speedlimit": 500, |
||||
|
"node_connector": 14, |
||||
|
"disconnect_ip": "", |
||||
|
"forbidden_ip": "", |
||||
|
"forbidden_port": "", |
||||
|
"protocol_param": "", |
||||
|
"obfs_param": "", |
||||
|
"uuid": "f5c3822f-2eca-38f6-b0d6-78533d15d372", |
||||
|
"protocol": "origin", |
||||
|
"obfs": "plain", |
||||
|
"port": 10373, |
||||
|
"passwd": "2_bBtiUI", |
||||
|
"u": 5311482594, |
||||
|
"id": 2, |
||||
|
"email": "2_2_bBtiUI" |
||||
|
}, |
||||
|
{ |
||||
|
"is_multi_user": 0, |
||||
|
"method": "aes-256-gcm", |
||||
|
"d": 11714963720, |
||||
|
"node_speedlimit": 500, |
||||
|
"node_connector": 14, |
||||
|
"disconnect_ip": "", |
||||
|
"forbidden_ip": "127.0.0.0/8,::1/128", |
||||
|
"forbidden_port": "", |
||||
|
"protocol_param": "", |
||||
|
"obfs_param": "", |
||||
|
"uuid": "c9f311cd-0aaa-31ff-a0b7-11463c17e863", |
||||
|
"protocol": "origin", |
||||
|
"obfs": "plain", |
||||
|
"port": 10556, |
||||
|
"passwd": "4_6TUdjP", |
||||
|
"u": 74239142, |
||||
|
"id": 4, |
||||
|
"email": "4_4_6TUdjP" |
||||
|
} |
||||
|
] |
||||
|
let result = {ret:1, data: userData} |
||||
|
console.info('GET /users/ result:', result) |
||||
|
res.send(result) |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
// POST /aliveip 上送用户在线ip
|
||||
|
router.post('/aliveip', async function (req, res) { |
||||
|
|
||||
|
console.info('POST /users/aliveip nodeId:', req.query.node_id) |
||||
|
console.info('POST /users/aliveip body:', req.body) |
||||
|
|
||||
|
res.send({ret:1, data:'ok'}) |
||||
|
}) |
||||
|
|
||||
|
// POST /traffic
|
||||
|
router.post('/traffic', async function (req, res) { |
||||
|
console.info('POST /users/traffic nodeId:', req.query.node_id) |
||||
|
console.info('POST /users/traffic body:', req.body) |
||||
|
// create user in req.body
|
||||
|
res.send({ret:1, data:'ok'}) |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
router.post('/detectlog', async function(req, res, next) { |
||||
|
console.info('POST /users/detectlog nodeId:', req.query.node_id) |
||||
|
console.info('POST /users/detectlog body:', req.body) |
||||
|
res.send({ret:1, data:'ok'}) |
||||
|
}); |
||||
|
|
||||
|
module.exports = router;//暴露模块
|
||||
Loading…
Reference in new issue