vpn_based_remote_access_system
Version:
毕设:基于OpenVPN的远程访问系统
205 lines (183 loc) • 7.88 kB
JavaScript
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}.`);
}
}
};