UNPKG

vpn_based_remote_access_system

Version:

毕设:基于OpenVPN的远程访问系统

205 lines (183 loc) 7.88 kB
const http = require('http'); const url = require('url'); const net = require('net'); const fs = require('fs'); const sqlite3 = require('sqlite3').verbose(); const { logInfo, logError } = require('./logs')('Proxy'); const db = new sqlite3.Database('./users.db', sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => { if (err) { logError(err.message); } }); // ���������ļ� const config = JSON.parse(fs.readFileSync('config.json', 'utf8')); class ProxyServer { constructor(port, duration = 1, isCheckUserIp = false) { this.port = port; // Ϊ�û�����Ķ˿� this.duration = duration; // �������Ŀ���ʱ�����Է���Ϊ��λ this.isCheckUserIp = isCheckUserIp; // �Ƿ����û� IP����Ϊ true����ÿ������������������������ݿ��е��Ƿ�һ�� //this.username = ''; // �û��������ֶ������� this.connections = new Set(); this.server = http.createServer(this.requestListener.bind(this, port)); this.server.on('connection', this.connectionListener.bind(this)); this.server.on('connect', this.connectListener.bind(this, port)); } requestListener(port, req, res) { const clientIP = req.socket.remoteAddress; // ��ȡ�û� IP /*const ipSelectQuery = `SELECT ip FROM user_ips WHERE port = ?`; db.get(ipSelectQuery, [port], (selectErr, ipRow) => { if (selectErr) { return logError(selectErr.message); } console.log(ipRow.ip); // ����û� IP �����ݿ����Ƿ�һ�£���һ���򷵻ش��� if (this.isCheckUserIp && ipRow.ip !== clientIP) { logError(`Connection from ${clientIP} rejected, because it does not match to the record: ${ipRow.ip}.`); res.writeHead(403); res.end('Access denied'); return; } });*/ logInfo(`HTTP request from ${clientIP}: ${req.method} ${req.url}`); const { hostname, path } = url.parse(req.url); const proxyReq = http.request({ hostname, port: config.forwardPort, // ʹ�������ļ��е�ת���˿� path, method: req.method, headers: req.headers, }, (proxyRes) => { logInfo(`HTTP response: ${proxyRes.statusCode}`); res.writeHead(proxyRes.statusCode, proxyRes.headers); proxyRes.pipe(res); }); req.pipe(proxyReq); } connectionListener(socket) { this.connections.add(socket); socket.on('close', () => { this.connections.delete(socket); }); } // ���� TCP ���� connectListener(port, req, cltSocket, head) { const clientIP = req.socket.remoteAddress; // ��ȡ�û� IP const ipSelectQuery = `SELECT ip FROM user_ips WHERE port = ?`; db.get(ipSelectQuery, [port], (selectErr, ipRow) => { if (selectErr) { logError(selectErr.message); cltSocket.write('HTTP/1.1 500 Internal Server Error\r\n\r\n'); cltSocket.end(); return; } // ����û� IP �����ݿ����Ƿ�һ�£���һ���򷵻ش��� if (this.isCheckUserIp && ipRow.ip !== clientIP) { //console.error('Access denied'); logError(`Connection from ${clientIP} rejected, because it does not match to the record: ${ipRow.ip}.`); cltSocket.write('HTTP/1.1 403 Forbidden\r\n\r\n'); cltSocket.end(); return; } }); const { hostname } = url.parse(`http://${req.url}`); const srvSocket = net.connect(config.forwardPort, hostname, () => { cltSocket.write('HTTP/1.1 200 Connection Established\r\nProxy-agent: Node.js-Proxy\r\n\r\n'); srvSocket.write(head); srvSocket.pipe(cltSocket); cltSocket.pipe(srvSocket); }); // �ͻ����׽��ִ��󣬱������ǿͻ��������ж����ӣ������־�в����� cltSocket.on('error', err => { logInfo(`Client has interrupted the connection.`); srvSocket.end(); cltSocket.end(); }); srvSocket.on('error', err => { logInfo(`Server has interrupted the connection.`); cltSocket.end(); srvSocket.end(); }); } startServer() { return new Promise((resolve, reject) => { if (!this.server.listening) { // ��������ʼ���� this.server.listen(this.port, () => { logInfo(`HTTP proxy server is listening on port ${this.port} now.`); updateServerRunningStatus(this.port, 1); // �����ɹ����������ݱ��ڵķ�����״̬Ϊ 1 if (this.duration > 0) { setTimeout(() => { this.shutdownServer(); logInfo(`Server on port ${this.port} has shut down after ${this.duration} minutes.`); }, this.duration * 60 * 1000); // ��ʱ } resolve(); // �ɹ��������� Promise }); // ���������¼����ڳ���ʱ�ܾ� Promise this.server.on('error', (error) => { logError(`Server failed to start: ${error.message}`); reject(error); // �������������ʧ�ܣ���ܾ� Promise }); } else { logInfo(`Server is already listening on port ${this.port}.`); resolve(); // ����������Ѿ��ڼ�������ֱ�ӽ�� Promise } }); } shutdownServer() { this.server.close(() => { logInfo(`HTTP server on port ${this.port} closed.`); updateServerRunningStatus(this.port, 0); // �������رգ��������ݱ��ڵķ�����״̬Ϊ 0 removeServer(this); // ���������Ƴ���ʵ�� }); for (const socket of this.connections) { socket.destroy(); } } } // �������ݿ��ֶ� isServerRunning ��״̬����֪Ϊ�θ��²��� function updateServerRunningStatus(port, status) { db.run(`UPDATE user_ips SET isServerRunning = ? WHERE port = ?`, [status, port], (err) => { if (err) { logError(`Failed to update server running status: ${err.message}`); } else { logInfo(`Server running on port ${port} has changed its status to ${status}.`); } }); } // ��servers�������Ƴ�ָ���ķ�����ʵ�� function removeServer(serverInstance) { const index = servers.findIndex(server => server === serverInstance); if (index !== -1) { servers.splice(index, 1); logInfo(`Server on port ${serverInstance.port} removed from the server list.`); } } // ͨ���˿ںŹرշ����� let servers = []; module.exports = { ProxyServer, addServer: function (server) { servers.push(server); }, getServersList: function () { return servers; }, searchServerByPort: function searchServerByPort(port) { return servers.find(server => server.port === port) || null; }, stopAllServers: function () { servers.forEach(server => server.shutdownServer()); servers = []; }, stopServerByPort: function stopServerByPort(port) { const index = servers.findIndex(server => server.port === port); if (index !== -1) { servers[index].shutdownServer(); // ֹͣ������ servers.splice(index, 1); // ���������Ƴ��÷����� logInfo(`Proxy server on port ${port} has been shut down.`); } else { logInfo(`No proxy server found on port ${port}.`); } } };