Commit 4d5a35ec authored by Ahmad's avatar Ahmad

init

parents
Pipeline #199 canceled with stages
const os = require('os');
const axios = require('axios');
const cron = require('node-cron');
const cronIpToRedis = require('node-cron');
const fs = require('fs');
const path = require('path');
const ut = require('util');
const readFiles = ut.promisify(fs.readFile);
const writeFile = ut.promisify(fs.writeFile);
const {exec} = require('child_process');
const express = require('express')
const shell = require('shelljs');
const pm2 = require('pm2')
const execAsync = ut.promisify(require('child_process').exec);
const app = express()
let Xray = require('./xray')
let xrayManager = new Xray()
const {spawn} = require('child_process');
const processName = `config.json`;
let uniqueIps = new Set();
let storeConfig=null
let cpuUser = 0;
let totalRAM = 0;
let usedRAM = 0;
let freeRAM = 0;
let networkUsage
let uptime
const child_process = require('child_process');
const BASE_URL = "https://server.vpsl.xyz";
app.get('/', (req, res) => {
res.send('Hello World!')
//run()
})
app.get('/rst2', (req, res) => {
return reboot()
})
app.get('/test', (req, res) => {
// console.log(req.params.acc)
res.sendfile('jetmtp.png')
})
app.get('/delall', (req, res) => {
res.send('done')
// forceCreateNew()
})
app.get('/resetProcc', (req, res) => {
res.send('done')
// restartXray()
})
app.get('/system-info', async (req, res) => {
try {
res.json({
cpuUser,
totalRAM,
usedRAM,
freeRAM,
networkUsage,
uptime,
users:{ count: uniqueIps.size, ips: Array.from(uniqueIps) }
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// New routes to get system resource information
app.get('/cpu-usage', async (req, res) => {
try {
res.json({ cpuUser });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.get('/ram-usage', async (req, res) => {
try {
res.json({ ramUsage:freeRAM });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.get('/total-ram', async (req, res) => {
try {
res.json({ totalRAM });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.get('/used-ram', async (req, res) => {
try {
res.json({ usedRAM });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.get('/network-usage', async (req, res) => {
try {
res.json(networkUsage);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.get('/uptime', async (req, res) => {
try {
res.json({ uptime });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.get('/users', async (req, res) => {
try {
res.json({ count: uniqueIps.size, ips: Array.from(uniqueIps) });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => console.log(`Example app listening on port 3000!`))
async function main() {
let newConfig=await getConfig()
newConfig=JSON.stringify(newConfig)
if (storeConfig === null || newConfig !==storeConfig)
{
console.log('config has been changed')
applyChanges(newConfig)
storeConfig=newConfig
}
else
{
console.log('config not been changed')
}
}
async function applyChanges(newConfig) {
const configFilePath = path.join('/usr/local/x-ui/', `config.json`);
await writeFile(configFilePath, newConfig);
const processExists = await xrayManager.isProcessRunning(processName);
if (!processExists) {
await startProcess();
}
// Sort clients by id
}
async function startProcess() {
return new Promise((resolve, reject) => {
const configFilePath = path.join('/usr/local/x-ui/', `config.json`);
//console.log(configFilePath)
pm2.connect((error) => {
if (error) {
console.error(`PM2 connection error: ${error.message}`);
reject(error);
} else {
pm2.start(
{
name: `runConfig`,
script: './xray',
args: `run -c config.json`,
cwd: '/usr/local/x-ui',
watch: [configFilePath],
ignore_watch: ['node_modules'],
watch_options: {
followSymlinks: false,
}
},
(error) => {
if (error) {
console.error(`Error starting PM2 process: ${error.message}`);
reject(error);
} else {
console.log(`PM2 process for config.json started successfully.`);
resolve();
}
pm2.disconnect();
}
);
}
});
});
}
async function sleep(millis) {
return new Promise(resolve => setTimeout(resolve, millis));
}
async function runGetUsers() {
uniqueIps.clear();
const filePath = '/usr/local/x-ui/access.log';
getSystemUsage()
const data = await readFiles(filePath, 'utf8');
const regex = /(\d+\.\d+\.\d+\.\d+):\d+ accepted/g;
let match;
while ((match = regex.exec(data)) !== null) {
uniqueIps.add(match[1]);
}
await writeFile(filePath, ''); // Clear the file after reading
try {
sendUsageData(cpuUser, freeRAM, uptime, networkUsage.rx, networkUsage.tx);
}
catch (e)
{
}
// Log the unique IPs or handle them as needed
}
async function updateFirewall() {
let blockedIps = await getAllBlockIpRanges();
// Add rules for each blocked IP to DROP packets
for (const ip of blockedIps) {
child_process.execSync(`sudo iptables -A INPUT -s ${ip.ip} -j DROP`);
child_process.execSync(`sudo iptables -A OUTPUT -d ${ip.ip} -j DROP`);
}
}
async function getSystemUsage() {
try {
await getSystemInfo()
networkUsage = await getNetworkUsage();
uptime = getUptime()
// sendUsageData(cpuUsage, ramUsage, uptime, networkUsage.rx, networkUsage.tx);
} catch (error) {
// console.log(error)
console.log(`Error: ${error}`);
}
}
async function getSystemInfo() {
const command = `
top -bn1 | awk '
/Cpu\\(s\\)/ { cpu = $2 }
/MiB Mem/ {
total = $4
free = $8
used = total - free
}
END {
printf "{ \\"cpu_user\\": %.1f, \\"total_mem\\": %.1f, \\"used_mem\\": %.1f, \\"free_mem\\": %.1f }", cpu, total, used, free
}'`;
try {
const { stdout, stderr } = await execAsync(command);
if (stderr) {
throw new Error(stderr);
}
// Parse the JSON output
const systemInfo = JSON.parse(stdout);
// Assign to variables
cpuUser = systemInfo.cpu_user;
totalRAM = systemInfo.total_mem;
usedRAM = systemInfo.used_mem;
freeRAM = systemInfo.free_mem;
} catch (error) {
console.error('Error:', error.message);
}
}
async function reboot() {
exec('sudo reboot', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
// console.error(`stderr: ${stderr}`);
});
}
function getNetworkUsage() {
return new Promise((resolve, reject) => {
shell.exec('vnstat -tr 5', {silent: true}, (code, stdout, stderr) => {
if (code !== 0) {
reject(stderr);
} else {
const lines = stdout.trim().split('\n');
const rxLine = lines.find(line => line.trim().startsWith('rx'));
const txLine = lines.find(line => line.trim().startsWith('tx'));
let rx = parseFloat(rxLine.split(/\s+/)[2]);
let tx = parseFloat(txLine.split(/\s+/)[2]);
const rxUnit = rxLine.split(/\s+/)[3];
const txUnit = txLine.split(/\s+/)[3];
// Convert to MB if unit is KB
if (rxUnit.toLowerCase() === 'kbit/s') {
rx /= 1024;
}
if (txUnit.toLowerCase() === 'kbit/s') {
tx /= 1024;
}
// If rx or tx is less than 1, set it to 1
rx = rx < 1 ? 1 : rx;
tx = tx < 1 ? 1 : tx;
if (txUnit.toLowerCase() === 'bit/s') {
tx = 1;
rx = 1;
}
resolve({rx: rx.toFixed(2), tx: tx.toFixed(2)});
}
});
});
}
function getUptime() {
const uptime = os.uptime();
return (uptime / 86400).toFixed(2); // Convert to days
}
async function getConfig() {
try {
const response = await axios.get(`${BASE_URL}/getXrayConfig`, {
params: {
},
timeout: 30000
});
return response.data;
} catch (error) {
throw error;
}
}
async function getAccByIp() {
try {
const response = await axios.get(`${BASE_URL}/getAccByIP`, {timeout: 30000});
return response.data;
} catch (error) {
throw error
}
}
async function sendUsageData(cpu, ram, uptime, rx, tx) {
try {
const response = await axios.get(`${BASE_URL}/vUsage`, {
params: {
cpu: cpu,
ram: ram,
uptime: uptime,
rx: rx,
tx: tx
},
timeout: 3000
});
return
} catch (error) {
console.log('Error sending usage data:', error);
return null;
}
}
async function getAllBlockIpRanges() {
try {
const response = await axios.get(`${BASE_URL}/getAllBlockIpRanges`, {timeout: 30000});
return response.data;
} catch (error) {
throw error
}
}
main()
updateFirewall()
cron.schedule(' */1 * * * *', main);
cronIpToRedis.schedule(' */1 * * * *', runGetUsers);
//cronServiceCheck.schedule('*/5 * * * * *', firewallUpdater);
{
"name": "ray",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^1.7.2",
"express": "^4.19.2",
"node-cron": "^3.0.3",
"pm2": "^5.4.1",
"shelljs": "^0.8.5"
}
}
File added
const { exec } = require('child_process');
const path = require('path');
class XrayStarter {
constructor() {
this.command = './xray';
this.cwd = '/usr/local/x-ui';
}
isProcessRunning(configName) {
return new Promise((resolve) => {
const searchCommand = `sudo ps aux | grep "${configName}" | grep -v grep`;
exec(searchCommand, (error, stdout) => {
if (stdout) {
console.log('Process',configName,'found')
resolve(true); // Process found
} else {
console.log('Process',configName,'not found')
resolve(false); // Process not found
}
});
});
}
killProcesses(configName) {
return new Promise((resolve, reject) => {
const killCommand = `sudo pkill -f "${configName}"`;
exec(killCommand, (error) => {
if (error) {
reject(`Error killing processes for ${configName}: ${error.message}`);
} else {
resolve();
}
});
});
}
async restart(configName) {
try {
// console.log(`Xray process for ${configName} is already running. Killing it...`);
await this.killProcesses(configName);
// console.log(`Killed processes for ${configName}.`);
// console.log(`Restarted Xray process for ${configName} in the background.`);
} catch (error) {
console.error(`Error while restarting Xray process for ${configName}: ${error}`);
}
await this.start(configName);
console.log('Service Restarted')
}
start(configName) {
// const configFilePath = path.join(this.cwd, configName);
// Start Xray in the background and silently using exec
let commandStr = `cd /usr/local/x-ui/ && sudo ./xray run -c ${configName} > /dev/null 2>&1 &`;
if (configName ==='config1000.json')
commandStr = `sudo /usr/local/x-ui/xray2 run -c ${configName} > /dev/null 2>&1 &`;
exec(commandStr, { cwd: this.cwd }, (error) => {
if (error) {
console.error(`Error starting Xray process: ${error.message}`);
} else {
console.log(`Started Xray process for ${configName} in the background.`);
}
});
}
}
module.exports = XrayStarter;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment